CVS update: /cowiki/includes/cowiki/class/parse/

[email protected] 21 Mar 2005 16:45:50 -0000
Newsgroups gmane.comp.php.cowiki.cvs
Message-ID <[email protected]>
User: cmarble 
Date: 05/03/21 08:45:50

Modified:
 /cowiki/includes/cowiki/class/parse/
  class.WikiParser.php, class.WikiReverseParser.php

Log:
 Issue number:  198
 Obtained from: 
 Submitted by:  cmarble
 Reviewed by:   
 
 New table syntax (see my posts to cowiki-dev).
 
 Bullets may be used within table if the syntax is used thus...
 
 <table>
 |-                  new table row
 |cellparam|         new cell with HTML parameters
 cell text           cell content, on consecutive lines until pipe
 * list              is found at first character on line
 |-
 etc...
 </table>
 
 Unfortunately, there is a heisenbug in the xmldoc target, which
 I'm adding to the issue tracker... #211.

File Changes:

Directory: /cowiki/includes/cowiki/class/parse/
===============================================

File [changed]: class.WikiParser.php
Url: http://cowiki.tigris.org/source/browse/cowiki/includes/cowiki/class/parse/class.WikiParser.php?r1=1.43&r2=1.44
Delta lines:  +174 -188
-----------------------
--- class.WikiParser.php	19 Mar 2005 13:25:10 -0000	1.43
+++ class.WikiParser.php	21 Mar 2005 16:45:50 -0000	1.44
@@ -2,7 +2,7 @@
 
 /**
  *
- * $Id: class.WikiParser.php,v 1.43 2005/03/19 13:25:10 kscr Exp $
+ * $Id: class.WikiParser.php,v 1.44 2005/03/21 16:45:50 cmarble Exp $
  *
  * This file is part of coWiki. coWiki is free software under the terms of
  * the GNU General Public License (GPL). Read the LICENSE file. If you did
@@ -21,130 +21,42 @@
  * @author      Daniel T. Gorski, <[email protected]>
  * @copyright   (C) Daniel T. Gorski, {@link http://www.develnet.org}
  * @license     http://www.gnu.org/licenses/gpl.html
- * @version     $Revision: 1.43 $
+ * @version     $Revision: 1.44 $
  *
  */
 
