]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/plugin/MediawikiTable.php
getName should not translate
[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 getDescription()
56     {
57         return _("Layout tables using a Mediawiki-like markup style.");
58     }
59
60     function getDefaultArguments()
61     {
62         return array();
63     }
64
65     function run($dbi, $argstr, &$request, $basepage)
66     {
67         include_once 'lib/BlockParser.php';
68         // MediawikiTablePlugin markup is new.
69         $markup = 2.0;
70
71         // We allow the compact Mediawiki syntax with:
72         // - multiple cells on the same line (separated by "||"),
73         // - multiple header cells on the same line (separated by "!!").
74         $argstr = str_replace("||", "\n| ", $argstr);
75         $argstr = str_replace("!!", "\n! ", $argstr);
76
77         $lines = explode("\n", $argstr);
78
79         $table = HTML::table();
80         $caption = HTML::caption();
81         $thead = HTML::thead();
82         $tbody = HTML::tbody();
83
84         // Do we need a <thead>?
85         // 0 = unknown
86         // 1 = inside (parsing cells)
87         // 2 = false (no thead, only tbody)
88         // 3 = true (there is a thead)
89         $theadstatus = 0;
90
91         // We always generate an Id for the table.
92         // This is convenient for tables of class "sortable".
93         // If user provides an Id, the generated Id will be overwritten below.
94         $table->setAttr("id", GenerateId("MediawikiTable"));
95
96         if (substr($lines[0], 0, 2) == "{|") {
97             // Start of table
98             $lines[0] = substr($lines[0], 2);
99         }
100         if (($lines[0][0] != '|') and ($lines[0][0] != '!')) {
101             $line = array_shift($lines);
102             $attrs = parse_attributes($line);
103             foreach ($attrs as $key => $value) {
104                 if (in_array($key, array("id", "class", "title", "style",
105                     "bgcolor", "frame", "rules", "border",
106                     "cellspacing", "cellpadding",
107                     "summary", "align", "width"))
108                 ) {
109                     $table->setAttr($key, $value);
110                 }
111             }
112         }
113
114         if (count($lines) == 1) { // empty table, we only have closing "|}" line
115             return HTML::raw('');
116         }
117
118         foreach ($lines as $line) {
119             if (substr($line, 0, 2) == "|}") {
120                 // End of table
121                 continue;
122             }
123             if (substr($line, 0, 2) == "|-") {
124                 if (isset($row)) {
125                     if (isset($cell)) {
126                         if (isset($content)) {
127                             if (is_numeric(trim($content))) {
128                                 $cell->pushContent(HTML::p(array('style' => "text-align:right"), trim($content)));
129                             } else {
130                                 $cell->pushContent(TransformText(trim($content), $markup, $basepage));
131                             }
132                             unset($content);
133                         }
134                         $row->pushContent($cell);
135                         unset($cell);
136                     }
137                     if (!empty($row->_content)) {
138                         if ($theadstatus == 1) { // inside
139                             $theadstatus = 3; // true
140                             $thead->pushContent($row);
141                         } else {
142                             $tbody->pushContent($row);
143                         }
144                     }
145                 }
146                 $row = HTML::tr();
147                 $attrs = parse_attributes(substr($line, 2));
148                 foreach ($attrs as $key => $value) {
149                     if (in_array($key, array("id", "class", "title", "style",
150                         "bgcolor", "align", "valign"))
151                     ) {
152                         $row->setAttr($key, $value);
153                     }
154                 }
155                 continue;
156             }
157
158             // Table summary
159             if (substr($line, 0, 2) == "|=") {
160                 $line = substr($line, 2);
161                 $table->setAttr("summary", trim($line));
162             }
163
164             // Table caption
165             if (substr($line, 0, 2) == "|+") {
166
167                 $line = substr($line, 2);
168                 $pospipe = strpos($line, "|");
169                 $posbracket = strpos($line, "[");
170                 if (($pospipe !== false) && (($posbracket === false) || ($posbracket > $pospipe))) {
171                     $attrs = parse_attributes(substr($line, 0, $pospipe));
172                     foreach ($attrs as $key => $value) {
173                         if (in_array($key, array("id", "class", "title", "style",
174                             "align", "lang"))
175                         ) {
176                             $caption->setAttr($key, $value);
177                         }
178                     }
179                     $line = substr($line, $pospipe + 1);
180                 }
181
182                 $caption->setContent(TransformInline(trim($line)));
183             }
184
185             if (((substr($line, 0, 1) == "|") or (substr($line, 0, 1) == "!")) and isset($row)) {
186                 if (isset($cell)) {
187                     if (isset ($content)) {
188                         if (is_numeric(trim($content))) {
189                             $cell->pushContent(HTML::p(array('style' => "text-align:right"), trim($content)));
190                         } else {
191                             $cell->pushContent(TransformText(trim($content), $markup, $basepage));
192                         }
193                         unset($content);
194                     }
195                     $row->pushContent($cell);
196                 }
197                 if (substr($line, 0, 1) == "!") {
198                     if ($theadstatus == 0) { // unknown
199                         $theadstatus = 1; // inside
200                     }
201                     $cell = HTML::th(); // Header
202                 } else {
203                     if ($theadstatus == 1) { // inside
204                         $theadstatus = 2; // false
205                     }
206                     $cell = HTML::td();
207                 }
208                 $line = substr($line, 1);
209
210                 // If there is a "|" in the line, the start of line
211                 // (before the "|") is made of attributes.
212                 // The end of the line (after the "|") is the cell content
213                 // This is not true if the pipe is inside [], {{}} or {{{}}}
214                 // | [foo|bar]
215                 // The following cases must work:
216                 // | foo
217                 // | [foo|bar]
218                 // | class="xxx" | foo
219                 // | class="xxx" | [foo|bar]
220                 // | {{tmpl|arg=val}}
221                 // | {{image.png|alt}}
222                 // | {{{ xxx | yyy }}}
223                 $pospipe = strpos($line, "|");
224                 $posbracket = strpos($line, "[");
225                 $poscurly = strpos($line, "{");
226                 if (($pospipe !== false) && (($posbracket === false) || ($posbracket > $pospipe)) && (($poscurly === false) || ($poscurly > $pospipe))) {
227                     $attrs = parse_attributes(substr($line, 0, $pospipe));
228                     foreach ($attrs as $key => $value) {
229                         if (in_array($key, array("id", "class", "title", "style", "scope",
230                             "colspan", "rowspan", "width", "height",
231                             "bgcolor", "align", "valign"))
232                         ) {
233                             $cell->setAttr($key, $value);
234                         }
235                     }
236                     $line = substr($line, $pospipe + 1);
237                     if (is_numeric(trim($line))) {
238                         $cell->pushContent(HTML::p(array('style' => "text-align:right"), trim($line)));
239                     } else {
240                         $cell->pushContent(TransformText(trim($line), $markup, $basepage));
241                     }
242                     continue;
243                 }
244             }
245             if (isset($row) and isset($cell)) {
246                 $line = str_replace("?\>", "?>", $line);
247                 $line = str_replace("\~", "~", $line);
248                 if (empty($content)) $content = '';
249                 $content .= $line . "\n";
250             }
251         }
252         if (isset($row)) {
253             if (isset($cell)) {
254                 if (isset($content)) {
255                     if (is_numeric(trim($content))) {
256                         $cell->pushContent(HTML::p(array('style' => "text-align:right"), trim($content)));
257                     } else {
258                         $cell->pushContent(TransformText(trim($content), $markup, $basepage));
259                     }
260
261                 }
262                 $row->pushContent($cell);
263             }
264             // If user put and extra "|-" without cells just before "|}"
265             // we ignore it to get valid XHTML code
266             if (!empty($row->_content)) {
267                 $tbody->pushContent($row);
268             }
269         }
270         if (!empty($caption->_content)) {
271             $table->pushContent($caption);
272         }
273         if (!empty($thead->_content)) {
274             $table->pushContent($thead);
275         }
276         if (!empty($tbody->_content)) {
277             $table->pushContent($tbody);
278         }
279         if (!empty($table->_content)) {
280             return $table;
281         } else {
282             return HTML::raw('');
283         }
284     }
285 }
286
287 // Local Variables:
288 // mode: php
289 // tab-width: 8
290 // c-basic-offset: 4
291 // c-hanging-comment-ender-p: nil
292 // indent-tabs-mode: nil
293 // End: