Re: [cowiki-dev] coWiki definition, new parser

PAUL HANCHETT <[email protected]>
Newsgroups gmane.comp.php.cowiki.devel
Message-ID <[email protected]>
OK, I'll look at it Archie!  My computer is going to be down for a good 
part of the day, so it will probably be tomorrow before I really get to it.

I have a question for you-- The result of the parser is an XML document, 
right?  PHP5 includes both XML and XSLT out of the box.  Why not use 
XSLT to reverse transform the XML to wiki-text, as well as into HTML for 
display?

Actually, I'm also wondering if there isn't an advantage to using a tool 
like Smarty for processing our templates.  Using someone else's code 
base leaves that much less for us to support (of course there are risks 
and other debates...)

Interested in opinions...

Paul

Archie Campbell wrote:

> It's not pretty and there are some bleeding edges in this working copy.
>
> I've done it like this because I can't stand <1><1></1></1> giving 
> <1><1></1> and hurling the rest back on yourself. There are two bits 
> doing noop, which is why the thing is broken, probably. That was a 
> mistake, actually. Please toy with it. Be merciless with the copy and 
> gentle with me, that's probably the best idea.
>
> It may become necessary to permute the WikiReverseParser into 
> something resembling the modified WikiParser.
>
> I'll get there once the latter is well behaved.
>
> So. I'm off to Scotland for a week; enjoy breaking things.
>
> Regards,
>
> Archie
>
> Archie Campbell wrote:
>
>> Guys,
>>
>> The WikiParser is trotting along nicely. I'm currently working on 
>> links, to be followed by the toc and then variables and anything 
>> leftover from Paul's specification the other day.
>>
>> I'm going on holiday to Scotland for 5 days; from tomorrow evening 
>> until next Sunday, I'll be exclusively real world. I propose to send 
>> a patch from 0.3.4 with the new parser as a work-in-progress. If you 
>> chaps could patch an old copy of Boron and have some fun breaking 
>> things, I'll also include a TEST.IDIOM document with brief 
>> descriptions of any limitations that the code needs, even temporarily.
>>
>> The question is... where do I put the patch? And, should I go from 
>> 0.3.4 or CVS HEAD?
>>
>> I'm actually quite enjoying the coding, which is nice. It looks 
>> nothing like the old version, and has made strides in definition, I 
>> think.
>>
>> Regards,
>>
>> cmarble
>>
>> P.S. Post-AprilFD, would anyone at Google fancy a coWiki? chortle
>>
>> Sy wrote:
>>
>>>On Apr 2, 2005 2:54 AM, Daniel T. Gorski <[email protected]> wrote:
>>>
>>>  
>>>
>>>>>>I would like to have more features listed that are beyond other wikis and
>>>>>>make coWiki special, very special :)
>>>>>>        
>>>>>>
>>>
>>>It is necessary to create a good document which describes things more
>>>technically before the release of the Beauty milestone.  We will need
>>>to distinguish ourselves from other solutions.  This document will
>>>help us understand the coWiki "Character" and make that milestone more
>>>profound.
>>>
>>>This is now on my to do list.  =/
>>>
>>>---------------------------------------------------------------------
>>>To unsubscribe, e-mail: [email protected]
>>>For additional commands, e-mail: [email protected]
>>>
>>>
>>>
>>>  
>>>
>
> ------------------------------------------------------------------------
>
> so we can mail * you a copy immediately. * *
>
> * Helping hands: Matt Ho 
> * 
>
> * * @package parse * @subpackage class * @access public * * @author 
> Daniel T. Gorski, * @copyright (C) Daniel T. Gorski, {@link 
> http://www.develnet.org} * @license 
> http://www.gnu.org/licenses/gpl.html * @version $Revision: 1.36 $ * */ 
> /** * coWiki - Wiki parser class * * @package parse * @subpackage 
> class * @access public * * @author Daniel T. Gorski, * @since coWiki 
> 0.3.0 */ class WikiParser extends Object { protected static $Instance 
> = null; protected $aToc = array(); protected $aEmph = array(); // 
> -------------------------------------------------------------------- 
> /** * Get instance * * @access public * * @author Daniel T. Gorski, * 
> @since coWiki 0.3.0 */ public function getInstance() { if 
> (!self::$Instance) { self::$Instance = new WikiParser; } return 
> self::$Instance; } // 
> -------------------------------------------------------------------- 
> /** * @access protected * * @author Daniel T. Gorski, * @since coWiki 
> 0.3.0 */ protected function __construct() {} // --- Helper methods 
> ------------------------------------------------- /** * Set doc toc * 
> * @access protected * * @author Daniel T. Gorski, * @since coWiki 
> 0.3.0 */ protected function setDocToc($sStr) { $this->sDocToc = $sStr; 
> } // 
> -------------------------------------------------------------------- 
> /** * Get doc toc * * @access protected * * @author Daniel T. Gorski, 
> * @since coWiki 0.3.0 */ protected function getDocToc() { return 
> $this->sDocToc; } // 
> -------------------------------------------------------------------- 
> /** * Get token count * * @access protected * * @author Daniel T. 
> Gorski, * @since coWiki 0.3.0 */ protected function getTokenCount() { 
> return sizeof($this->aToken); } // 
> -------------------------------------------------------------------- 
> /** * Set restore flag * * @access protected * * @author Daniel T. 
> Gorski, * @since coWiki 0.3.0 */ protected function 
> setRestoreFlag($bFlag) { $this->bRestoreFlag = $bFlag; } // 
> -------------------------------------------------------------------- 
> /** * Get restore flag * * @access protected * * @author Daniel T. 
> Gorski, * @since coWiki 0.3.0 */ protected function getRestoreFlag() { 
> return $this->bRestoreFlag; } // 
> -------------------------------------------------------------------- 
> // --- Element creators 
> ----------------------------------------------- /** * Create a 
> -element * * @access protected * * @author Daniel T. Gorski, * @since 
> coWiki 0.3.0 */ protected function createNoopElement(&$sStr) { return 
> ''.$sStr.''; } // 
> -------------------------------------------------------------------- 
> /** * Create a -element * * @access protected * * @author Daniel T. 
> Gorski, * @since coWiki 0.3.0 */ protected function 
> createRemarkElement(&$sStr) { return ''.$sStr.''; } // 
> -------------------------------------------------------------------- 
> /** * Create a <
>
>>-element
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function createPreElement(&$sStr) {
>        return "
>
>\r".str_replace("\n", "\r", $sStr)."\r
>
>";
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Create a <|>-element
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function createCodeElement(&$sStr) {
>        return "|\r".str_replace("\n", "\r", $sStr)."\r|";
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Create a -element
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function createPostingElement(&$sStr) {
>        return "\r".str_replace("\n", "\r", $sStr)."\r";
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Create a simple -element
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function createSimplePluginElement(&$sStr) {
>        return '';
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Create a parameterized -element
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function createParamPluginElement(&$sStr, &$sAttr) {
>        if (trim($sAttr) == '') {
>            return $this->createSimplePluginElement($sStr);
>        }
>        return '';
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Create a -element
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function createHeadingElement(&$sStr, &$sLevel) {
>        return ''.$sStr.'';
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Create a -element
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function createLinkElement($sStr) {
>        $aStr = explode(')(', $sStr);
>
>        $sStr =  '';
>        $sStr .=   trim($this->restoreTokens($aStr[0]));
>        $sStr .= '';
>
>        return $sStr;
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Create uri element
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function createUriElement(&$sStr) {
>        $sStr = '';
>        return $sStr;
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Create toc element
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function createTocElement() {
>        // Setting $i = 0 leads to undesired repetition of the first
>        // "title" element in a bullet list
>
>        // The default behaviour of  is not to display the first
>        // level
>        $i = 1;
>        $sStr = '';
>
>        if (sizeof($this->aToc) > 0) {
>            $sStr = $this->buildToc($i, $this->aToc[$i]['DEPTH']);
>            if ($sStr != '') {
>                $sStr = '|
>
>       ' . $sStr . '
>
>';
>            }
>        }
>
>        return ''.$this->restoreTokens($sStr).'';
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Create rule element
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function createRuleElement() {
>        return '
>------------------------------------------------------------------------
>';
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Create simple table element
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function createSimpleTableElement(&$sStr) {
>        return '
> ' .$this->buildTable($sStr) .'
>
>';
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Create param table element
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function createParamTableElement(&$sStr, &$sAttr) {
>        if (trim($sAttr) == '') {
>            return $this->createSimpleTableElement($sStr);
>        }
>        return '
> ' .$this->buildTable($sStr) .'
>
>';
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Create quote element
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function createQuoteElement(&$sStr) {
>        return '"'.$this->invokeParagraphs($sStr).'"';
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Create var element
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function createVarElement(&$sStr, &$sName) {
>        return '';
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Create break element
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function createBreakElement() {
>        return '
>';
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Create sub element
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.3
>     */
>    protected function createSubElement(&$sStr) {
>        return '_'.$sStr.' ';
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Create sup element
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.3
>     */
>    protected function createSupElement(&$sStr) {
>        return '^'.$sStr.' ';
>    }
>
>    // --------------------------------------------------------------------
>
>    protected function createJustificationElement(&$sStr, &$mMeta) {
>	return '<'.$mMeta.'>'.$this->invokeParagraphs($sStr).'';
>    }
>
>    protected function createEmphasisElement(&$sStr, &$mMeta) {
>
>	$sOpen = $sClose = '';
>	for ($i=0 ; $i < strlen($mMeta) ; $i++ ){
>	    switch(substr($mMeta,$i,1)){
>		case '_':
>		    $sOpen .= "_";
>		    $sClose = "_".$sClose;
>		    break;
>		case '-':
>		    if(!strcmp(substr($mMeta,$i+1,1),'-')){
>			$sOpen .= "";
>			$sClose = "".$sClose;
>			$i++;
>		    }
>		    break;
>		case '=':
>		    $sOpen .= "";
>		    $sClose = "".$sClose;
>		    break;
>		case '*':
>		    $sOpen .= "*";
>		    $sClose = "*".$sClose;
>		    break;
>		case '/':
>		    $sOpen .= "/";
>		    $sClose = "/".$sClose;
>		    break;
>            }
>	}
>	return $sOpen . $sStr . $sClose;
>    }
>
>    // --- Element creator helpers ----------------------------------------
>
>    /**
>     * Generate "toc" (Document Table of Contents)
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function buildToc(&$i, &$nDepth) {
>        $sStr = '';
>
>        // Iterate though all toc-entries
>        while (isset($this->aToc[$i]['DEPTH'])
>               && $this->aToc[$i]['DEPTH'] == $nDepth) {
>
>            $sStr .= '';
>#             $sStr .=    ''.$sAlias.'';
>
>            $i++;
>
>            // Recurse (indent) if toc-entry is nested
>            if (isset($this->aToc[$i]['DEPTH'])) {
>
>                if ($this->aToc[$i]['DEPTH'] > $nDepth) {
>                    $sStr .= '
>
>       '; $sStr .= $this->buildToc($i, $this->aToc[$i]['DEPTH']); $sStr
>       .= '
>
>';
>                }
>            }
>
>            $sStr .= '
>';
>        }
>
>        return $sStr;
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Catch paragraphs
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function invokeParagraphs(&$sStr) {
>        // Remove multiple newlines
>        $sStr = preg_replace('=\n+=', "\n", $sStr);
>
>        // Insert paragraphs
>        $sStr = preg_replace('=\n([^\r]+)$=Um', '
>
> \1
>
>', $sStr);
>
>        return $sStr;
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * All strings passed to this method MUST NOT contain any "<" or ">".
>     * Treat this string with "htmlentities()" or a similar function first.
>     *
>     * @access  public
>     * @param   string  The wiki source string
>     * @return  string  Wiki XML
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    public function parse($sStr) {
>
>	$sRet = '';
>	$sContent = '';
>	$bList = false;
>	$bTable = false;
>	$bGreedy = false;
>	$aList = array();
>	$aTable = array();
>	$aRows;
>
>        // {{{ DEBUG }}}
>        Logger::info('Start parsing wiki document.');
>
>        // ---
>
>        $sStr = trim(escape($sStr));
>
>        // Replace possible tabulators
>        $sStr = str_replace("\t", '    ', $sStr);
>
>        // Replace possible \r\n or \n\r with \n
>        $sStr = str_replace("\r\n", "\n", $sStr);
>        $sStr = str_replace("\n\r", "\n", $sStr);
>
>	$aRows = explode( "\n",$sStr."\n" );
>
>
>        $i = 0; $n = sizeof( $aRows );
>	$sRow = $aRows[$i]."\n";
>
>	$t = 0; $l = -1;
>
>
>	//table & list
>	while( true ) {
>	    $sContent = '';
>	    $aMatches = array();
>	    //table of contents alone ^$
>	    if( preg_match( '=^<toc(/?)>$=', $sRow ) ) {
>		$sRet .= "\n\t\t\n";
>	    //end of table
>	    } else if( $t > 0 && preg_match( '=^</table>=i',
>						$sRow, $aMatches  )) {
>	        $sParam = trim($aTable[$t][0]);
>		if( $sParam == '') {
>		    $sRet .= "\n".'
> '.$this->buildTable($aTable[$t]). '
>
>'."\n";
>		} else {
>		    $sRet .= "\n".'
> '. $this->buildTable($aTable[$t]).'
>
>'."\n";
>		}
>		if( --$t == 0 ){
>  		    $bTable = false;
>		}
>	    //beginning of table
>	    } else if( preg_match( '=^<table([^>]*)>$=i',
>					$sRow, $aMatches )) {
>		$bTable = true;
>		$aTable[++$t] = array();
>		array_push( $aTable[$t], $aMatches[1] );
>	    //beginning of list
>	    } else if( preg_match( '=^([\s*#]{0,}[*#]) ([^\n]*)$=',
>				    $sRow, $aMatches )) {
>	        $bList = true;
>		$aList[++$l] = array();
>		$aList[$l]['TEXT'] = $this->processContent( $aMatches[2] );
>		$aList[$l]['DEPTH'] = strlen( $aMatches[1] );
>		$aList[$l]['TYPE'] = (substr($aMatches[1],-1)=='*'?
>							      'ul':'ol');
>	    //pre code posting q start at BOL, are greedy until 
>	    // closing tag anywhere on a line
>	    } else if (preg_match( '=^<(pre|code|posting|q)>=i',
>				    $sRow, $aMatch ) ) {
>	        $sRow = substr( $sRow, strlen($aMatch[0]) );
>		do {
>		    if (preg_match( '=(.*)</'.$aMatch[1].'>=i',
>				    $sRow, $aMatches )) {
>			$sRet .= '<'.$aMatch[1].'>'.$sContent . 
>				$aMatches[1].'';
>			break;
>		    } else {
>			$sContent .= $sRow;
>		    }
>		    if( ++$i < $n ){
>		        $sRow = $aRows[$i];
>		    }else{
>		        break;
>		    }
>		} while(true);
>		if( $i == $n ) {
>		    $sRet .= '<'.$aMatch[1].'>'.
>				$sContent .
>				 '';
>		    break;
>		}
>	    //horizontal rule
>	    } else if (preg_match( '=^-{3,}(\s|$)=', $sRow, $aMatches ) ) {
>	        $sRet .= '
>------------------------------------------------------------------------
>'."\n";
>	    //noop
>	    } else if (preg_match( '=((.*)<noop>)=i',
>					$sRow, $aMatches )) {
>		$sContent = $this->processContent( $aMatches[2], false )
>				. '';
>		$sRow = substr( $sRow, strlen($aMatches[1]) );
>		do {
>		    if (preg_match( '=(.*)</noop>=' , 
>				    $sRow, $aMatches )) {
>  		        $sContent .= $aMatches[1] . '';
>			break;
>		    } else {
>		        $sContent .= $sRow;
>		    }
>		    if(++$i<$n){
>		        $sRow = $aRows[$i];
>		    } else {
>		        break;
>		    }
>		} while(true);
>		$sRet .= $sContent;
>	    } else {
>		//end of list
>		if($bList) {
>		    $d = 0;
>		    $sListType = $aList[$d]['TYPE'];
>		    $nDepth = $aList[$d]['DEPTH'];
>		    $sContent .= "\n".''.
>				    '<'.$sListType.'>'.
>				      $this->buildList($d,$nDepth,$aList).
>				    ''.
>		             ''."\n";
>    		    $bList = false;
>		    $aList = array();
>		    $l = -1;
>		    if($bTable){
>		        array_push( $aTable[$t], $sContent );
>			array_push( $aTable[$t], $sRow );
>		    }else{
>			$sRet .= $sContent;
>			$sRet .= $this->processContent( $sRow );
>		    }
>		//more table
>		}else if($bTable) {
>		    array_push( $aTable[$t], $sRow );
>		//non table/list row
>		}else{
>		    $sContent = trim($this->processContent( $sRow ));
>		    if( $sContent != '' ){
>			$sRet .= '
>
> '.$sContent.'
>
>'."\n";
>		    }
>		}
>	    }
>	    if(sizeof($aMatches)) {
>		$sRow = substr( $sRow, strlen( $aMatches[0] ) );
>	    } else if ( ++$i < $n ) {
>		$sRow = $aRows[$i]."\n";
>	    } else {
>	        break;
>	    }
>	}
>	
>	if( preg_match( '=^(.*)\n\t\t\n(.*)$=s', $sRet, $aMatches )) {
>   	    $t = 1;
>	    if (sizeof($this->aToc) > 0) {
>		$sToc = $this->buildToc($t, $this->aToc[$t]['DEPTH']);
>		if ($sToc != '') {
>		    $sToc = '
>
>       ' . $sToc . '
>
>';
>		}
>	    }
>	    return $aMatches[1] . $sToc . $aMatches[2];
>	}
>
>        // {{{ DEBUG }}}
>        Logger::info('Finished parsing wiki document.');
>
>	return $sRet;
>    }
>
>    protected function resetEmphasis() {
>        $this->$aEmph = array(
>		       "b" => false,
>		       "u" => false,
>		       "i" => false,
>		       "f" => false,
>		       "s" => false,
>		       "j" => '',
>		       "p" => ''
>		);
>    }
>
>    protected function processContent( $sStr, $bClose = true ) {
>        $sRet = '';
>       	$aMatches = array();
>	if ($bClose) {
>	    $this->resetEmphasis();
>	}
>	$sStr = ltrim( $sStr );
>
>	while( strlen( $sStr ) > 0 ) {
>	    if ($sStr == "\n"){
>		break;
>	    }
>	    //noop
>	    if (preg_match( '=^<noop>(.*)</noop>=is',
>					$sStr, $aMatches )) {
>	        $sRet .= '' . $aMatches[1] . '';
>	    //links (()()) & [[][]]
>	    }else if( preg_match( '=^\(\(([^\(\)]+|[^\(\)]+' .
>				    '\([^\(\)]+\)[^\(\)]*|' .
>			            '[^\(\)]+\)\([^\(\)]+)\)\)=Usx',
>				  $sStr, $aMatches )) {
>	        $aLink = explode( ')(', $aMatches[1] );
>		$aLink[0] = str_replace( '|', '¦', $aLink[0] );
>	        $sRet .= '';
>		if ( isset( $aLink[1]) ) {
>		    $sRet .= trim($aLink[1]);
>		} else {
>		    $sRet .= trim($aLink[0]);
>		}
>	        $sRet .= '';
>	    //WikiWords
>	    }else if( preg_match( '=^([A-Z][a-z]+([A-Z][a-z]+)+)=s',
>				    $sStr, $aMatches )) {
>	      $sLink = trim(preg_replace( '=([A-Z])=', ' \1',
>						$aMatches[1] ));
>		$sRet .= '' .
>				 $sLink . '';
>	    //URIs
>	    }else if( preg_match(
>		'=^(http://|https://|ftp://|mailto:|news:)
>                   ([-_A-Z0-9\S]*)
>                   (\*\s|\=\s|"|<|>|<|>|\(|\)|\s|$)??
>                 =six',
>				  $sStr, $aMatches )) {
>	        $sRet .= '';
>	    //headings
>	    }else if( preg_match( '=^(\+{1,})\s*(.*)$=s',
>				    $sStr, $aMatches )) {
>                $sContent = $this->processContent($aMatches[2]);
>		if( preg_match( '=
>						([^<]*)=USx',
>				$sContent, $aLinkMatches ) ) {
>		    $sAlias = !empty($aLinkMatches[2])
>                               ? $aLinkMatches[2]
>                               : $aLinkMatches[1]
>                               ;
>		} else {
>		    $sAlias = $sContent;
>		}
>		$i = sizeof($this->aToc);
>		$this->aToc[$i]['TEXT'] = $sAlias;
>		$this->aToc[$i]['DEPTH'] = strlen( $aMatches[1] );		
>		$sTag = 'h'.strlen($aMatches[1]);
>		$sRet .= '<'. $sTag .'>'.
>			 $sContent .
>			 '';
>            //breaks
>	    //justification
>	    }else if( preg_match( '=^<(/??)(left|center|right)>=is',
>				  $sStr, $aMatches )) {
>	        if( $aMatches[1] == '/' &&
>		    $this->aEmph['j'] == $aMatches[2]{0} ) {
>		    $sRet .= '';
>		    $this->aEmph['j'] = '';
>		} else if ( $aMatches[1] == '' &&
>			    $this->aEmph['j'] == '' ) {
>		    $sRet .= '<'. $aMatches[2] .'>';
>		    $this->aEmph['j'] = $aMatches[2]{0};
>		}
>	    //subscript, superscript
>	    }else if( preg_match( '=^<(/??)(sub|sup)>=is',
>				  $sStr, $aMatches ) ) {
>	        if( $aMatches[1] == '/' &&
>		    $this->aEmph['p'] == $aMatches[2] ) {
>		    $sRet .= '';
>		    $this->aEmph['p'] = '';
>		}else if ( $aMatches[1] == '' &&
>			   $this->aEmph['p'] == '' ) {
>		    $sRet .= '<' . $aMatches[2] . '>';
>		    $this->aEmph['p'] = $aMatches[2];
>		}
>	    //emphasis		
>		
>		/*
>	    }else if( preg_match( '#^([^-=\*_/]*?)
> 				      ([-=\*_/]{2,})
> 	 			    ([^-=\*_/]*?)#x',
>		*/		
>				
>	    }else if( preg_match( '#^([-=\*_/]{2,})#',
>	 	      $sStr, $aMatches ) ) {
>		while( strlen( $aMatches[1] ) ) {
>		    if( strlen( $aMatches[1] ) >= 2 &&
>			$aMatches[1]{0} == $aMatches[1]{1} ) {
>			if( strlen( $aMatches[1] ) > 3 &&
>			    $aMatches[1]{1} == $aMatches[1]{2} &&
>			    $aMatches[1]{3} == $aMatches[1]{2} ) {
>  			    $sRet .= str_repeat( $aMatches[1]{0}, 2 );
>			    $aMatches[1] = substr( $aMatches[1], 4 );
>			    continue;
>			}
>		        $sEmph = '';
>		        switch ( $aMatches[1]{0} ) {
>			case '-':
>			    $sEmph=($this->aEmph["s"]?'/':'').'strike';
>			    $this->aEmph["s"] = !$this->aEmph["s"];
>			    break;
>			case '=':
>			    $sEmph=($this->aEmph["f"]?'/':'').'tt';
>			    $this->aEmph["f"] = !$this->aEmph["f"];
>			    break;
>			case '*':
>			    $sEmph=($this->aEmph["b"]?'/':'').'b';
>			    $this->aEmph["b"] = !$this->aEmph["b"];
>			    break;
>			case '_':
>			    $sEmph=($this->aEmph["u"]?'/':'').'u';
>			    $this->aEmph["u"] = !$this->aEmph["u"];
>			    break;
>			case '/':
>			    $sEmph=($this->aEmph["i"]?'/':'').'i';
>			    $this->aEmph["i"] = !$this->aEmph["i"];
>			    break;
>			}
>			$sRet .= '<'.$sEmph.'>';
>		        $aMatches[1] = substr( $aMatches[1], 2 );
>		    } else {
>			$sRet .= $aMatches[1]{0};
>			$aMatches[1] = substr( $aMatches[1], 1 );
>		    }
>		}
>            }else if( preg_match( '#^((([-=\*_/]{1})(?!\3)|\s|[A-Za-z0-9])*)#x',
>				    $sStr, $aMatches ) ) {
>	        $sRet .= $aMatches[0];
>	    }
>	    if( isset($aMatches[0]) ) {
>	        $sStr = substr( $sStr, strlen($aMatches[0]) );
>	    }else{
>	        break;
>	    }
>	}
>	if($bClose) {
>	    if( $this->aEmph['s'] ) { $sRet .= ''; }
>	    if( $this->aEmph['f'] ) { $sRet .= ''; }
>	    if( $this->aEmph['b'] ) { $sRet .= ''; }
>	    if( $this->aEmph['u'] ) { $sRet .= ''; }
>	    if( $this->aEmph['i'] ) { $sRet .= ''; }
>	    if( $this->aEmph['p'] != '' ) {
>	        $sRet .= 'aEmph['p'] .'>';
>	    }   
>	    $this->resetEmphasis();
>	}
>	/*
>	if( $this->aEmph['j'] != '' ) {
>	    switch( $this->aEmph['j'] ) {
>	    case 'l': $sRet .= '';break;
>	    case 'r': $sRet .= '';break;
>	    case 'c': $sRet .= '';break;
>	    }
>	}
>	*/
>	return $sRet;
>    }
>
>    /**
>     * &build table
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function buildTable( &$aTable ) {
>
>	$sRet = '';
>	$sContent = '';
>	$sRow = '';
>	$bPriorRow = false;
>
>	$j = 1;
>	$v = sizeof($aTable);
>
>	while( ++$j < $v ) {
>
>	  /*
>            if (!strlen(trim($aTable[$j]))) {
>                return ''.$sStr.'';
>            }
>	  */
>
>	    //rows expected to hold table syntax (pipes), may instead
>	    //make room for ongoing content (tables, lists, etc)
>	    $sRow = $aTable[$j];
>
>	    //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 .= '\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 .= '>';
>		}
>
>		//look ahead now.
>		if ($sRow == "\n") {
>		  //look ahead to close our content
>		    while( ++$j<$v ){
>			$sRow = $aTable[$j];
>			//pipe syntax (will force $sContent) to continue
>			if ($sRow{0} == '|' || $sRow{0} == '!') {
>			    $sRet .= $this->processContent($sContent);
>			    switch($nType){
>			      case 1:
>			        $sRet .= "\n";
>			        break;
>			      case 2:
>			        $sRet .= "\n";
>			        break;
>			    }
>			    --$j;
>			    continue 3;
>			} else {
>			    //non-pipe (ever-increasing) content
>			    $sContent .= $sRow;
>			}
>		    }
>		    $j = $v;
>		    $sRet .= $this->processContent($sContent);
>		    switch($nType){
>		      case 1:
>		        $sRet .= "\n";
>		        break;
>		      case 2:
>		        $sRet .= "\n";
>		        break;
>		    }
>		    continue 2;
>		} elseif ( ( $sRow{0} == "|" || $sRow{0} == "!") && 
>			($sRow{1} == "|" || $sRow{1} == "!") ) {
>		    $sRow = substr($sRow, 1);
>		    $sRet .= $this->processContent($sContent);
>		    switch($nType){
>		      case 1:
>			$sRet .= "\n";
>			break;
>		      case 2:
>			$sRet .= "\n";
>			break;
>		    }
>		    continue 1;
>	        }
>	    }
>	}
>	if( $bPriorRow ) {
>	    return $sRet."";
>	} else {
>	    return $sRet;
>	}
>    }
>
>    protected function buildList(&$i, &$nDepth, &$aList) {
>        $sStr = '';
>
>        // Iterate though all list-entries
>        while (isset($aList[$i]['DEPTH'])
>               && $aList[$i]['DEPTH'] == $nDepth) {
>
>            $sStr .= '';
>#             $sStr .=    $aList[$i]['TEXT'];
>
>            $i++;
>
>            // Recurse (indent) if list-entry is nested
>            if (isset($aList[$i]['DEPTH'])) {
>
>                if ($aList[$i]['DEPTH'] > $nDepth) {
>
>                    // Correct items that are intended too deep
>                    $aList[$i]['DEPTH'] = $nDepth + 1;
>                
>                    $sListType = $aList[$i]['TYPE'];
>
>                    $sStr .=  '<'.$sListType.'>';
>                    $sStr .=    $this->buildList(
>                                    $i,
>                                    $aList[$i]['DEPTH'],
>				    $aList
>                                );
>                    $sStr .=  '';
>                }
>            }
>
>            $sStr .= '
>';
>        }
>
>        return $sStr;
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Treat NOOP (no operation)
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function processNoOperation(&$sStr) {
>
>        // Treat  ... 
>        // This tag can not be nested.
>        $sStr = preg_replace_callback(
>            '=<noop>(.+)</noop>=Usi',
>            array(&$this, 'tokenizeNoOperation'),
>            $sStr
>        );
>
>        return $sStr;
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Treat REMARKS
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function processRemark(&$sStr) {
>
>        // Treat  ... 
>        // This tag can not be nested.
>        $sStr = preg_replace_callback(
>            '=<rem>(.+)</rem>=Usi',
>            array(&$this, 'tokenizeRemark'),
>            $sStr
>        );
>
>        return $sStr;
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Treat preformatted PRE
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function processPre(&$sStr) {
>
>        // Treat 
>
> ... 
>
>
>        // Each tag will be recognized at the begin of a line only!
>        // This tag can not be nested.
>        $sStr = preg_replace_callback(
>            '=^<pre>\n(.+)\n</pre>(\s|$)=Umsi',
>            array(&$this, 'tokenizePre'),
>            $sStr
>        );
>
>        return $sStr;
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Treat preformatted CODE
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function processCode(&$sStr) {
>
>        // Treat | ... |
>        // Each tag will be recognized at the begin of a line only!
>        // This tag can not be nested.
>        $sStr = preg_replace_callback(
>            '=^<code>\n(.+)\n</code>(\s|$)=Umsi',
>            array(&$this, 'tokenizeCode'),
>            $sStr
>        );
>
>        return $sStr;
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Treat POSTING
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function processPosting(&$sStr) {
>
>        // Treat  ... 
>        // Each tag will be recognized at the begin of a line only!
>        // This tag can not be nested.
>        $sStr = preg_replace_callback(
>            '=^<posting>\n(.+)\n</posting>(\s|$)=Umsi',
>            array(&$this, 'tokenizePosting'),
>            $sStr
>        );
>
>        return $sStr;
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * ((foo)), ((foo)(bar))
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function processLink(&$sStr) {
>
>        // Treat square-bracket-links ((foo)), ((foo)(bar))
>        // These tags can not be nested.
>        $sPattern = '=\(\(([^\(\)]+|[^\(\)]+\([^\(\)]+\)[^\(\)]*|' .
>            '[^\(\)]+\)\([^\(\)]+)\)\)=U';
>
>        $sStr = preg_replace_callback(
>            $sPattern,
>            array(&$this, 'tokenizeLink'),
>            $sStr
>        );
>
>        return $sStr;
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Convert WikiWords
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function processWikiWord(&$sStr) {
>
>        // Treat WikiWordLinks
>        $sStr = preg_replace_callback(
>            '=([ \n\[\{\']|")([A-Z][a-z]+([A-Z][a-z]+)+)=',
>            array(&$this, 'tokenizeWikiWord'),
>            $sStr
>        );
>
>        return $sStr;
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Automatically clickable URIs
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function processClickable(&$sStr) {
>
>        // Treat clickable URIs (http:, mailto: etc.)
>        $sStr = preg_replace_callback(
>            '=  (http://|https://|ftp://|mailto:|news:)
>                (\S+)
>                (\*\s|\=\s|"|<|>|<|>|\(|\)|\s|$)
>             =Usmix',
>            array(&$this, 'tokenizeClickable'),
>            $sStr
>        );
>
>        return $sStr;
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * 
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function processToc(&$sStr) {
>        // Treat 
>        $sStr = preg_replace_callback(
>            '=\n<toc>=Usi',
>            array(&$this, 'tokenizeToc'),
>            $sStr
>        );
>
>        return $sStr;
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * 
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function processSimplePlugin(&$sStr) {
>
>        // Treat 
>        $sStr = preg_replace_callback(
>            '=<plugin +([a-z0-9_.]+)>=Usi',
>            array(&$this, 'tokenizeSimplePlugin'),
>            $sStr
>        );
>
>        return $sStr;
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * 
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function processParamPlugin(&$sStr) {
>
>        // Treat 
>        $sStr = preg_replace_callback(
>            '=<plugin +([a-z0-9_.]+) +(.*)>=Usi',
>            array(&$this, 'tokenizeParamPlugin'),
>            $sStr
>        );
>
>        return $sStr;
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Emphasis: bold, italic, monospaced ...
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function processEmphasis(&$sStr) {
>
>      /*
>	emphasis markup may be as widely spaced as an entire paragraph
>
>	/x/ - italics
>	*x* - bold
>	--x-- - strikethrough
>	_x_ - underlined
>	=x= - monospaced
>      */
>
>      $sEmph= '(-{2}|[_=\*/]+)';
>      $sCont= '([^\n_=*/]*)';
>      $sWord= '([^ \n/](\S?|.*(\S|\t)))';
>
>        $sStr = $this->collapseEmphasis( $sStr );
>
>        $sStr = preg_replace_callback(
>            '~  ((-{2}|[_=*/])+)
>		(([^\n_=*/])+)
>                ((-{2}|[_=*/])+)
>            ~mix',
>	    array(&$this,'tokenizeEmphasis'),
>            $sStr
>        );
>
>        return $sStr;
>    }
>
>    protected function collapseEmphasis(&$sStr) {
>
>	//italic
>        $sStr = preg_replace(
>            '=<(em|i)>(.*)</\1>=ms',
>            '/\2/',
>            $sStr
>        );
>	//bold
>        $sStr = preg_replace(
>            '=<(strong|b)>(.*)</\1>=ms',
>            '*\2*',
>            $sStr
>        );
>	//monospaced
>        $sStr = preg_replace(
>            '=<tt>(.*)</tt>=ms',
>            '=\1=',
>            $sStr
>        );
>	//strikethrough
>        $sStr = preg_replace(
>            '=<strike>(.*)</strike>=ms',
>            '--\1--',
>            $sStr
>        );
>	//underlined
>        $sStr = preg_replace(
>            '=<u>(.*)</u>=ms',
>            '_\1_',
>            $sStr
>        );
>
>        return $sStr;
>    }
>
>    /**
>     * (Again) treat %VARIABLES%, that may occur in the document.
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function processVariable(&$sStr) {
>        $sStr = preg_replace_callback(
>                '=%([A-Z0-9_]+)%=U',
>                array(&$this, 'tokenizeVariable'),
>                $sStr
>        );
>
>        return $sStr;
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Headings (+ -> H1, ++ -> H2, etc.)
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function processHeading(&$sStr) {
>
>        // Treat headings (+, ++, +++ etc);
>        // Each tag will be recognized at the begin of a line only!
>        $sStr = preg_replace_callback(
>            '=^(\+{1,6}) ([^\r\n]+)=m',
>            array(&$this, 'tokenizeHeading'),
>            $sStr
>        );
>
>        return $sStr;
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Headings (+ -> H1, ++ -> H2, etc.)
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function processHorizontalRule(&$sStr) {
>
>        // Treat horizontal rules (---)
>        $sStr = preg_replace_callback(
>            '=^-{3,}(\s|$)=m',
>            array(&$this, 'tokenizeHorizontalRule'),
>            $sStr
>        );
>
>        return $sStr;
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Breaks (
>)
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function processBreak(&$sStr) {
>
>        // Treat a break
>        $sStr = preg_replace_callback(
>            '=<br>=Ui',
>            array(&$this, 'tokenizeBreak'),
>            $sStr
>        );
>
>        return $sStr;
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Subs (_)
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.3
>     */
>    protected function processSub(&$sStr) {
>
>        // Treat a _
>        $sStr = preg_replace_callback(
>            '=<sub>(.*)</sub>=Ui',
>            array(&$this, 'tokenizeSub'),
>            $sStr
>        );
>
>        return $sStr;
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Sups (^)
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.3
>     */
>    protected function processSup(&$sStr) {
>
>        // Treat a ^
>        $sStr = preg_replace_callback(
>            '=<sup>(.*)</sup>=Ui',
>            array(&$this, 'tokenizeSup'),
>            $sStr
>        );
>
>        return $sStr;
>    }
>
>    // --------------------------------------------------------------------
>
>    protected function processJustification(&$sStr) {
>        $sStr = preg_replace_callback(
>            '=<(left|center|right)>(.*)</\1>=Usi',
>	    array(&$this, 'tokenizeJustification'),
>            $sStr );
>
>        return $sStr;
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Ordered and unordered bullet lists (Asterisk *, Hash #)
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function processList(&$sStr) {
>
>        // Treat lists
>        $sStr = preg_replace_callback(
>	    /* '=\n(( {0,})(\*|#)+ (.*))$=Us',*/
>            '=\n((\*|#) (.*)\n)(?! {0,}(\*|#))=Us',
>	    array(&$this, 'tokenizeList'),
>            $sStr
>        );
>
>        return $sStr;
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Create list
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function createList(&$sStr, &$mMeta) {
>
>        // Fix multiple bullets at the beginning of the line.
>        // E.g. fix sick things like this to make it intuitive:
>        //
>        // * Item 1     <-->   * Item 1
>        //  * Item 2    <-->    * Item 2
>        // ** Item 3    <-->    * Item 3
>        // *** Item 4   <-->     * Item 4
>        // **** Item 5  <-->      * Item 5
>        // ** Item 6    <-->    * Item 6
>
>        $aArr = explode("\n", $sStr);
>
>        for ($i=0, $n=sizeof($aArr); $i<$n; $i++) {
>            $aArr[$i] = preg_replace_callback(
>                          '=^((\*|#)*)(\2) (.*)$=',
>                          array($this, 'createListMultiBulletHelper'),
>                          $aArr[$i]
>                        );
>        }
>
>        $sStr = join("\n", $aArr);
>
>        preg_match_all(
>            '=^( {0,})(\*|#)+ (.*)$=Ums',
>            $sStr,
>            $aList
>        );
>
>        $this->aList = array();
>
>        for ($i=0; $iaList[$i]['TEXT'] = $this->restoreTokens($mMeta);
>	  //$this->aList[$i]['TEXT']  = $aList[3][$i];
>	    $sEmp = $this->restoreTokens($this->processEmphasis($aList[3][$i]));
>	    $this->aList[$i]['TEXT'] = $sEmp;
>            $this->aList[$i]['DEPTH'] = strspn($aList[1][$i], ' ');
>            $this->aList[$i]['TYPE']  = $aList[2][$i];
>        }
>
>        $i = 0;
>        $nDepth = $this->aList[$i]['DEPTH'];
>
>        // Determine the type of the first list element:
>        // Ordered or unordered?
>        $sListType = ($aList[2][0] == '*') ? 'ul' : 'ol';
>
>        return ''
>                  .'<'.$sListType.'>'
>                      .$this->buildList($i, $nDepth)
>                  .''
>              .'';
>    }
>
>    private function createListMultiBulletHelper(&$aMatches) {
>        return str_repeat(' ', strlen($aMatches[1]))
>                .$aMatches[3].' '.$aMatches[4];
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Build list
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    /**
>     * Treat TABLE
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function processSimpleTable(&$sStr) {
>
>        // Treat     
> __^^...
>
>
>__^^        // Each tag will be recognized at the begin of a line only!
>        // This tag can not be nested.
>        $sStr = preg_replace_callback(
>            '=^<table>\n(.+)\n</table>(\s|$)=Umsi',
>            array(&$this, 'tokenizeTable'),
>            $sStr
>        );
>
>        return $sStr;
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Process param table
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function processParamTable(&$sStr) {
>
>        // Treat     
> __^^...
>
>
>__^^        // Each tag will be recognized at the begin of a line only!
>        // This tag can not be nested.
>        $sStr = preg_replace_callback(
>            '=^<table +([^>]*)>\n(.+)\n</table>(\s|$)=Umsi',
>            array(&$this, 'tokenizeParamTable'),
>            $sStr
>        );
>
>        return $sStr;
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Treat (block-)quote
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function processQuote(&$sStr) {
>
>        // Treat " ... "
>        // Each tag will be recognized at the begin of a line only!
>        // This tag can not be nested.
>        $sStr = preg_replace_callback(
>            '=^<q>(.+)\n+</q>(\s|$)=Umsi',
>            array(&$this, 'tokenizeQuote'),
>            $sStr
>        );
>
>        return $sStr;
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Collect referenced nodes to where the document is linking to
>     *
>     * @access  protected
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    protected function addReferencedNode($Obj) {
>        $this->RefNodes->add($Obj);
>    }
>
>    // --------------------------------------------------------------------
>
>    /**
>     * Get referenced nodes
>     *
>     * @access  public
>     *
>     * @author  Daniel T. Gorski, 
>     * @since   coWiki 0.3.0
>     */
>    public function getReferencedNodes() {
>        return $this->RefNodes;
>    }
>
>} // of class
>
>/*
>    Prospero:  That cross you wear around your neck; is it only a decoration,
>               or are you a true Christian believer?
>
>    Francesca: Yes, I believe - truly.
>
>    Prospero:  Then I want you to remove it at once! - and never to wear it
>               within this castle again! Do you know how a falcon is trained
>               my dear? Her eyes are sown shut. Blinded temporarily she
>               suffers the whims of her God patiently, until her will is
>               submerged and she learns to serve - as your God taught and
>               blinded you with crosses.
>
>    Francesca: You had me take off my cross because it offended ...
>
>    Prospero:  It offended no-one. No - it simply appears to me to be
>               discourteous to ... to wear the symbol of a deity long dead.
>               My ancestors tried to find it. And to open the door that
>               seperates us from our Creator.
>
>    Francesca: But you need no doors to find God. If you believe ...
>
>    Prospero:  Believe?! If you believe you are gullible. Can you look
>               around this world and believe in the goodness of a god who
>               rules it? Famine, Pestilence, War, Disease and Death!
>               They rule this world.
>
>    Francesca: There is also love and life and hope.
>
>    Prospero:  Very little hope I assure you. No. If a god of love and life
>               ever did exist ... he is long since dead. Someone ...
>               something rules in his place.
>*/
>
>?>
>
>    
>
>__^^
>    
>------------------------------------------------------------------------
>__^^
>---------------------------------------------------------------------
>To unsubscribe, e-mail: [email protected]
>For additional commands, e-mail: [email protected]    
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.