-/**
- * coWiki token "no operation"
- */
-define('WIKI_TOKEN_NOOP',          1);
-
-/**
- * coWiki token "preformated"
- */
-define('WIKI_TOKEN_PRE',           2);
-
-/**
- * coWiki token "source code"
- */
-define('WIKI_TOKEN_CODE',          3);
-
-/**
- * coWiki token "posting"
- */
-define('WIKI_TOKEN_POSTING',       4);
-
-/**
- * coWiki token "hyperlink"
- */
-define('WIKI_TOKEN_LINK',          5);
-
-/**
- * coWiki token "Uniform Ressource Identifier (URI)"
- */
-define('WIKI_TOKEN_URI',           6);
-
-/**
- * coWiki token "Table of Contents (ToC)"
- */
-define('WIKI_TOKEN_TOC',           7);
-
-/**
- * coWiki token "plugin with parameter(s)"
- */
-define('WIKI_TOKEN_PARAM_PLUGIN',  8);
-
-/**
- * coWiki token "plugin without parameter(s)"
- */
-define('WIKI_TOKEN_SIMPLE_PLUGIN', 9);
-
-/**
- * coWiki token "heading"
- */
-define('WIKI_TOKEN_HEADING',       10);
-
-/**
- * coWiki token "horicontal ruler"
- */
-define('WIKI_TOKEN_HR',            11);
-
-/**
- * coWiki token "list"
- */
-define('WIKI_TOKEN_LIST',          12);
-
-/**
- * coWiki token "quotation"
- */
-define('WIKI_TOKEN_QUOTE',         13);
-
-/**
- * coWiki token "system variable"
- */
-define('WIKI_TOKEN_VAR',           14);
-
-/**
- * coWiki token "line break"
- */
-define('WIKI_TOKEN_BREAK',         15);
-
-/**
- * coWiki token "table with parameter(s)"
- */
-define('WIKI_TOKEN_PARAM_TABLE',   16);
-
-/**
- * coWiki token "table without parameter(s)"
- */
-define('WIKI_TOKEN_SIMPLE_TABLE',  17);
-
-/**
- * coWiki token "remark"
- */
-define('WIKI_TOKEN_REM',           18);
-
-/**
- * coWiki token "subscript"
- */    
-define('WIKI_TOKEN_SUB',           19);
-
-/**
- * coWiki token "superscript"
- */    
-define('WIKI_TOKEN_SUP',           20);
-
-/**
- * coWiki token "justification"
- */    
-define('WIKI_TOKEN_JUSTIFICATION', 21);
-
-/**
- * coWiki token "emphasis"
- */    
-define('WIKI_TOKEN_EMPHASIS',      22);
-
+    // We should solve this with lex/yacc (flex/bison), but mass hosters
+    // usually do not allow their users to execute binaries. So let's
+    // fight this (dumb) way.
+
+    // On the other hand, the coWiki syntax is quite loose and is not easy
+    // to express by a BNF parser, IMO.
+
+    define('WIKI_TOKEN_NOOP',          1);
+    define('WIKI_TOKEN_PRE',           2);
+    define('WIKI_TOKEN_CODE',          3);
+    define('WIKI_TOKEN_POSTING',       4);
+    define('WIKI_TOKEN_LINK',          5);
+    define('WIKI_TOKEN_URI',           6);
+    define('WIKI_TOKEN_TOC',           7);
+    define('WIKI_TOKEN_PARAM_PLUGIN',  8);
+    define('WIKI_TOKEN_SIMPLE_PLUGIN', 9);
+    define('WIKI_TOKEN_HEADING',       10);
+    define('WIKI_TOKEN_HR',            11);
+    define('WIKI_TOKEN_LIST',          12);
+    define('WIKI_TOKEN_QUOTE',         13);
+    define('WIKI_TOKEN_VAR',           14);
+    define('WIKI_TOKEN_BREAK',         15);
+    define('WIKI_TOKEN_PARAM_TABLE',   16);
+    define('WIKI_TOKEN_SIMPLE_TABLE',  17);
+    define('WIKI_TOKEN_REM',           18);
+    define('WIKI_TOKEN_SUB',           19);
+    define('WIKI_TOKEN_SUP',           20);
+    define('WIKI_TOKEN_JUSTIFICATION', 21);
+    define('WIKI_TOKEN_EMPHASIS',      22);
 /**
  * coWiki - Wiki parser class
  *
- * We should solve this with lex/yacc (flex/bison), but mass hosters
- * usually do not allow their users to execute binaries. So let's
- * fight this (dumb) way.
- *
- * On the other hand, the coWiki syntax is quite loose and is not easy
- * to express by a BNF parser, IMO.
- *
  * @package     parse
  * @subpackage  class
  * @access      public
@@ -488,7 +400,7 @@
     // --------------------------------------------------------------------
 
     /**
-     * Create a <<pre>>-element
+     * Create a <pre>-element
      *
      * @access  protected
      *
@@ -502,7 +414,7 @@
     // --------------------------------------------------------------------
 
     /**
-     * Create a <<code>>-element
+     * Create a <code>-element
      *
      * @access  protected
      *
@@ -1505,7 +1417,7 @@
 
         $sStr = preg_replace_callback(
             '~  ((-{2}|[_=*/])+)
-		([^\n_=*/]+)
+		(([^\n_=*/])+)
                 ((-{2}|[_=*/])+)
             ~mix',
 	    array(&$this,'tokenizeEmphasis'),
