]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/plugin/MediawikiTable.php
private --> protected
[SourceForge/phpwiki.git] / lib / plugin / MediawikiTable.php
1 <?php
2
3 /*
4  * Copyright (C) 2003 Sameer D. Sahasrabuddhe
5  * Copyright (C) 2005 $ThePhpWikiProgrammingTeam
6  * Copyright (C) 2008-2010 Marc-Etienne Vargenau, Alcatel-Lucent
7  *
8  * This file is part of PhpWiki.
9  *
10  * PhpWiki is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * PhpWiki is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License along
21  * with PhpWiki; if not, write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 */
24
25 /*
26  * Standard Alcatel-Lucent disclaimer for contributing to open source
27  *
28  * "The MediawikiTablePlugin ("Contribution") has not been tested and/or
29  * validated for release as or in products, combinations with products or
30  * other commercial use. Any use of the Contribution is entirely made at
31  * the user's own responsibility and the user can not rely on any features,
32  * functionalities or performances Alcatel-Lucent has attributed to the
33  * Contribution.
34  *
35  * THE CONTRIBUTION BY ALCATEL-LUCENT IS PROVIDED AS IS, WITHOUT WARRANTY
36  * OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
37  * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, COMPLIANCE,
38  * NON-INTERFERENCE AND/OR INTERWORKING WITH THE SOFTWARE TO WHICH THE
39  * CONTRIBUTION HAS BEEN MADE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
40  * ALCATEL-LUCENT BE LIABLE FOR ANY DAMAGES OR OTHER LIABLITY, WHETHER IN
41  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
42  * CONTRIBUTION OR THE USE OR OTHER DEALINGS IN THE CONTRIBUTION, WHETHER
43  * TOGETHER WITH THE SOFTWARE TO WHICH THE CONTRIBUTION RELATES OR ON A STAND
44  * ALONE BASIS."
45  */
46
47 /**
48  * MediawikiTablePlugin
49  * A PhpWiki plugin that allows insertion of tables using a Mediawiki-like
50  * syntax.
51  */
52 class WikiPlugin_MediawikiTable
53     extends WikiPlugin
54 {
55     function getName()
56     {
57         return _("MediawikiTable");
58     }
59
60     function getDescription()
61     {
62         return _("Layout tables using a Mediawiki-like markup style.");
63     }
64
65     function getDefaultArguments()
66     {
67         return array();
68     }
69
70     function run($dbi, $argstr, &$request, $basepage)
71     {
72         include_once 'lib/BlockParser.php';
73         // MediawikiTablePlugin markup is new.
74         $markup = 2.0;
75
76         // We allow the compact Mediawiki syntax with:
77         // - multiple cells on the same line (separated by "||"),
78         // - multiple header cells on the same line (separated by "!!").
79         $argstr = str_replace("||", "\n| ", $argstr);
80         $argstr = str_replace("!!", "\n! ", $argstr);
81
82         $lines = explode("\n", $argstr);
83
84         $table = HTML::table();
85         $caption = HTML::caption();
86         $thead = HTML::thead();
87         $tbody = HTML::tbody();
88
89         // Do we need a <thead>?
90         // 0 = unknown
91         // 1 = inside (parsing cells)
92         // 2 = false (no thead, only tbody)
93         // 3 = true (there is a thead)
94         $theadstatus = 0;
95
96         // We always generate an Id for the table.
97         // This is convenient for tables of class "sortable".
98         // If user provides an Id, the generated Id will be overwritten below.
99         $table->setAttr("id", GenerateId("MediawikiTable"));
100
101         if (substr($lines[0], 0, 2) == "{|") {
102             // Start of table
103             $lines[0] = substr($lines[0], 2);
104         }
105         if (($lines[0][0] != '|') and ($lines[0][0] != '!')) {
106             $line = array_shift($lines);
107             $attrs = parse_attributes($line);
108             foreach ($attrs as $key => $value) {
109                 if (in_array($key, array("id", "class", "title", "style",
110                     "bgcolor", "frame", "rules", "border",
111                     "cellspacing", "cellpadding",
112                     "summary", "align", "width"))
113                 ) {
114                     $table->setAttr($key, $value);
115                 }
116             }
117         }
118
119         if (count($lines) == 1) { // empty table, we only have closing "|}" line
120             return HTML::raw('');
121         }
122
123         foreach ($lines as $line) {
124             if (substr($line, 0, 2) == "|}") {
125                 // End of table
126                 continue;
127             }
128             if (substr($line, 0, 2) == "|-") {
129                 if (isset($row)) {
130                     if (isset($cell)) {
131                         if (isset($content)) {
132                             if (is_numeric(trim($content))) {
133                                 $cell->pushContent(HTML::p(array('style' => "text-align:right"), trim($content)));
134                             } else {
135                                 $cell->pushContent(TransformText(trim($content), $markup, $basepage));
136                             }
137                             unset($content);
138                         }
139                         $row->pushContent($cell);
140                         unset($cell);
141                     }
142                     if (!empty($row->_content)) {
143                         if ($theadstatus == 1) { // inside
144                             $theadstatus = 3; // true
145                             $thead->pushContent($row);
146                         } else {
147                             $tbody->pushContent($row);
148                         }
149                     }
150                 }
151                 $row = HTML::tr();
152                 $attrs = parse_attributes(substr($line, 2));
153                 foreach ($attrs as $key => $value) {
154                     if (in_array($key, array("id", "class", "title", "style",
155                         "bgcolor", "align", "valign"))
156                     ) {
157                         $row->setAttr($key, $value);
158                     }
159                 }
160                 continue;
161             }
162
163             // Table summary
164             if (substr($line, 0, 2) == "|=") {
165                 $line = substr($line, 2);
166                 $table->setAttr("summary", trim($line));
167             }
168
169             // Table caption
170             if (substr($line, 0, 2) == "|+") {
171
172                 $line = substr($line, 2);
173                 $pospipe = strpos($line, "|");
174                 $posbracket = strpos($line, "[");
175                 if (($pospipe !== false) && (($posbracket === false) || ($posbracket > $pospipe))) {
176                     $attrs = parse_attributes(substr($line, 0, $pospipe));
177                     foreach ($attrs as $key => $value) {
178                         if (in_array($key, array("id", "class", "title", "style",
179                             "align", "lang"))
180                         ) {
181                             $caption->setAttr($key, $value);
182                         }
183                     }
184                     $line = substr($line, $pospipe + 1);
185                 }
186
187                 $caption->setContent(TransformInline(trim($line)));
188             }
189
190             if (((substr($line, 0, 1) == "|") or (substr($line, 0, 1) == "!")) and isset($row)) {
191                 if (isset($cell)) {
192                     if (isset ($content)) {
193                         if (is_numeric(trim($content))) {
194                             $cell->pushContent(HTML::p(array('style' => "text-align:right"), trim($content)));
195                         } else {
196                             $cell->pushContent(TransformText(trim($content), $markup, $basepage));
197                         }
198                         unset($content);
199                     }
200                     $row->pushContent($cell);
201                 }
202                 if (substr($line, 0, 1) == "!") {
203                     if ($theadstatus == 0) { // unknown
204                         $theadstatus = 1; // inside
205                     }
206                     $cell = HTML::th(); // Header
207                 } else {
208                     if ($theadstatus == 1) { // inside
209                         $theadstatus = 2; // false
210                     }
211                     $cell = HTML::td();
212                 }
213                 $line = substr($line, 1);
214
215                 // If there is a "|" in the line, the start of line
216                 // (before the "|") is made of attributes.
217                 // The end of the line (after the "|") is the cell content
218                 // This is not true if the pipe is inside [], {{}} or {{{}}}
219                 // | [foo|bar]
220                 // The following cases must work:
221                 // | foo
222                 // | [foo|bar]
223                 // | class="xxx" | foo
224                 // | class="xxx" | [foo|bar]
225                 // | {{tmpl|arg=val}}
226                 // | {{image.png|alt}}
227                 // | {{{ xxx | yyy }}}
228                 $pospipe = strpos($line, "|");
229                 $posbracket = strpos($line, "[");
230                 $poscurly = strpos($line, "{");
231                 if (($pospipe !== false) && (($posbracket === false) || ($posbracket > $pospipe)) && (($poscurly === false) || ($poscurly > $pospipe))) {
232                     $attrs = parse_attributes(substr($line, 0, $pospipe));
233                     foreach ($attrs as $key => $value) {
234                         if (in_array($key, array("id", "class", "title", "style", "scope",
235                             "colspan", "rowspan", "width", "height",
236                             "bgcolor", "align", "valign"))
237                         ) {
238                             $cell->setAttr($key, $value);
239                         }
240                     }
241                     $line = substr($line, $pospipe + 1);
242                     if (is_numeric(trim($line))) {
243                         $cell->pushContent(HTML::p(array('style' => "text-align:right"), trim($line)));
244                     } else {
245                         $cell->pushContent(TransformText(trim($line), $markup, $basepage));
246                     }
247                     continue;
248                 }
249             }
250             if (isset($row) and isset($cell)) {
251                 $line = str_replace("?\>", "?>", $line);
252                 $line = str_replace("\~", "~", $line);
253                 if (empty($content)) $content = '';
254                 $content .= $line . "\n";
255             }
256         }
257         if (isset($row)) {
258             if (isset($cell)) {
259                 if (isset($content)) {
260                     if (is_numeric(trim($content))) {
261                         $cell->pushContent(HTML::p(array('style' => "text-align:right"), trim($content)));
262                     } else {
263                         $cell->pushContent(TransformText(trim($content), $markup, $basepage));
264                     }
265
266                 }
267                 $row->pushContent($cell);
268             }
269             // If user put and extra "|-" without cells just before "|}"
270             // we ignore it to get valid XHTML code
271             if (!empty($row->_content)) {
272                 $tbody->pushContent($row);
273             }
274         }
275         if (!empty($caption->_content)) {
276             $table->pushContent($caption);
277         }
278         if (!empty($thead->_content)) {
279             $table->pushContent($thead);
280         }
281         if (!empty($tbody->_content)) {
282             $table->pushContent($tbody);
283         }
284         if (!empty($table->_content)) {
285             return $table;
286         } else {
287             return HTML::raw('');
288         }
289     }
290 }
291
292 // Local Variables:
293 // mode: php
294 // tab-width: 8
295 // c-basic-offset: 4
296 // c-hanging-comment-ender-p: nil
297 // indent-tabs-mode: nil
298 // End: