4 * Copyright (C) 2003 Sameer D. Sahasrabuddhe
5 * Copyright (C) 2005 $ThePhpWikiProgrammingTeam
6 * Copyright (C) 2008-2010 Marc-Etienne Vargenau, Alcatel-Lucent
8 * This file is part of PhpWiki.
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.
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.
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.
26 * Standard Alcatel-Lucent disclaimer for contributing to open source
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
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
48 * MediawikiTablePlugin
49 * A PhpWiki plugin that allows insertion of tables using a Mediawiki-like
52 class WikiPlugin_MediawikiTable
57 return _("MediawikiTable");
60 function getDescription()
62 return _("Layout tables using a Mediawiki-like markup style.");
65 function getDefaultArguments()
70 function run($dbi, $argstr, &$request, $basepage)
72 include_once 'lib/BlockParser.php';
73 // MediawikiTablePlugin markup is new.
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);
82 $lines = explode("\n", $argstr);
84 $table = HTML::table();
85 $caption = HTML::caption();
86 $thead = HTML::thead();
87 $tbody = HTML::tbody();
89 // Do we need a <thead>?
91 // 1 = inside (parsing cells)
92 // 2 = false (no thead, only tbody)
93 // 3 = true (there is a thead)
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"));
101 if (substr($lines[0], 0, 2) == "{|") {
103 $lines[0] = substr($lines[0], 2);
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"))
114 $table->setAttr($key, $value);
119 if (count($lines) == 1) { // empty table, we only have closing "|}" line
120 return HTML::raw('');
123 foreach ($lines as $line) {
124 if (substr($line, 0, 2) == "|}") {
128 if (substr($line, 0, 2) == "|-") {
131 if (isset($content)) {
132 if (is_numeric(trim($content))) {
133 $cell->pushContent(HTML::p(array('style' => "text-align:right"), trim($content)));
135 $cell->pushContent(TransformText(trim($content), $markup, $basepage));
139 $row->pushContent($cell);
142 if (!empty($row->_content)) {
143 if ($theadstatus == 1) { // inside
144 $theadstatus = 3; // true
145 $thead->pushContent($row);
147 $tbody->pushContent($row);
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"))
157 $row->setAttr($key, $value);
164 if (substr($line, 0, 2) == "|=") {
165 $line = substr($line, 2);
166 $table->setAttr("summary", trim($line));
170 if (substr($line, 0, 2) == "|+") {
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",
181 $caption->setAttr($key, $value);
184 $line = substr($line, $pospipe + 1);
187 $caption->setContent(TransformInline(trim($line)));
190 if (((substr($line, 0, 1) == "|") or (substr($line, 0, 1) == "!")) and isset($row)) {
192 if (isset ($content)) {
193 if (is_numeric(trim($content))) {
194 $cell->pushContent(HTML::p(array('style' => "text-align:right"), trim($content)));
196 $cell->pushContent(TransformText(trim($content), $markup, $basepage));
200 $row->pushContent($cell);
202 if (substr($line, 0, 1) == "!") {
203 if ($theadstatus == 0) { // unknown
204 $theadstatus = 1; // inside
206 $cell = HTML::th(); // Header
208 if ($theadstatus == 1) { // inside
209 $theadstatus = 2; // false
213 $line = substr($line, 1);
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 {{{}}}
220 // The following cases must work:
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"))
238 $cell->setAttr($key, $value);
241 $line = substr($line, $pospipe + 1);
242 if (is_numeric(trim($line))) {
243 $cell->pushContent(HTML::p(array('style' => "text-align:right"), trim($line)));
245 $cell->pushContent(TransformText(trim($line), $markup, $basepage));
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";
259 if (isset($content)) {
260 if (is_numeric(trim($content))) {
261 $cell->pushContent(HTML::p(array('style' => "text-align:right"), trim($content)));
263 $cell->pushContent(TransformText(trim($content), $markup, $basepage));
267 $row->pushContent($cell);
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);
275 if (!empty($caption->_content)) {
276 $table->pushContent($caption);
278 if (!empty($thead->_content)) {
279 $table->pushContent($thead);
281 if (!empty($tbody->_content)) {
282 $table->pushContent($tbody);
284 if (!empty($table->_content)) {
287 return HTML::raw('');
296 // c-hanging-comment-ender-p: nil
297 // indent-tabs-mode: nil