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 > 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 <b>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> <b>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 <b>Emphasize
>> phrase</p><p>cannot continue</b> across a line.</p>
>> TestCase
>> ParserItalicTagFormattingTest->testMismatchedEmphasizedPhrase()
>> failed: expected <p>this phrase <i>is mismatched</p>, actual
>> <p>this phrase <i>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> <i>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 <i>Emphasize
>> phrase</p><p>cannot continue</i> across a line.</p>
>> TestCase
>> ParserUnderlineTagFormattingTest->testMismatchedEmphasizedPhrase()
>> failed: expected <p>this phrase <u>is mismatched</p>, actual
>> <p>this phrase <u>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> <u>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 <u>Emphasize
>> phrase</p><p>cannot continue</u> across a line.</p>
>> TestCase
>> ParserFixedwidthTagFormattingTest->testMismatchedEmphasizedPhrase()
>> failed: expected <p>this phrase <tt>is mismatched</p>, actual
>> <p>this phrase <tt>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> <tt>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 <tt>Emphasize
>> phrase</p><p>cannot continue</tt> 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 <strike>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> <strike>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
>> <strike>Emphasize phrase</p><p>cannot
>> continue</strike> 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) );
}
}
?>