home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / PhpDocumentor / phpDocumentor / ParserDescCleanup.inc < prev    next >
Encoding:
Text File  |  2008-07-02  |  56.5 KB  |  1,487 lines

  1. <?php
  2. /**
  3.  * All of the functions to clean up and handle the long description
  4.  * of a DocBlock are in this file.
  5.  *
  6.  * The primary functionality is based on Parser and WordParser, and modified to recognize
  7.  * only the tokens defined in the PHPDOCUMENTOR_PDP_* constants
  8.  * 
  9.  * phpDocumentor :: automatic documentation generator
  10.  * 
  11.  * PHP versions 4 and 5
  12.  *
  13.  * Copyright (c) 2002-2006 Gregory Beaver
  14.  * 
  15.  * LICENSE:
  16.  * 
  17.  * This library is free software; you can redistribute it
  18.  * and/or modify it under the terms of the GNU Lesser General
  19.  * Public License as published by the Free Software Foundation;
  20.  * either version 2.1 of the License, or (at your option) any
  21.  * later version.
  22.  * 
  23.  * This library is distributed in the hope that it will be useful,
  24.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  25.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  26.  * Lesser General Public License for more details.
  27.  * 
  28.  * You should have received a copy of the GNU Lesser General Public
  29.  * License along with this library; if not, write to the Free Software
  30.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  31.  *
  32.  * @package    phpDocumentor
  33.  * @subpackage Parsers
  34.  * @author     Gregory Beaver <cellog@php.net>
  35.  * @copyright  2002-2006 Gregory Beaver
  36.  * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL
  37.  * @version    CVS: $Id: ParserDescCleanup.inc,v 1.13 2007/12/13 02:56:45 ashnazg Exp $
  38.  * @link       http://www.phpdoc.org
  39.  * @link       http://pear.php.net/PhpDocumentor
  40.  * @see        Parser, WordParser
  41.  * @since      1.2
  42.  */
  43.  
  44. /**#@+
  45.  * {@link parserDescParser} token constants
  46.  */
  47. /** when <<code>> is found in a desc */
  48. define('PHPDOCUMENTOR_PDP_EVENT_CODE', 600);
  49. /** when <<code>> is found in a desc */
  50. define('PHPDOCUMENTOR_PDP_STATE_CODE', 700);
  51. /** when <<p>> is found in a desc */
  52. define('PHPDOCUMENTOR_PDP_EVENT_P', 601);
  53. /** when <<p>> is found in a desc */
  54. define('PHPDOCUMENTOR_PDP_STATE_P', 701);
  55. /** when \n\n is found in a desc */
  56. define('PHPDOCUMENTOR_PDP_EVENT_DOUBLECR', 602);
  57. /** when \n\n is found in a desc */
  58. define('PHPDOCUMENTOR_PDP_STATE_DOUBLECR', 702);
  59. /** when <<pre>> is found in a desc */
  60. define('PHPDOCUMENTOR_PDP_EVENT_PRE', 603);
  61. /** when <<pre>> is found in a desc */
  62. define('PHPDOCUMENTOR_PDP_STATE_PRE', 703);
  63. /** when <<ul>>/<<ol>> is found in a desc */
  64. define('PHPDOCUMENTOR_PDP_EVENT_LIST', 604);
  65. /** when <<ul>>/<<ol>> is found in a desc */
  66. define('PHPDOCUMENTOR_PDP_STATE_LIST', 704);
  67. /** when <<b>> is found in a desc */
  68. define('PHPDOCUMENTOR_PDP_EVENT_B', 605);
  69. /** when <<b>> is found in a desc */
  70. define('PHPDOCUMENTOR_PDP_STATE_B', 705);
  71. /** when <<i>> is found in a desc */
  72. define('PHPDOCUMENTOR_PDP_EVENT_I', 606);
  73. /** when <<i>> is found in a desc */
  74. define('PHPDOCUMENTOR_PDP_STATE_I', 706);
  75. /** when <<br>> is found in a desc */
  76. define('PHPDOCUMENTOR_PDP_EVENT_BR', 607);
  77. /** when <<br>> is found in a desc */
  78. define('PHPDOCUMENTOR_PDP_STATE_BR', 707);
  79. /** when the << potential escape for tags is found in a desc */
  80. define('PHPDOCUMENTOR_PDP_EVENT_ESCAPE',608);
  81. /** when the << potential escape for tags is found in a desc */
  82. define('PHPDOCUMENTOR_PDP_STATE_ESCAPE',708);
  83. /** when << /pre>> is found in a <<pre>><</pre>> section */
  84. define('PHPDOCUMENTOR_PDP_EVENT_ESCAPE_PRE',609);
  85. /** when << /pre>> is found in a <<pre>><</pre>> section */
  86. define('PHPDOCUMENTOR_PDP_STATE_ESCAPE_PRE',709);
  87. /** when << /code>> is found in a <<code>><</code>> section  */
  88. define('PHPDOCUMENTOR_PDP_EVENT_ESCAPE_CODE',610);
  89. /** when << /code>> is found in a <<code>><</code>> section  */
  90. define('PHPDOCUMENTOR_PDP_STATE_ESCAPE_CODE',710);
  91. /** when <<var>> is found in a desc  */
  92. define('PHPDOCUMENTOR_PDP_EVENT_VAR',611);
  93. /** when <<var>> is found in a desc  */
  94. define('PHPDOCUMENTOR_PDP_STATE_VAR',711);
  95. /** when <<samp>> is found in a desc  */
  96. define('PHPDOCUMENTOR_PDP_EVENT_SAMP',612);
  97. /** when <<samp>> is found in a desc  */
  98. define('PHPDOCUMENTOR_PDP_STATE_SAMP',712);
  99. /** when <<kbd>> is found in a desc  */
  100. define('PHPDOCUMENTOR_PDP_EVENT_KBD',613);
  101. /** when <<kbd>> is found in a desc  */
  102. define('PHPDOCUMENTOR_PDP_STATE_KBD',713);
  103. /** when a simple list is found in a desc
  104.  *
  105.  * like
  106.  * <pre>
  107.  *  o item 1
  108.  *  o item 2
  109.  * </pre>
  110.  */
  111. define('PHPDOCUMENTOR_PDP_EVENT_SIMLIST',614);
  112. /** when a simple list is found in a desc
  113.  *
  114.  * like
  115.  * <pre>
  116.  *  o item 1
  117.  *  o item 2
  118.  * </pre>
  119.  */
  120. define('PHPDOCUMENTOR_PDP_STATE_SIMLIST',714);
  121. /**#@-*/
  122. /**
  123. * Like WordParser but designed to handle an array with strings and
  124. * {@link parserInlineTag}s
  125. * @package phpDocumentor
  126. * @subpackage WordParsers
  127. * @author Greg Beaver <cellog@php.net>
  128. * @since 1.2
  129. */
  130. class ObjectWordParser extends WordParser
  131. {
  132.     /**
  133.      * Determines whether text searching is case-sensitive or not
  134.      * @access private
  135.      */
  136.     var $_casesensitive = false;
  137.     
  138.     function ObjectWordParser($casesensitive = false)
  139.     {
  140.         $this->_casesensitive = $casesensitive;
  141.     }
  142.     
  143.     /**
  144.      * Set the word parser to go.
  145.      *
  146.      * @param array {@link parserStringWithInlineTags::$value} style-array, with
  147.      *              alternating text and inline tags
  148.      */
  149.     function setup(&$input)
  150.     {
  151. //        if (is_string($input[0])) $input[0] = ltrim($input[0]);
  152.         $this->data = & $input;
  153.         $this->pos = 0;
  154.         $this->linenum = 0;
  155.         $this->linenumpos = 0;
  156.         $this->cache = array();
  157.         reset($this->data);
  158.         list($this->index,) = each($this->data);
  159.         if (!is_object($this->data[$this->index]))
  160.         $this->size = strlen($this->data[$this->index]);
  161.         else $this->size = 0;
  162.         //$this->run = 0;
  163.         //$this->word = WORD_PARSER_RET_WORD;
  164.     }
  165.     
  166.     function getWord()
  167.     {
  168.         if (!isset($this->data[$this->index])) return false;
  169.         // return any inline tags unchanged
  170.         if (is_object($this->data[$this->index]))
  171.         {
  172.             $index = $this->index;
  173.             list($this->index,) = each($this->data);
  174.             $this->pos = 0;
  175.             if ($this->index)
  176.             {
  177.                 if (!is_object($this->data[$this->index]))
  178.                 $this->size = strlen($this->data[$this->index]);
  179.                 else $this->size = 0;
  180.                 $this->cache = array();
  181.                 return $this->data[$index];
  182.             } else
  183.             {
  184.                 return false;
  185.             }
  186.         }
  187.         //$st = $this->mtime();
  188.         if ($this->size == $this->pos)
  189.         {
  190.             // cycle to next line in the array
  191.             list($this->index,) = each($this->data);
  192.             if (!$this->index) return false;
  193.             $this->pos = 0;
  194.             if (!is_object($this->data[$this->index]))
  195.             $this->size = strlen($this->data[$this->index]);
  196.             else $this->size = 0;
  197.             $this->cache = array();
  198.             return $this->getWord();
  199.         }
  200.  
  201.         $npos = $this->size;
  202.         if (is_array($this->wordseperators))
  203.         {
  204.             //$this->wordseperators = array();
  205.             foreach($this->wordseperators as $sep)
  206.             {
  207.                 if (isset($this->cache[$sep]))
  208.                 $tpos = $this->cache[$sep];
  209.                 else
  210.                 $tpos = false;
  211.                 if ($tpos < $this->pos || !is_int($tpos))
  212.                 {
  213.                     if ($this->_casesensitive)
  214.                         $tpos = strpos($this->data[$this->index],$sep,$this->pos);
  215.                     else
  216.                         $tpos = strpos(strtolower($this->data[$this->index]),$sep,$this->pos);
  217.                 }
  218.             
  219.                 if ( ($tpos < $npos) && !($tpos === false))
  220.                 {
  221.                     //echo trim($sep) . "=$tpos\n";
  222.                     $npos = $tpos;
  223.                     $seplen = strlen($sep);
  224.                 } 
  225.                   else if (!($tpos === false))
  226.                 {
  227.                     $this->cache[$sep] = $tpos;
  228.                 }
  229.             }
  230.         } else {
  231.             // its time to cycle
  232.             return "";
  233.         }
  234.  
  235.         $len = $npos - $this->pos;
  236.         if ($len == 0)
  237.         {
  238.             $len = $seplen;
  239.         }
  240.  
  241.         //$st3 = $this->mtime();
  242.         $word = substr($this->data[$this->index],$this->pos,$len);
  243.         
  244.         // Change random other os newlines to the unix one
  245.         if ($word == "\r" || $word == "\r\n")
  246.         {
  247.             $word = "\n";
  248.         }
  249.         
  250.         if ($this->linenumpos <= $this->pos)
  251.         {
  252.             $this->linenumpos = $this->pos + $len;
  253.             $this->linenum += count(explode("\n",$word)) - 1;
  254.         }
  255.  
  256.         if ($this->getsource)
  257.         {
  258.             $this->source .= $word;
  259.         }
  260.         $this->pos = $this->pos + $len;
  261.         //$this->word = WORD_PARSER_RET_SEP;
  262.  
  263.         // Things like // commenats rely on the newline to find their end so im going to have to return them
  264.         // never return worthless white space /t ' '
  265.         if ($this->returnWhiteSpace == false)
  266.         {
  267.             if (strlen(trim($word)) == 0 && $word != "\n") 
  268.             {
  269.                 $word = $this->getWord();
  270.             }
  271.         }
  272.         //$this->time3 = $this->time3 + ($this->mtime() - $st3);
  273.         //$this->time = $this->time + ($this->mtime() - $st);
  274.         return $word;
  275.     }
  276.     
  277.     /**
  278.      * Determine if the next word is an inline tag
  279.      * @return boolean
  280.      */
  281.     function nextIsObjectOrNonNL()
  282.     {
  283.         return (($this->size == $this->pos) && isset($this->data[$this->index + 1])
  284.             && is_object($this->data[$this->index + 1])) ||
  285.                (($this->size > $this->pos) && !in_array($this->data[$this->index]{$this->pos}, array("\n", "\r")));
  286.     }
  287. }
  288.  
  289. /**
  290.  * Parses a DocBlock description to retrieve abstract representations of
  291.  * <<pre>>,<<code>>,<<p>>,<<ul>>,<<ol>>,<<li>>,<<b>>,<<i>>
  292.  * @tutorial phpDocumentor.howto.pkg#basics.desc
  293.  * @package phpDocumentor
  294.  * @subpackage Parsers
  295.  * @author Greg Beaver <cellog@php.net>
  296.  * @since 1.2
  297.  */
  298. class parserDescParser extends Parser
  299. {
  300.     /**#@+
  301.      * @access private
  302.      */
  303.     /**
  304.      * @var array
  305.      */
  306.     var $eventHandlers = array(PHPDOCUMENTOR_PDP_EVENT_CODE => 'handleCode',
  307.                                PHPDOCUMENTOR_PDP_EVENT_PRE => 'handlePre',
  308.                                PHPDOCUMENTOR_PDP_EVENT_P => 'handleP',
  309.                                PHPDOCUMENTOR_PDP_EVENT_DOUBLECR => 'handleDoubleCR',
  310.                                PHPDOCUMENTOR_PDP_EVENT_LIST => 'handleList',
  311.                                PHPDOCUMENTOR_PDP_EVENT_B => 'handleB',
  312.                                PHPDOCUMENTOR_PDP_EVENT_I => 'handleI',
  313.                                PHPDOCUMENTOR_PDP_EVENT_VAR => 'handleVar',
  314.                                PHPDOCUMENTOR_PDP_EVENT_KBD => 'handleKbd',
  315.                                PHPDOCUMENTOR_PDP_EVENT_SAMP => 'handleSamp',
  316.                                PHPDOCUMENTOR_PDP_EVENT_BR => 'handleBr',
  317.                                PHPDOCUMENTOR_PDP_EVENT_ESCAPE => 'handleEscape',
  318.                                PHPDOCUMENTOR_PDP_EVENT_ESCAPE_CODE => 'handleEscapeCode',
  319.                                PHPDOCUMENTOR_PDP_EVENT_ESCAPE_PRE => 'handleEscapePre',
  320.                                PHPDOCUMENTOR_PDP_EVENT_SIMLIST => 'handleSimpleList',
  321.                                PARSER_EVENT_NOEVENTS => 'defaultHandler',
  322.                                );
  323.     
  324.     /**
  325.      * @var array
  326.      */
  327.     var $pars = array();
  328.     /**
  329.      * Determines whether parsing of <p> tags will occur, or double CR will
  330.      * be used
  331.      * @var boolean
  332.      */
  333.     var $parse_Ps;
  334.     /**
  335.      * Context stack.
  336.      *
  337.      * Values can be 'normal', or any tag container like 'my_i', 'my_b'.  This
  338.      * is used to determine which tag text or nested tags should be added to
  339.      * @var array
  340.      */
  341.     var $_context = array('normal');
  342.     /**#@-*/
  343.     
  344.     /**
  345.      * sets $wp to be a {@link ObjectWordParser}
  346.      * 
  347.      * $wp is the word parser that retrieves tokens
  348.      */
  349.     function parserDescParser()
  350.     {
  351.         $this->wp = new ObjectWordParser;
  352.     }
  353.     
  354.     /**
  355.      * Parse a long or short description for tags
  356.      *
  357.      * @param array array of strings or {@link parserInlineTag}s
  358.      * @param boolean true if the description is a short description. (only 1 paragraph allowed in short desc)
  359.      * @param string name of the class to instantiate for each paragraph.  parserDesc for desc/sdesc,
  360.      *               parserStringWithInlineTags for tag data
  361.      * @staticvar integer used for recursion limiting if a handler for an event is not found
  362.      */
  363.     function parse (&$parse_data,$sdesc = false,$ind_type = 'parserDesc')
  364.     {
  365.         static $endrecur = 0;
  366.         global $_phpDocumentor_setting;
  367.         if (!is_array($parse_data) || count($parse_data) == 0)
  368.         {
  369.             return false;
  370.         }
  371.         $this->p_vars['indtype'] = $ind_type;
  372.         $this->setupStates($sdesc);
  373.         if (isset($_phpDocumentor_setting['javadocdesc']) && $_phpDocumentor_setting['javadocdesc'] == 'on')
  374.             $this->parse_Ps = true;
  375.  
  376.         // initialize variables so E_ALL error_reporting doesn't complain
  377.         $pevent = 0;
  378.         $word = 0;
  379.         $this->p_vars['curpar'] = 0;
  380.         $this->pars = array();
  381.         $this->p_vars['start'] = true;
  382.         $this->p_vars['event_stack'] = new EventStack;
  383.  
  384.         $this->wp->setup($parse_data,$sdesc);
  385.         $this->wp->setWhitespace(true);
  386.         $this->p_vars['list_count'] = 0;
  387.         if ($sdesc) $this->p_vars['start'] = false;
  388.  
  389.         // beware of infinite loops
  390.         $infiniteLoopCatcher = 0;
  391.         do
  392.         {
  393.             $infiniteLoopCatcher++;
  394.             if (!isset($this->pars[$this->p_vars['curpar']])) $this->pars[$this->p_vars['curpar']] = new $ind_type;
  395.             $lpevent = $pevent;
  396.             $pevent = $this->p_vars['event_stack']->getEvent();
  397.             if ($lpevent != $pevent)
  398.             {
  399.                 $this->p_vars['last_pevent'] = $lpevent;
  400.             }
  401.  
  402.             if ($this->p_vars['last_pevent'] != $pevent)
  403.             {
  404.                 // its a new event so the word parser needs to be reconfigured 
  405.                 $this->configWordParser($pevent);
  406.             }
  407.  
  408.  
  409.             $this->p_vars['last_word'] = $word;
  410.             $word = $this->wp->getWord();
  411.  
  412.             if (PHPDOCUMENTOR_DEBUG == true)
  413.             {
  414.                 echo "----------------\n";
  415.                 echo "LAST: |" . htmlentities($this->p_vars['last_word']) . "|\n";
  416. //                echo "INDEX: ".$this->p_vars['curpar']."\n";
  417.                 echo "PEVENT: " . $this->getParserEventName($pevent) . "\n";
  418.                 echo "LASTPEVENT: " . $this->getParserEventName($this->p_vars['last_pevent']) . "\n";
  419.                 echo $this->wp->getPos() . " WORD: |".htmlentities($word)."|\n\n";
  420.                 var_dump($this->_context);
  421.             }
  422.             if (isset($this->eventHandlers[$pevent]))
  423.             {
  424.                 $handle = $this->eventHandlers[$pevent];
  425.                 if ($word !== false) $this->$handle($word, $pevent);
  426.                 else
  427.                 {
  428.                     if (!count($this->pars[$this->p_vars['curpar']]->value)) unset($this->pars[$this->p_vars['curpar']]);
  429.                 }
  430.             } else
  431.             {
  432.                 debug('WARNING: possible error, no ParserDescParser handler for event number '.$pevent);
  433.                 if ($endrecur++ == 25)
  434.                 {
  435.                     addErrorDie(PDERROR_LOOP_RECURSION_LIMIT_REACHED);
  436.                 }
  437.             }
  438.             if (is_object($word) || trim($word) != '')
  439.             {
  440.                 $this->p_vars['start'] = false;
  441.             }
  442.  
  443.             if ($infiniteLoopCatcher > 10000) {
  444.                 echo PHP_EOL . "FATAL ERROR:  Somehow we got into an infinite loop in parserDescCleanup->parse()'s do-while loop...";
  445.                 echo PHP_EOL . "    The line being parsed was:  " . $word . PHP_EOL . PHP_EOL;
  446.                 addErrorDie(PDERROR_LOOP_RECURSION_LIMIT_REACHED);
  447.             }
  448.         } while (is_object($word) || !($word === false) && $word != '');
  449.         $context = $this->getContext();
  450.         if ($context != 'normal')
  451.         {
  452.             if ($context == 'list' && $this->p_flags['simplelist'])
  453.             {
  454.                 $this->p_vars['lists'][0]->addItem($this->p_vars['list_item'][0]);
  455.                 unset($this->p_vars['list_item'][0]);
  456.                 $this->setContext('normal');
  457.                 $this->addText($this->p_vars['lists'][0]);
  458.             } else addError(PDERROR_UNCLOSED_TAG,str_replace('my_','',$context));
  459.         }
  460.         if ($this->p_vars['list_count'] > 0) addError(PDERROR_UNMATCHED_LIST_TAG);
  461.         if ($sdesc)
  462.         $this->publishEvent(2,$this->pars);
  463.         else
  464.         $this->publishEvent(1,$this->pars);
  465.     }
  466.     /**#@+ @access private */
  467.     /**
  468.      * basic handling
  469.      *
  470.      * This function checks to see if the first thing in
  471.      * a description is the <p> tag.  If so, it will switch
  472.      * into a mode of parsing out paragraphs by <p> instead
  473.      * of a double line-break
  474.      *
  475.      * It also removes extra whitespace
  476.      * @uses doSimpleList()
  477.      */
  478.     function defaultHandler($word, $pevent)
  479.     {
  480.         $context = $this->getContext();
  481.         if ($context != 'normal') $this->setContext('normal');
  482.         if ($this->p_vars['start'] && is_string($word) && strtolower($word) == '<p>')
  483.         {
  484.             $this->parse_Ps = true;
  485.         }
  486.         if (is_string($word) && $this->checkEventPush($word, $pevent)) return;
  487. //        if (!isset($this->parse_Ps) || !$this->parse_Ps)
  488.         {
  489.             if (is_string($word) && is_string($this->p_vars['last_word']) &&
  490.                   ($word == ' ' && $this->p_vars['last_word'] == ' ')) return;
  491.             if ($pevent == PARSER_EVENT_NOEVENTS)
  492.             {
  493.                 if ($this->doSimpleList($word)) return;
  494.             }
  495.             $this->addText($word);
  496.         }
  497.     }
  498.     
  499.     /**
  500.      * Retrieve the current top-level tag to add text into
  501.      * @uses $_context
  502.      */
  503.     function getContext()
  504.     {
  505.         array_push($this->_context,$a = array_pop($this->_context));
  506.         return $a;
  507.     }
  508.     
  509.     /**
  510.      * Pop a context off of the context stack
  511.      * @uses $_context
  512.      */
  513.     function dropContext()
  514.     {
  515.         array_pop($this->_context);
  516.         if (count($this->_context) == 0)
  517.         $this->_context = array('normal');
  518.     }
  519.     
  520.     /**
  521.      * @uses $_context
  522.      * @param string context name
  523.      */
  524.     function setContext($context)
  525.     {
  526.         array_push($this->_context,$context);
  527.     }
  528.     
  529.     /**
  530.      * add input as text to the current paragraph or list
  531.      * @param string|parserInlineTag
  532.      */
  533.     function addText($text)
  534.     {
  535.         $context = $this->getContext();
  536.         if ($context == 'list')
  537.         {
  538. //            debug('aded to '.$context);
  539.             if (!is_object($this->p_vars['list_item'][$this->p_vars['list_count']])) {
  540.                 addErrorDie(PDERROR_UL_IN_UL);
  541.             }
  542.             $this->p_vars['list_item'][$this->p_vars['list_count']]->add($text);
  543.         } elseif ($context != 'normal')
  544.         {
  545. //            debug('added to '.$context);
  546.             $this->p_vars[$context]->add($text);
  547.         } else
  548.         {
  549. //            debug('added to normal ');
  550.             $indtype = $this->p_vars['indtype'];
  551.             if (!isset($this->pars[$this->p_vars['curpar']]))
  552.                 $this->pars[$this->p_vars['curpar']] = new $indtype;
  553.             $this->pars[$this->p_vars['curpar']]->add($text);
  554.         }
  555.     }
  556.     
  557.     /**#@-*/
  558.     /**#@+
  559.      * @access private
  560.      * @param string|parserInlineTag token from the ObjectWordParser
  561.      * @param integer parser event from {@link ParserDescCleanup.inc}
  562.      */
  563.     /**
  564.      * Handles special case where a description needs the text "<tag>" and tag
  565.      * is one of code, b, i, pre, var, or any other valid in-DocBlock html tag.
  566.      *
  567.      * the text <<<code>>> in a DocBlock will parse out as <<code>>, instead
  568.      * of being parsed as markup.
  569.      */
  570.     function handleEscape($word, $pevent)
  571.     {
  572.         $this->p_vars['event_stack']->popEvent();
  573.         if (!in_array($word, $this->tokens[PHPDOCUMENTOR_PDP_STATE_ESCAPE]))
  574.         {
  575.             if ($word == '<')
  576.             {
  577.                 $this->addText($word);
  578.                 $this->wp->backupPos($word.$word);
  579.             } else
  580.             $this->wp->backupPos($word);
  581.             return;
  582.         }
  583.         $this->addText('<'.str_replace('>>','>',$word));
  584.     }
  585.     
  586.     /**
  587.      * Just like {@link handleEscape}, except the only valid escape is
  588.      * <<</pre>>>
  589.      */
  590.     function handleEscapePre($word, $pevent)
  591.     {
  592.         $this->p_vars['event_stack']->popEvent();
  593.         $this->addText('</pre>');
  594.     }
  595.     
  596.     /**
  597.      * Just like {@link handleEscape}, except the only valid escape is
  598.      * <<</code>>>
  599.      */
  600.     function handleEscapeCode($word, $pevent)
  601.     {
  602.         $this->p_vars['event_stack']->popEvent();
  603.         $this->addText('</code>');
  604.     }
  605.     
  606.     /**
  607.      * Handle "<<br>>"
  608.      * Add a new {@link parserBr}
  609.      * @uses addText()
  610.      */
  611.     function handleBr($word, $pevent)
  612.     {
  613.         if (is_string($word) && $this->checkEventPop($word, $pevent))
  614.         {
  615.             $this->addText(new parserBr);
  616.         }
  617.     }
  618.     
  619.     /**
  620.      * Handles simple lists
  621.      *
  622.      * phpEdit has an ingenious facility to handle simple lists used in a
  623.      * DocBlock like this:
  624.      *
  625.      * - item 1
  626.      * - item 2
  627.      * - item 3
  628.      *
  629.      * The DocBlock is:
  630.      * <pre>
  631.      * * - item 1
  632.      * * - item 2
  633.      * * - item 3
  634.      * </pre>
  635.      * This function converts these simple lists into the parserList class
  636.      * @param boolean true if this is the first list item in the list
  637.      */
  638.     function handleSimpleList($word, $pevent, $start = false)
  639.     {
  640.         if (is_object($word) && $this->p_flags['in_item'])
  641.         {
  642.             $this->p_vars['list_item'][0]->add($word);
  643.             return;
  644.         }
  645.         if (is_string($word) && $this->checkEventPush($word, $pevent))
  646.         {
  647.             $this->p_flags['in_event'] = true;
  648.             return;
  649.         }
  650.         $ltrimword = @substr($word, @strpos($word, ltrim($word)));
  651.         $is_valid = false;
  652.         if (strlen(trim($word)) == 0)
  653.         {
  654.             if ($this->wp->nextIsObjectOrNonNL())
  655.             {
  656.                 $is_valid = true;
  657.             }
  658.         }
  659.         if ($word == "\n" && is_string($this->p_vars['last_word'])
  660.             && $this->p_vars['last_word']{strlen($this->p_vars['last_word']) - 1}
  661.                 == "\n")
  662.         {
  663.             if ($this->p_flags['in_item'])
  664.             {
  665.                 $this->p_vars['lists'][0]->addItem($this->p_vars['list_item'][0]);
  666.                 unset($this->p_vars['list_item'][0]);
  667.                 $this->setContext('normal');
  668.                 $this->p_flags['simplelist'] = false;
  669.                 $this->addText($this->p_vars['lists'][0]);
  670.                 unset($this->p_vars['lists']);
  671.                 unset($this->p_vars['last_list']);
  672.                 $this->wp->backuppos($word);
  673.                 $this->p_vars['event_stack']->popEvent();
  674.                 $this->p_flags['in_item'] = false;
  675. //                debug('end of list 3');
  676.                 return;
  677.             } else
  678.             {
  679.                 $this->wp->backuppos($word);
  680.                 $this->p_vars['event_stack']->popEvent();
  681.                 $this->p_flags['in_item'] = false;
  682. //                debug('not a list 2');
  683.                 return;
  684.             }
  685.         }
  686.         $start_list = $this->getStartList($word);
  687.         if (substr($ltrimword,0,strlen($start_list)) != $start_list 
  688.              || $this->p_flags['in_event'] || is_object($this->p_vars['last_word']))
  689.         {
  690.             if (((strlen($this->p_vars['whitespace']) + 1) < strlen(substr($word,0,strpos($word, $ltrimword))))
  691.                    || $word == "\n"
  692.                    || $is_valid
  693.                    || $this->p_flags['in_event']
  694.                    || (is_object($this->p_vars['last_word']) && $this->p_flags['in_item']))
  695.             {
  696.                 $this->p_vars['list_item'][0]->add($word);
  697.                 $this->resetStartList($start_list);
  698.                 $this->p_flags['in_event'] = false;
  699. //                debug('middle of list');
  700.             } else
  701.             {
  702.                 if ($this->p_flags['in_item'])
  703.                 {
  704.                     $this->p_vars['lists'][0]->addItem($this->p_vars['list_item'][0]);
  705.                     unset($this->p_vars['list_item'][0]);
  706.                     $this->setContext('normal');
  707.                     $this->p_flags['simplelist'] = false;
  708.                     $this->addText($this->p_vars['lists'][0]);
  709.                     unset($this->p_vars['lists']);
  710.                     unset($this->p_vars['last_list']);
  711.                     $this->wp->backuppos($word);
  712.                     $this->p_vars['event_stack']->popEvent();
  713.                     $this->p_flags['in_item'] = false;
  714. //                    debug('end of list 1');
  715.                     return;
  716.                 } else
  717.                 {
  718.                     $this->wp->backuppos($word);
  719.                     $this->p_vars['event_stack']->popEvent();
  720.                     $this->p_flags['in_item'] = false;
  721. //                    debug('not a list');
  722.                     return;
  723.                 }
  724.             }
  725.         } else
  726.         {
  727.             if ($this->p_vars['whitespace'] != substr($word,0,strpos($word, $start_list)))
  728.             { // if the whitespace is greater than that preceding the list
  729.               // delimiter, it's a multi-line list item
  730.                 $this->setContext('normal');
  731.                 $this->p_flags['simplelist'] = false;
  732.                 $this->addText($this->p_vars['lists'][0]);
  733.                 unset($this->p_vars['lists']);
  734.                 $this->wp->backuppos($word);
  735.                 $this->p_vars['event_stack']->popEvent();
  736.                 unset($this->p_vars['last_list']);
  737.                 $this->p_flags['in_item'] = false;
  738. //                debug('end of list 2');
  739.                 return;
  740.             } else
  741.             {
  742.                 if ($this->p_flags['in_item'])
  743.                 {
  744.                     // end of a list item, add it to the list
  745.                     $this->p_vars['lists'][0]->addItem($this->p_vars['list_item'][0]);
  746.                     unset($this->p_vars['list_item'][0]);
  747.                 }
  748. //                debug('next list item');
  749.                 $this->p_vars['list_item'][0] = new parserStringWithInlineTags;
  750.                 $this->p_vars['list_item'][0]->add(ltrim(substr($ltrimword,strlen($start_list))));
  751.                 $this->p_flags['in_item'] = true;
  752.             }
  753.         }
  754.     }
  755.     /**#@-*/
  756.     /**
  757.      * Get the next list marker
  758.      *
  759.      * In unordered lists, this will be something like "o", "-"
  760.      *
  761.      * In ordered lists, this will be either the number "3", "5" or "3.", "5."
  762.      * @return string text of the next list marker to look for
  763.      * @param string current word from the parser
  764.      * @access private
  765.      */
  766.     function getStartList($word)
  767.     {
  768.         // unordered, return the first marker found
  769.         if (!$this->p_flags['orderedlist']) return $this->p_vars['start_list'];
  770.         if (isset($this->p_vars['last_list']))
  771.         {
  772.             $this->p_vars['save_list'] = $this->p_vars['last_list'];
  773.             $next = $this->p_vars['last_list'];
  774.             // increment to next list number, convert to string
  775.             if (substr($this->p_vars['start_list'], strlen($this->p_vars['start_list']) - 1) == '.')
  776.                 $next = (substr($next, 0, strpos($next,'.')) + 1) . '.';
  777.             else
  778.                 $next = ($next + 1) . '';
  779. //                debug("next is '$next'");
  780.             if ($this->p_vars['whitespace'] == substr($word,0,strpos($word, $next)))
  781.                 return $this->p_vars['last_list'] = $next;
  782.             // the next number is not in this word, so return but don't save
  783.             return $next;
  784.         } else
  785.         {
  786.             $this->p_vars['last_list'] = $this->p_vars['start_list'];
  787.             return $this->p_vars['start_list'];
  788.         }
  789.     }
  790.     
  791.     /**
  792.      * Set the next list marker to the current list marker
  793.      *
  794.      * In ordered lists, this will ensure that the next number returned is the
  795.      * right number
  796.      * @param string token for next list marker
  797.      * @access private
  798.      */
  799.     function resetStartList($start)
  800.     {
  801.         if (!isset($this->p_vars['save_list'])) return false;
  802.         $this->p_vars['last_list'] = $this->p_vars['save_list'];
  803.     }
  804.     
  805.     /**#@+
  806.      * @access private
  807.      * @param string|parserInlineTag token from the ObjectWordParser
  808.      * @param integer parser event from {@link ParserDescCleanup.inc}
  809.      */
  810.     /**
  811.      * Handles <<ol>>,<<li>>,<<ul>>
  812.      *
  813.      * This allows parsing of lists nested to any level.  Using
  814.      * the lists and list_item temporary variables and using
  815.      * list_count to control nesting, the method creates a {@link parserList}
  816.      * for each <<ol>> or <<ul>> tag, and a
  817.      * standard {@link parserStringWithInlineTags} for all the text, adding
  818.      * in nested lists as if they were inline tags (the conversion interface
  819.      * is the same for both object types)
  820.      */
  821.     function handleList($word, $pevent)
  822.     {
  823.         if (is_string($word) && $this->checkEventPush($word, $pevent))
  824.         {
  825.             return;
  826.         }
  827.         $ordered = false;
  828.         if (!is_object($this->p_vars['last_word']) && strtolower($this->p_vars['last_word']) == '<ol>')
  829.         {
  830.             // ordered list
  831.             $ordered = true;
  832.         }
  833.         // start a new list
  834.         if (!is_object($this->p_vars['last_word']) && (strtolower($this->p_vars['last_word']) == '<ol>' || strtolower($this->p_vars['last_word']) == '<ul>'))
  835.         {
  836.             $this->p_flags['in_item'] = false;
  837.             $this->setContext('list');
  838.             $this->p_vars['lists'][++$this->p_vars['list_count']] = new parserList($ordered);
  839.         }
  840.         if (!is_object($word) && strtolower($word) == '<li>')
  841.         {
  842.             if ($this->p_flags['in_item'])
  843.             {
  844.                 // end of a list item (no end tag), add it to the list
  845.                 $this->p_vars['lists'][$this->p_vars['list_count']]->addItem($this->p_vars['list_item'][$this->p_vars['list_count']]);
  846.                 unset($this->p_vars['list_item'][$this->p_vars['list_count']]);
  847.             }
  848.             // start a new list item
  849.             $this->p_vars['list_item'][$this->p_vars['list_count']] = new parserStringWithInlineTags;
  850.             $this->p_flags['in_item'] = true;
  851.         } else
  852.         {
  853.             if (is_object($word) || (strtolower($word) != '</li>'))
  854.             {
  855.                 if (is_object($word) || (strtolower($word) != '</ul>' && strtolower($word) != '</ol>'))
  856.                 {
  857.                     // item text
  858.                     if (isset($this->p_vars['list_item'][$this->p_vars['list_count']]))
  859.                     {
  860.                         if (is_string($word) && $word == ' ' &&
  861.                               $this->p_vars['last_word'] == ' ') return;
  862.                         $this->p_vars['list_item'][$this->p_vars['list_count']]->add($word);
  863.                     }
  864.                 } else
  865.                 {
  866.                     if ($this->p_flags['in_item'])
  867.                     {
  868.                         // end the current list item before ending a list
  869.                         $this->p_vars['lists'][$this->p_vars['list_count']]->addItem($this->p_vars['list_item'][$this->p_vars['list_count']]);
  870.                         unset($this->p_vars['list_item'][$this->p_vars['list_count']]);
  871.                         $this->p_flags['in_item'] = false;
  872.                     }
  873.                     if (is_string($word) && $this->checkEventPop($word, $pevent))
  874.                     {
  875.                         if ($this->p_vars['list_count'] > 1)
  876.                         {
  877.                             // this is a sublist, add it to the list item of the parent list
  878.                             if (!isset($this->p_vars['list_item'][$this->p_vars['list_count'] - 1])) {
  879.                                 addErrorDie(PDERROR_UL_IN_UL);
  880.                             }
  881.                             $this->p_vars['list_item'][$this->p_vars['list_count'] - 1]->add($this->p_vars['lists'][$this->p_vars['list_count']]);
  882.                             // remove the sublist item and sublist, drop to parent list
  883.                             unset($this->p_vars['lists'][$this->p_vars['list_count']]);
  884.                             unset($this->p_vars['lists'][$this->p_vars['list_count']]);
  885.                             $this->p_vars['list_count']--;
  886.                             $this->p_flags['in_item'] = true;
  887.                         } else
  888.                         {
  889.                             // this is a primary list and it has concluded
  890.                             $this->pars[$this->p_vars['curpar']]->add($this->p_vars['lists'][$this->p_vars['list_count']]);
  891.                             unset($this->p_vars['lists']);
  892.                             unset($this->p_vars['list_item']);
  893.                             $this->p_vars['list_count'] = 0;
  894.                             $this->dropContext();
  895.                         }
  896.                     }
  897.                 }
  898.             } else
  899.             {
  900.                 // check to make sure our list item is not unclosed
  901.                 if (!$this->p_flags['in_item'])
  902.                 {
  903.                     addError(PDERROR_TEXT_OUTSIDE_LI);
  904.                 } else
  905.                 {
  906.                     // end of a list item, add it to the list
  907.                     $this->p_vars['lists'][$this->p_vars['list_count']]->addItem($this->p_vars['list_item'][$this->p_vars['list_count']]);
  908.                     unset($this->p_vars['list_item'][$this->p_vars['list_count']]);
  909.                     $this->p_flags['in_item'] = false;
  910.                 }
  911.             }
  912.         }
  913.     }
  914.  
  915.     /**
  916.      * Handles <<code>><</code>> blocks
  917.      */
  918.     function handleCode($word, $pevent)
  919.     {
  920.         if (!isset($this->p_vars['my_code']))
  921.         {
  922.             $this->setContext('my_code');
  923.             $this->p_vars['my_code'] = new parserCode;
  924.         }
  925.         if (is_string($word) && $this->checkEventPush($word, $pevent)) return;
  926.         if (is_object($word) || strtolower($word) != '</code>') $this->p_vars['my_code']->add($word);
  927.         if (is_string($word))
  928.         {
  929.             if ($this->checkEventPop($word,$pevent))
  930.             {
  931.                 $this->dropContext();
  932.                 $this->addText($this->p_vars['my_code']);
  933.                 unset($this->p_vars['my_code']);
  934.             }
  935.         }
  936.     }
  937.     
  938.     /**
  939.      * Handles <<pre>><</pre>> blocks
  940.      */
  941.     function handlePre($word, $pevent)
  942.     {
  943.         if (!isset($this->p_vars['my_pre']))
  944.         {
  945.             $this->setContext('my_pre');
  946.             $this->p_vars['my_pre'] = new parserPre;
  947.         }
  948.         if (is_string($word) && $this->checkEventPush($word, $pevent)) return;
  949.         if (is_object($word) || strtolower($word) != '</pre>') $this->p_vars['my_pre']->add($word);
  950.         if (is_string($word))
  951.         {
  952.             if ($this->checkEventPop($word,$pevent))
  953.             {
  954.                 $this->dropContext();
  955.                 $this->addText($this->p_vars['my_pre']);
  956.                 unset($this->p_vars['my_pre']);
  957.             }
  958.         }
  959.     }
  960.     
  961.     /**
  962.      * Handles <<b>><</b>> blocks
  963.      */
  964.     function handleB($word, $pevent)
  965.     {
  966.         if (!isset($this->p_vars['my_b']))
  967.         {
  968.             $this->setContext('my_b');
  969.             $this->p_vars['my_b'] = new parserB;
  970.         }
  971.         if (is_string($word))
  972.         {
  973.             if ($this->checkEventPop($word,$pevent))
  974.             {
  975.                 $this->dropContext();
  976.                 $this->addText($this->p_vars['my_b']);
  977.                 unset($this->p_vars['my_b']);
  978.             } else
  979.             {
  980.                 $this->p_vars['my_b']->add($word);
  981.             }
  982.         } else $this->p_vars['my_b']->add($word);
  983.     }
  984.     
  985.     /**
  986.      * Handles <<i>><</i>> blocks
  987.      */
  988.     function handleI($word, $pevent)
  989.     {
  990.         if (!isset($this->p_vars['my_i']))
  991.         {
  992.             $this->p_vars['my_i'] = new parserI;
  993.             $this->setContext('my_i');
  994.         }
  995.         if (is_string($word))
  996.         {
  997.             if ($this->checkEventPop($word,$pevent))
  998.             {
  999.                 $this->dropContext();
  1000.                 $this->addText($this->p_vars['my_i']);
  1001.                 unset($this->p_vars['my_i']);
  1002.             } else
  1003.             {
  1004.                 $this->p_vars['my_i']->add($word);
  1005.             }
  1006.         } else $this->p_vars['my_i']->add($word);
  1007.     }
  1008.     
  1009.     /**
  1010.      * Handles <<var>><</var>> blocks
  1011.      */
  1012.     function handleVar($word, $pevent)
  1013.     {
  1014.         if (!isset($this->p_vars['my_var']))
  1015.         {
  1016.             $this->setContext('my_var');
  1017.             $this->p_vars['my_var'] = new parserDescVar;
  1018.         }
  1019.         if (is_string($word))
  1020.         {
  1021.             if ($this->checkEventPop($word,$pevent))
  1022.             {
  1023.                 $this->dropContext();
  1024.                 $this->addText($this->p_vars['my_var']);
  1025.                 unset($this->p_vars['my_var']);
  1026.             } else
  1027.             {
  1028.                 $this->p_vars['my_var']->add($word);
  1029.             }
  1030.         } else $this->p_vars['my_var']->add($word);
  1031.     }
  1032.     
  1033.     /**
  1034.      * Handles <<samp>><</samp>> blocks
  1035.      */
  1036.     function handleSamp($word, $pevent)
  1037.     {
  1038.         if (!isset($this->p_vars['my_samp']))
  1039.         {
  1040.             $this->setContext('my_samp');
  1041.             $this->p_vars['my_samp'] = new parserSamp;
  1042.         }
  1043.         if (is_string($word))
  1044.         {
  1045.             if ($this->checkEventPop($word,$pevent))
  1046.             {
  1047.                 $this->dropContext();
  1048.                 $this->addText($this->p_vars['my_samp']);
  1049.                 unset($this->p_vars['my_samp']);
  1050.             } else
  1051.             {
  1052.                 $this->p_vars['my_samp']->add($word);
  1053.             }
  1054.         } else $this->p_vars['my_samp']->add($word);
  1055.     }
  1056.     
  1057.     /**
  1058.      * Handles <<kbd>><</kbd>> blocks
  1059.      */
  1060.     function handleKbd($word, $pevent)
  1061.     {
  1062.         if (!isset($this->p_vars['my_kbd']))
  1063.         {
  1064.             $this->setContext('my_kbd');
  1065.             $this->p_vars['my_kbd'] = new parserKbd;
  1066.         }
  1067.         if (is_string($word))
  1068.         {
  1069.             if ($this->checkEventPop($word,$pevent))
  1070.             {
  1071.                 $this->dropContext();
  1072.                 $this->addText($this->p_vars['my_kbd']);
  1073.                 unset($this->p_vars['my_kbd']);
  1074.             } else
  1075.             {
  1076.                 $this->p_vars['my_kbd']->add($word);
  1077.             }
  1078.         } else $this->p_vars['my_kbd']->add($word);
  1079.     }
  1080.     
  1081.     /**
  1082.      * Handles <<p>><</p>> blocks
  1083.      *
  1084.      * Note that the only time <<p>> will be interpreted as delimiting a
  1085.      * paragraph is if it is the first thing in the description.
  1086.      */
  1087.     function handleP($word, $pevent)
  1088.     {
  1089.         if (!isset($this->parse_Ps)) $this->parse_Ps = false;
  1090.         if (is_string($word))
  1091.         {
  1092.             if (is_string($word) && $this->checkEventPush($word, $pevent)) return;
  1093.         }
  1094.         if (!$this->parse_Ps)
  1095.         {
  1096.             $this->p_vars['event_stack']->popEvent();
  1097.             if (!is_object($word) && strtolower($this->p_vars['last_word']) == '<p>') $this->addText('<p>');
  1098.             $this->addText($word);
  1099.             return;
  1100.         }
  1101.         if (is_string($word) && $word == "\n") $word = " ";
  1102.         if (is_string($word))
  1103.         {
  1104.             if ($this->checkEventPop($word, $pevent))
  1105.             {
  1106.                 $this->p_vars['curpar']++;
  1107.                 return;
  1108.             }
  1109.             // if no closing tag, pretend there was one
  1110.             if (!is_object($word) && strtolower($word) == '<p>' && $this->parse_Ps)
  1111.             {
  1112.                 $this->p_vars['curpar']++;
  1113.                 return;
  1114.             }
  1115.         }
  1116.         if ($this->p_vars['start'])
  1117.         {
  1118.             $this->addText($word);
  1119.         } else
  1120.         {// if the <p> is not at the beginning of the desc, then it is not
  1121.          // possible to parse into paragraphs using this tag
  1122.             if ($word === ' ' && $this->p_vars['last_word'] === ' ') return;
  1123.             $this->addText($word);
  1124.         }
  1125.     }
  1126.     
  1127.     /**
  1128.      * Handles \n\n as a paragraph marker
  1129.      * @uses doSimpleList()
  1130.      */
  1131.     function handleDoubleCR($word, $pevent)
  1132.     {
  1133.         $this->p_vars['event_stack']->popEvent();
  1134.         if ($word == "\n")
  1135.         {
  1136.             // only use this if <p> isn't being used
  1137.             if ((!isset($this->parse_Ps) || !$this->parse_Ps))
  1138.             {
  1139.                 if ($this->p_vars['last_word'] == "\n")
  1140.                 {
  1141.                     $this->p_vars['curpar']++;
  1142.                     $this->parse_Ps = false;
  1143.                 } else
  1144.                 {
  1145.                     if (is_string($word) && !$this->checkEventPush($word, $pevent))
  1146.                     {
  1147.                         if ($word == ' ' && $this->p_vars['last_word'] == ' ') return;
  1148.                         $this->addText($word);
  1149.                     }
  1150.                 }
  1151.             } else
  1152.             {
  1153.                 if (is_string($word) && !$this->checkEventPush($word, $pevent))
  1154.                 {
  1155.                     if ($word == ' ' && $this->p_vars['last_word'] == ' ') return;
  1156.                     $this->addText($word);
  1157.                 }
  1158.             }
  1159.         } else
  1160.         {
  1161.             if ($this->p_vars['last_word'] == "\n")
  1162.             {
  1163.                 if ((!isset($this->parse_Ps) || !$this->parse_Ps))
  1164.                 {
  1165.                     $this->addText(' ');
  1166.                 }
  1167.             }
  1168.             if (is_string($word) && !($e = $this->checkEventPush($word, $pevent)))
  1169.             {
  1170.                 if ($word == ' ' && $this->p_vars['last_word'] == ' ') return;
  1171.                 if ($this->doSimpleList($word)) return;
  1172.                 $this->addText($word);
  1173.             }
  1174.         }
  1175.     }
  1176.     
  1177.     /**#@-*/
  1178.     /**
  1179.      * Return a simple list, if found
  1180.      *
  1181.      * This helper function extracts a simple list beginning with any of
  1182.      * 'o','-'.'#','+','0','1','0.','1.' and starts parsing it.
  1183.      * @param string line that may contain a simple list
  1184.      * @return boolean true if a list is found, false otherwise
  1185.      */
  1186.     function doSimpleList($word)
  1187.     {
  1188.         if ($this->p_flags['in_event']) return true;
  1189.         if (is_object($word)) return false;
  1190.         $ltrimword = ltrim($word);
  1191.         if ((strlen($ltrimword) != strlen($word))
  1192.              && strlen($ltrimword) > 1
  1193.              && ((in_array($ltrimword{0},array('o','-','1','0','#','+')) && $ltrimword{1} == ' '))
  1194.                  || ((strlen($ltrimword) >= 2) && (substr($ltrimword,0,2) === '1.' || substr($ltrimword,0,2) === '0.') && $ltrimword{2} == ' '))
  1195.         {
  1196.             // save the whitespace for comparison
  1197.             $this->p_vars['whitespace'] = substr($word,0,strlen($word) - strlen($ltrimword));
  1198.             $this->p_vars['start_list'] = $ltrimword{0};
  1199.             if ($this->p_vars['start_list'] != '1' && $this->p_vars['start_list'] != '1.' &&
  1200.                 $this->p_vars['start_list'] != '0' && $this->p_vars['start_list'] != '0.')
  1201.             {
  1202.                 $this->p_flags['orderedlist'] = false;
  1203.             } else
  1204.             {
  1205.                 if (substr($ltrimword,0,2) == '1.')
  1206.                 {
  1207.                     $this->p_vars['start_list'] = '1.';
  1208.                 }
  1209.                 $this->p_flags['orderedlist'] = true;
  1210.             }
  1211.             $this->p_vars['event_stack']->pushEvent(PHPDOCUMENTOR_PDP_EVENT_SIMLIST);
  1212.             $this->setContext('list');
  1213.             $this->p_flags['simplelist'] = true;
  1214.             $this->p_vars['lists'][0] = new parserList($this->p_flags['orderedlist']);
  1215.             $this->p_vars['list_count'] = 0;
  1216.             $this->handleSimpleList($word, PHPDOCUMENTOR_PDP_EVENT_SIMLIST, true);
  1217.             return true;
  1218.         }
  1219.         return false;
  1220.     }
  1221.     /**
  1222.     * setup the parser tokens, and the pushEvent/popEvent arrays
  1223.     * @see $tokens, $pushEvent, $popEvent
  1224.     * @param boolean determines whether to allow paragraph parsing
  1225.     * @global boolean used to determine whether to slow things down or not by
  1226.     * eliminating whitespace from comments
  1227.     */
  1228.     
  1229.     function setupStates($sdesc)
  1230.     {
  1231.         $this->p_flags['in_item'] = false;
  1232.         $this->p_flags['in_event'] = false;
  1233.         $this->p_flags['simplelist'] = false;
  1234.         $this->_context = array('normal');
  1235.         $this->tokens[STATE_NOEVENTS]            = array("\n", "<code>", "<pre>", "<ol>", "<ul>", 
  1236.                                                          "<b>", "<i>", '<var>', '<kbd>', '<samp>', "<br", '<<');
  1237.         if (!$sdesc)
  1238.         {
  1239.             $this->tokens[STATE_NOEVENTS][] = "<p>";
  1240.             $this->tokens[STATE_NOEVENTS][] = "</p>";
  1241.         }
  1242.         if (PHPDOCUMENTOR_KILL_WHITESPACE) $this->tokens[STATE_NOEVENTS][] = ' ';
  1243.         $this->tokens[PHPDOCUMENTOR_PDP_STATE_P]        = array("</p>","<code>","<pre>","\n","<ol>","<ul>","<b>","<i>","<br","<p>", '<<',
  1244.                                                                 '<var>', '<kbd>', '<samp>');
  1245.         if (PHPDOCUMENTOR_KILL_WHITESPACE) $this->tokens[PHPDOCUMENTOR_PDP_STATE_P][] = ' ';
  1246.         $this->tokens[PHPDOCUMENTOR_PDP_STATE_CODE]        = array("</code>", '<</code>>');
  1247.         $this->tokens[PHPDOCUMENTOR_PDP_STATE_PRE]        = array("</pre>", '<</pre>>');
  1248.         $this->tokens[PHPDOCUMENTOR_PDP_STATE_LIST]        = array("<ul>","<ol>","</ul>","</ol>","<li>","</li>","<b>","<i>","<br", '<<',"<code>","<pre>","<br",
  1249.                                                                    '<var>', '<kbd>', '<samp>');
  1250.         $this->tokens[PHPDOCUMENTOR_PDP_STATE_DOUBLECR]        = array("\n","<ol>","<ul>","<code>","<pre>","<b>","<i>","<br","<p>","</p>",
  1251.                                                                        '<var>', '<kbd>', '<samp>', '<<');
  1252.         $this->tokens[PHPDOCUMENTOR_PDP_STATE_SIMLIST]      = array("\n",'<var>', '<kbd>', '<samp>','<b>','<i>', '<pre>', '<code>',
  1253.                                                                     '<br', '<<');
  1254.  
  1255.         $this->tokens[PHPDOCUMENTOR_PDP_STATE_B]    = array("<code>","\n","<pre>","<ol>","<ul>","</b>","<i>","<br", '<<',
  1256.                                                             '<var>', '<kbd>', '<samp>');
  1257.         $this->tokens[PHPDOCUMENTOR_PDP_STATE_KBD]    = array("<code>","\n","<pre>","<ol>","<ul>","<b>","<i>","<br", '<<',
  1258.                                                             '<var>', '</kbd>', '<samp>');
  1259.         $this->tokens[PHPDOCUMENTOR_PDP_STATE_VAR]    = array("<code>","\n","<pre>","<ol>","<ul>","<b>","<i>","<br", '<<',
  1260.                                                             '</var>', '<kbd>', '<samp>');
  1261.         $this->tokens[PHPDOCUMENTOR_PDP_STATE_SAMP]    = array("<code>","\n","<pre>","<ol>","<ul>","<b>","<i>","<br", '<<',
  1262.                                                             '<var>', '<kbd>', '</samp>');
  1263.         $this->tokens[PHPDOCUMENTOR_PDP_STATE_I]    = array("<code>","\n","<pre>","<ol>","<ul>","<b>","</i>","<br", '<<',
  1264.                                                             '<var>', '<kbd>', '<samp>');
  1265.         $this->tokens[PHPDOCUMENTOR_PDP_STATE_BR]    = array(">","/>");
  1266.         $this->tokens[PHPDOCUMENTOR_PDP_STATE_ESCAPE]    = array('code>>', '/code>>', 'pre>>', '/pre>>', 'b>>', '/b>>', 
  1267.                                                                  'i>>', '/i>>', 'ol>>', '/ol>>', 'ul>>', '/ul>>', 'li>>', '/li>>', 
  1268.                                                                  'br>>', 'br />>', 'p>>', '/p>>', 'samp>>', '/samp>>', 
  1269.                                                                  'kbd>>', '/kbd>>', 'var>>', '/var>>'); 
  1270.         if (PHPDOCUMENTOR_KILL_WHITESPACE) $this->tokens[PHPDOCUMENTOR_PDP_STATE_DOUBLECR][] = ' ';
  1271.  
  1272.         // For each event word to event mapings
  1273.         $this->pushEvent[PARSER_EVENT_NOEVENTS] = 
  1274.             array(
  1275.                 "<code>"    => PHPDOCUMENTOR_PDP_EVENT_CODE,
  1276.                 "<pre>"    => PHPDOCUMENTOR_PDP_EVENT_PRE,
  1277.                 "<p>" => PHPDOCUMENTOR_PDP_EVENT_P,
  1278.                 "<var>" => PHPDOCUMENTOR_PDP_EVENT_VAR,
  1279.                 "<samp>" => PHPDOCUMENTOR_PDP_EVENT_SAMP,
  1280.                 "<kbd>" => PHPDOCUMENTOR_PDP_EVENT_KBD,
  1281.                 "<ol>" => PHPDOCUMENTOR_PDP_EVENT_LIST,
  1282.                 "<ul>" => PHPDOCUMENTOR_PDP_EVENT_LIST,
  1283.                 "<b>" => PHPDOCUMENTOR_PDP_EVENT_B,
  1284.                 "<i>" => PHPDOCUMENTOR_PDP_EVENT_I,
  1285.                 "<br" => PHPDOCUMENTOR_PDP_EVENT_BR,
  1286.                 "\n" => PHPDOCUMENTOR_PDP_EVENT_DOUBLECR,
  1287.                 '<<' => PHPDOCUMENTOR_PDP_EVENT_ESCAPE,
  1288.             );
  1289. ##########################
  1290.         $this->pushEvent[PHPDOCUMENTOR_PDP_EVENT_CODE] =
  1291.             array(
  1292.                 '<</code>>' => PHPDOCUMENTOR_PDP_EVENT_ESCAPE_CODE,
  1293.             );
  1294.          
  1295.         $this->popEvent[PHPDOCUMENTOR_PDP_EVENT_CODE] = array("</code>");
  1296. ##########################
  1297.         $this->pushEvent[PHPDOCUMENTOR_PDP_EVENT_PRE] =
  1298.             array(
  1299.                 '<</pre>>' => PHPDOCUMENTOR_PDP_EVENT_ESCAPE_PRE,
  1300.             );
  1301.          
  1302.         $this->popEvent[PHPDOCUMENTOR_PDP_EVENT_PRE] = array("</pre>");
  1303. ##########################
  1304.          
  1305.         $this->popEvent[PHPDOCUMENTOR_PDP_EVENT_BR] = array(">","/>");
  1306. ##########################
  1307.         $this->pushEvent[PHPDOCUMENTOR_PDP_EVENT_P] =
  1308.             array(
  1309.                 "<code>" => PHPDOCUMENTOR_PDP_EVENT_CODE,
  1310.                 "<ol>" => PHPDOCUMENTOR_PDP_EVENT_LIST,
  1311.                 "<ul>" => PHPDOCUMENTOR_PDP_EVENT_LIST,
  1312.                 "<var>" => PHPDOCUMENTOR_PDP_EVENT_VAR,
  1313.                 "<samp>" => PHPDOCUMENTOR_PDP_EVENT_SAMP,
  1314.                 "<kbd>" => PHPDOCUMENTOR_PDP_EVENT_KBD,
  1315.                 "<pre>" => PHPDOCUMENTOR_PDP_EVENT_PRE,
  1316.                 "<b>" => PHPDOCUMENTOR_PDP_EVENT_B,
  1317.                 "<i>" => PHPDOCUMENTOR_PDP_EVENT_I,
  1318.                 "<br" => PHPDOCUMENTOR_PDP_EVENT_BR,
  1319.                 '<<' => PHPDOCUMENTOR_PDP_EVENT_ESCAPE,
  1320.             );
  1321.          
  1322.         $this->popEvent[PHPDOCUMENTOR_PDP_EVENT_P] = array("</p>");
  1323. ##########################
  1324.         
  1325.         $this->pushEvent[PHPDOCUMENTOR_PDP_EVENT_LIST] =
  1326.             array(
  1327.                 "<ul>" => PHPDOCUMENTOR_PDP_EVENT_LIST,
  1328.                 "<ol>" => PHPDOCUMENTOR_PDP_EVENT_LIST,
  1329.                 "<code>" => PHPDOCUMENTOR_PDP_EVENT_CODE,
  1330.                 "<var>" => PHPDOCUMENTOR_PDP_EVENT_VAR,
  1331.                 "<samp>" => PHPDOCUMENTOR_PDP_EVENT_SAMP,
  1332.                 "<kbd>" => PHPDOCUMENTOR_PDP_EVENT_KBD,
  1333.                 "<b>" => PHPDOCUMENTOR_PDP_EVENT_B,
  1334.                 "<i>" => PHPDOCUMENTOR_PDP_EVENT_I,
  1335.                 "<pre>" => PHPDOCUMENTOR_PDP_EVENT_PRE,
  1336.                 "<br" => PHPDOCUMENTOR_PDP_EVENT_BR,
  1337.                 '<<' => PHPDOCUMENTOR_PDP_EVENT_ESCAPE,
  1338.             );
  1339.         
  1340.         $this->popEvent[PHPDOCUMENTOR_PDP_EVENT_LIST] = array("</ul>","</ol>");
  1341. ##########################
  1342.  
  1343.         $this->pushEvent[PHPDOCUMENTOR_PDP_EVENT_SIMLIST] = 
  1344.             array(
  1345.                 "<code>"    => PHPDOCUMENTOR_PDP_EVENT_CODE,
  1346.                 "<pre>"    => PHPDOCUMENTOR_PDP_EVENT_PRE,
  1347.                 "<p>" => PHPDOCUMENTOR_PDP_EVENT_P,
  1348.                 "<var>" => PHPDOCUMENTOR_PDP_EVENT_VAR,
  1349.                 "<samp>" => PHPDOCUMENTOR_PDP_EVENT_SAMP,
  1350.                 "<kbd>" => PHPDOCUMENTOR_PDP_EVENT_KBD,
  1351.                 "<b>" => PHPDOCUMENTOR_PDP_EVENT_B,
  1352.                 "<i>" => PHPDOCUMENTOR_PDP_EVENT_I,
  1353.                 "<br" => PHPDOCUMENTOR_PDP_EVENT_BR,
  1354.                 '<<' => PHPDOCUMENTOR_PDP_EVENT_ESCAPE,
  1355.             );
  1356. ##########################
  1357.         
  1358.         $this->pushEvent[PHPDOCUMENTOR_PDP_EVENT_DOUBLECR] =
  1359.             array(
  1360.                 "<code>" => PHPDOCUMENTOR_PDP_EVENT_CODE,
  1361.                 "<ol>" => PHPDOCUMENTOR_PDP_EVENT_LIST,
  1362.                 "<ul>" => PHPDOCUMENTOR_PDP_EVENT_LIST,
  1363.                 "<pre>" => PHPDOCUMENTOR_PDP_EVENT_PRE,
  1364.                 "<b>" => PHPDOCUMENTOR_PDP_EVENT_B,
  1365.                 "<i>" => PHPDOCUMENTOR_PDP_EVENT_I,
  1366.                 "<var>" => PHPDOCUMENTOR_PDP_EVENT_VAR,
  1367.                 "<samp>" => PHPDOCUMENTOR_PDP_EVENT_SAMP,
  1368.                 "<kbd>" => PHPDOCUMENTOR_PDP_EVENT_KBD,
  1369.                 "<br" => PHPDOCUMENTOR_PDP_EVENT_BR,
  1370.                 "<p>" => PHPDOCUMENTOR_PDP_EVENT_P,
  1371.                 '<<' => PHPDOCUMENTOR_PDP_EVENT_ESCAPE,
  1372.             );
  1373.         
  1374. ##########################
  1375.         $this->pushEvent[PHPDOCUMENTOR_PDP_EVENT_B] =
  1376.             array(
  1377.                 "<code>" => PHPDOCUMENTOR_PDP_EVENT_CODE,
  1378.                 "<ol>" => PHPDOCUMENTOR_PDP_EVENT_LIST,
  1379.                 "<ul>" => PHPDOCUMENTOR_PDP_EVENT_LIST,
  1380.                 "<pre>" => PHPDOCUMENTOR_PDP_EVENT_PRE,
  1381.                 "<var>" => PHPDOCUMENTOR_PDP_EVENT_VAR,
  1382.                 "<samp>" => PHPDOCUMENTOR_PDP_EVENT_SAMP,
  1383.                 "<kbd>" => PHPDOCUMENTOR_PDP_EVENT_KBD,
  1384.                 "<br" => PHPDOCUMENTOR_PDP_EVENT_BR,
  1385.                 '<i>' => PHPDOCUMENTOR_PDP_EVENT_I,
  1386.                 '<<' => PHPDOCUMENTOR_PDP_EVENT_ESCAPE,
  1387.             );
  1388.          
  1389.         $this->popEvent[PHPDOCUMENTOR_PDP_EVENT_B] = array("</b>");
  1390.  
  1391. ##########################
  1392.         $this->pushEvent[PHPDOCUMENTOR_PDP_EVENT_I] =
  1393.             array(
  1394.                 "<code>" => PHPDOCUMENTOR_PDP_EVENT_CODE,
  1395.                 "<ol>" => PHPDOCUMENTOR_PDP_EVENT_LIST,
  1396.                 "<ul>" => PHPDOCUMENTOR_PDP_EVENT_LIST,
  1397.                 "<pre>" => PHPDOCUMENTOR_PDP_EVENT_PRE,
  1398.                 "<var>" => PHPDOCUMENTOR_PDP_EVENT_VAR,
  1399.                 "<samp>" => PHPDOCUMENTOR_PDP_EVENT_SAMP,
  1400.                 "<kbd>" => PHPDOCUMENTOR_PDP_EVENT_KBD,
  1401.                 "<br" => PHPDOCUMENTOR_PDP_EVENT_BR,
  1402.                 '<b>' => PHPDOCUMENTOR_PDP_EVENT_B,
  1403.                 '<<' => PHPDOCUMENTOR_PDP_EVENT_ESCAPE,
  1404.             );
  1405.          
  1406.         $this->popEvent[PHPDOCUMENTOR_PDP_EVENT_I] = array("</i>");
  1407.  
  1408. ##########################
  1409.         $this->pushEvent[PHPDOCUMENTOR_PDP_EVENT_VAR] =
  1410.             array(
  1411.                 "<code>" => PHPDOCUMENTOR_PDP_EVENT_CODE,
  1412.                 "<ol>" => PHPDOCUMENTOR_PDP_EVENT_LIST,
  1413.                 "<ul>" => PHPDOCUMENTOR_PDP_EVENT_LIST,
  1414.                 "<pre>" => PHPDOCUMENTOR_PDP_EVENT_PRE,
  1415.                 "<i>" => PHPDOCUMENTOR_PDP_EVENT_I,
  1416.                 "<samp>" => PHPDOCUMENTOR_PDP_EVENT_SAMP,
  1417.                 "<kbd>" => PHPDOCUMENTOR_PDP_EVENT_KBD,
  1418.                 "<br" => PHPDOCUMENTOR_PDP_EVENT_BR,
  1419.                 '<b>' => PHPDOCUMENTOR_PDP_EVENT_B,
  1420.                 '<<' => PHPDOCUMENTOR_PDP_EVENT_ESCAPE,
  1421.             );
  1422.          
  1423.         $this->popEvent[PHPDOCUMENTOR_PDP_EVENT_VAR] = array("</var>");
  1424.  
  1425. ##########################
  1426.         $this->pushEvent[PHPDOCUMENTOR_PDP_EVENT_SAMP] =
  1427.             array(
  1428.                 "<code>" => PHPDOCUMENTOR_PDP_EVENT_CODE,
  1429.                 "<ol>" => PHPDOCUMENTOR_PDP_EVENT_LIST,
  1430.                 "<ul>" => PHPDOCUMENTOR_PDP_EVENT_LIST,
  1431.                 "<pre>" => PHPDOCUMENTOR_PDP_EVENT_PRE,
  1432.                 "<var>" => PHPDOCUMENTOR_PDP_EVENT_VAR,
  1433.                 "<i>" => PHPDOCUMENTOR_PDP_EVENT_I,
  1434.                 "<kbd>" => PHPDOCUMENTOR_PDP_EVENT_KBD,
  1435.                 "<br" => PHPDOCUMENTOR_PDP_EVENT_BR,
  1436.                 '<b>' => PHPDOCUMENTOR_PDP_EVENT_B,
  1437.                 '<<' => PHPDOCUMENTOR_PDP_EVENT_ESCAPE,
  1438.             );
  1439.          
  1440.         $this->popEvent[PHPDOCUMENTOR_PDP_EVENT_SAMP] = array("</samp>");
  1441.  
  1442. ##########################
  1443.         $this->pushEvent[PHPDOCUMENTOR_PDP_EVENT_KBD] =
  1444.             array(
  1445.                 "<code" => PHPDOCUMENTOR_PDP_EVENT_CODE,
  1446.                 "<ol>" => PHPDOCUMENTOR_PDP_EVENT_LIST,
  1447.                 "<ul>" => PHPDOCUMENTOR_PDP_EVENT_LIST,
  1448.                 "<pre" => PHPDOCUMENTOR_PDP_EVENT_PRE,
  1449.                 "<var>" => PHPDOCUMENTOR_PDP_EVENT_VAR,
  1450.                 "<samp>" => PHPDOCUMENTOR_PDP_EVENT_SAMP,
  1451.                 "<i>" => PHPDOCUMENTOR_PDP_EVENT_I,
  1452.                 "<br" => PHPDOCUMENTOR_PDP_EVENT_BR,
  1453.                 '<b>' => PHPDOCUMENTOR_PDP_EVENT_B,
  1454.                 '<<' => PHPDOCUMENTOR_PDP_EVENT_ESCAPE,
  1455.             );
  1456.          
  1457.         $this->popEvent[PHPDOCUMENTOR_PDP_EVENT_KBD] = array("</kbd>");
  1458.     }
  1459.     
  1460.     function getParserEventName ($value)
  1461.     {    
  1462.         $lookup = array(
  1463.             PARSER_EVENT_NOEVENTS         => "PARSER_EVENT_NOEVENTS",
  1464.             PHPDOCUMENTOR_PDP_EVENT_CODE        => "PHPDOCUMENTOR_PDP_EVENT_CODE",
  1465.             PHPDOCUMENTOR_PDP_EVENT_P        => "PHPDOCUMENTOR_PDP_EVENT_P",
  1466.             PHPDOCUMENTOR_PDP_EVENT_B        => "PHPDOCUMENTOR_PDP_EVENT_B",
  1467.             PHPDOCUMENTOR_PDP_EVENT_I        => "PHPDOCUMENTOR_PDP_EVENT_I",
  1468.             PHPDOCUMENTOR_PDP_EVENT_BR        => "PHPDOCUMENTOR_PDP_EVENT_BR",
  1469.             PHPDOCUMENTOR_PDP_EVENT_VAR        => "PHPDOCUMENTOR_PDP_EVENT_VAR",
  1470.             PHPDOCUMENTOR_PDP_EVENT_SAMP        => "PHPDOCUMENTOR_PDP_EVENT_SAMP",
  1471.             PHPDOCUMENTOR_PDP_EVENT_KBD        => "PHPDOCUMENTOR_PDP_EVENT_KBD",
  1472.             PHPDOCUMENTOR_PDP_EVENT_ESCAPE        => "PHPDOCUMENTOR_PDP_EVENT_ESCAPE",
  1473.             PHPDOCUMENTOR_PDP_EVENT_ESCAPE_CODE        => "PHPDOCUMENTOR_PDP_EVENT_ESCAPE_CODE",
  1474.             PHPDOCUMENTOR_PDP_EVENT_ESCAPE_PRE        => "PHPDOCUMENTOR_PDP_EVENT_ESCAPE_PRE",
  1475.             PHPDOCUMENTOR_PDP_EVENT_DOUBLECR        => "PHPDOCUMENTOR_PDP_EVENT_DOUBLECR",
  1476.             PHPDOCUMENTOR_PDP_EVENT_LIST    => "PHPDOCUMENTOR_PDP_EVENT_LIST",
  1477.             PHPDOCUMENTOR_PDP_EVENT_PRE => "PHPDOCUMENTOR_PDP_EVENT_PRE",
  1478.             PHPDOCUMENTOR_PDP_EVENT_SIMLIST => "PHPDOCUMENTOR_PDP_EVENT_SIMLIST",
  1479.         );
  1480.         if (isset($lookup[$value]))
  1481.         return $lookup[$value];
  1482.         else return $value;
  1483.     }
  1484. }
  1485.  
  1486. ?>
  1487.