Re: [cowiki-dev] creating nested directories?

PAUL HANCHETT <[email protected]>
Newsgroups gmane.comp.php.cowiki.devel
Message-ID <[email protected]>
The unit tests are now correct (for the cases they check).  Source 
paragraphs ending in <CR> only still are not converted into multiple <P> 
units:

    TestCase ParserBasicFormattingTest->testCROnlyLineEndings() failed:
    Multiple lines ending in CR expected <p>A</p><p>B</p><p>C</p>,
    actual <p>A
    B

    C</p>


Agree that we probably won't see lines ending in only <CR>; but lets 
make the parser robust!

Paul

Archie Campbell wrote:

> Please can you fix it before I wade in and break something. The parser 
> outputs entities for bad tags, so that the xml doesn't get confused.
>
> Lines ending in <CR> i.e.
>
> <textarea>
> A
> B
> C
> </textarea>
>
> *are* paragraphised, as expected. Also when a line is inserted between 
> characters.
>
> Crunch time: will it be faster to create unit tests for other 
> processing, or rely on eyeball scrapes of test documents?
>
> Only you can tell.
>
> Regards,
>
> Archie
>
> P.S. Have some new files. Bugfixes.
>
> PAUL HANCHETT wrote:
>
>> OK Archie, here's what I've got so far.  You need Pear::PHPUnit to 
>> run this.  I'm doing it from inside Eclipse.
>>
>>     * I'm only testing basic formatting-- Bold, Italic, Underline,
>>       Strikeout, Fixed, and paragraphs.  Come to think of it I don't
>>       test the <p> or <b> tag...
>>
>>     * I've found that a bogus tag (not recognized html) causes the
>>       parser to hang somehow.  Haven't traced it to see what's going
>>       on.  The test is commented out in unittest.php.
>>
>>     * Also, lines ending only in <CR> are not seen as new
>>       paragraphs.  Every other combination is OK.
>>
>> The stuff in amber is where the output of the parser uses &gt for > 
>> and I haven't got a conversion on the test.  I'll get this done or 
>> you can fix it if you want.
>>
>> Here are the test results from my machine:
>>
>>     TestCase ParserBasicFormattingTest->testEmptyString() passed
>>     TestCase ParserBasicFormattingTest->testBlankLines() passed
>>     TestCase ParserBasicFormattingTest->testShortLine() passed
>>     TestCase ParserBasicFormattingTest->testParagraphLine() passed
>>     TestCase ParserBasicFormattingTest->testTwoParagraphs() passed
>>     TestCase ParserBasicFormattingTest->testCRLFLineEndings() passed
>>     TestCase ParserBasicFormattingTest->testLFCRLineEndings() passed
>>     TestCase ParserBoldAsteriskFormattingTest->testEmphasizeWord() passed
>>     TestCase ParserBoldAsteriskFormattingTest->testEmphasizePhrase()
>>     passed
>>     TestCase ParserBoldAsteriskFormattingTest->testEmphasizeLine() passed
>>     TestCase
>>     ParserBoldAsteriskFormattingTest->testMismatchedEmphasizedPhrase()
>>     passed
>>     TestCase
>>     ParserBoldAsteriskFormattingTest->testMismatchedEmphasizedPhrase2()
>>     passed
>>     TestCase
>>     ParserBoldAsteriskFormattingTest->testMismatchedEmphasizedPhrase3()
>>     passed
>>     TestCase
>>     ParserBoldAsteriskFormattingTest->testMismatchedEmphasizedPhrase4()
>>     passed
>>     TestCase
>>     ParserBoldAsteriskFormattingTest->testEmphasizeEndsAtEoln() passed
>>     TestCase ParserItalicSlashFormattingTest->testEmphasizeWord() passed
>>     TestCase ParserItalicSlashFormattingTest->testEmphasizePhrase()
>>     passed
>>     TestCase ParserItalicSlashFormattingTest->testEmphasizeLine() passed
>>     TestCase
>>     ParserItalicSlashFormattingTest->testMismatchedEmphasizedPhrase()
>>     passed
>>     TestCase
>>     ParserItalicSlashFormattingTest->testMismatchedEmphasizedPhrase2()
>>     passed
>>     TestCase
>>     ParserItalicSlashFormattingTest->testMismatchedEmphasizedPhrase3()
>>     passed
>>     TestCase
>>     ParserItalicSlashFormattingTest->testMismatchedEmphasizedPhrase4()
>>     passed
>>     TestCase
>>     ParserItalicSlashFormattingTest->testEmphasizeEndsAtEoln() passed
>>     TestCase
>>     ParserUnderlineUnderbarFormattingTest->testEmphasizeWord() passed
>>     TestCase
>>     ParserUnderlineUnderbarFormattingTest->testEmphasizePhrase() passed
>>     TestCase
>>     ParserUnderlineUnderbarFormattingTest->testEmphasizeLine() passed
>>     TestCase
>>     ParserUnderlineUnderbarFormattingTest->testMismatchedEmphasizedPhrase()
>>     passed
>>     TestCase
>>     ParserUnderlineUnderbarFormattingTest->testMismatchedEmphasizedPhrase2()
>>     passed
>>     TestCase
>>     ParserUnderlineUnderbarFormattingTest->testMismatchedEmphasizedPhrase3()
>>     passed
>>     TestCase
>>     ParserUnderlineUnderbarFormattingTest->testMismatchedEmphasizedPhrase4()
>>     passed
>>     TestCase
>>     ParserUnderlineUnderbarFormattingTest->testEmphasizeEndsAtEoln()
>>     passed
>>     TestCase
>>     ParserFixedwidthEqualsFormattingTest->testEmphasizeWord() passed
>>     TestCase
>>     ParserFixedwidthEqualsFormattingTest->testEmphasizePhrase() passed
>>     TestCase
>>     ParserFixedwidthEqualsFormattingTest->testEmphasizeLine() passed
>>     TestCase
>>     ParserFixedwidthEqualsFormattingTest->testMismatchedEmphasizedPhrase()
>>     passed
>>     TestCase
>>     ParserFixedwidthEqualsFormattingTest->testMismatchedEmphasizedPhrase2()
>>     passed
>>     TestCase
>>     ParserFixedwidthEqualsFormattingTest->testMismatchedEmphasizedPhrase3()
>>     passed
>>     TestCase
>>     ParserFixedwidthEqualsFormattingTest->testMismatchedEmphasizedPhrase4()
>>     passed
>>     TestCase
>>     ParserFixedwidthEqualsFormattingTest->testEmphasizeEndsAtEoln()
>>     passed
>>     TestCase ParserstrikeoutHyphenFormattingTest->testEmphasizeWord()
>>     passed
>>     TestCase
>>     ParserstrikeoutHyphenFormattingTest->testEmphasizePhrase() passed
>>     TestCase ParserstrikeoutHyphenFormattingTest->testEmphasizeLine()
>>     passed
>>     TestCase
>>     ParserstrikeoutHyphenFormattingTest->testMismatchedEmphasizedPhrase()
>>     passed
>>     TestCase
>>     ParserstrikeoutHyphenFormattingTest->testMismatchedEmphasizedPhrase2()
>>     passed
>>     TestCase
>>     ParserstrikeoutHyphenFormattingTest->testMismatchedEmphasizedPhrase3()
>>     passed
>>     TestCase
>>     ParserstrikeoutHyphenFormattingTest->testMismatchedEmphasizedPhrase4()
>>     passed
>>     TestCase
>>     ParserstrikeoutHyphenFormattingTest->testEmphasizeEndsAtEoln() passed
>>     TestCase ParserBoldTagFormattingTest->testEmphasizeWord() passed
>>     TestCase ParserBoldTagFormattingTest->testEmphasizePhrase() passed
>>     TestCase ParserBoldTagFormattingTest->testEmphasizeLine() passed
>>     TestCase ParserItalicTagFormattingTest->testEmphasizeWord() passed
>>     TestCase ParserItalicTagFormattingTest->testEmphasizePhrase() passed
>>     TestCase ParserItalicTagFormattingTest->testEmphasizeLine() passed
>>     TestCase ParserUnderlineTagFormattingTest->testEmphasizeWord() passed
>>     TestCase ParserUnderlineTagFormattingTest->testEmphasizePhrase()
>>     passed
>>     TestCase ParserUnderlineTagFormattingTest->testEmphasizeLine() passed
>>     TestCase ParserFixedwidthTagFormattingTest->testEmphasizeWord()
>>     passed
>>     TestCase ParserFixedwidthTagFormattingTest->testEmphasizePhrase()
>>     passed
>>     TestCase ParserFixedwidthTagFormattingTest->testEmphasizeLine()
>>     passed
>>     TestCase ParserBasicFormattingTest->testCROnlyLineEndings()
>>     failed: Multiple lines ending in CR expected
>>     <p>A</p><p>B</p><p>C</p>, actual <p>A
>>     B
>>
>>     C</p>
>>     TestCase
>>     ParserBoldTagFormattingTest->testMismatchedEmphasizedPhrase()
>>     failed: expected <p>this phrase <b>is mismatched</p>, actual
>>     <p>this phrase &lt;b&gt;is mismatched</p>
>>     TestCase
>>     ParserBoldTagFormattingTest->testMismatchedEmphasizedPhrase2()
>>     failed: expected <p>this phrase <b origin="html">is</b>
>>     <b>mismatched in an intersting way</p>, actual <p>this phrase <b
>>     origin="html">is</b> &lt;b&gt;mismatched in an intersting way</p>
>>     TestCase ParserBoldTagFormattingTest->testEmphasizeEndsAtEoln()
>>     failed: expected <p>A <b>Emphasize phrase</p><p>cannot
>>     continue</b> across a line.</p>, actual <p>A &lt;b&gt;Emphasize
>>     phrase</p><p>cannot continue&lt;/b&gt; across a line.</p>
>>     TestCase
>>     ParserItalicTagFormattingTest->testMismatchedEmphasizedPhrase()
>>     failed: expected <p>this phrase <i>is mismatched</p>, actual
>>     <p>this phrase &lt;i&gt;is mismatched</p>
>>     TestCase
>>     ParserItalicTagFormattingTest->testMismatchedEmphasizedPhrase2()
>>     failed: expected <p>this phrase <i origin="html">is</i>
>>     <i>mismatched in an intersting way</p>, actual <p>this phrase <i
>>     origin="html">is</i> &lt;i&gt;mismatched in an intersting way</p>
>>     TestCase ParserItalicTagFormattingTest->testEmphasizeEndsAtEoln()
>>     failed: expected <p>A <i>Emphasize phrase</p><p>cannot
>>     continue</i> across a line.</p>, actual <p>A &lt;i&gt;Emphasize
>>     phrase</p><p>cannot continue&lt;/i&gt; across a line.</p>
>>     TestCase
>>     ParserUnderlineTagFormattingTest->testMismatchedEmphasizedPhrase()
>>     failed: expected <p>this phrase <u>is mismatched</p>, actual
>>     <p>this phrase &lt;u&gt;is mismatched</p>
>>     TestCase
>>     ParserUnderlineTagFormattingTest->testMismatchedEmphasizedPhrase2()
>>     failed: expected <p>this phrase <u origin="html">is</u>
>>     <u>mismatched in an intersting way</p>, actual <p>this phrase <u
>>     origin="html">is</u> &lt;u&gt;mismatched in an intersting way</p>
>>     TestCase
>>     ParserUnderlineTagFormattingTest->testEmphasizeEndsAtEoln()
>>     failed: expected <p>A <u>Emphasize phrase</p><p>cannot
>>     continue</u> across a line.</p>, actual <p>A &lt;u&gt;Emphasize
>>     phrase</p><p>cannot continue&lt;/u&gt; across a line.</p>
>>     TestCase
>>     ParserFixedwidthTagFormattingTest->testMismatchedEmphasizedPhrase()
>>     failed: expected <p>this phrase <tt>is mismatched</p>, actual
>>     <p>this phrase &lt;tt&gt;is mismatched</p>
>>     TestCase
>>     ParserFixedwidthTagFormattingTest->testMismatchedEmphasizedPhrase2()
>>     failed: expected <p>this phrase <tt origin="html">is</tt>
>>     <tt>mismatched in an intersting way</p>, actual <p>this phrase
>>     <tt origin="html">is</tt> &lt;tt&gt;mismatched in an intersting
>>     way</p>
>>     TestCase
>>     ParserFixedwidthTagFormattingTest->testEmphasizeEndsAtEoln()
>>     failed: expected <p>A <tt>Emphasize phrase</p><p>cannot
>>     continue</tt> across a line.</p>, actual <p>A &lt;tt&gt;Emphasize
>>     phrase</p><p>cannot continue&lt;/tt&gt; across a line.</p>
>>     TestCase ParserStrikeoutTagFormattingTest->testEmphasizeWord()
>>     failed: expected <p>start <strike origin="wiki">middle</strike>
>>     end</p>, actual <p>start <strike origin="html">middle</strike>
>>     end</p>
>>     TestCase ParserStrikeoutTagFormattingTest->testEmphasizePhrase()
>>     failed: expected <p>start <strike origin="wiki">middle
>>     words</strike> end</p>, actual <p>start <strike
>>     origin="html">middle words</strike> end</p>
>>     TestCase ParserStrikeoutTagFormattingTest->testEmphasizeLine()
>>     failed: expected <p><strike origin="wiki">middle
>>     words</strike></p>, actual <p><strike origin="html">middle
>>     words</strike></p>
>>     TestCase
>>     ParserStrikeoutTagFormattingTest->testMismatchedEmphasizedPhrase()
>>     failed: expected <p>this phrase <strike>is mismatched</p>, actual
>>     <p>this phrase &lt;strike&gt;is mismatched</p>
>>     TestCase
>>     ParserStrikeoutTagFormattingTest->testMismatchedEmphasizedPhrase2()
>>     failed: expected <p>this phrase <strike origin="wiki">is</strike>
>>     <strike>mismatched in an intersting way</p>, actual <p>this
>>     phrase <strike origin="html">is</strike> &lt;strike&gt;mismatched
>>     in an intersting way</p>
>>     TestCase
>>     ParserStrikeoutTagFormattingTest->testEmphasizeEndsAtEoln()
>>     failed: expected <p>A <strike>Emphasize phrase</p><p>cannot
>>     continue</strike> across a line.</p>, actual <p>A
>>     &lt;strike&gt;Emphasize phrase</p><p>cannot
>>     continue&lt;/strike&gt; across a line.</p>
>>
>>
>>     *--------------------------------------------------
>>       78 tests, passed=59, failed=19, errors=0
>>     --------------------------------------------------*
>>
>
> ------------------------------------------------------------------------
>
> so we can mail * you a copy immediately. * * @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.13 $ * */ /** * coWiki - coWiki parser class * * @package parse * 
> @subpackage class * @access public * * @author Daniel T. Gorski, * 
> @since coWiki 0.3.0 * @author Archie Campbell * @since coWiki 0.4.0 * 
> * @todo [D11N] Complete documentation */ class CoWikiParser extends 
> WikiParser { /** * Get instance * * @access public * @return mixed * * 
> @author Daniel T. Gorski, * @since coWiki 0.3.0 * * @todo [D11N] Check 
> description * @todo [D11N] Check return type */ public function 
> getInstance() { if (!self::$Instance) { self::$Instance = new 
> CoWikiParser; } return self::$Instance; } protected function 
> __construct() {} // --- Element creators 
> ----------------------------------------------- /** * Create a 
> -element. This method overwrites the parent one. * * @access protected 
> * @param string * @return mixed * * @author Daniel T. Gorski, * @since 
> coWiki 0.3.0 * @author Archie Campbell * @since coWiki 0.4.0 */ 
> protected function createLinkElement($sStr, $bSquare = false) { $aStr 
> = explode(($bSquare?"][":")("),$sStr); $sRef = false; $sAlias = false; 
> if (isset($aStr[0])) { $sRef = trim($this->restoreTokens($aStr[0])); } 
> if (isset($aStr[1])) { $sAlias = trim($this->restoreTokens($aStr[1])); 
> } // Check if reference string is an URI, if so return the // element 
> $sPattern = '^(http://|https://|ftp://|mailto:|news:).*'; if 
> (preg_match('=' . $sPattern . '=', $sRef)) { return 
> $this->createUriLinkElement($sRef, $sAlias, $bSquare); } // Obviously 
> the reference string is not an URI. Check if it has // a reference to 
> an other web. Means: "webname|documentname" $aWebRef = explode('|', 
> $sRef); // Do we have a reference to an other web? if 
> (sizeof($aWebRef) > 1) { $sWeb = trim($aWebRef[0]); $sRef = 
> trim($aWebRef[1]); return $this->createGlobalLinkElement($sWeb, $sRef, 
> $sAlias, $bSquare); } // The reference string was not an URI and it 
> has no reference // to an other web -> Look up in database. return 
> $this->createLocalLinkElement($sRef, $sAlias, $bSquare); } /** * If a 
> link is an URI * * @access protected * @param string * @param string * 
> @return string * * @author Daniel T. Gorski, * @since coWiki 0.3.0 * 
> @author Archie Campbell * @since coWiki 0.4.0 */ protected function 
> createUriLinkElement($sRef, $sAlias, $bSquare) { $sStr = ' '; if 
> ($sAlias && $sAlias != '') { $sStr .= $sAlias ; } $sStr .= ''; return 
> $sStr; } /** * If a link references to an other web (global) * * 
> @access protected * @param string * @param string * @param string * 
> @return string * * @author Daniel T. Gorski, * @since coWiki 0.3.0 * 
> @author Archie Campbell * @since coWiki 0.4.0 */ protected function 
> createGlobalLinkElement($sWeb, $sRef, $sAlias, $bSquare) { $Context = 
> RuntimeContext::getInstance(); $sWebStr = unescape($sWeb); $sRefStr = 
> unescape($sRef); // Find web by its name $WebNode = 
> $Context->getDocumentDAO()->getWebByName($sWebStr); // Found web if 
> (is_object($WebNode)) { // If document reference string is empty 
> ((web|)), just link // to the web directly if ($sRefStr == '') { $Node 
> = $WebNode; } else { // Otherwise find a document by its name (in the 
> // referenced web) $Node = $Context->getDocumentDAO()->getNodeByName( 
> $sRefStr, $WebNode->get('treeId'), 'node_id, name' ); } // Found 
> document if (is_object($Node)) { // Remember resolved reference 
> $this->addReferencedNode($Node); // Create element $sStr = ' '; $sStr 
> .= $sAlias; $sStr .= ''; } } if (!is_object($WebNode) || 
> !is_object($Node)) { $sStr = ' '; $sStr .= $sAlias; $sStr .= ''; } 
> return $sStr; } /** * If a link references within a web only (local) * 
> * @access protected * @param string * @param string * @return string * 
> * @author Daniel T. Gorski, * @since coWiki 0.3.0 * @author Archie 
> Campbell * @since coWiki 0.4.0 */ protected function 
> createLocalLinkElement($sRef, $sAlias, $bSquare) { $Context = 
> RuntimeContext::getInstance(); // Get current directory/document 
> object $Node = $Context->getCurrentNode(); $aData = false; $sRefStr = 
> unescape($sRef); // Find document by its name (in the local web) 
> $NewNode = $Context->getDocumentDAO()->getNodeByName( $sRefStr, 
> $Node->get('treeId'), 'node_id, name' ); if (is_object($NewNode)) { // 
> Remember resolved reference $this->addReferencedNode($NewNode); // 
> Create element $sStr = ' '; $sStr .= $sAlias; $sStr .= ''; } if 
> (!is_object($NewNode)) { $sStr = ' '; $sStr .= $sAlias; $sStr .= ''; } 
> return $sStr; } } // of class /* Moments lost though time remains I am 
> so proud of what we were No pain remains, no feeling Eternity awaits 
> Grant me wings that I might fly My restless soul is longing No pain 
> remains, no feeling Eternity awaits */ ?>
> ------------------------------------------------------------------------
>
> so we can mail * you a copy immediately. * * @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.15 $ * */ /** * coWiki - coWiki reverse parser class * * @package 
> parse * @subpackage class * @access public * * @author Daniel T. 
> Gorski, * @since coWiki 0.3.0 * @author Archie Campbell * @since 
> coWiki 0.4.0 * * @todo [D11N] Complete documentation */ class 
> CoWikiReverseParser extends WikiReverseParser { protected $aWebList = 
> array(); /** * Get instance * * @access public * @return mixed * * 
> @author Daniel T. Gorski, * @since coWiki 0.3.0 * * @todo [D11N] Check 
> description * @todo [D11N] Check return type */ public function 
> getInstance() { if (!self::$Instance) { self::$Instance = new 
> CoWikiReverseParser; } return self::$Instance; } /** * Class 
> constructor * * @access protected * @return void * * @author Daniel T. 
> Gorski, * @since coWiki 0.3.0 */ protected function __construct() { 
> $Context = RuntimeContext::getInstance(); // If link references point 
> to an other web, we will need // some web data. Get the names of all 
> webs. $Node = $Context->getDocumentDAO()->getWebComposite(); // 
> Iterate through children $It = $Node->getItems()->iterator(); while 
> ($Obj = $It->next()) { $this->aWebList[$Obj->get('id')] = 
> $Obj->get('name'); } } /** * Process link * * @access protected * 
> @param string * @return string * * @author Daniel T. Gorski, * @since 
> coWiki 0.3.0 * * @todo [D11N] Check description */ protected function 
> processLink(&$sStr) { $sStr = preg_replace_callback( '= (.*)=Umsi', 
> array(&$this, 'buildStrRefLink'), $sStr ); $sStr = 
> preg_replace_callback( '= (.*)=Umsi', array(&$this, 
> 'buildHyperRefLink'), $sStr ); $sStr = preg_replace_callback( '= 
> (.*)=Umsi', array(&$this, 'buildIdRefLink'), $sStr ); return $sStr; } 
> /** * Build id ref link * * @access protected * @param array * @return 
> mixed * * @author Daniel T. Gorski, * @since coWiki 0.3.0 * @author 
> Archie Campbell * @since coWiki 0.4.0 * * @todo [D11N] Check 
> description */ protected function buildIdRefLink(&$aMatches) { 
> $Context = RuntimeContext::getInstance(); // Get current 
> directory/document object $Node = $Context->getCurrentNode(); // Get 
> referenced node (faster: get required fields only) $RefNode = 
> $Context->getDocumentDAO()->getNodeById( $aMatches[1], 'tree_id, 
> parent_id, name' ); // If no referenced document was found if 
> (!is_object($RefNode)) { if ($aMatches[0]=='square') { return 
> '['.'['.$aMatches[1].']['.$aMatches[2].']'. 
> __('I18N_DOC_DELETED_DOCUMENT').']'; } else { return 
> '['.'('.$aMatches[1].')('.$aMatches[2].')'. 
> __('I18N_DOC_DELETED_DOCUMENT').']'; } } // Normalize! $aMatches[2] = 
> unescape($aMatches[2]); $sPrefix = ''; // Link reference in an other 
> web? if ($Node->get('treeId') != $RefNode->get('treeId')) { if 
> (isset($this->aWebList[$RefNode->get('treeId')])) { $sPrefix = 
> escape($this->aWebList[$RefNode->get('treeId')]); $sPrefix .= '|'; } 
> else { $sPrefix = 'UNKNOWN|'; } // Special treatment if links point to 
> a web if ($RefNode->get('isWeb')) { // Link directly to a web with an 
> alias if ($aMatches[2] != '') { if( $aMatches[0]=='square' ) { return 
> '[['.$sPrefix.']['.escape($aMatches[2]).']]'; } else { return 
> '(('.$sPrefix.')('.escape($aMatches[2]).'))'; } } // Link directly to 
> a web without alias if ($aMatches[0]=='square') { return 
> '[['.$sPrefix.']]'; } else { return '(('.$sPrefix.'))'; } } } // --- 
> // Generate normal link without alias if ($aMatches[2] == '') { if 
> ($aMatches[0]=='square') { return '[[' .$sPrefix 
> .escape($RefNode->get('name')) .']]'; } else { return '((' .$sPrefix 
> .escape($RefNode->get('name')) .'))'; } } // Generate normal link with 
> an alias if ($aMatches[0] == 'square' ) { return '[' .'[' .$sPrefix 
> .$this->noopDelimiters(escape($RefNode->get('name'))) .']' .'[' 
> .escape($aMatches[2]) . ']' .']'; } else { return '(' .'(' .$sPrefix 
> .$this->noopDelimiters(escape($RefNode->get('name'))) .')' .'(' 
> .escape($aMatches[2]) . ')' .')'; } } /** * Build hyper ref link * * 
> @access protected * @param array * @return mixed * * @author Daniel T. 
> Gorski, * @since coWiki 0.3.0 * @author Archie Campbell * @since 
> coWiki 0.4.0 * * @todo [D11N] Check description */ protected function 
> buildHyperRefLink(&$aMatches) { if (trim($aMatches[2]) == '') { if( 
> $aMatches[0] == 'square' ) { return '[[' . $aMatches[1] . ']]'; } else 
> { return '((' . $aMatches[1] . '))'; } } if( $aMatches[0] == 'square' 
> ) { return '[[' . $aMatches[1] . '][' . $aMatches[2] . ']]'; } else { 
> return '((' . $aMatches[1] . ')(' . $aMatches[2] . '))'; } } } // of 
> class ?>
> ------------------------------------------------------------------------
>
> 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 * @author Archie Campbell * @since coWiki 0.4.0 */ class 
> WikiParser extends Object { protected static $Instance = null; 
> protected $aToc = array(), $aRows = array(), $iRow = 0; protected 
> $aEmph = array(); protected $RefNodes = null; // 
> -------------------------------------------------------------------- 
> /** * 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; } /** * 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() { $this->resetEmphasis(); } 
> // --- Helper methods 
> ------------------------------------------------- /** * @access 
> protected * * @author Daniel T. Gorski, * @since coWiki 0.3.0 */ 
> protected function restoreTokens($sStr){ return $sStr; } /** * 
> 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) { $sAlias = 
> # $this->aToc[$i]['TEXT']; $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; } // 
> -------------------------------------------------------------------- 
> /** * parse * * @access public * @param string The wiki source string 
> * @return string Wiki XML * * @author Archie Campbell * @since coWiki 
> 0.4.0 */ public function parse($sStr) { $sRet = ''; $sContent = ''; 
> $bList = false; $bTable = false; $bBegin = false; $aList = array(); 
> $aTable = array(); // {{{ DEBUG }}} Logger::info('Start parsing wiki 
> document.'); // Init reference collection $this->RefNodes = new 
> Vector; $this->resetEmphasis(); // --- $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); $this->aRows = 
> explode( "\n",$sStr."\n" ); $this->iRow = 0; $sRow = 
> $this->aRows[$this->iRow]; $bBegin = true; $t = 0; $l = -1; while( 
> true ) { $sContent = ''; $aMatches = array(); //table of contents 
> alone ^$ if( $bBegin && preg_match( '=^<toc(/?)>$=', $sRow, $aMatches 
> )) { $sRet .= "\n\t\t\n"; //plugins }else if( $bBegin && preg_match( 
> '=^<plugin +([A-Za-z0-9_.]+)( +([^&]*))?(/?)>=i', $sRow, $aMatches )) 
> { if(isset($aMatches[3])){ $sRet .= ''; }else{ $sRet .= ''; } 
> //headings }else if( $bBegin && preg_match( '=^(\+{1,})\s*(.*)$=s', 
> $sRow, $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 . ''; 
> //end of table } else if( $bBegin && ($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( $bBegin && preg_match( '=^<table([^>]*)>$=Ui', $sRow, 
> $aMatches )) { $bTable = true; $aTable[++$t] = array(); array_push( 
> $aTable[$t], $aMatches[1] ); //beginning of list } else if( $bBegin && 
> 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'); //horizontal rule } else if ($bBegin && 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(++$this->iRowaRows)){ $sRow = $this->aRows[$this->iRow]; } 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 ); }else{ $sRet .= $sContent; } //more table }else 
> if($bTable) { array_push( $aTable[$t], $sRow ); $sRow = ''; //non 
> table/list row }else{ $sContent = $this->processContent( $sRow ); if( 
> $sContent != '' ){ $sRet .= '
>
> '.$sContent.'
>
> '; } $sRow = ''; } } if(isset($aMatches[0])) { $sRow = substr( $sRow, 
> strlen( $aMatches[0] ) ); $bBegin = false; } if ( trim($sRow) == '' ) 
> { if( ++$this->iRow < sizeof($this->aRows) ) { $sRow = 
> $this->aRows[$this->iRow]; $bBegin = true; } else { break; } } } if( 
> preg_match( '=^(.*)\n\t\t\n(.*)$=s', $sRet, $aMatches )) { $t = 0; if 
> (sizeof($this->aToc) > 0) { $sToc = $this->buildToc($t, 
> $this->aToc[$t]['DEPTH']); if ($sToc != '') { $sToc = '
>
>       ' . $sToc . ' 
>
> '; } else { $sToc = ''; } } return $aMatches[1] . $sToc . 
> $aMatches[2]; } // {{{ DEBUG }}} Logger::info('Finished parsing wiki 
> document.'); return $sRet; } /** * reset Emphasis * * @access 
> protected * * @author Archie Campbell * @since coWiki 0.4.0 */ 
> protected function resetEmphasis() { $this->aEmph = array( "b" => 
> false, "u" => false, "i" => false, "f" => false, "s" => false, "j" => 
> '', "p" => '' ); } /** * processContent * * @access protected * 
> @return string * * @author Archie Campbell * @since coWiki 0.4.0 */ 
> protected function processContent( $sStr ) { $sRet = ''; $aMatches = 
> array(); $this->resetEmphasis(); $sStr = ltrim( $sStr ); while( trim( 
> $sStr ) != '' ) { //noop if (preg_match( '=^<noop>=is', $sStr, 
> $aMatches )) { //greedily munch all until $sStr = substr( $sStr, 
> strlen( $aMatches[0] ) ); $sContent = ''; while( !preg_match( 
> '=^</noop>=is', $sStr, $aMatches ) ) { preg_match( 
> '=([^&]|(\&(?![lg])))*=is', $sStr, $aMatches ); $sContent .= 
> $aMatches[0]; $sStr = substr( $sStr, strlen( $aMatches[0] ) ); if ( 
> $sStr == "\n" ) { if ( ++$this->iRow < sizeof($this->aRows) ) { $sStr 
> = $this->aRows[$this->iRow]; } else { $sStr = ''; break; } } } $sRet 
> .= '' . $sContent . ''; //paragraphs } else if (preg_match( 
> '=^<(/??)p>=i', $sStr, $aMatches) ) { //justification } else if( 
> preg_match( '=^<(/?)(left|center|right)>=i', $sStr, $aMatches )) { 
> $sRet .= '<'.$aMatches[1].$aMatches[2].'>'; /* 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}; } */ //pre code posting q start 
> at BOL, are greedy until // closing tag anywhere on a line } else if 
> (preg_match( '=^<(pre|code|posting|q|rem)>=i', $sStr, $aMatch ) ) { 
> $sStr = substr( $sStr, strlen($aMatch[0]) ); do { if (preg_match( 
> '=(.*)</'.$aMatch[1].'>=i', $sStr, $aMatches )) { $sRet .= 
> '<'.$aMatch[1].'>'.$sContent . $aMatches[1].''; break; } else { 
> $sContent .= $sStr ."\n"; } if( ++$this->iRow < sizeof($this->aRows) 
> ){ $sStr = $this->aRows[$this->iRow]; }else{ break; } } while(true); 
> if( $this->iRow == sizeof($this->aRows) ) { $sRet .= 
> '<'.$aMatch[1].'>'. $sContent . ''; break; } //line-break }else if( 
> preg_match( '=^<br([ /]+)>=is', $sStr, $aMatches )) { $sRet .= '
> '; //variables }else if( preg_match( '=^%([A-Z0-9_]+)%=U', $sStr, 
> $aMatches )) { $sRet .= ''; //links (()()) }else if( preg_match( 
> '=^\(\(([^\(\)]+|[^\(\)]+' . '\([^\(\)]+\)[^\(\)]*|' . 
> '[^\(\)]+\)\([^\(\)]+)\)\)=Usx', $sStr, $aMatches )) { $sRet .= 
> $this->createLinkElement( $aMatches[1] ); //links [[][]] }else if( 
> preg_match( '=^\[\[([^\[\]]+|[^\[\]]+' . '\[[^\[\]]+\][^\[\]]*|' . 
> '[^\[\]]+\]\[[^\[\]]+)\]\]=Usx', $sStr, $aMatches )) { $sRet .= 
> $this->createLinkElement( $aMatches[1], true ); /* $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 . ''; */ /* //urls }else if( 
> preg_match( '=^<url(\s+)( (http://|https://|ftp://|mailto:|news:) 
> ([-_A-Z0-9\S]*) (\*\s|\=\s|"|<|>|<|>|\(|\)|\s|$)?? )>=six', $sStr, 
> $aMatches ) ) { */ //URIs }else if( preg_match( 
> '=^(http://|https://|ftp://|mailto:|news:) ([-_A-Z0-9\S]*) 
> (\*\s|\=\s|"|<|>|<|>|\(|\)|\s|$)?? =six', $sStr, $aMatches )) { $sRet 
> .= ''; //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( 
> '#^<(/??)(strike|tt|b|u|i)>#is', $sStr, $aMatches ) ) { 
> switch($aMatches[2]{0}){ case 's': case 'S': if( $aMatches[1]=='/' ) { 
> $sRet .= "\x11"; } else { $sRet .= "\x06"; } break; case 't': case 
> 'T': if( $aMatches[1]=='/' ) { $sRet .= "\x12"; } else { $sRet .= 
> "\x07"; } break; case 'b': case 'B': if( $aMatches[1]=='/' ) { $sRet 
> .= "\x13"; } else { $sRet .= "\x08"; } break; case 'u': case 'U': if( 
> $aMatches[1]=='/' ) { $sRet .= "\x14"; } else { $sRet .= "\x09"; } 
> break; case 'i': case 'I': if( $aMatches[1]=='/' ) { $sRet .= "\x15"; 
> } else { $sRet .= "\x10"; } break; } //emphasis }else if( preg_match( 
> '#^([-=\*_/]{2})#', $sStr, $aMatches ) ) { if(preg_match( 
> '#^['.$aMatches[1]{0}.']{1,}#', substr($sStr,strlen($aMatches[0])), 
> $aHead) ) { $aMatches[0] .= $aHead[0]; $sRet .= $aMatches[0]; } else { 
> switch($aMatches[1]{0}){ case '-': $sRet .= "\x01"; break; case '=': 
> $sRet .= "\x02"; break; case '*': $sRet .= "\x03"; break; case '_': 
> $sRet .= "\x04"; break; case '/': $sRet .= "\x05"; break; } } 
> //unknown tags }else if( preg_match( '#^<[^>&]*>#', $sStr, $aMatches ) 
> ) { $sRet .= $aMatches[0]; }else if( preg_match( 
> '#^((([-=\*_/]{1})(?!\3))|[^-=\*_/&]|(&(?![lg])))*#', $sStr, $aMatches 
> ) ) { $sRet .= $aMatches[0]; } if( isset($aMatches[0]) ) { $sStr = 
> substr( $sStr, strlen($aMatches[0]) ); } } //process emphasis tokens 
> $sStr = $sRet; $sRet = ''; $p = 0; //while found wiki tokens (count) 
> //convert in pairs or replace (as we go) 
> $this->replaceWikiTokens("\x01","-","strike",$sStr); 
> $this->replaceWikiTokens("\x02","=","tt",$sStr); 
> $this->replaceWikiTokens("\x03","*","b",$sStr); 
> $this->replaceWikiTokens("\x04","_","u",$sStr); 
> $this->replaceWikiTokens("\x05","/","i",$sStr); //while found html 
> tokens (paired) //correspond or replace (suitably as we go) 
> $this->replaceHtmlTokens("\x06","\x11","strike",$sStr); 
> $this->replaceHtmlTokens("\x07","\x12","tt",$sStr); 
> $this->replaceHtmlTokens("\x08","\x13","b",$sStr); 
> $this->replaceHtmlTokens("\x09","\x14","u",$sStr); 
> $this->replaceHtmlTokens("\x10","\x15","i",$sStr); return $sStr; } 
> protected function replaceWikiTokens( $char,$wiki,$sHtml, &$sStr ) { 
> $sRet = ''; $open = false; $c = substr_count($sStr,$char); if(!$c) { 
> return; } while( $c ) { if($sStr{0} == $char){ if($c >= 2 || ($c == 1 
> && $open) ) { $sRet .= '<'.($open?'/':'').$sHtml. ($open?'':' 
> origin="wiki"').'>'; $open = !$open; $c--; } else { $sRet .= 
> str_repeat($wiki,2); $c--; } } else { $sRet .= $sStr{0}; } $sStr = 
> substr($sStr,1); } $sRet .= $sStr; $sStr = $sRet; } protected function 
> replaceHtmlTokens( $start, $end, $sHtml, &$sStr ) { $sRet = ''; $open 
> = false; $s = substr_count($sStr,$start); $e = 
> substr_count($sStr,$end); if(!$s && !$e) { return; } while( $s || $e ) 
> { if($sStr{0} == $start){ if($e > 0){ $sRet .= '<'.$sHtml.' 
> origin="html">'; $open = true; } else { $sRet .= '<'.$sHtml.'>'; } 
> $s--; } else if($sStr{0} == $end){ if($open){ $sRet .= ''; $open = 
> false; } else { $sRet .= '</'.$sHtml.'>'; } $e--; } else { $sRet .= 
> $sStr{0}; } $sStr = substr($sStr,1); } $sRet .= $sStr; $sStr = $sRet; 
> } /** * &build table * * @access protected * @return string * * 
> @author Archie Campbell * @since coWiki 0.4.0 */ protected function 
> buildTable( &$aTable ) { $sRet = ''; $sContent = ''; $sRow = ''; 
> $bPriorRow = false; $aMatches = array(); $j = 0; $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 (isset($aMatches[2]) && $aMatches[2]{0}==' ') 
> { //left a space to denote no params $sRet .= '>'; $sContent .= 
> substr($aMatches[2],1); //expect double pipe, bang or newline } elseif 
> (isset($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 (trim($sRow) == '') { //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; } } /** * 
> &build list * * @access protected * @return string * * @author Archie 
> Campbell * @since coWiki 0.4.0 */ 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 indented 
> 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; } // 
> -------------------------------------------------------------------- } 
> // 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. 
> */ ?>
> ------------------------------------------------------------------------
>
> so we can mail * you a copy immediately. * * @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.17 $ * */ /** * coWiki - Wiki reverse parser class * * @package 
> parse * @subpackage class * @access public * * @author Daniel T. 
> Gorski, * @since coWiki 0.3.0 * @author Archie Campbell * @since 
> coWiki 0.4.0 * * @todo [D11N] Complete documentation */ class 
> WikiReverseParser extends Object { protected static $Instance = null, 
> $Context = null, $DocDAO = null; private $rParser = null; private 
> $ignoreToc = false, $aList = array(), $nDepth = 0, $aType = array(), 
> $aTable = array(), // $nTable = null; $sLink = array(), $fLink = 
> array(), $aState = array(0), $sContent = '', $aRow = array(), 
> $nListIndent = null; // 
> -------------------------------------------------------------------- 
> /** * Get instance * * @access public * @return mixed * * @author 
> Daniel T. Gorski, * @since coWiki 0.3.0 * * @todo [D11N] Check 
> description * @todo [D11N] Check return type */ public function 
> getInstance() { if (!self::$Instance) { self::$Instance = new 
> WikiReverseParser; } return self::$Instance; } // 
> -------------------------------------------------------------------- 
> /** * Parse * * @access protected * @param string * @return void * * 
> @author Daniel T. Gorski, * @since coWiki 0.3.0 * * @todo [D11N] Check 
> description */ protected function __construct() { $this->Context = 
> RuntimeContext::getInstance(); $this->DocDAO = 
> $this->Context->getDocumentDAO(); } // 
> -------------------------------------------------------------------- 
> // FIX: THIS METHOD DO NOT COVER ALL POSSIBLE OCCURANCES OF DELIMITERS 
> // YET! THIS HAS TO BE CHECKED AND FIXED. /** * If a string reference 
> contains delimiters, escape them with * * @access protected * @param 
> string * @return mixed * * @author Daniel T. Gorski, * @since coWiki 
> 0.3.0 * * @todo [D11N] Check return type */ protected function 
> noopDelimiters(&$sStr) { // Escape leading delimiters if 
> (substr($sStr, 0, 2) == '()') { $sStr = 
> '<noop>()</noop>'.substr($sStr, 2); } else if (substr($sStr, 0, 1) == 
> '(') { $sStr = '<noop>(</noop>'. substr($sStr, 1); } // Escape 
> trailing delimiters if (substr($sStr, -2) == '()') { $sStr = 
> substr($sStr, 0, -2).'<noop>()</noop>'; } else if (substr($sStr, -1) 
> == ')') { $sStr = substr($sStr, 0, -1).'<noop>)</noop>'; } // Escape 
> double closing $sStr = str_replace('))', '<noop>))</noop>', $sStr); // 
> Replace web/document delimiter return str_replace('¦', '|', $sStr); } 
> // 
> -------------------------------------------------------------------- 
> /** * Helper functions * * @author Archie Campbell * @since coWiki 
> 0.4.0 * */ protected function appendRow($sStr){ 
> array_push($this->aRow,$sStr); $this->clearContent(); } protected 
> function clearContent(){ $this->sContent = ''; } protected function 
> clearRow() { if($this->sContent!=''){ 
> $this->appendRow($this->sContent); } } protected function 
> textListItem( $sData ) { $this->aList[sizeof($this->aList)-1]['TEXT'] 
> .= $sData; } protected function pushTableItem( $sData ) { 
> array_push($this->aTable[sizeof($this->aTable)-1],$sData); } /** * 
> Parse * * @access public * @param string * @return mixed * * @author 
> Archie Campbell * @since coWiki 0.4.0 * */ public function 
> parse($sStr) { //return $this->dummy($sStr); if 
> (!function_exists('xml_parser_create')) { return false; } 
> $this->rParser = @xml_parser_create(); if (!$this->rParser) { return 
> false; } xml_parser_set_option($this->rParser, 
> XML_OPTION_CASE_FOLDING, 0); xml_parser_set_option($this->rParser, 
> XML_OPTION_SKIP_WHITE, 1); // 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); // Prepare XML, add root element 
> $sStr = '' . $sStr . ''; xml_set_default_handler( $this->rParser, 
> array(&$this,'xml_default_handler') ); xml_set_element_handler( 
> $this->rParser, array(&$this,'xml_start_handler'), 
> array(&$this,'xml_end_handler') ); xml_set_character_data_handler( 
> $this->rParser, array(&$this,'xml_cdata_handler') ); if(!xml_parse( 
> $this->rParser, $sStr )){ echo 
> xml_error_string(xml_get_error_code($this->rParser)); } return 
> implode("\n",$this->aRow); } /** * xml element start handler * * 
> @access protected * * @author Archie Campbell * @since coWiki 0.4.0 * 
> */ protected function xml_start_handler( &$parser, $sName, $aAttrib ) 
> { if($this->ignoreToc){ return; } switch($sName){ case 'document': 
> $this->aRow = array(); break; case 'toc': $this->clearRow(); 
> $this->ignoreToc = true; break; case 'plugin': $this->clearRow(); 
> $sStr = '1){ foreach($aAttrib as $attr => $value){ if($attr != 
> 'name'){ $sStr .= ' '.$attr.'='.$value; } } } $sStr .= '>'; 
> $this->appendRow($sStr); break; //table syntax case 'table': 
> $this->clearRow(); array_push($this->aState,6);/*WRP_TABL*/ 
> array_push($this->aTable,array($aAttrib));//[][0] break; case 
> 'caption': array_push($this->aState,7);/*WRP_CAPN*/ 
> $this->clearContent(); break; case 'tr': 
> array_push($this->aState,8);/*WRP_TROW*/ $sStr = '|-'; 
> if(sizeof($aAttrib)){ foreach($aAttrib as $attr => $value){ $sStr .= 
> $attr.'="'.$value.'" '; } } $this->pushTableItem( $sStr ); break; case 
> 'th': array_push($this->aState,9);/*WRP_THED*/ $sStr = '!'; 
> if(sizeof($aAttrib)){ foreach($aAttrib as $attr => $value){ $sStr .= 
> $attr.'="'.$value.'" '; } } $sStr .= ' '; $this->pushTableItem( $sStr 
> ); break; case 'td': array_push($this->aState,10);/*WRP_TCEL*/ $sStr = 
> '|'; if(sizeof($aAttrib)){ foreach($aAttrib as $attr => $value){ $sStr 
> .= $attr.'="'.$value.'" '; } } $sStr .= ' '; $this->pushTableItem( 
> $sStr ); break; //list syntax case 'list': $this->clearRow(); 
> array_push($this->aState,1);/*WRP_LIST*/ break; case 'ol': case 'ul': 
> $this->nDepth++; array_push($this->aType,$sName); break; case 'li': 
> switch(end($this->aState)){ case 1: if(strlen($this->sContent)){ 
> $this->textListItem($this->sContent); } array_push( $this->aList, 
> array( 'DEPTH'=>$this->nDepth, 'TYPE'=>(end($this->aType)=='ol'? 
> "#":"*"), 'TEXT'=>'' )); break; default: echo $sName . "insanity"; 
> exit; } $this->clearContent(); break; //paragraphs case 'p': 
> $this->clearRow(); break; //noop case 'noop': $this->sContent .= ''; 
> array_push($this->aState,5); break; //justification case 'left': case 
> 'right': case 'center': $this->sContent .= '<'.$sName.'>'; break; 
> //pre, code, posting, quote case 'pre': case 'code': case 'posting': 
> case 'q': case 'rem': $this->clearRow(); array_push($this->aState,4); 
> break; //line-break case 'br': $this->clearRow(); break; //variables 
> case 'var': $this->sContent .= "%".$aAttrib['name']."%"; break; 
> //headings case 'h1': case 'h2': case 'h3': case 'h4': case 'h5': case 
> 'h6': array_push($this->aState,3); break; //wiki links case 'uri': 
> $this->sContent .= $aAttrib['strref']; break; case 'link': 
> array_push($this->aState,2); if( isset($aAttrib['strref']) ) { 
> $this->fLink = array(&$this, 'buildStrRefLink'); $this->sLink[1] = 
> $aAttrib['strref']; }else if( isset($aAttrib['href']) ) { $this->fLink 
> = array(&$this, 'buildHyperRefLink'); $this->sLink[1] = 
> $aAttrib['href']; }else if( isset($aAttrib['idref']) ) { $this->fLink 
> = array(&$this, 'buildIdRefLink'); $this->sLink[1] = 
> $aAttrib['idref']; } $this->sLink[0] = $aAttrib['origin']; break; 
> //subscript & superscript case 'sub': case 'sup': $this->sContent .= 
> '<'.$sName.'>'; break; //horizontal rule case 'hr':break; //emphasis 
> (strike,tt,b,u,i) //WRP_ST WRP_TT WRP_B WRP_U WRP_I //11 12 13 14 15 
> case 'strike': if(isset($aAttrib['origin']) && 
> $aAttrib['origin']=='html'){ array_push($this->aState,11); 
> $this->sContent .= ""; }else{ $this->sContent .= "--"; } break; case 
> 'tt': if(isset($aAttrib['origin']) && $aAttrib['origin']=='html'){ 
> array_push($this->aState,12); $this->sContent .= ""; }else{ 
> $this->sContent .= "=="; } break; case 'b': 
> if(isset($aAttrib['origin']) && $aAttrib['origin']=='html'){ 
> array_push($this->aState,13); $this->sContent .= "*"; }else{ 
> $this->sContent .= "**"; } break; case 'u': 
> if(isset($aAttrib['origin']) && $aAttrib['origin']=='html'){ 
> array_push($this->aState,14); $this->sContent .= "_"; }else{ 
> $this->sContent .= "__"; } break; case 'i': 
> if(isset($aAttrib['origin']) && $aAttrib['origin']=='html'){ 
> array_push($this->aState,15); $this->sContent .= "/"; }else{ 
> $this->sContent .= "//"; } break; default: echo $sName . " start" . 
> "\n"; } } /** * xml element end handler * * @access protected * * 
> @author Archie Campbell * @since coWiki 0.4.0 * */ protected function 
> xml_end_handler( &$parser, $sName ) { if($this->ignoreToc){ if($sName 
> == 'toc'){ $this->appendRow(""); $this->ignoreToc = false; return; } } 
> switch($sName){ case 'document': $this->clearRow(); break; case 
> 'plugin': break; //table syntax case 'table': 
> if(array_pop($this->aState)!=6) { echo "insanity in table"; exit; } 
> $aTable = array_pop($this->aTable); $sStr = '
> $value ){ $sStr .= " ".$attr.'="'.$value.'"'; } $sStr .= 
> (sizeof($aTable)==1?'/>':'>'); $this->appendRow( $sStr ); for ($i = 1; 
> $i < sizeof($aTable) ; $i++){ $this->appendRow( $aTable[$i] ); } 
> $this->appendRow('
>
> '); break; //caption case 'caption': if(array_pop($this->aState)!=7) { 
> echo "insanity in caption"; exit; } $this->pushTableItem( "|+ 
> ".$this->sContent ); $this->clearContent(); break; case 'tr': 
> if(array_pop($this->aState)!=8) { echo "insanity in trow"; exit; } 
> break; case 'th': if(array_pop($this->aState)!=9) { echo "insanity in 
> thead"; exit; } if($this->sContent != ''){ 
> $this->pushTableItem($this->sContent); $this->clearContent(); } break; 
> case 'td': if(array_pop($this->aState)!=10) { echo "insanity in 
> tcell"; exit; } if($this->sContent != ''){ 
> $this->pushTableItem($this->sContent); $this->clearContent(); } break; 
> //list syntax case 'list': if(array_pop($this->aState)!=1) { echo 
> "insanity in list"; exit; }; foreach($this->aList as $li){ $sStr = 
> str_repeat($li['TYPE'],$li['DEPTH']). " ".$li['TEXT']; 
> switch(end($this->aState)){ case 9: case 10: $this->pushTableItem( 
> $sStr ); break; default: $this->appendRow( $sStr ); } } 
> $this->clearContent(); $this->aList = array(); break; case 'ol': case 
> 'ul': $this->nDepth--; array_pop($this->aType); break; case 'li': 
> $this->textListItem($this->sContent); $this->clearContent(); break; 
> //paragraphs case 'p': $this->appendRow( "\n".$this->sContent ); 
> break; //noop case 'noop': $this->sContent .= '/_**_/'; 
> array_pop($this->aState); break; //justification case 'left': case 
> 'right': case 'center': $this->sContent .= ''; break; //pre, code, 
> posting, quote case 'pre': case 'code': case 'posting': case 'q': case 
> 'rem': $this->sContent = '<'.$sName.'>'. $this->sContent. ''; 
> array_pop($this->aState); if(end($this->aState)!=1){ 
> $this->clearRow(); } break; //line-break case 'br': $this->appendRow( '
> ' ); break; //variables case 'var': break; //headings case 'h1': case 
> 'h2': case 'h3': case 'h4': case 'h5': case 'h6': $this->appendRow( 
> str_repeat("+",substr($sName,1,1)). " ". $this->sContent); array_pop( 
> $this->aState ); break; //wiki links case 'uri': break; case 'link': 
> if(array_pop($this->aState)!=2){ echo "insanity in link"; exit; } 
> $sStr = call_user_func($this->fLink, $this->sLink); $this->sContent .= 
> $sStr; break; //subscript & superscript case 'sub': case 'sup': 
> $this->sContent .= ''; break; //horizontal rule case 'hr': 
> $this->appendRow("---"); break; //emphasis (strike,tt,b,u,i) case 
> 'strike': if(end($this->aState)==11){ array_pop($this->aState); 
> $this->sContent .= "/_**_/"; } else { $this->sContent .= "--"; } 
> break; case 'tt': if(end($this->aState)==12){ 
> array_pop($this->aState); $this->sContent .= "/_**_/"; } else { 
> $this->sContent .= "=="; } break; case 'b': 
> if(end($this->aState)==13){ array_pop($this->aState); $this->sContent 
> .= "/_*_/"; } else { $this->sContent .= "**"; } break; case 'u': 
> if(end($this->aState)==14){ array_pop($this->aState); $this->sContent 
> .= "/_/"; } else { $this->sContent .= "__"; } break; case 'i': 
> if(end($this->aState)==15){ array_pop($this->aState); $this->sContent 
> .= "/"; } else { $this->sContent .= "//"; } break; default: echo 
> $sName . " end" . "\n"; } } /** * xml element default handler * * 
> @access protected * * @author Archie Campbell * @since coWiki 0.4.0 * 
> */ protected function xml_default_handler( &$parser, $sData ) { 
> if(!$this->ignoreToc){ $this->sContent .= html_entity_decode($sData); 
> } } /** * xml cdata handler * * @access protected * * @author Archie 
> Campbell * @since coWiki 0.4.0 * */ protected function 
> xml_cdata_handler( &$parser, $sData ) { if($this->ignoreToc){ return; 
> } if( trim($sData) != '' ) { switch( end($this->aState) ){ case 
> 1:/*WRP_LIST*/ case 3:/*WRP_HEAD*/ case 4:/*WRP_PCPQ*/ case 
> 5:/*WRP_NOOP*/ case 7:/*WRP_CAPT*/ case 9:/*WRP_THED*/ $this->sContent 
> .= $sData; break; case 2:/*WRP_LINK*/ $this->sLink[2]=trim($sData); 
> break; default:/*text*/ $this->sContent .= $sData; } } } // 
> -------------------------------------------------------------------- 
> /** * Build str ref link * * @access protected * @param array * 
> @return mixed * * @author Daniel T. Gorski, * @since coWiki 0.3.0 * * 
> @todo [D11N] Check description */ protected function 
> buildStrRefLink(&$aMatches) { if ($aMatches[1] == $aMatches[2] || 
> trim($aMatches[2]) == '') { if( $aMatches[0] == 'square' ) { return 
> '[[' . $this->noopDelimiters($aMatches[1]) . ']]'; } else { return 
> '((' . $this->noopDelimiters($aMatches[1]) . '))'; } } if($aMatches[0] 
> == 'square' ) { return '[' . $this->noopDelimiters($aMatches[1]) . ']' 
> .'[' . $aMatches[2] . ']]'; } else { return '((' . 
> $this->noopDelimiters($aMatches[1]) . ')' .'(' . $aMatches[2] . '))'; 
> } } } // of class ?>
> ------------------------------------------------------------------------
>
> so we can mail * you a copy immediately. * * @package render * 
> @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.39 $ * */ /** * The FrontHtmlTransformer is a low-end replacement 
> for a XSLT processor. * Its main purpose is to transform and render 
> the internal coWiki documents * (that are stored as simple XML) into 
> HTML. This class is a Singelton. * You can not instantiate this class 
> directly (with $foo = new class), but * have to get its instance: * * 
> Example: * | * // This won't work * $Trans = new 
> FrontHtmlTransformer(); * * // This is the right way * $Trans = 
> FrontHtmlTransformer::getInstance(); * | * * @package render * 
> @subpackage class * @access public * * @author Daniel T. Gorski, * 
> @since coWiki 0.3.0 */ class FrontHtmlTransformer extends Object { 
> protected static $Instance = null; protected $Context = null, $DocDAO 
> = null, $Response = null, $Registry = null, $Utility = null, 
> $nTopicCount = 0, $aNodeBackup = array(), $bChangedRef = false, 
> $bRepair = true; // 
> -------------------------------------------------------------------- 
> /** * Get the unique instance of the class (This class is implemented 
> as * Singleton). * * @access public * @return Object The class 
> instance * * @author Daniel T. Gorski, * @since coWiki 0.3.0 */ public 
> function getInstance() { if (!self::$Instance) { self::$Instance = new 
> FrontHtmlTransformer; } return self::$Instance; } // 
> -------------------------------------------------------------------- 
> /** * Class constructor * * @access protected * @return void * * 
> @author Daniel T. Gorski, * @since coWiki 0.3.0 */ protected function 
> __construct() { $this->Context = RuntimeContext::getInstance(); 
> $this->DocDAO = $this->Context->getDocumentDAO(); $this->Response = 
> $this->Context->getResponse(); $this->Registry = 
> $this->Context->getRegistry(); $this->Utility = 
> $this->Context->getUtility(); } // --- Simple HTML transformer for 
> front page display ----------------- /** * Return the transformed 
> (converted) HTML * * @access public * @param object The node (document 
> object) you are working on * @param boolean Determines whether to 
> 'repair' and store document * references. Repairing means lookup of 
> new * documents by their name (title). * @return string The 
> transformed HTML * * @author Daniel T. Gorski, * @since coWiki 0.3.0 
> */ public function &transform($Node, $bRepair = true) { 
> $this->nTopicCount = 1; $this->bChangedRef = false; $this->bRepair = 
> $bRepair; // Set $this->Registry->set('META_KEYWORDS', 
> $Node->get('keywords')); $sStr = $Node->get('content'); // Look for 
> new and lost documents, gather the names of existing // ones $sStr = 
> preg_replace_callback( '= (.*)=Usi', array($this, 
> '_checkDocReferences'), $sStr ); // If we have found a new or lost 
> document, we have to save // the modified source if 
> ($this->bChangedRef && $this->bRepair) { $Node->set('content', $sStr); 
> // Store modified source 
> $this->Context->getDocumentDAO()->storeContentOnly($Node); } // --- 
> Now the transforming starts -------------------------------- // 
> Transform remarks $sStr = preg_replace_callback( '=(.*)=Usi', 
> array($this, '_transformRemark'), $sStr ); // Transform preformatted 
> text $sStr = preg_replace_callback( '=
>
>(.*)
>
> =Usi', array($this, '_transformPre'), $sStr ); // Transform code $sStr 
> = preg_replace_callback( '=|(.*)|=Usi', array($this, 
> '_transformCode'), $sStr ); // Transform posting $sStr = 
> preg_replace_callback( '=(.*)=Usi', array($this, '_transformPosting'), 
> $sStr ); // Transform missing document (link) $sStr = 
> preg_replace_callback( '= (.*)=Usi', array($this, 
> '_transformMissingDocument'), $sStr ); // Transform exisisting 
> document (link) $sStr = preg_replace_callback( '= (.*)=Usi', 
> array($this, '_transformExistingDocument'), $sStr ); // Transform link 
> with URI $sStr = preg_replace_callback( '= (.*)=Usi', array($this, 
> '_transformUri'), $sStr ); $sStr = preg_replace_callback( '= 
> (.*)=Usi', array($this, '_transformTopic'), $sStr ); $sStr = 
> preg_replace_callback( '==Usi', array($this, '_transformUri'), $sStr 
> ); $sStr = preg_replace_callback( '==Usi', array($this, 
> '_transformPlugin'), $sStr ); $sStr = preg_replace_callback( 
> '=(.*)=Usi', array($this, '_transformHeading'), $sStr ); $sStr = 
> preg_replace( '==Usi', '{%\1%}', $sStr ); $sStr = 
> preg_replace_callback( '="(.*)"=Usi', array($this, '_transformQuote'), 
> $sStr ); $sStr = preg_replace_callback( 
> '=<(left|center|right)>(.*)=Usi', array($this, 
> '_transformJustification'), $sStr ); // Get rid of remaining XML 
> elements $aArr = array( '', '', '', '', '', '', '', '' ); $sStr = 
> str_replace($aArr, '', $sStr); $sStr = $this->finish($sStr, $Node); 
> return $sStr; } // 
> -------------------------------------------------------------------- 
> /** * Check document references callback. * * @access protected * 
> @param array RegEx matches defined in preg_replace_callback(). * 
> @return string Converted string. * * @author Daniel T. Gorski, * 
> @since coWiki 0.3.0 */ protected function 
> &_checkDocReferences(&$aMatches) { $sAlias = $aMatches[3]; // Remove s 
> if any $sRef = str_replace('', '', $aMatches[2]); $sRef = 
> str_replace('', '', $sRef); if ($aMatches[1] == 'strref') { // Check 
> if 'strref' is a reference to an other web. // Means: 
> "webname¦documentname" $aWebRef = explode('¦', $sRef); // Do we have a 
> reference to an other web? if (sizeof($aWebRef) > 1) { $sGlobalStrRef 
> = $this->_checkGlobalStrRef( $aWebRef[0], $aWebRef[1], $sAlias ); 
> return $sGlobalStrRef; } // If the reference does not point to an 
> other web $sLocalStrRef = $this->_checkLocalStrRef($sRef, $sAlias); 
> return $sLocalStrRef; } if ($aMatches[1] == 'idref') { $Node = 
> $this->DocDAO->getNodeById( $sRef, 'node_id, tree_id, name' ); if 
> (is_object($Node)) { // Save document node for further use 
> $this->aNodeBackup[$Node->get('id')] = $Node; $sStr = ' '; // Do we 
> have an alias? if ($Node->get('name') != $sAlias) { $sStr .= $sAlias; 
> } $sStr .= ''; } // Referenced document not found, try history if 
> (!is_object($Node)) { $Node = $this->DocDAO->getHistNodeForId($sRef, 
> 'name'); if (is_object($Node)) { $this->bChangedRef = true; $sStr = ' 
> '; // Do we have an alias? if ($Node->get('name') != $sAlias) { $sStr 
> .= $sAlias; } $sStr .= ''; } } // "Deleted document" if 
> (!is_object($Node)) { $this->bChangedRef = true; $sStr = 
> '['.'('.$sRef.')('.$sAlias.')'. __('I18N_DOC_DELETED_DOCUMENT').']'; } 
> } return $sStr; } // 
> -------------------------------------------------------------------- 
> /** * Check references to an other web (global) callback. * * @access 
> protected * @return string Converted string. * * @author Daniel T. 
> Gorski, * @since coWiki 0.3.0 */ protected function 
> &_checkGlobalStrRef(&$sWeb, &$sRef, &$sAlias) { $sWebStr = 
> trim(unescape($sWeb)); $sRefStr = trim(unescape($sRef)); // Find web 
> node by its name $WebNode = $this->DocDAO->getWebByName($sWebStr); // 
> Found web if (is_object($WebNode)) { // Find document by its name (in 
> the referenced web) $Node = $this->DocDAO->getNodeByName( $sRefStr, 
> $WebNode->get('treeId'), 'node_id, name' ); // Found document if 
> (is_object($Node)) { // Save document node for further use 
> $this->bChangedRef = true; $this->aNodeBackup[$Node->get('id')] = 
> $Node; $sStr = ' '; // Do we have an alias? if ($Node->get('name') != 
> $sAlias) { $sStr .= $sAlias; } $sStr .= ''; } } // Did not found web, 
> keep the link as it is if (!is_object($WebNode) || !is_object($Node)) 
> { $sStr = ' '; $sStr .= $sAlias; $sStr .= ''; } return $sStr; } // 
> -------------------------------------------------------------------- 
> /** * Check references within a web only (local) callback. * * @access 
> protected * @return string Converted string. * * @author Daniel T. 
> Gorski, * @since coWiki 0.3.0 */ protected function 
> &_checkLocalStrRef(&$sRef, &$sAlias) { // Get current 
> directory/document object $Node = $this->Context->getCurrentNode(); 
> $sRefStr = trim(unescape($sRef)); $Node = 
> $this->DocDAO->getNodeByName( $sRefStr, $Node->get('treeId'), 
> 'node_id, tree_id, name' ); // Save document info for further use if 
> (is_object($Node)) { // Save document node for further use 
> $this->bChangedRef = true; $this->aNodeBackup[$Node->get('id')] = 
> $Node; $sStr = ' '; // Do we have an alias? if ($Node->get('name') != 
> $sAlias) { $sStr .= $sAlias; } $sStr .= ''; } if (!is_object($Node)) { 
> // Keep the link as it is $sStr = ' '; $sStr .= $sAlias; $sStr .= ''; 
> } return $sStr; } // 
> -------------------------------------------------------------------- 
> /** * Act on missing documents callback. * * @access protected * 
> @return string Converted string. * * @author Daniel T. Gorski, * 
> @since coWiki 0.3.0 */ protected function 
> &_transformMissingDocument(&$aMatches) { // Get current 
> directory/document object $Node = $this->Context->getCurrentNode(); // 
> Check if 'strref' is a reference to an other web. // Means: 
> "webname|documentname" $aWebRef = explode('|', $aMatches[1]); // Do we 
> have a reference to an other web? if (sizeof($aWebRef) > 1) { $sStr = 
> '['; $sStr .= __('I18N_DOC_UNRESOLVED_WEB_REFERENCE').': '; $sStr .= 
> $aMatches[1]; $sStr .= ']'; return $sStr; } // Remove s if any 
> $aMatches[1] = str_replace('', '', $aMatches[1]); $aMatches[1] = 
> str_replace('', '', $aMatches[1]); // Missing local document, provide 
> a link to edit $sQuery = 'cmd=' . CMD_NEWDOC . '&newdocname=' . 
> urlencode(unescape($aMatches[1])); if (is_object($Node)) { $sQuery .= 
> '&node=' . $Node->get('parentId') . '&refnode='.$Node->get('id'); } 
> $sStr = ''; // Do we have an alias? $sStr .= ($aMatches[2] == '') ? 
> $aMatches[1] : $aMatches[2]; $sStr .= ' 
> <%27;%0A%20%20%20%20%20%20%20%20$sStr%20.=%20$this-%3EResponse-%3EgetControllerHref%28$sQuery%29;%0A%20%20%20%20%20%20%20%20$sStr%20.=%20%20%27>'; 
> $sStr .= '*?*'; return $sStr; } // 
> -------------------------------------------------------------------- 
> /** * Act on existing documents callback. * * @access protected * 
> @return string Converted string. * * @author Daniel T. Gorski, * 
> @since coWiki 0.3.0 */ protected function 
> &_transformExistingDocument(&$aMatches) { $sStr = ''; // Possible 
> alias if (isset($aMatches[2]) && $aMatches[2] != '') { $sStr .= 
> $aMatches[2]; } else { $sStr .= 
> escape($this->aNodeBackup[$aMatches[1]]->get('name')); } $sStr .= ' 
> <%27;%0A%20%20%20%20%20%20%20%20$sStr%20.=%20%20%20%20$this-%3EResponse-%3EgetControllerHref%28%27node=%27.$aMatches%5B1%5D%29;%0A%20%20%20%20%20%20%20%20$sStr%20.=%20%20%27>'; 
> return $sStr; } // 
> -------------------------------------------------------------------- 
> /** * Act on remarks callback. * * @access protected * @return string 
> Converted string. * * @author Daniel T. Gorski, * @since coWiki 0.3.0 
> */ protected function &_transformRemark(&$aMatches) { $sStr = ''; 
> return $sStr; } // 
> -------------------------------------------------------------------- 
> /** * Act on preformatted text callback. * * @access protected * 
> @return string Converted string. * * @author Daniel T. Gorski, * 
> @since coWiki 0.3.0 */ protected function &_transformPre(&$aMatches) { 
> $sStr = '
>
>' . $aMatches[1] . '
>
> '; return $sStr; } // 
> -------------------------------------------------------------------- 
> /** * Act on code callback. * * @access protected * @return string 
> Converted string. * * @author Daniel T. Gorski, * @since coWiki 0.3.0 
> */ protected function &_transformCode(&$aMatches) { if 
> ($this->Registry->get('COLOR_CODE_COLORIZE')) { return '
>
>'
>                      .$this->Utility->colorizeCode($aMatches[1])
>                   .'
>
> '; } $sStr = '
>
>' . $aMatches[1] . '
>
> '; return $sStr; } // 
> -------------------------------------------------------------------- 
> /** * Act on posting callback. * * @access protected * @return string 
> Converted string. * * @author Daniel T. Gorski, * @since coWiki 0.3.0 
> */ protected function &_transformPosting(&$aMatches) { $sStr = '
>
>'
>                  .$this->Utility->colorizeQuote($aMatches[1])
>               .'
>
> '; return $sStr; } // 
> -------------------------------------------------------------------- 
> /** * Execute plugins callback. * * @access protected * @return string 
> Converted string. * * @author Daniel T. Gorski, * @since coWiki 0.3.0 
> */ protected function &_transformPlugin(&$aMatches) { // Reset 
> Layouter attributes $this->Context->getLayouter()->init(); // Set 
> plugin parameters if (isset($aMatches[2]) && $aMatches[2] != '') { 
> $this->Context->setPluginParam($aMatches[2]); } // Load plugin $sStr = 
> $this->Context->getPluginLoader()->load('Custom'.$aMatches[1]); // 
> Clean plugin data $this->Context->cleanPluginParams(); return $sStr; } 
> // 
> -------------------------------------------------------------------- 
> /** * Created (URI) links and obfuscate them callback. * * @access 
> protected * @return string Converted string. * * @author Daniel T. 
> Gorski, * @since coWiki 0.3.0 */ protected function 
> &_transformUri(&$aMatches) { $sStr1 = $aMatches[1]; if 
> (isset($aMatches[2]) && $aMatches[2] != '') { $sStr2 = $aMatches[2]; } 
> else { // Because extremely long URIs won't wrap in browser output // 
> and shred the output horizontally, we'll shorten them a bit. // If you 
> change it, also change the PrintHtmlTransformer. // FIX: This 
> behaviour might me toggleable or configureable in // length via the 
> core.conf file. $sStr2 = shortenUrl($aMatches[1]); } $sTarget = ' 
> target="_blank"'; // No new window for mailto: URIs if (substr($sStr1, 
> 0, 7) == 'mailto:') { $sTarget = ''; } // obfuscate email if set in 
> config and if no ftp link if 
> ($this->Registry->get('RUNTIME_EMAIL_OBFUSCATE') && substr($sStr1, 0, 
> 7) == 'mailto:') { $sStr1 = obfuscateEmail($sStr1); $sStr2 = 
> obfuscateEmail($sStr2); } $sStr = ''.$sStr2.' <%27.$sStr1.%27>'; 
> return $sStr; } // 
> -------------------------------------------------------------------- 
> /** * Create a topic callback. * * @access protected * @return string 
> Converted string. * * @author Daniel T. Gorski, * @since coWiki 0.3.0 
> */ protected function &_transformTopic(&$aMatches) { $sUri = 
> $this->Response->getControllerAction(); $sStr = ''; $sStr .= 
> $aMatches[2]; $sStr .= ' 
> <%27%20.%20$sUri%20.%20%27#A%27%20.%20$aMatches%5B1%5D%20.%20%27>'; 
> return $sStr; } // 
> -------------------------------------------------------------------- 
> /** * Create a header (title) callback. * * @access protected * 
> @return string Converted string. * * @author Daniel T. Gorski, * 
> @since coWiki 0.3.0 */ protected function 
> &_transformHeading(&$aMatches) { $sStr = ''; $sStr .= 
> ''.$aMatches[2].''; return $sStr; } // 
> -------------------------------------------------------------------- 
> /** * Create an inteded text callback. * * @access protected * @return 
> string Converted string. * * @author Daniel T. Gorski, * @since coWiki 
> 0.3.0 */ protected function &_transformQuote(&$aMatches) { $sStr = '
>
>     '; $sStr .= $aMatches[1]; $sStr .= '
>
> '; return $sStr; } // 
> -------------------------------------------------------------------- 
> protected function &_transformJustification(&$aMatches) { $sStr = '
> '; $sStr .= $aMatches[2]; $sStr .= '
> '; /* $sStr = '
>
> '; $sStr .= $aMatches[2]; $sStr .= '
>
> '; */ return $sStr; } // 
> -------------------------------------------------------------------- 
> /** * Manipulate the finished string, if necessary * * @access 
> protected * @return string The manipulated string. * * @author Daniel 
> T. Gorski, * @since coWiki 0.3.0 */ protected function &finish(&$sStr, 
> $Node) { return $sStr; } } // of class /* Rachel: Do you like our owl? 
> Deckard: Is it artificial? Rachel: Of course it is. Deckard: Must be 
> expensive. Rachel: Very. Rachel: I'm Rachel. Deckard: Deckard. Rachel: 
> Its seems you feel our work is not a benefit to the public. Deckard: 
> Replicants are like any other machines. They are either a benefit or a 
> hazard. If they're a benefit, it's not my problem. Rachel: May I ask 
> you a personal question? Deckard: Sure. Rachel: Have you ever retired 
> a human, by mistake? Deckard: No. Rachel: But in your position that is 
> a risk? Tyrell: Is this to be an empathy test? Capilary dilation of 
> the so called blush response ... fluctuation of the pupil ... 
> involuntary dilation of the iris ... Deckard: We call it Voight-Kampff 
> for short. Rachel: Mr. Deckard, Dr. Elden Tyrell. Tyrell: Demonstrate 
> it. I want to see it work. Deckard: Were is the subject? Tyrell: I 
> want to see it work on a person. I want to see a negative before I 
> provide you with a positive. Deckard: What's that gonna prove? Tyrell: 
> Indulge me. Deckard: On you? Tyrell: Try her. */ ?>
>
>------------------------------------------------------------------------
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: [email protected]
>For additional commands, e-mail: [email protected]
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
setup.php (text/html, 1.5 KB)
<?php
	//--------------------------------------------------------
	//	This line has to be set because the test code is 
	//	not presently in the coWiki directory structure.
	//--------------------------------------------------------
	$base_path = "C:\\Big Drive\\Projects\\cowiki\\includes\\cowiki\\";
	
	//--------------------------------------------------------
	//	The ClassLoader is used to locate and load coWiki class files
	//--------------------------------------------------------
	include_once $base_path.'class/class.ClassLoader.php';
	
	//--------------------------------------------------------
	//	This function is called when PHP can't locate a class
	//--------------------------------------------------------
	function __autoload($sClass) {
	    ClassLoader::getInstance()->load($sClass);
	}
	
	//	Some classes need functions defined here.  Go ahead and pre-load.
	include_once $base_path.'core.function.php';
    
    //	Preload the PHPUnit stuff too.
	require_once 'PHPUnit.php';

    //
    //	PHPUnit_TestResult only calls the start and end test callbacks.
    //	*Not* very useful...
    //
	class ConsoleListener extends PHPUnit_TestListener {
		function addError($test, $t) {
            // print "MyListener::addError() called.\n";
		}

        function addFailure($test, $t) {
            // print "MyListener::addFailure() called.\n";
		}
        
		function endTest($test) {
            // print "MyListener::endTest() called.\n";
		}
        
		function startTest($test) {
            // print "MyListener::startTest() called.\n";
		}
	}

?>
unittest.php (text/html, 1.8 KB)
<?php
	
	require_once 'setup.php';
    
    require_once 'ParserBasicFormattingTest.php';
	
	/*
	 $suite = new PHPUnit_TestSuite();
	 $suite->addTest(new ParserTest('testAdd'));
	
	 $result = PHPUnit::run($suite);
	 print $result->toHTML();
	
	 Alternatively, you can pass a class name to the PHPUnit_TestSuite()
	 constructor and let it automatically add all methods of that class
	 that start with 'test' to the suite:
	
	
	 <?php
	*/
    
	$suite  = new PHPUnit_TestSuite();
    $result = new PHPUnit_TestResult();
    $result->addListener(new ConsoleListener);
    
    $suite->addTestSuite( ParserBasicFormattingTest );
    $suite->addTestSuite( ParserBoldAsteriskFormattingTest );
    $suite->addTestSuite( ParserItalicSlashFormattingTest );
    $suite->addTestSuite( ParserUnderlineUnderbarFormattingTest );
    $suite->addTestSuite( ParserFixedwidthEqualsFormattingTest );
    $suite->addTestSuite( ParserstrikeoutHyphenFormattingTest );

    $suite->addTestSuite( ParserBoldTagFormattingTest );
    $suite->addTestSuite( ParserItalicTagFormattingTest );
    $suite->addTestSuite( ParserUnderlineTagFormattingTest );
    $suite->addTestSuite( ParserFixedwidthTagFormattingTest );
    $suite->addTestSuite( ParserStrikeoutTagFormattingTest );
    
    // Hangs: Bad tags are not handled.
    $suite->addTestSuite( ParserBadTagFormattingTest );

    $suite->run( $result );
	
    print $result->toString()."\n\n";
    printf( "--------------------------------------------------\n");
    printf( "  %d tests, passed=%d, failed=%d, errors=%d\n", 
            sizeof($result->passedTests())+$result->failureCount(), 
            sizeof($result->passedTests()), 
            $result->failureCount(), 
            $result->errorCount()
            );
    printf( "--------------------------------------------------\n");
    
?>
ParserBasicFormattingTest.php (text/html, 23.3 KB)
<?php

    //--------------------------------------------------------------------------
    //	Basic tests for formatting paragraphs
    //--------------------------------------------------------------------------
	class ParserBasicFormattingTest extends PHPUnit_TestCase {
		var $p = nil;
		
		//--------------------------------------------------------------
		//	Setup: Set up an instance of the parser for testing
		//--------------------------------------------------------------
		function setUp() {
			$this->p = CoWikiParser::getInstance();
		}
		
		//--------------------------------------------------------------
		//	Test an empty string
		//--------------------------------------------------------------
		function testEmptyString() {
		    $inputString = "";
		    $outputString = "";
		    $messageString = "Empty input should produce empty output";
		    $this->assertEquals( $outputString, $this->p->parse($inputString), $messageString );
		}
		
		//--------------------------------------------------------------
		//	Test blank lines
		//--------------------------------------------------------------
		function testBlankLines() {
		    $inputString = "\n\n\r\n";
		    $outputString = "";
		    $messageString = "Blank lines should produce empty output";
		    $this->assertEquals( $outputString, $this->p->parse($inputString), $messageString );
		}
		
		//--------------------------------------------------------------
		//	Test line with no terminator
		//--------------------------------------------------------------
		function testShortLine() {
		    $inputString = "Line with no eol";
		    $outputString = "<p>Line with no eol</p>";
		    $messageString = "Lines with no <eol> are a paragraph";
		    $this->assertEquals( $outputString, $this->p->parse($inputString), $messageString );
		}
		
		//--------------------------------------------------------------
		//	Test a single plain paragraph
		//--------------------------------------------------------------
		function testParagraphLine() {
		    $inputString = "Line with eol\n";
		    $outputString = "<p>Line with eol</p>";
		    $messageString = "Lines with <eol> are a paragraph";
		    $this->assertEquals( $outputString, $this->p->parse($inputString), $messageString );
		}
		
		//--------------------------------------------------------------
		//	Test two paragraphs separated by <eoln>
		//--------------------------------------------------------------
		function testTwoParagraphs() {
		    $inputString = "Line with eol\n\nAnd another paragraph\n";
		    $outputString = "<p>Line with eol</p><p>And another paragraph</p>";
		    $messageString = "Multiple lines ending in <eol> are paragraphs";
		    $this->assertEquals( $outputString, $this->p->parse($inputString), $messageString );
		}
		
		//--------------------------------------------------------------
		//	Test paragraphs are recognized with <cr> only eoln
		//--------------------------------------------------------------
		function testCROnlyLineEndings() {
		    $inputString = "A\rB\r\rC";
		    $outputString = "<p>A</p><p>B</p><p>C</p>";
		    $messageString = "Multiple lines ending in CR";
		    $this->assertEquals( $outputString, $this->p->parse($inputString), $messageString );
		}
		
		//--------------------------------------------------------------
		//	Test paragraphs are recognized with <cr><lf> eoln
		//--------------------------------------------------------------
		function testCRLFLineEndings() {
		    $inputString = "A\r\nB\r\nC";
		    $outputString = "<p>A</p><p>B</p><p>C</p>";
		    $messageString = "Multiple lines ending in CR-LF";
		    $this->assertEquals( $outputString, $this->p->parse($inputString), $messageString );
		}
		
		//--------------------------------------------------------------
		//	Test paragraphs are recognized with <lf><cr> eoln
		//--------------------------------------------------------------
		function testLFCRLineEndings() {
		    $inputString = "A\n\rB\n\rC";
		    $outputString = "<p>A</p><p>B</p><p>C</p>";
		    $messageString = "Multiple lines ending in CR-LF";
		    $this->assertEquals( $outputString, $this->p->parse($inputString), $messageString );
		}
		
	}
    
	//--------------------------------------------------------------------------
	//	Basic tests for formatting text within paragraphs
	//--------------------------------------------------------------------------
    class ParserEmphasisFormattingTest extends PHPUnit_TestCase {
		var $p = nil;
	    
	    var $testType = "Undefined";
	    var $formatChar = "?";
	    var $startTag = "<start>";
	    var $endTag = "</start>";
	    
		
		//--------------------------------------------------------------
		//	Standard constructor for unit tests.
		//--------------------------------------------------------------
		function __construct($name, $type, $format, $start, $end ) {
	        $this->formatChar = $format;
	        $this->startTag = $start;
	        $this->endTag = $end;
			$this->PHPUnit_TestCase($name);
		}
		
		//--------------------------------------------------------------
		//	Setup: Set up an instance of the parser for testing
		//--------------------------------------------------------------
		function setUp() {
			$this->p = CoWikiParser::getInstance();
		}
		
		//--------------------------------------------------------------
		//	Helper function to generate input and output strings 
		//--------------------------------------------------------------
		function generateWikiEmphasis( $emphasis, $startTag, $endTag, 
                                       $begin, $middle, $ending, 
                                       &$input, &$output ) {
		    $input = $begin.$emphasis.$middle.$emphasis.$ending;
		    $output = "<p>".$begin.$startTag.$middle.$endTag.$ending."</p>";
		}
	
		//--------------------------------------------------------------
		//	TODO:	Need to check how special characters like punctuation
		//			affect emphasis.  "This *word!* should /emphasize/.
		//--------------------------------------------------------------
	    
		
		//--------------------------------------------------------------
		//	Test emphasis on a single word
		//--------------------------------------------------------------
		function testEmphasizeWord() {
		    $inputString = ""; $outputString = "";
		    $this->generateWikiEmphasis( $this->formatChar.$this->formatChar, 
	                                     $this->startTag, $this->endTag, 
	                                     "start ", "middle", " end", 
                                         $inputString, $outputString );
	        $this->assertEquals( $outputString, $this->p->parse($inputString) );
	    }
		    
		//--------------------------------------------------------------
		//	Test emphasis on a phrase
		//--------------------------------------------------------------
	    function testEmphasizePhrase() {
			$inputString = ""; $outputString = "";
			$this->generateWikiEmphasis( $this->formatChar.$this->formatChar, 
	                                     $this->startTag, $this->endTag, 
	            						 "start ", "middle words", " end", $inputString, $outputString );
			$this->assertEquals( $outputString, $this->p->parse($inputString) );
		}
	    
		//--------------------------------------------------------------
		//	Test emphasize an entire line (no terminator)
		//--------------------------------------------------------------
	    function testEmphasizeLine() {
			$inputString = ""; $outputString = "";
			$this->generateWikiEmphasis( $this->formatChar.$this->formatChar, 
	                                     $this->startTag, $this->endTag, 
				 						 "", "middle words", "", $inputString, $outputString );
			$this->assertEquals( $outputString, $this->p->parse($inputString) );
		}
	    
		//--------------------------------------------------------------
		//	Test mismatched emphasis
		//--------------------------------------------------------------
	    function testMismatchedEmphasizedPhrase() {
			$inputString = "this phrase ".$this->formatChar.$this->formatChar."is mismatched"; 
			$outputString = "<p>this phrase ".$this->formatChar.$this->formatChar."is mismatched</p>";
			$this->assertEquals( $outputString, $this->p->parse($inputString) );
		}
	    
		//--------------------------------------------------------------
		//	Test "this phrase **is** **mismatched in an intersting way"
		//--------------------------------------------------------------
	    function testMismatchedEmphasizedPhrase2() {
			$inputString = "this phrase ".$this->formatChar.$this->formatChar."is".$this->formatChar.$this->formatChar.
	        			   " ".$this->formatChar.$this->formatChar."mismatched in an intersting way"; 
			$outputString = "<p>this phrase ".$this->startTag."is".$this->endTag." ".$this->formatChar.$this->formatChar."mismatched in an intersting way</p>";
			$this->assertEquals( $outputString, $this->p->parse($inputString) );
		}
	    
		//------------------------------------------------------------------
		//	Test "this phrase ***is*** ****mismatched in an intersting way"
		//------------------------------------------------------------------
	    function testMismatchedEmphasizedPhrase3() {
			$inputString = "this phrase ".$this->formatChar.$this->formatChar.$this->formatChar."is".$this->formatChar.$this->formatChar.$this->formatChar.
	        			   " ".$this->formatChar.$this->formatChar.$this->formatChar.$this->formatChar."mismatched in an intersting way"; 
			$outputString = "<p>this phrase ".$this->formatChar.$this->formatChar.$this->formatChar."is".$this->formatChar.$this->formatChar.$this->formatChar.
	        		        " ".$this->formatChar.$this->formatChar.$this->formatChar.$this->formatChar.'mismatched in an intersting way</p>';
			$this->assertEquals( $outputString, $this->p->parse($inputString) );
		}
	    
		//--------------------------------------------------------------------
		//	Test "this phrase ****is**** ****mismatched in an intersting way"
		//--------------------------------------------------------------------
	    function testMismatchedEmphasizedPhrase4() {
			$inputString = "this phrase ".$this->formatChar.$this->formatChar.$this->formatChar.$this->formatChar.
	        			   "is".$this->formatChar.$this->formatChar.$this->formatChar.$this->formatChar.
	                       " ".$this->formatChar.$this->formatChar.$this->formatChar.$this->formatChar."mismatched in an intersting way";
			$outputString = "<p>this phrase ".$this->formatChar.$this->formatChar.$this->formatChar.$this->formatChar.
	        			    "is".$this->formatChar.$this->formatChar.$this->formatChar.$this->formatChar.
	                        " ".$this->formatChar.$this->formatChar.$this->formatChar.$this->formatChar."mismatched in an intersting way</p>";
			$this->assertEquals( $outputString, $this->p->parse($inputString) );
		}
	    
		//------------------------------------------------------------------
		//	Test "A **Emphasize phrase\ncannot continue** across a line."
		//------------------------------------------------------------------
	    function testEmphasizeEndsAtEoln() {
			$inputString = "A ".$this->formatChar.$this->formatChar."Emphasize phrase\ncannot continue"
	                       .$this->formatChar.$this->formatChar." across a line.";
			$outputString = "<p>A ".$this->formatChar.$this->formatChar."Emphasize phrase</p><p>cannot continue"
	                        .$this->formatChar.$this->formatChar." across a line.</p>";
			$this->assertEquals( $outputString, $this->p->parse($inputString) );
		}
	    
	        
	}
    
	//--------------------------------------------------------------------------
	//	Asterisk: Bold emphasis for text within paragraphs
	//--------------------------------------------------------------------------
    class ParserBoldAsteriskFormattingTest extends ParserEmphasisFormattingTest {
		function __construct($name) {
			ParserEmphasisFormattingTest::__construct($name, "Bold", "*", '<b origin="wiki">', "</b>");
		}
    }
	
	//--------------------------------------------------------------------------
	//	Slash: Italic emphasis for text within paragraphs
	//--------------------------------------------------------------------------
    class ParserItalicSlashFormattingTest extends ParserEmphasisFormattingTest {
		function __construct($name) {
			ParserEmphasisFormattingTest::__construct($name, "Italics", "/", '<i origin="wiki">', "</i>");
		}
    }
	
	//--------------------------------------------------------------------------
	//	Underline: Underscore emphasis for text within paragraphs
	//--------------------------------------------------------------------------
    class ParserUnderlineUnderbarFormattingTest extends ParserEmphasisFormattingTest {
		function __construct($name) {
			ParserEmphasisFormattingTest::__construct($name, "Underline", "_", '<u origin="wiki">', "</u>");
		}
    }
	
	//--------------------------------------------------------------------------
	//	Equals: Fixed font emphasis for text within paragraphs
	//--------------------------------------------------------------------------
    class ParserFixedwidthEqualsFormattingTest extends ParserEmphasisFormattingTest {
		function __construct($name) {
			ParserEmphasisFormattingTest::__construct($name, "Fixed", "=", '<tt origin="wiki">', "</tt>");
		}
    }
	
	//--------------------------------------------------------------------------
	//	Hyphen: Strikeout emphasis for text within paragraphs
	//--------------------------------------------------------------------------
    class ParserstrikeoutHyphenFormattingTest extends ParserEmphasisFormattingTest {
		function __construct($name) {
			ParserEmphasisFormattingTest::__construct($name, "Fixed", "-", '<strike origin="wiki">', "</strike>");
		}
    }

	//--------------------------------------------------------------------------
	//	Basic tests for formatting text with <tags> within paragraphs
	//--------------------------------------------------------------------------
    class ParserTagEmphasisFormattingTest extends PHPUnit_TestCase {
		var $p = nil;
	    
	    var $testType = "Undefined";
	    var $startFormat = "<?>";
	    var $endFormat = "</?>";
	    var $startTag = "<start>";
	    var $endTag = "</start>";
	    
		
		//--------------------------------------------------------------
		//	Standard constructor for unit tests.
		//--------------------------------------------------------------
		function __construct($name, $type, $formatStart, $formatEnd, $start, $end ) {
	        $this->startFormat = $formatStart;
	        $this->endFormat = $formatEnd;
	        $this->startTag = $start;
	        $this->endTag = $end;
			$this->PHPUnit_TestCase($name);
		}
		
		//--------------------------------------------------------------
		//	Setup: Set up an instance of the parser for testing
		//--------------------------------------------------------------
		function setUp() {
			$this->p = CoWikiParser::getInstance();
		}
		
		//--------------------------------------------------------------
		//	Helper function to generate input and output strings 
		//--------------------------------------------------------------
		function generateWikiEmphasis( $emphasisStart, $emphasisEnd, 
                                        $startTag, $endTag, $begin, $middle, $ending, 
                                        &$input, &$output ) {
		    $input = $begin.$emphasisStart.$middle.$emphasisEnd.$ending;
		    $output = "<p>".$begin.$startTag.$middle.$endTag.$ending."</p>";
		}
	
		//--------------------------------------------------------------
		//	TODO:	Need to check how special characters like punctuation
		//			affect emphasis.  "This *word!* should /emphasize/.
		//--------------------------------------------------------------
	    
		
		//--------------------------------------------------------------
		//	Test emphasis on a single word
		//--------------------------------------------------------------
		function testEmphasizeWord() {
		    $inputString = ""; $outputString = "";
		    $this->generateWikiEmphasis( $this->startFormat, $this->endFormat, 
	                                     $this->startTag, $this->endTag, 
	                                     "start ", "middle", " end", 
                                         $inputString, $outputString );
	        $this->assertEquals( $outputString, $this->p->parse($inputString) );
	    }
		    
		//--------------------------------------------------------------
		//	Test emphasis on a phrase
		//--------------------------------------------------------------
	    function testEmphasizePhrase() {
			$inputString = ""; $outputString = "";
			$this->generateWikiEmphasis( $this->startFormat, $this->endFormat, 
	                                     $this->startTag, $this->endTag, 
	            						 "start ", "middle words", " end", $inputString, $outputString );
			$this->assertEquals( $outputString, $this->p->parse($inputString) );
		}
	    
		//--------------------------------------------------------------
		//	Test emphasize an entire line (no terminator)
		//--------------------------------------------------------------
	    function testEmphasizeLine() {
			$inputString = ""; $outputString = "";
			$this->generateWikiEmphasis( $this->startFormat, $this->endFormat,  
	                                     $this->startTag, $this->endTag, 
				 						 "", "middle words", "", $inputString, $outputString );
			$this->assertEquals( $outputString, $this->p->parse($inputString) );
		}
	    
		//--------------------------------------------------------------
		//	Test mismatched emphasis
		//--------------------------------------------------------------
	    function testMismatchedEmphasizedPhrase() {
			$inputString = "this phrase ".$this->startFormat."is mismatched"; 
			$outputString = "<p>this phrase ".htmlentities($this->startFormat)
                            ."is mismatched</p>";
			$this->assertEquals( $outputString, $this->p->parse($inputString) );
		}
	    
		//--------------------------------------------------------------
		//	Test "this phrase <b>is</b> <b>mismatched in an intersting way"
		//--------------------------------------------------------------
	    function testMismatchedEmphasizedPhrase2() {
			$inputString = "this phrase ".$this->startFormat."is".$this->endFormat.
	        			   " ".$this->startFormat."mismatched in an intersting way"; 
			$outputString = "<p>this phrase ".$this->startTag."is".$this->endTag." "
                            .htmlentities($this->startFormat)
                            ."mismatched in an intersting way</p>";
			$this->assertEquals( $outputString, $this->p->parse($inputString) );
		}
	    
		//------------------------------------------------------------------
		//	Test "A **Emphasize phrase\ncannot continue** across a line."
		//------------------------------------------------------------------
	    function testEmphasizeEndsAtEoln() {
			$inputString = "A ".$this->startFormat."Emphasize phrase\ncannot continue"
	                       .$this->endFormat." across a line.";
			$outputString = "<p>A ".htmlentities($this->startFormat)
                            ."Emphasize phrase</p><p>cannot continue"
	                        .htmlentities($this->endFormat)." across a line.</p>";
			$this->assertEquals( $outputString, $this->p->parse($inputString) );
		}
	    
	        
	}
    
	//--------------------------------------------------------------------------
	//	<b>: Bold emphasis for text within paragraphs
	//--------------------------------------------------------------------------
    class ParserBoldTagFormattingTest extends ParserTagEmphasisFormattingTest {
		function __construct($name) {
			ParserTagEmphasisFormattingTest::__construct($name, "Bold", 
            											"<b>", "</b>", 
                                                        '<b origin="html">', "</b>");
		}
    }
	
	//--------------------------------------------------------------------------
	//	<i>: Italic emphasis for text within paragraphs
	//--------------------------------------------------------------------------
    class ParserItalicTagFormattingTest extends ParserTagEmphasisFormattingTest {
		function __construct($name) {
			ParserTagEmphasisFormattingTest::__construct($name, "Italics", 
            											"<i>", "</i>", 
                                                        '<i origin="html">', "</i>");
		}
    }
	
	//--------------------------------------------------------------------------
	//	<u>: Underscore emphasis for text within paragraphs
	//--------------------------------------------------------------------------
    class ParserUnderlineTagFormattingTest extends ParserTagEmphasisFormattingTest {
		function __construct($name) {
			ParserTagEmphasisFormattingTest::__construct($name, "Underline", 
            											"<u>", "</u>", 
                                                        '<u origin="html">', "</u>");
		}
    }
	
	//--------------------------------------------------------------------------
	//	<tt>: Fixed font emphasis for text within paragraphs
	//--------------------------------------------------------------------------
    class ParserFixedwidthTagFormattingTest extends ParserTagEmphasisFormattingTest {
		function __construct($name) {
			ParserTagEmphasisFormattingTest::__construct($name, "Fixed", 
            											"<tt>", "</tt>", 
                                                        '<tt origin="html">', "</tt>");
		}
    }
	
	//--------------------------------------------------------------------------
	//	<s>: Strikeout emphasis for text within paragraphs
	//--------------------------------------------------------------------------
    class ParserStrikeoutTagFormattingTest extends ParserTagEmphasisFormattingTest {
		function __construct($name) {
			ParserTagEmphasisFormattingTest::__construct($name, "Strikeout", 
            											"<strike>", "</strike>", 
                                                        '<strike origin="html">', "</strike>");
		}
    }

	//--------------------------------------------------------------------------
	//	<bad>: Should handle bad tags OK!
	//--------------------------------------------------------------------------
    class ParserBadTagFormattingTest extends ParserTagEmphasisFormattingTest {
		function __construct($name) {
			ParserTagEmphasisFormattingTest::__construct($name, "Bad Tag", 
            											"<bad>", "</bad>", 
                                                        '<bad>', "</bad>");
		}

        //--------------------------------------------------------------
		//	Helper function to generate input and output strings 
		//--------------------------------------------------------------
		function generateWikiEmphasis( $emphasisStart, $emphasisEnd, 
                                        $startTag, $endTag, $begin, $middle, $ending, 
                                        &$input, &$output ) {
		    $input = $begin.$emphasisStart.$middle.$emphasisEnd.$ending;
		    $output = "<p>".htmlentities($begin.$startTag.$middle.$endTag.$ending)."</p>";
		}
	

		//--------------------------------------------------------------
		//	Test "this phrase <b>is</b> <b>mismatched in an intersting way"
		//--------------------------------------------------------------
	    function testMismatchedEmphasizedPhrase2() {
			$inputString = "this phrase ".$this->startFormat."is".$this->endFormat.
	        			   " ".$this->startFormat."mismatched in an intersting way"; 
			$outputString = "<p>this phrase "
                            .htmlentities($this->startTag."is".$this->endTag)." "
                            .htmlentities($this->startFormat)
                            ."mismatched in an intersting way</p>";
			$this->assertEquals( $outputString, $this->p->parse($inputString) );
		}
	    
    }

   
   
    	
?>
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.