@@ -1553,7 +1465,7 @@
 
     protected function tokenizeEmphasis(&$aMatches) {
 	//proper emphatic nesting	
-        if ($aMatches[1]==strrev($aMatches[4])) {
+        if ($aMatches[1]==strrev($aMatches[5])) {
 	    return $this->tokenize($aMatches[3],WIKI_TOKEN_EMPHASIS, $aMatches[1]);
 	} else {
 	    return $aMatches[0];
@@ -2056,75 +1968,149 @@
 
         $aRows = explode("\n", $sStr);
         $aTable = array();
+	$nHeads = 0;
+	$sRet = '';
+	$sContent = '';
+	$sTable = '';
+	$sRow = '';
+	$bPriorRow = false;
 
+	//$i = -1;
+	//$n = sizeof($aRows);
         for ($i=0, $n=sizeof($aRows); $i<$n; $i++) {
+	  //while( ++$i < $n ) {
 
-            // Row MUST start with pipe
-            if (strlen(trim($aRows[$i])) == 0 || $aRows[$i]{0} != '|') {
+            if (!strlen(trim($aRows[$i]))) {
                 return '<tr valign="top"><td colspan="1">'.$sStr.'</td></tr>';
             }
 
-            $aRows[$i] = substr($aRows[$i], 1);
-
-            // Row MAY have one (or more) trailing pipes
-            if (substr($aRows[$i], -1) == '|') {
-                $aRows[$i] = substr($aRows[$i], 0, -1);
+	    //rows expected to hold table syntax (pipes), may instead
+	    //make room for ongoing content (tables, lists, etc)
+	    $sRow = $aRows[$i]."\n";
+
+	    //find table syntax within a (long?) row
+	    while( strlen($sRow) && preg_match(
+		    '=^([\|!][-+]?)( {0,1}[^\|!\n]*)?=',
+		    $sRow,
+		    $aMatches) ) {
+
+		//found exploded row begins with pipe syntax, poss params
+		$sRow = substr( $sRow, strlen($aMatches[0]) );
+
+		$nType = 0;
+		//tables made of cells, headers, rows, caption
+		if ($aMatches[1]=="|") {
+		    $sRet .= '<td';
+		    $nType = 1;
+		}else if ($aMatches[1]=="!") {
+		    $sRet .= '<th';
+		    $nType = 2;
+		}else if ($aMatches[1]=="|-") {
+		    if ($bPriorRow) {
+		        $sRet .= "</tr>\n<tr";
+		    } else {
+			$sRet .= '<tr';
             }
-
-            // Mark and remember all <noop>s in table row
-            $this->aTblRowNoop = array();
-            $aRows[$i] = preg_replace_callback(
-                            '#(<noop>.*</noop>)#U',
-                            array(&$this, 'extractTableRowNoops'),
-                            $aRows[$i]
-                         );
-
-            // Exchange column delemiter
-            $aRows[$i] = str_replace('|', "\x02", $aRows[$i]);
-
-            // Restore <noop>s in table row
-            for ($j=0, $m=sizeof($this->aTblRowNoop); $j<$m; $j++) {
-                $aRows[$i] = preg_replace(
-                                "#\x01#",
-                                $this->aTblRowNoop[$j],
-                                $aRows[$i],
-                                1
-                             );
+		    $nType = 3;
+		    $bPriorRow = true;
+		}else if ($aMatches[1]=="|+") {
+		    $sRet .= '<caption>'.$aMatches[2]."</caption>\n";
+		    continue 1;
+		}
+
+		//content can be large, room for it here
+		$sContent = '';
+
+		if ($aMatches[2]{0}==' ') {
+		  //left a space to denote no params
+		    $sRet .= '>';
+		    $sContent .= substr($aMatches[2],1);
+		    //expect double pipe, bang or newline
+		} elseif (strlen($aMatches[2])) {
+		  //got params. look for pipe syntax that blocked last preg
+		    $sRet .= ' '.unescape($aMatches[2]).'>';
+		    if (preg_match('=^\|([^\|!\n]*)=',$sRow,$aMatches)) {
+		      //got rest of pipe syntax (...|text)
+			$sContent .= $aMatches[1];
+			$sRow = substr( $sRow, strlen($aMatches[0]) );
+		    }
+		} else {
+		    $sRet .= '>';
             }
 
-            // Divide columns
-            $aCols = explode("\x02", $aRows[$i]);
-
-            $nSpan = 0;
-            $sRow = '';
-
-            for ($j=0, $m=sizeof($aCols); $j<$m; $j++) {
-
-                if (strlen($aCols[$j]) == 0) {
-                    $nSpan++;
-                    if ($j < $m-1) {
-                        continue;
+		//look ahead now.
+		if ($sRow == "\n") {
+		  //look ahead to close our content
+		    while( ++$i<$n ){
+			$sRow = $aRows[$i];
+			//pipe syntax (will force $sContent) to continue
+			if ($sRow{0} == '|' || $sRow{0} == '!') {
+			    $sRet .= $sContent;
+			    switch($nType){
+			      case 1:
+			        $sRet .= "</td>\n";
+			        break;
+			      case 2:
+			        $sRet .= "</th>\n";
+			        break;
                     }
+			    --$i;
+			    continue 3;
+			    /*			    
+			} else if (preg_match("=^&lt;nest=i", $sRow)) {
+			    $sTable = $sRow."\n";
+			    while( ++$i < $n ){
+                                $sRow = $aRows[$i];
+			        if(preg_match("=^&lt;/nest&gt;=i", $sRow)) {
+			            $sTable .= $sRow."\n";
+				    $sTable = preg_replace("=^&lt;nest=i","&lt;table",$sTable);
+				    $sTable = preg_replace("=&lt;/nest=i","&lt;/table",$sTable);
+				    $sTable = $this->processSimpleTable( $sTable );
+				    $sTable = $this->processParamTable( $sTable );
+			            $sContent .= $this->restoreTokens( $sTable );
+			            continue 2;
+                                } else {
+				    $sTable .= $sRow."\n";
                 }
-
-                if ($nSpan) {
-                    $sRow .= '<td colspan="'.($nSpan+1).'">';
-                    $sRow .=   $aCols[$j];
-                    $sRow .= '</td>';
-                    $nSpan = 0;
-                    continue;
                 }
-
-                $sRow .= '<td colspan="1">'.$aCols[$j].'</td>';
+			    */
+			} else {
+			    //non-pipe (ever-increasing) content
+			    $sContent .= $sRow;
             }
-
-            $aTable[] = '<tr valign="top">'
-                          .$sRow
-                        .'</tr>';
         }
-
-        $sTable = join('', $aTable);
-        return $sTable;
+		    $i = $n;
+		    $sRet .= $sContent;
+		    switch($nType){
+		      case 1:
+		        $sRet .= "</td>\n";
+		        break;
+		      case 2:
+		        $sRet .= "</th>\n";
+		        break;
+		    }
+		    continue 2;
+		} elseif ( ( $sRow{0} == "|" || $sRow{0} == "!") && 
+			($sRow{1} == "|" || $sRow{1} == "!") ) {
+		    $sRow = substr($sRow, 1);
+		    $sRet .= $sContent;
+		    switch($nType){
+		      case 1:
+			$sRet .= "</td>\n";
+			break;
+		      case 2:
+			$sRet .= "</th>\n";
+			break;
+		    }
+		    continue 1;
+	        }
+	    }
+	}
+	if( $bPriorRow ) {
+	    return $sRet."</tr>";
+	} else {
+	    return $sRet;
+	}
     }
 
     // --------------------------------------------------------------------

File [changed]: class.WikiReverseParser.php
Url: http://cowiki.tigris.org/source/browse/cowiki/includes/cowiki/class/parse/class.WikiReverseParser.php?r1=1.15&r2=1.16
Delta lines:  +29 -7
--------------------
--- class.WikiReverseParser.php	15 Mar 2005 17:16:27 -0000	1.15
+++ class.WikiReverseParser.php	21 Mar 2005 16:45:50 -0000	1.16
@@ -2,7 +2,7 @@
 
 /**
  *
- * $Id: class.WikiReverseParser.php,v 1.15 2005/03/15 17:16:27 cmarble Exp $
+ * $Id: class.WikiReverseParser.php,v 1.16 2005/03/21 16:45:50 cmarble Exp $
  *
  * This file is part of coWiki. coWiki is free software under the terms of
  * the GNU General Public License (GPL). Read the LICENSE file. If you did
@@ -17,7 +17,7 @@
  * @author      Daniel T. Gorski, <[email protected]>
  * @copyright   (C) Daniel T. Gorski, {@link http://www.develnet.org}
  * @license     http://www.gnu.org/licenses/gpl.html
- * @version     $Revision: 1.15 $
+ * @version     $Revision: 1.16 $
  *
  */
 
@@ -145,8 +145,8 @@
         $sStr = $this->processSub($sStr);
 	$sStr = $this->processJustification($sStr);
         $sStr = $this->processEmphasis($sStr);
-        $sStr = $this->processList($sStr);
         $sStr = $this->processTable($sStr);
+        $sStr = $this->processList($sStr);
         $sStr = $this->processQuote($sStr);    // last one!
 
         return trim(unescape($sStr));
@@ -797,27 +797,49 @@
     protected function buildTable(&$aMatches) {
         $sStr = "\n&lt;table".$aMatches[1]."&gt;\n";
 
+	// Caption before first tr
+	if(preg_match(
+	    '=<caption>(.*)</caption>=Uis',
+	    $aMatches[2],
+	    $aCaption
+	)) {
+            $sStr .= "|+ " . $aCaption[1][0] . "\n";
+	}
+
         // Isolate rows
         preg_match_all(
-            '=<tr[^>]*>(.+)</tr>=USs',
+            '=<tr ?([^>]*)>(.+)</tr>=Uis',
             $aMatches[2],
             $aRows
         );
 
         // Treat cells
         for ($i=0, $n=sizeof($aRows[1]); $i<$n; $i++) {
+	    $sStr .= "|-" . trim($aRows[1][$i]) . "\n";
+
             preg_match_all(
-                '=<td colspan\="([0-9]+)">(.*)</td>=USs',
-                $aRows[1][$i],
+                '=<t(d|h) ?([^>]*)>(.*)</t\1>=Uis',
+                $aRows[2][$i],
                 $aCells
             );
 
             for ($j=0, $m=sizeof($aCells[1]); $j<$m; $j++) {
-                $sStr .= str_repeat('|', $aCells[1][$j]);
-                $sStr .= $aCells[2][$j];
+	        switch($aCells[1][$j]){
+  		  case "d":
+		    $sSep = '|';
+		    break;
+		  case "h":
+		    $sSep = "!";
+		    break;
+		}
+	        if( strlen($aCells[2][$j]) ) {
+		    $sStr .= $sSep . trim($aCells[2][$j]) . "|\n" . $aCells[3][$j] ."\n";
+		} else {
+		    $sStr .= $sSep . "\n" . $aCells[3][$j] ."\n";
+		}
             }
 
-            $sStr .= "\n";
+            $sStr;
         }
 
         return $sStr . "&lt;/table&gt;\n";