phpDocumentor
[ class tree: phpDocumentor ] [ index: phpDocumentor ] [ all elements ]

Source for file HighlightParser.inc

Documentation is available at HighlightParser.inc

  1. <?php
  2. /**
  3.  * Source Code Highlighting
  4.  *
  5.  * The classes in this file are responsible for the dynamic @example, @filesource
  6.  * and {@}source} tags output.  Using the phpDocumentor_HighlightWordParser,
  7.  * the phpDocumentor_HighlightParser retrieves PHP tokens one by one from the
  8.  * array generated by {@link phpDocumentorTWordParser} source retrieval functions
  9.  * and then highlights them individually.
  10.  *
  11.  * It accomplishes this highlighting through the assistance of methods in
  12.  * the output Converter passed to its parse() method, and then returns the
  13.  * fully highlighted source as a string
  14.  *
  15.  * phpDocumentor :: automatic documentation generator
  16.  * 
  17.  * PHP versions 4 and 5
  18.  *
  19.  * Copyright (c) 2002-2008 Gregory Beaver
  20.  * 
  21.  * LICENSE:
  22.  * 
  23.  * This library is free software; you can redistribute it
  24.  * and/or modify it under the terms of the GNU Lesser General
  25.  * Public License as published by the Free Software Foundation;
  26.  * either version 2.1 of the License, or (at your option) any
  27.  * later version.
  28.  * 
  29.  * This library is distributed in the hope that it will be useful,
  30.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  31.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  32.  * Lesser General Public License for more details.
  33.  * 
  34.  * You should have received a copy of the GNU Lesser General Public
  35.  * License along with this library; if not, write to the Free Software
  36.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  37.  *
  38.  * @category   ToolsAndUtilities
  39.  * @package    phpDocumentor
  40.  * @subpackage Parsers
  41.  * @author     Gregory Beaver <cellog@php.net>
  42.  * @copyright  2002-2008 Gregory Beaver
  43.  * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL
  44.  * @version    CVS: $Id: HighlightParser.inc 253641 2008-02-24 02:35:44Z ashnazg $
  45.  * @filesource
  46.  * @link       http://www.phpdoc.org
  47.  * @link       http://pear.php.net/PhpDocumentor
  48.  * @tutorial   tags.example.pkg, tags.filesource.pkg, tags.inlinesource.pkg
  49.  * @since      1.2.0beta3
  50.  * @todo       CS cleanup - change package to PhpDocumentor
  51.  */
  52.  
  53. /**
  54.  * Retrieve tokens from an array of tokens organized by line numbers
  55.  *
  56.  * @category   ToolsAndUtilities
  57.  * @package    phpDocumentor
  58.  * @subpackage Parsers
  59.  * @author     Gregory Beaver <cellog@php.net>
  60.  * @copyright  2002-2008 Gregory Beaver
  61.  * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL
  62.  * @version    Release: @VER@
  63.  * @link       http://www.phpdoc.org
  64.  * @link       http://pear.php.net/PhpDocumentor
  65.  * @since      1.2.0beta3
  66.  * @todo       CS cleanup - change package to PhpDocumentor
  67.  * @todo       CS cleanup - change class name to PhpDocumentor_*
  68.  */
  69. class phpDocumentor_HighlightWordParser extends phpDocumentorTWordParser
  70. {
  71.     /**
  72.      * Hash used to keep track of line numbers that have already been initialized
  73.      * @var array 
  74.      * @access private
  75.      */
  76.     var $_listLineNums array();
  77.     /**
  78.      * Initialize the parser object
  79.      *
  80.      * @param array                         &$input  the input
  81.      * @param phpDocumentor_HighlightParser &$parser the parser
  82.      *
  83.      * @return void 
  84.      */
  85.     function setup(&$input&$parser)
  86.     {
  87.         $this->_parser     &$parser;
  88.         $this->data        &$input;
  89.         $this->_all        $input;
  90.         $this->_sourceline 0;
  91.         $this->pos         0;
  92.         $this->linenum     0;
  93.     }
  94.    
  95.     /**
  96.      * debugging function
  97.      *
  98.      * @return void 
  99.      * @access private
  100.      */
  101.     function printState()
  102.     {
  103.         $linenum $this->linenum;
  104.         $pos     $this->pos;
  105.         if (!isset($this->_all[$this->linenum][$this->pos])) {
  106.             $linenum++;
  107.             $pos 0;
  108.         }
  109.         $details '';
  110.         $token   $this->_all[$linenum][$pos];
  111.         if (is_array($token)) {
  112.             $details token_name($token[0]);
  113.             $token   htmlspecialchars($token[1]);
  114.         else {
  115.             $token htmlspecialchars($token);
  116.         }
  117.         debug('Next Token ' $this->linenum '-' $this->pos ':' $details);
  118.         var_dump($token);
  119.     }
  120.    
  121.     /**
  122.      * Retrieve the position of the next token that will be parsed
  123.      * in the internal token array
  124.      *
  125.      * @return array format: array(line number, position)
  126.      */
  127.     function nextToken()
  128.     {
  129.         $linenum $this->linenum;
  130.         $pos     $this->pos;
  131.         if (!isset($this->_all[$this->linenum][$this->pos])) {
  132.             $linenum++;
  133.             $pos 0;
  134.         }
  135.         if (!isset($this->_all[$linenum][$pos])) {
  136.             return false;
  137.         }
  138.         return array($linenum$pos);
  139.     }
  140.    
  141.     /**
  142.      * Retrieve the next token
  143.      *
  144.      * @return array|stringeither array(PHP token constant, token) or string
  145.      *                       non-specific separator
  146.      */
  147.     function getWord()
  148.     {
  149.         if (!isset($this->_all[$this->linenum][$this->pos])) {
  150.             $this->linenum++;
  151.             $this->pos 0;
  152.             if (!isset($this->_all[$this->linenum])) {
  153.                 return false;
  154.             }
  155.             $this->_parser->newLineNum();
  156.             return $this->getWord();
  157.         }
  158.         $word $this->_all[$this->linenum][$this->pos++];
  159.         return str_replace("\t"'    '$word);
  160.     }
  161.  
  162.     /**
  163.      * back the word parser to the previous token as defined by $last_token
  164.      *
  165.      * @param array|string$last_token token, or output from {@link nextToken()}
  166.      * @param bool         $is_pos     if true, backupPos interprets $last_token
  167.      *                                  to be the position in the internal token
  168.      *                                  array of the last token
  169.      *
  170.      * @return void 
  171.      */
  172.     function backupPos($last_token$is_pos false)
  173.     {
  174.         if (!$last_token{
  175.             return;
  176.         }
  177.         if ($is_pos{
  178.             $this->linenum $last_token[0];
  179.             $this->pos     $last_token[1];
  180.             return;
  181.         }
  182.         if ($last_token === false{
  183.             return;
  184.         }
  185.  
  186.         //fancy_debug('before', $this->linenum, $this->pos, 
  187.         //    token_name($this->_all[$this->linenum][$this->pos][0]),
  188.         //    htmlentities($this->_all[$this->linenum][$this->pos][1]),
  189.         //    $this->_all[$this->linenum]);
  190.  
  191.         do {
  192.             $this->pos--;
  193.             if ($this->pos 0{
  194.                 $this->linenum--;
  195.                 if ($this->linenum 0{
  196.                     var_dump($last_token);
  197.                     break;
  198.                 }
  199.                 $this->pos count($this->_all[$this->linenum]1;
  200.             }
  201.         while (!$this->tokenEquals($last_tokenstr_replace("\t"'    '
  202.             $this->_all[$this->linenum][$this->pos])));
  203.  
  204.         //fancy_debug('after', $this->linenum, $this->pos,
  205.         //    token_name($this->_all[$this->linenum][$this->pos][0]),
  206.         //    htmlentities($this->_all[$this->linenum][$this->pos][1]));
  207.     }
  208. }
  209.  
  210. /**
  211.  * Highlights source code using {@link parse()}
  212.  *
  213.  * @category   ToolsAndUtilities
  214.  * @package    phpDocumentor
  215.  * @subpackage Parsers
  216.  * @author     Gregory Beaver <cellog@php.net>
  217.  * @copyright  2002-2008 Gregory Beaver
  218.  * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL
  219.  * @version    Release: @VER@
  220.  * @link       http://www.phpdoc.org
  221.  * @link       http://pear.php.net/PhpDocumentor
  222.  * @since      1.2.0beta3
  223.  * @todo       CS cleanup - change package to PhpDocumentor
  224.  * @todo       CS cleanup - change class name to PhpDocumentor_*
  225.  */
  226. class phpDocumentor_HighlightParser extends phpDocumentorTParser
  227. {
  228.     /**#@+
  229.      * @access private
  230.      */
  231.  
  232.     /**
  233.      * Highlighted source is built up in this string
  234.      * @var string 
  235.      */
  236.     var $_output;
  237.  
  238.     /**
  239.      * contents of the current source code line as it is parsed
  240.      * @var string 
  241.      */
  242.     var $_line;
  243.  
  244.     /**
  245.      * Used to retrieve highlighted tokens
  246.      * @var Converter a descendant of Converter
  247.      */
  248.     var $_converter;
  249.  
  250.     /**
  251.      * Path to file being highlighted, if this is from a @filesource tag
  252.      * @var false|stringfull path
  253.      */
  254.     var $_filesourcepath;
  255.  
  256.     /**
  257.      * @var array 
  258.      */
  259.     var $eventHandlers = array(
  260.         PARSER_EVENT_ARRAY                      => 'defaultHandler',
  261.         PARSER_EVENT_CLASS                      => 'handleClass',
  262.         PARSER_EVENT_COMMENT                    => 'handleComment',
  263.         PARSER_EVENT_DOCBLOCK_TEMPLATE          => 'handleDocBlockTemplate',
  264.         PARSER_EVENT_END_DOCBLOCK_TEMPLATE      => 'handleEndDocBlockTemplate',
  265.         PARSER_EVENT_LOGICBLOCK                 => 'handleLogicBlock',
  266.         PARSER_EVENT_METHOD_LOGICBLOCK          => 'handleMethodLogicBlock',
  267.         PARSER_EVENT_NOEVENTS                   => 'defaultHandler',
  268.         PARSER_EVENT_OUTPHP                     => 'defaultHandler',
  269.         PARSER_EVENT_CLASS_MEMBER               => 'handleClassMember',
  270.         PARSER_EVENT_DEFINE                     => 'defaultHandler',
  271.         PARSER_EVENT_DEFINE_PARAMS              => 'defaultHandler',
  272.         PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS  => 'defaultHandler',
  273.         PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS => 'defaultHandler',
  274.         PARSER_EVENT_DOCBLOCK                   => 'handleDocBlock',
  275.         PARSER_EVENT_TAGS                       => 'handleTags',
  276.         PARSER_EVENT_DESC                       => 'handleDesc',
  277.         PARSER_EVENT_DOCKEYWORD                 => 'handleTag',
  278.         PARSER_EVENT_DOCKEYWORD_EMAIL           => 'handleDockeywordEmail',
  279.         PARSER_EVENT_EOFQUOTE                   => 'handleQuote',
  280.         PARSER_EVENT_FUNCTION                   => 'handleFunction',
  281.         PARSER_EVENT_METHOD                     => 'handleMethod',
  282.         PARSER_EVENT_FUNCTION_PARAMS            => 'handleFunctionParams',
  283.         PARSER_EVENT_FUNC_GLOBAL                => 'handleFuncGlobal',
  284.         PARSER_EVENT_INLINE_DOCKEYWORD          => 'handleInlineDockeyword',
  285.         PARSER_EVENT_INCLUDE                    => 'defaultHandler',
  286.         PARSER_EVENT_INCLUDE_PARAMS             => 'defaultHandler',
  287.         PARSER_EVENT_QUOTE                      => 'handleQuote',
  288.         PARSER_EVENT_QUOTE_VAR                  => 'handleQuoteVar',
  289.         PARSER_EVENT_PHPCODE                    => 'handlePhpCode',
  290.         PARSER_EVENT_SINGLEQUOTE                => 'handleSingleQuote',
  291.         PARSER_EVENT_STATIC_VAR                 => 'defaultHandler',
  292.         PARSER_EVENT_STATIC_VAR_VALUE           => 'defaultHandler',
  293.         PARSER_EVENT_VAR                        => 'handleVar',
  294.     );
  295.  
  296.     /**
  297.      * event handlers for @tags
  298.      * @tutorial tags.pkg
  299.      */
  300.     var $tagHandlers array(
  301.         '*'              => 'defaultTagHandler',
  302.         'abstract'       => 'coreTagHandler',
  303.         'access'         => 'coreTagHandler',
  304.         'author'         => 'coreTagHandler',
  305.         'category'       => 'coreTagHandler',
  306.         'copyright'      => 'coreTagHandler',
  307.         'deprecated'     => 'coreTagHandler',
  308.         'example'        => 'coreTagHandler',
  309.         'filesource'     => 'coreTagHandler',
  310.         'final'          => 'coreTagHandler',
  311.         'global'         => 'globalTagHandler',
  312.         'ignore'         => 'coreTagHandler',
  313.         'license'        => 'coreTagHandler',
  314.         'link'           => 'coreTagHandler',
  315.         'name'           => 'coreTagHandler',
  316.         'package'        => 'coreTagHandler',
  317.         'param'          => 'paramTagHandler',
  318.         'parameter'      => 'paramTagHandler',
  319.         'see'            => 'coreTagHandler',
  320.         'since'          => 'coreTagHandler',
  321.         'subpackage'     => 'coreTagHandler',
  322.         'internal'       => 'coreTagHandler',
  323.         'return'         => 'returnTagHandler',
  324.         'static'         => 'coreTagHandler',
  325.         'staticvar'      => 'staticvarTagHandler',
  326.         'throws'         => 'coreTagHandler',
  327.         'todo'           => 'coreTagHandler',
  328.         'tutorial'       => 'coreTagHandler',
  329.         'uses'           => 'coreTagHandler',
  330.         'var'            => 'varTagHandler',
  331.         'version'        => 'coreTagHandler',
  332.         'property'       => 'propertyTagHandler',
  333.         'property-read'  => 'propertyTagHandler',
  334.         'property-write' => 'propertyTagHandler',
  335.         'method'         => 'propertyTagHandler'
  336.     );
  337.     /**#@-*/
  338.    
  339.     /**
  340.      * wraps the current line (via the converter) and resets it to empty
  341.      *
  342.      * @return void 
  343.      * @uses Converter::SourceLine() encloses {@link $_line} in a
  344.      *                                converter-specific format
  345.      */
  346.     function newLineNum()
  347.     {
  348.         if ($this->_pf_no_output_yet{
  349.             return;
  350.         }
  351.         $this->_flush_save();
  352.         $this->_line   .= $this->_converter->flushHighlightCache();
  353.         $this->_output .= $this->_converter->SourceLine($this->_wp->linenum,
  354.             $this->_line$this->_path);
  355.         $this->_line    '';
  356.     }
  357.    
  358.     /**
  359.      * Start the parsing at a certain line number
  360.      *
  361.      * @param int $num line number
  362.      *
  363.      * @return void 
  364.      */
  365.     function setLineNum($num)
  366.     {
  367.         $this->_wp->linenum $num;
  368.     }
  369.    
  370.     /**
  371.      * Parse a new file
  372.      *
  373.      * The parse() method is a do...while() loop that retrieves tokens one by
  374.      * one from the {@link $_event_stack}, and uses the token event array set up
  375.      * by the class constructor to call event handlers.
  376.      *
  377.      * The event handlers each process the tokens passed to them, and use the
  378.      * {@link _addoutput()} method to append the processed tokens to the
  379.      * {@link $_line} variable.  The word parser calls {@link newLineNum()}
  380.      * every time a line is reached.
  381.      *
  382.      * In addition, the event handlers use special linking functions
  383.      * {@link _link()} and its cousins (_classlink(), etc.) to create in-code
  384.      * hyperlinks to the documentation for source code elements that are in the
  385.      * source code.
  386.      *
  387.      * @param array         &$parse_data       the parse data
  388.      * @param Converter     &$converter        the converter object
  389.      * @param bool          $inlinesourceparse whether this data is from an
  390.      *                                          inline {@}source} tag
  391.      * @param string|false $class             if a string, it is the name of the
  392.      *                                          class whose method we are parsing
  393.      *                                          containing a {@}source} tag
  394.      * @param false|integer$linenum           starting line number from
  395.      *                                          {@}source linenum}
  396.      * @param false|string $filesourcepath    full path to file with @filesource
  397.      *                                          tag, if this is a @filesource parse
  398.      *
  399.      * @staticvar int used for recursion limiting if a handler for
  400.      *                 an event is not found
  401.      * @return bool 
  402.      * @uses setupStates() initialize parser state variables
  403.      * @uses configWordParser() pass $parse_data to prepare retrieval of tokens
  404.      * @todo CS cleanup - rename tokenizer_ext constant to uppercase
  405.      */
  406.     function parse (&$parse_data&$converter$inlinesourceparse false,
  407.         $class false$linenum false$filesourcepath false)
  408.     {
  409.         if (!tokenizer_ext{
  410.             if (is_array($parse_data)) {
  411.                 $parse_data join($parse_data'');
  412.             }
  413.             $parse_data    explode("\n"$parse_data);
  414.             $this->_output '';
  415.             foreach ($parse_data as $linenum => $line{
  416.                 if ($linenum 0{
  417.                     $this->_output .= $converter->SourceLine($linenum,
  418.                         $line$filesourcepath);
  419.                 }
  420.             }
  421.             return $converter->PreserveWhiteSpace($this->_output);
  422.         }
  423.         static $endrecur  0;
  424.         $this->_converter &$converter;
  425.         $converter->startHighlight();
  426.         $this->_path $filesourcepath;
  427.         $this->setupStates($inlinesourceparse$class);
  428.  
  429.         $this->configWordParser($parse_data);
  430.         if ($linenum !== false{
  431.             $this->setLineNum($linenum);
  432.         }
  433.         // initialize variables so E_ALL error_reporting doesn't complain
  434.         $pevent 0;
  435.         $word   0;
  436.  
  437.         do {
  438.             $lpevent $pevent;
  439.             $pevent  $this->_event_stack->getEvent();
  440.             if ($lpevent != $pevent{
  441.                 $this->_last_pevent $lpevent;
  442.             }
  443.  
  444.             if ($pevent == PARSER_EVENT_CLASS_MEMBER{
  445.                 $this->_wp->setWhitespace(true);
  446.             else {
  447.                 $this->_wp->setWhitespace(false);
  448.             }
  449.  
  450.             if (!is_array($word)) {
  451.                 $lw $word;
  452.             }
  453.             if (is_array($word&& $word[0!= T_WHITESPACE{
  454.                 $lw $word;
  455.             }
  456.             $dbg_linenum $this->_wp->linenum;
  457.             $dbg_pos     $this->_wp->getPos();
  458.             $word        $this->_wp->getWord();
  459.             if (is_array($word&& ($word[0== T_WHITESPACE || 
  460.                 $word[0== T_COMMENT&& 
  461.                 $pevent != PARSER_EVENT_CLASS_MEMBER
  462.             {
  463.                 //debug("added " . $this->_wp->linenum . '-' . $this->_wp->pos);
  464.                 $this->_addoutput($word);
  465.                 continue;
  466.             else {
  467.                 $this->_pv_last_word $lw;
  468.             }
  469.             if ($pevent != PARSER_EVENT_DOCBLOCK{
  470.                 $this->_pv_last_next_word $this->_pv_next_word;
  471.                 $this->_pv_next_word      $this->_wp->nextToken();
  472.             }
  473.             // in wordparser, have to keep track of lines
  474.             //$this->publishEvent(PHPDOCUMENTOR_EVENT_NEWLINENUM, 
  475.             //    $this->_wp->linenum);
  476.             if (PHPDOCUMENTOR_DEBUG == true{
  477.                 echo "LAST: ";
  478.                 if (is_array($this->_pv_last_word)) {
  479.                     echo token_name($this->_pv_last_word[0]
  480.                         ' => |' .
  481.                         htmlspecialchars($this->_pv_last_word[1]);
  482.                 else {
  483.                     echo "|" $this->_pv_last_word;
  484.                 }
  485.                 echo "|\n";
  486.                 echo "PEVENT: " $this->getParserEventName($pevent"\n";
  487.                 echo "LASTPEVENT: " .
  488.                     $this->getParserEventName($this->_last_pevent"\n";
  489.                 //echo "LINE: "   . $this->_line   . "\n";
  490.                 //echo "OUTPUT: " . $this->_output . "\n";
  491.                 echo $dbg_linenum '-' $dbg_pos ": ";
  492.                 if (is_array($word)) {
  493.                     echo token_name($word[0]' => |' htmlspecialchars($word[1]);
  494.                 else {
  495.                     echo '|'.htmlspecialchars($word);
  496.                 }
  497.                 echo "|\n";
  498.                 $this->_wp->printState();
  499.                 echo "NEXT TOKEN: ";
  500.                 $tok1 $this->_pv_next_word;
  501.                 $tok  $this->_wp->_all[$tok1[0]][$tok1[1]];
  502.                 if (is_array($tok)) {
  503.                     echo token_name($tok[0]' => ' $tok1[0'-' $tok1[1.
  504.                         '|' htmlspecialchars($tok[1]);
  505.                 else {
  506.                     echo "|" $tok;
  507.                 }
  508.                 echo "|\n";
  509.                 echo "-------------------\n\n\n";
  510.                 flush();
  511.             }
  512.             if ($word !== false && isset($this->eventHandlers[$pevent])) {
  513.                 $handle $this->eventHandlers[$pevent];
  514.                 $this->$handle($word$pevent);
  515.             elseif ($word !== false{
  516.                 debug('WARNING: possible error, no handler for event number '
  517.                      . $pevent);
  518.                 if ($endrecur++ == 25{
  519.                     die("FATAL ERROR, recursion limit reached");
  520.                 }
  521.             }
  522.         while (!($word === false));
  523.         if (strlen($this->_line)) {
  524.             $this->newLineNum();
  525.         }
  526.         return $this->_output;
  527.     }
  528.  
  529.     /**#@+
  530.      * Event Handlers
  531.      *
  532.      * All Event Handlers use {@link checkEventPush()} and
  533.      * {@link checkEventPop()} to set up the event stack and parser state.
  534.      *
  535.      * @param string|array $word   token value
  536.      * @param int          $pevent parser event from {@link Parser.inc}
  537.      *
  538.      * @return void
  539.      * @access private
  540.      */
  541.     /**
  542.      * Most tokens only need highlighting, and this method handles them
  543.      */
  544.     function defaultHandler($word$pevent)
  545.     {
  546.         $this->_addoutput($word);
  547.         if ($this->checkEventPush($word$pevent)) {
  548.             return;
  549.         }
  550.         $this->checkEventPop($word$pevent);
  551.     }
  552.    
  553.     /**
  554.      * Handles global declarations in a function, like:
  555.      *
  556.      * <code>
  557.      * function foobar()
  558.      * {
  559.      *     global $_phpDocumentor_setting;
  560.      * }
  561.      * </code>
  562.      *
  563.      * @uses _globallink() instead of _addoutput(), to link to global variables
  564.      *        if they are used in a function
  565.      */
  566.     function handleFuncGlobal($word$pevent)
  567.     {
  568.         if ($this->checkEventPush($word$pevent)) {
  569.             return;
  570.         }
  571.         $this->_globallink($word);
  572.         $this->checkEventPop($word$pevent);
  573.     }
  574.    
  575.     /**
  576.      * Handles strings in quotation marks and heredoc
  577.      *
  578.      * Special handling is needed for strings that contain variables like:
  579.      *
  580.      * <code>$a = "$test string"</code>
  581.      *
  582.      * The tokenizer parses out tokens '"',array(T_VARIABLE,'$test'),' string',
  583.      * and '"'.  Since it is possible to have $this->classvar in a string,
  584.      * we save a variable name just in case the next token is -> to allow linking
  585.      * to class members.  Otherwise, the string is simply highlighted.
  586.      *
  587.      * constant strings (with no $variables in them) are passed as a single
  588.      * entity, and so will be saved in the last token parsed.  This means the
  589.      * event handler must tell the word parser to re-retrieve the current token
  590.      * so that the correct event handler can process it.
  591.      */
  592.     function handleQuote($word$pevent)
  593.     {
  594.         if ($this->_pf_inmethod && is_array($word&& $word[0== T_VARIABLE{
  595.             $this->_pv_lastvar $word;
  596.         }
  597.         if ($this->checkEventPush($word$pevent)) {
  598.             $this->_addoutput($word);
  599.             return;
  600.         }
  601.         if ($this->_pf_quote_active &&
  602.             (($this->_pv_last_word == '"' && 
  603.             $this->_last_pevent != PARSER_EVENT_QUOTE||
  604.             (is_array($this->_pv_last_word&& 
  605.             $this->_pv_last_word[0== T_END_HEREDOC &&
  606.             $this->_last_pevent != PARSER_EVENT_EOFQUOTE))
  607.         {
  608.             $this->_pf_quote_active false;
  609.             $this->_wp->backupPos($word);
  610.             $this->_event_stack->popEvent();
  611.             return;
  612.         }
  613.         if (!$this->_pf_quote_active && 
  614.             (($this->_pv_last_word == '"' && 
  615.             $this->_last_pevent != PARSER_EVENT_QUOTE||
  616.             (is_array($this->_pv_last_word&& 
  617.             $this->_pv_last_word[0== T_END_HEREDOC &&
  618.             $this->_last_pevent != PARSER_EVENT_EOFQUOTE))
  619.         {
  620.             if (is_array($word&& $word[0== T_VARIABLE{
  621.                 $this->_pv_lastvar $word;
  622.             }
  623.             $this->_pf_quote_active      true;
  624.             $this->_save_highlight_state $this->_converter->getHighlightState();
  625.             $this->_converter->startHighlight();
  626.             $this->_addoutput($word);
  627.             $this->checkEventPop($word$pevent);
  628.             return;
  629.         elseif (is_array($this->_pv_last_word&& 
  630.             $this->_pv_last_word[0== T_CONSTANT_ENCAPSED_STRING
  631.         {
  632.             //$this->_pv_quote_data = $this->_pv_last_word[1];
  633.             $this->_event_stack->popEvent();
  634.             $this->_wp->backupPos($word);
  635.             return;
  636.         }
  637.         if ($this->checkEventPop($word$pevent)) {
  638.             $this->_pf_quote_active false;
  639.         }
  640.         $this->_addoutput($word);
  641.     }
  642.    
  643.     /**
  644.      * Handles {$variable} within a "quote"
  645.      *
  646.      * This is a simple handler, for a very complex
  647.      * array of legal syntax.  It is legal to nest control structures
  648.      * inside the {}, and other weird stuff.
  649.      */
  650.     function handleQuoteVar($word$pevent)
  651.     {
  652.         if ($this->checkEventPop($word$pevent)) {
  653.             $this->_pf_quote_active true;
  654.             $this->_addoutput($word);
  655.             return;
  656.         }
  657.         if ($this->_pf_inmethod && is_array($word&& $word[0== T_VARIABLE{
  658.             $this->_pv_lastvar $word;
  659.         }
  660.         if ($this->checkEventPush($word$pevent)) {
  661.             $this->_pf_quote_active false;
  662.             if (is_string($word&& ($word == '{' || $word == '"' || $word == "'")
  663.             {
  664.                 $this->_pf_quote_active true;
  665.                 $this->_pv_lastvar      false;
  666.             }
  667.         }
  668.         $this->_addoutput($word);
  669.     }
  670.    
  671.     /**
  672.      * Handles define() statements
  673.      *
  674.      * The only thing this handler cares about is retrieving the name of the
  675.      * define variable, and the end of the define statement, so after the name
  676.      * is found, it simply makes sure parentheses are matched as in this case:
  677.      *
  678.      * <code>
  679.      * define("test",array("hello",6 => 4, 5 => array('there')));
  680.      * </code>
  681.      *
  682.      * This handler and the DEFINE_PARAMS_PARENTHESIS handler (which is just
  683.      * {@link defaultHandler()} in this version, as nothing fancy is needed)
  684.      * work together to ensure proper parenthesis matching.
  685.      *
  686.      * If the define variable is documented, a link will be created to its
  687.      * documentation using the Converter passed.
  688.      */
  689.     function handleDefine($word$pevent)
  690.     {
  691.         static $token_save;
  692.         if (!isset($token_save)) {
  693.             $token_save array();
  694.         }
  695.         $e $this->checkEventPush($word$pevent);
  696.         if ($e && $e != PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS{
  697.             return;
  698.         }
  699.        
  700.         if (!isset($this->_pv_define_params_data)) {
  701.             $this->_pv_define_params_data '';
  702.         }
  703.        
  704.         if ($this->checkEventPop($word$pevent)) {
  705.             unset($token_save);
  706.             $this->_addoutput($word);
  707.         }
  708.         if ($this->_pf_definename_isset{
  709.             $this->_addoutput($word);
  710.         else {
  711.             if ($word != ","{
  712.                 $token_save[$word;
  713.                 if (is_array($word)) {
  714.                     $word $word[1];
  715.                 }
  716.                 $this->_pv_define_params_data .= $word;
  717.             else {
  718.                 if (substr($this->_pv_define_params_data01==
  719.                     substr($this->_pv_define_params_data,
  720.                         strlen($this->_pv_define_params_data1&&
  721.                     in_array(substr($this->_pv_define_params_data01)
  722.                         array('"'"'"))
  723.                 {
  724.                     // remove leading and ending quotation marks 
  725.                     // if there are only two
  726.                     $a substr($this->_pv_define_params_data01);
  727.                     $b substr($this->_pv_define_params_data1
  728.                         strlen($this->_pv_define_params_data2);
  729.                     if (strpos($b$a=== false{
  730.                         $this->_pv_define_params_data $b;
  731.                     }
  732.                 }
  733.                 $this->_pf_definename_isset true;
  734.  
  735.                 $link $this->_converter->getLink($this->_pv_define_params_data);
  736.                 foreach ($token_save as $token{
  737.                     if (is_object($link)) {
  738.                         if (is_array($token)) {
  739.                             $token $token[1];
  740.                         }
  741.                         $this->_addoutput($this->_converter->returnSee($link,
  742.                             $token));
  743.                     else {
  744.                         $this->_addoutput($save$token);
  745.                     }
  746.                 }
  747.                 $this->_pv_define_params_data '';
  748.             }
  749.         }
  750.     }
  751.    
  752.     /**
  753.      * Handles normal global code.  Special consideration is taken for DocBlocks
  754.      * as they need to retrieve the whole DocBlock before doing any output, so
  755.      * the parser flag {@link $_pf_no_output_yet} is set to tell
  756.      * {@link _addoutput()} not to spit anything out yet.
  757.      *
  758.      * @uses _link() make any global code that is a documentable element link
  759.      *        to the php manual or its documentation
  760.      */
  761.     function handlePhpCode($word$pevent)
  762.     {
  763.         $test $this->checkEventPush($word$pevent);
  764.         if ($test == PARSER_EVENT_DOCBLOCK || $test == PARSER_EVENT_COMMENT{
  765.             if (substr($word[1]02== '/*' && strpos($word[1]'*/')) {
  766.                 $this->_pv_last_word $word;
  767.                 if ($word[1== '/**#@-*/'{
  768.                     $this->_pf_docblock_template true;
  769.                 else {
  770.                     $this->_pf_docblock true;
  771.                 }
  772.                 return $this->handleDocBlock($wordPARSER_EVENT_DOCBLOCK);
  773.             }
  774.             $this->_pf_no_output_yet true;
  775.             $this->_pv_saveline      $this->_wp->linenum 1;
  776.             return;
  777.         }
  778.         if (is_array($word&& $word[0== T_DOUBLE_COLON{
  779.             $this->_pf_colon_colon true;
  780.         }
  781.         if (!$this->_pf_colon_colon && is_array($word&& $word[0== T_STRING{
  782.             $this->_pv_last_string $word;
  783.         }
  784.         $this->_link($word);
  785.         $this->checkEventPop($word$pevent);
  786.     }
  787.    
  788.     /**
  789.      * Handle the function declaration header
  790.      *
  791.      * This handler only sees the "function name" portion of the function
  792.      * declaration.  Handling of the function parameters is by
  793.      * {@link handleFunctionParams()}, and the function body is handled by
  794.      * {@link handleLogicBlock()}
  795.      */
  796.     function handleFunction($word$pevent)
  797.     {
  798.         if ($this->checkEventPush($word$pevent)) {
  799.             $this->_addoutput($word);
  800.             return;
  801.         }
  802.         if ($this->checkEventPop($word$pevent)) {
  803.             return;
  804.         }
  805.         $this->_link($word);
  806.     }
  807.    
  808.     /**
  809.      * Handle the method declaration header
  810.      *
  811.      * This handler only sees the "function name" portion of the method
  812.      * declaration.  Handling of the method parameters is by
  813.      * {@link handleFunctionParams()}, and the method body is handled by
  814.      * {@link handleMethodLogicBlock()}
  815.      */
  816.     function handleMethod($word$pevent)
  817.     {
  818.         if ($this->checkEventPush($word$pevent)) {
  819.             $this->_addoutput($word);
  820.             return;
  821.         }
  822.         if ($this->checkEventPop($word$pevent)) {
  823.             if ($word == ';'{
  824.                 $this->_addoutput($word);
  825.             }
  826.             return;
  827.         }
  828.         $this->_methodlink($word);
  829.     }
  830.    
  831.     /**
  832.      * Handler for the stuff between ( and ) in a function declaration
  833.      *
  834.      * <code>
  835.      * function handles($only,$these,$parameters){...}
  836.      * </code>
  837.      */
  838.     function handleFunctionParams($word$pevent)
  839.     {
  840.         if ($this->checkEventPush($word$pevent)) {
  841.             $this->_addoutput($word);
  842.             return;
  843.         }
  844.         $this->_addoutput($word);
  845.         $this->checkEventPop($word$pevent);
  846.     }
  847.    
  848.     /**
  849.      * Handler for function body.
  850.      *
  851.      * The function body is checked for php functions, documented constants,
  852.      * functions, and indirectly for global statements.  It hyperlinks to the
  853.      * documentation for detected elements is created.  Everything else is
  854.      * highlighted normally.
  855.      */
  856.     function handleLogicBlock($word$pevent)
  857.     {
  858.         if ($this->checkEventPush($word$pevent)) {
  859.             $this->_addoutput($word);
  860.             return;
  861.         }
  862.         if (is_array($word&& $word[0== T_DOUBLE_COLON{
  863.             $this->_pf_colon_colon true;
  864.         }
  865.         if (!$this->_pf_colon_colon && is_array($word&& $word[0== T_STRING{
  866.             $this->_pv_last_string $word;
  867.         }
  868.         $this->_link($word);
  869.         if ($this->checkEventPop($word$pevent)) {
  870.             $e $this->_event_stack->popEvent();
  871.             $this->_event_stack->pushEvent($e);
  872.             if ($e == PARSER_EVENT_FUNCTION{
  873.                 $this->_wp->backupPos($word)
  874.             }
  875.         }
  876.     }
  877.    
  878.     /**
  879.      * Handler for method body.
  880.      *
  881.      * Like functions, the method body is checked for php functions, documented
  882.      * constants, functions, and indirectly for global statements.  It also
  883.      * checks for "$this->XXXX" where XXXX is a class variable or method, and
  884.      * links to the documentation for detected elements is created.  Everything
  885.      * else is highlighted normally.
  886.      */
  887.     function handleMethodLogicBlock($word$pevent)
  888.     {
  889.         if (isset($this->_pv_prev_var_type)) {
  890.             //debug('prevtype is set');
  891.             if (!is_array($word)) {
  892.                 unset($this->_pv_prev_var_type);
  893.             else {
  894.                 if ($word[0!= T_WHITESPACE && 
  895.                     $word[0!= T_STRING && $word[0!= T_OBJECT_OPERATOR
  896.                 {
  897.                     //fancy_debug('unset', $word);
  898.                     unset($this->_pv_prev_var_type);
  899.                 }
  900.             }
  901.         }
  902.         $this->_pf_inmethod true;
  903.         if ($e $this->checkEventPush($word$pevent)) {
  904.             $this->_addoutput($word);
  905.             if ($e == PARSER_EVENT_CLASS_MEMBER{
  906.                 $this->_pf_no_output_yet true;
  907.             }
  908.             return;
  909.         }
  910.         if (is_array($word&& $word[0== T_DOUBLE_COLON{
  911.             $this->_pf_colon_colon true;
  912.         }
  913.         if (!$this->_pf_colon_colon && is_array($word&& $word[0== T_STRING{
  914.             $this->_pv_last_string $word;
  915.         }
  916.         if (is_array($word&& $word[0== T_VARIABLE{
  917.             $this->_pv_lastvar $word;
  918.         }
  919.         $this->_link($word);
  920.         if ($this->checkEventPop($word$pevent)) {
  921.             $this->_pf_inmethod false;
  922.             $e                  $this->_event_stack->popEvent();
  923.             $this->_event_stack->pushEvent($e);
  924.             if ($e == PARSER_EVENT_METHOD{
  925.                 $this->_wp->backupPos($word)
  926.             }
  927.         }
  928.     }
  929.    
  930.     /**
  931.      * Handles $obj->classmember in a method body
  932.      *
  933.      * This handler is responsible for linking to the documentation of a
  934.      * class member when it is used directly in a method body.
  935.      * 
  936.      * There are two methods of determining whether to link:
  937.      * - $this->member
  938.      * - $this->member->submember
  939.      *
  940.      * The first case is handled by the $_pv_lastvar variable, and the
  941.      * second case is handled by the $_pv_prev_var_type variable.  $_pv_lastvar
  942.      * is always set to the value of the last T_VARIABLE token, if and only if
  943.      * no text has occurred between the variable and a T_OBJECT_OPERATOR token
  944.      * "->".  handleClassMember will only link if the last variable encountered
  945.      * was $this.
  946.      *
  947.      * When $this->variable is encountered, the variable is looked up to see
  948.      * if it can be found, and if so, the contents of its @var tag are processed
  949.      * to see if the member variable is defined to have 1 and only 1 class.
  950.      * If so, the $_pv_prev_var_type variable is set to this classname.  When
  951.      * submember is processed, the HighlightParser checks to see if
  952.      * $_pv_prev_var_type::submember() or $_pv_prev_var_type::$submember exists,
  953.      * and if it does, it is linked to.
  954.      */
  955.     function handleClassMember($word$pevent)
  956.     {
  957.         if (!isset($this->_pv_lastvar&& !isset($this->_pv_prev_var_type)) {
  958.             //fancy_debug('returned from', $word, $this->_pv_prev_var_type);
  959.             $this->_pf_no_output_yet false;
  960.             $this->_event_stack->popEvent();
  961.             return $this->defaultHandler($word$pevent);
  962.         }
  963.         if (isset($this->_pv_cm_name)) {
  964.             $this->_pf_obj_op false;
  965.             $name             $this->_pv_cm_name;
  966.             unset($this->_pv_cm_name);
  967.             //debug('unset pvcmname');
  968.             $this->_event_stack->popEvent();
  969.             // control variable for _pv_prev_var_type
  970.             $setnow false;
  971.             if ((isset($this->_pv_lastvar&& $this->_pv_lastvar[1== '$this'||
  972.                 isset($this->_pv_prev_var_type)
  973.             {
  974.                 if (is_array($word&& $word[0== T_WHITESPACE{
  975.                     // preserve value of _pv_prev_var_type
  976.                     $setnow true;
  977.                     $save   $this->_wp->nextToken();
  978.                     $temp   $this->_wp->getWord();
  979.                     $this->_wp->backupPos($savetrue);
  980.                 }
  981.                 if ((is_string($word&& $word == '('|| (isset($temp&& 
  982.                     is_string($temp&& $temp == '(')
  983.                 {
  984.                     // it's a function
  985.                     $this->_pf_no_output_yet false;
  986.                     $this->_methodlink($name);
  987.                     unset($this->_pv_prev_var_type);
  988.                 else {
  989.                     // it's a variable
  990.                     //fancy_debug('name is ', $name);
  991.                     $this->_pf_no_output_yet false;
  992.                     $this->_varlink($nametrue);
  993.                     $templink 
  994.                         $this->_converter->getLink('object ' $this->_pv_class);
  995.                     $class    false;
  996.                     if (is_object($templink)) {
  997.                         $class $this->_converter->classes
  998.                             ->getClass($templink->name$templink->path);
  999.                     }
  1000.                     if ($class{
  1001.                         $varname $name;
  1002.                         if (is_array($varname)) {
  1003.                             $varname $name[1];
  1004.                         }
  1005.                         if ($varname{0!= '$'{
  1006.                             $varname '$'.$varname;
  1007.                         }
  1008.                         $var $class->getVar($this->_converter$varname);
  1009.                        
  1010.                         if (is_object($var&& $var->docblock->var{
  1011.                             $type $var->docblock->var->returnType;
  1012.                         }
  1013.                         if (isset($type)) {
  1014.                             if (strpos($type'object'=== false{
  1015.                                 $type 'object '.$type;
  1016.                             }
  1017.                             $type $this->_converter->getLink($type);
  1018.                             if (phpDocumentor_get_class($type== 'classlink'{
  1019.                                 // the variable's type is a class, 
  1020.                                 // save it for future ->
  1021.                                 //fancy_debug('set prev_var_type!', $type->name);
  1022.                                 $setnow                  true;
  1023.                                 $this->_pv_prev_var_type $type->name;
  1024.                             else {
  1025.                                 unset($this->_pv_prev_var_type);
  1026.                             }
  1027.                         else {
  1028.                             unset($this->_pv_prev_var_type);
  1029.                         }
  1030.                     else {
  1031.                         unset($this->_pv_prev_var_type);
  1032.                     }
  1033.                 }
  1034.             else {
  1035.                 $this->_pf_no_output_yet false;
  1036.                 // this does NewLinenum if necessary
  1037.                 $this->_wp->backupPos($word);
  1038.                 $this->_wp->getWord();
  1039.                 $this->_addoutput($name);
  1040.             }
  1041.             if (!$setnow{
  1042.                 //debug('unset prevtype, no setnow');
  1043.                 unset($this->_pv_prev_var_type);
  1044.             }
  1045.             unset($this->_pv_lastvar);
  1046.             $this->_pf_no_output_yet false;
  1047.             // this does NewLinenum if necessary
  1048.             $this->_wp->backupPos($word);
  1049.             $this->_wp->getWord();
  1050.             if ($word[0== T_OBJECT_OPERATOR{
  1051.                 $this->_wp->backupPos($word);
  1052.             else {
  1053.                 $this->_addoutput($word);
  1054.             }
  1055.             return;
  1056.         }
  1057.         if (!$this->_pf_obj_op && is_array($this->_pv_last_word&& 
  1058.             $this->_pv_last_word[0== T_OBJECT_OPERATOR
  1059.         {
  1060.             if ((isset($this->_pv_lastvar&& $this->_pv_lastvar[1== '$this'||
  1061.                 isset($this->_pv_prev_var_type)
  1062.             {
  1063.                 $this->_pf_obj_op true;
  1064.             else {
  1065.                 $this->_pf_no_output_yet false;
  1066.                 // this does NewLinenum if necessary
  1067.                 $this->_wp->backupPos($word);
  1068.                 $this->_wp->getWord();
  1069.                 $this->_addoutput($word);
  1070.                 $this->_event_stack->popEvent();
  1071.             }
  1072.         }
  1073.         if (is_array($word&& $word == T_WHITESPACE{
  1074.             $this->_pf_no_output_yet false;
  1075.             // this does NewLinenum if necessary
  1076.             $this->_wp->backupPos($word);
  1077.             $this->_wp->getWord();
  1078.             $this->_addoutput($word);
  1079.             return;
  1080.         }
  1081.         if ($this->_pf_obj_op{
  1082.             if (!(is_array($word&& ($word[0== T_STRING || 
  1083.                 $word[0== T_WHITESPACE))
  1084.             {
  1085.                 unset($this->_pv_lastvar);
  1086.                 //debug('unset lastvar');
  1087.                 $this->_event_stack->popEvent();
  1088.                 $this->_pf_no_output_yet false;
  1089.                 // this does NewLinenum if necessary
  1090.                 $this->_wp->backupPos($word);
  1091.                 $this->_wp->getWord();
  1092.                 $this->_addoutput($word);
  1093.                 return;
  1094.             }
  1095.             if ($word[0== T_STRING{
  1096.                 //fancy_debug('set pvcmname to', $word);
  1097.                 $this->_pv_cm_name $word;
  1098.             else {
  1099.                 $this->_pf_no_output_yet false;
  1100.                 // this does NewLinenum if necessary
  1101.                 $this->_wp->backupPos($word);
  1102.                 $this->_wp->getWord();
  1103.                 $this->_addoutput($word);
  1104.             }
  1105.         }
  1106.     }
  1107.    
  1108.     /**
  1109.      * Handles comments
  1110.      *
  1111.      * Comments are almost always single-line tokens, and so will be
  1112.      * in the last word.  This handler checks to see if the current token
  1113.      * is in fact a comment, and if it isn't, it backs up and returns control
  1114.      * to the parent event handler with that word.
  1115.      */
  1116.     function handleComment($word$pevent)
  1117.     {
  1118.         $w $this->_pv_last_word;
  1119.         // don't perform this check if this is a normal comment.  Docblocks
  1120.         // have the _pf_no_output_yet variable set to true
  1121.         if ($this->_pf_no_output_yet && is_array($w&& 
  1122.             (in_array($w[0]array(T_COMMENTT_DOC_COMMENT)) && 
  1123.             strpos($w[1]'/**'=== 0)
  1124.         {
  1125.             $this->_event_stack->popEvent();
  1126.             $this->_event_stack->pushEvent(PARSER_EVENT_DOCBLOCK);
  1127.             return $this->handleDocBlock($wordPARSER_EVENT_DOCBLOCK);
  1128.         }
  1129.         if ($this->_pf_no_output_yet{
  1130.             $flag                    1;
  1131.             $this->_pf_no_output_yet false;
  1132.             $this->_addoutput($this->_pv_last_word);
  1133.         }
  1134.         if (!is_array($word|| 
  1135.             !in_array($word[0]array(T_COMMENTT_DOC_COMMENT)) ||
  1136.             (in_array($word[0]array(T_COMMENTT_DOC_COMMENT)) && 
  1137.             strpos($word[1]'/**'=== 0)
  1138.         {
  1139.             $this->_event_stack->popEvent();
  1140.             if (strpos($this->_pv_last_word[1]"\n"!== false{
  1141.                 //$this->_wp->linenum++;
  1142.                 //$this->newLineNum();
  1143.             }
  1144.             $this->_wp->backupPos($this->_pv_last_word);
  1145.             $this->_wp->getWord();
  1146.             //var_dump($this->_wp->nextToken());
  1147.             return;
  1148.         elseif (isset($flag)) {
  1149.             $this->newLineNum();
  1150.         }
  1151.         $this->_addoutput($word);
  1152.         $this->checkEventPop($word$pevent);
  1153.         if (strpos($word[1]'*/'=== strlen($word[1]2{
  1154.             $this->_event_stack->popEvent();
  1155.         }
  1156.     }
  1157.    
  1158.     /**
  1159.      * Handle class declarations
  1160.      *
  1161.      * Handles the initial declaration line:
  1162.      *
  1163.      * <code>class X</code>
  1164.      * 
  1165.      * or
  1166.      * 
  1167.      * <code>class X extends Y implements I</code>
  1168.      *
  1169.      * @uses _classlink() to link to documentation for X and for Y class in
  1170.      *                     "class X extends Y"
  1171.      */
  1172.     function handleClass($word$pevent)
  1173.     {
  1174.         $this->_pf_in_class true;
  1175.         $a                  $this->checkEventPush($word$pevent);
  1176.  
  1177.         if (!isset($this->_pv_class&& is_array($word&& $word[0== T_STRING{
  1178.             $this->_pv_class $this->_converter->class $word[1];
  1179.             $this->_classlink($word);
  1180.             return;
  1181.         }
  1182.        
  1183.         if (is_array($word&& 
  1184.             in_array($word[0]array(T_PRIVATET_PROTECTEDT_PUBLIC))
  1185.         {
  1186.             $starttok $this->_wp->nextToken();
  1187.             $test     array(T_WHITESPACE);
  1188.             while ($test && $test[0== T_WHITESPACE{
  1189.                 $tok  $this->_wp->nextToken();
  1190.                 $test $this->_wp->getWord();
  1191.             // while
  1192.            
  1193.             if (is_array($test&& $test[0== T_VARIABLE{
  1194.                 $this->_wp->backupPos($toktrue);
  1195.                 return;
  1196.             }
  1197.             $this->_wp->backupPos($starttoktrue);
  1198.         }
  1199.        
  1200.         if (@in_array($this->_pv_last_word[0]
  1201.             array(T_PRIVATET_PROTECTEDT_PUBLIC))
  1202.         {
  1203.             if (is_array($word&& $word[0== T_VARIABLE{
  1204.                 $this->_wp->backupPos($this->_pv_last_word);
  1205.                 $this->_event_stack->pushEvent(PARSER_EVENT_VAR);
  1206.                 return;
  1207.             }
  1208.         }
  1209.  
  1210.         if ($this->_pf_extends_found && is_array($word&& $word[0== T_STRING{
  1211.             $this->_classlink($word);
  1212.             return;
  1213.         }
  1214.         if (is_array($word&& $word[0== T_EXTENDS{
  1215.             $this->_pf_extends_found true;
  1216.         }
  1217.         if ($a == PARSER_EVENT_DOCBLOCK{
  1218.             $this->_pf_no_output_yet true;
  1219.             $this->_pv_saveline      $this->_wp->linenum 1;
  1220.             return;
  1221.         }
  1222.         $this->_addoutput($word);
  1223.         if ($this->checkEventPop($word$pevent)) {
  1224.             $this->_pf_in_class false;
  1225.             unset($this->_pv_class);
  1226.         }
  1227.     }
  1228.    
  1229.     /**
  1230.      * Handles class variable declaration
  1231.      *
  1232.      * <code>
  1233.      * class X
  1234.      * {
  1235.      *     var $Y;
  1236.      * }
  1237.      * </code>
  1238.      *
  1239.      * @uses _varlink() make a link to $Y documentation in class variable
  1240.      *                   declaration "var $Y;"
  1241.      */
  1242.     function handleVar($word$pevent)
  1243.     {
  1244.         if ($this->checkEventPush($word$pevent)) {
  1245.             $this->_addoutput($word);
  1246.             return;
  1247.         }
  1248.         if (is_array($word&& $word[0== T_VARIABLE{
  1249.             return $this->_varlink($word);
  1250.         }
  1251.         $this->_addoutput($word);
  1252.         $this->checkEventPop($word$pevent);
  1253.     }
  1254.    
  1255.     /**
  1256.      * This handler is responsible for highlighting DocBlocks
  1257.      *
  1258.      * handleDocBlock determines whether the docblock is normal or a template,
  1259.      * and gathers all the lines of the docblock together before doing any
  1260.      * processing
  1261.      *
  1262.      * As it is not possible to distinguish any comment token from a docblock
  1263.      * token, this handler is also called for comments, and will pass control
  1264.      * to {@link handleComment()} if the comment is not a DocBlock
  1265.      *
  1266.      * @uses commonDocBlock() once all lines of the DocBlock have been retrieved
  1267.      */
  1268.     function handleDocBlock($word$pevent)
  1269.     {
  1270.         if (!($this->_pf_docblock || $this->_pf_docblock_template)) {
  1271.             if (strpos($this->_pv_last_word[1]'/**'!== 0{
  1272.                 // not a docblock
  1273.                 $this->_wp->backupPos($this->_pv_last_word);
  1274.                 $this->_event_stack->popEvent();
  1275.                 $this->_event_stack->pushEvent(PARSER_EVENT_COMMENT);
  1276.                 $this->_pf_no_output_yet false;
  1277.                 return;
  1278.             else {
  1279.                 $this->_pf_no_output_yet true;
  1280.                 $this->_pv_db_lines      array();
  1281.             }
  1282.         }
  1283.         $last_word $this->_pv_last_word[1];
  1284.         $dtype     '_pv_docblock';
  1285.         if ($last_word == '/**#@-*/'{
  1286.             // stop using docblock template
  1287.             $this->_pf_no_output_yet false;
  1288.             $this->_addDocBlockoutput('closetemplate'$last_word);
  1289.             if ($this->_pv_next_word !== false{
  1290.                 $this->_wp->backupPos($this->_pv_next_wordtrue);
  1291.             }
  1292.             $this->_event_stack->popEvent();
  1293.             return;
  1294.         }
  1295.         if (!($this->_pf_docblock || $this->_pf_docblock_template)) {
  1296.             $this->_pv_db_lines array();
  1297.             if (strpos($last_word'/**#@+'=== 0{
  1298.                 // docblock template definition
  1299.                 $this->_pf_docblock_template true;
  1300.             else {
  1301.                 $this->_pf_docblock true;
  1302.             }
  1303.             $this->_pv_db_lines[$last_word;
  1304.             if (strpos($last_word'*/'!== false{
  1305.                 $this->commonDocBlock();
  1306.                 return;
  1307.             }
  1308.             $this->_pv_db_lines[$word[1];
  1309.             if (strpos($word[1]'*/'!== false{
  1310.                 $this->commonDocBlock();
  1311.             }
  1312.         else {
  1313.             $this->_pv_db_lines[$word[1];
  1314.         }
  1315.         if (($this->_pf_docblock || $this->_pf_docblock_template&& 
  1316.             (strpos($word[1]'*/'!== false)
  1317.         {
  1318.             $this->commonDocBlock();
  1319.         }
  1320.     }
  1321.     /**#@-*/
  1322.  
  1323.     /**
  1324.      * This continuation of handleDocBlock splits DocBlock comments up into
  1325.      * phpDocumentor tokens.  It highlights DocBlock templates in a different
  1326.      * manner from regular DocBlocks, recognizes inline tags, regular tags,
  1327.      * and distinguishes between standard core tags and other tags, and
  1328.      * recognizes parameters to tags like @var.
  1329.      *
  1330.      * the type in "@var type description" will be highlighted as a php type,
  1331.      * and the var in "@param type $var description" will be highlighted as a
  1332.      * php variable.
  1333.      *
  1334.      * @return void 
  1335.      * @uses handleDesc() highlight inline tags in the description
  1336.      * @uses handleTags() highlight all tags
  1337.      * @access private
  1338.      */
  1339.     function commonDocBlock()
  1340.     {
  1341.         $this->_event_stack->popEvent();
  1342.         $lines $this->_pv_db_lines;
  1343.         $go    count($this->_pv_db_lines);
  1344.         for ($i=0$i $go$i++{
  1345.             if (substr(trim($lines[$i])02== '*/' || 
  1346.                 substr(trim($lines[$i])01!= '*' && 
  1347.                 substr(trim($lines[$i])03!= '/**'
  1348.             {
  1349.                 $lines[$iarray($lines[$i]false);
  1350.             elseif (substr(trim($lines[$i])03== '/**'{
  1351.                 $linesi array();
  1352.                 // remove leading "/**"
  1353.                 $linesi[1substr(trim($lines[$i])3);
  1354.                 if (empty($linesi[1])) {
  1355.                     $linesi[0$lines[$i];
  1356.                 else {
  1357.                     $linesi[0
  1358.                         substr($lines[$i]0strpos($lines[$i]$linesi[1]));
  1359.                 }
  1360.                 $lines[$i$linesi;
  1361.             else {
  1362.                 $linesi array();
  1363.                 // remove leading "* "
  1364.                 $linesi[1substr(trim($lines[$i])1);
  1365.                 if (empty($linesi[1])) {
  1366.                     $linesi[0$lines[$i];
  1367.                 else {
  1368.                     $linesi[0
  1369.                         substr($lines[$i]0strpos($lines[$i]$linesi[1]));
  1370.                 }
  1371.                 $lines[$i$linesi;
  1372.             }
  1373.         }
  1374.         for ($i 0$i count($lines)$i++{
  1375.             if ($lines[$i][1=== false{
  1376.                 continue;
  1377.             }
  1378.             if (substr(trim($lines[$i][1])01== '@' && 
  1379.                 substr(trim($lines[$i][1])02!= '@ '
  1380.             {
  1381.                 $tagindex $i;
  1382.                 $i        count($lines);
  1383.             }
  1384.         }
  1385.         if (isset($tagindex)) {
  1386.             $tags array_slice($lines$tagindex);
  1387.             $desc array_slice($lines0$tagindex);
  1388.         else {
  1389.             $tags array();
  1390.             $desc $lines;
  1391.         }
  1392.         //var_dump($desc, $tags);
  1393.         $this->_pf_no_output_yet false;
  1394.         $save                    $this->_wp->linenum;
  1395.         $this->_wp->linenum      $this->_pv_saveline;
  1396.         $this->handleDesc($desc);
  1397.         $this->handleTags($tags);
  1398.         $this->_pv_db_lines array();
  1399.         $this->_wp->linenum $save;
  1400.         if (strpos($this->_pv_last_word[1]'*/'!== false{
  1401.             $this->_wp->backupPos($this->_pv_next_wordtrue);
  1402.         }
  1403.         $this->_pf_docblock $this->_pf_docblock_template false;
  1404.     }
  1405.    
  1406.     /**
  1407.      * Handle the description area of a DocBlock
  1408.      *
  1409.      * This method simply finds inline tags and highlights them
  1410.      * separately from the rest of the description.
  1411.      *
  1412.      * @param mixed $desc the description piece(s)
  1413.      *
  1414.      * @return void 
  1415.      * @uses getInlineTags()
  1416.      * @access private
  1417.      */
  1418.     function handleDesc($desc)
  1419.     {
  1420.         $dbtype  'docblock';
  1421.         $dbtype .= ($this->_pf_docblock '' 'template');
  1422.         foreach ($desc as $line{
  1423.             $this->getInlineTags($line[0$line[1]);
  1424.             if (strpos($line[0]'*/'=== false &&
  1425.                 !(substr($line[0]02== '/*' && 
  1426.                 strpos($line[1]'*/'!== false)
  1427.             {
  1428.                 $this->newLineNum();
  1429.                 $this->_wp->linenum++;
  1430.             }
  1431.         }
  1432.         if ($this->_pf_internal{
  1433.             $this->_pf_internal false;
  1434.         }
  1435.     }
  1436.    
  1437.     /**
  1438.      * Handle phpDocumentor tags in a DocBlock
  1439.      *
  1440.      * This method uses the {@link $tagHandlers} array to determine which
  1441.      * method will handle tags found in the docblock, and passes the data to
  1442.      * the individual handlers one by one
  1443.      *
  1444.      * @param array $tags array of tags to handle
  1445.      *
  1446.      * @return void 
  1447.      * @access private
  1448.      */
  1449.     function handleTags($tags)
  1450.     {
  1451.         $newtags array();
  1452.         $curtag  array();
  1453.         for ($i=0$i count($tags)$i++{
  1454.             $tagsi trim($tags[$i][1]);
  1455.             if (substr($tagsi01== '@' && substr($tagsi02!= '@ '{
  1456.                 // start a new tag
  1457.                 $tags[$i][1array(substr($tags[$i][1]0
  1458.                     strpos($tags[$i][1]$tagsi))$tagsi);
  1459.                 if (!empty($curtag)) {
  1460.                     $newtags[$curtag;
  1461.                     $curtag    array();
  1462.                 }
  1463.                 $curtag[$tags[$i];
  1464.             else {
  1465.                 $curtag[$tags[$i];
  1466.             }
  1467.         }
  1468.         if (!empty($curtag)) {
  1469.             $newtags[$curtag;
  1470.         }
  1471.         foreach ($newtags as $tag{
  1472.             foreach ($tag as $i => $t{
  1473.                 if ($t[1=== false{
  1474.                     continue;
  1475.                 }
  1476.                 if (is_array($t[1])) {
  1477.                     $tag[$i][1][1]
  1478.                         = explode(" "str_replace("\t"'    '$t[1][1]));
  1479.                     $x $tag[$i][1][1];
  1480.                 }
  1481.             }
  1482.             $tagname   substr(array_shift($x)1);
  1483.             $restoftag $tag;
  1484.             if (isset($this->tagHandlers[$tagname])) {
  1485.                 $handle $this->tagHandlers[$tagname];
  1486.             else {
  1487.                 $handle $this->tagHandlers['*'];
  1488.             }
  1489.             $this->$handle($tagname$restoftag);
  1490.         }
  1491.     }
  1492.    
  1493.     /**
  1494.      * This handler recognizes all {@}inline} tags
  1495.      *
  1496.      * Normal inline tags are simply highlighted.  the {@}internal}} inline
  1497.      * tag {@tutorial tags.inlineinternal.pkg} is highlighted differently
  1498.      * to distinguish it from other inline tags.
  1499.      *
  1500.      * @param mixed $value       the tag value
  1501.      * @param bool  $endinternal indicates the end of an @internal tag
  1502.      *
  1503.      * @return void 
  1504.      * @access private
  1505.      */
  1506.     function getInlineTags($value$endinternal false)
  1507.     {
  1508.         if (!$value{
  1509.             return;
  1510.         }
  1511.         if ($this->_pf_internal && !$endinternal{
  1512.             if (strpos($value'}}'!== false{
  1513.                 $x strrpos($value'}}');
  1514.                 // add the rest of internal
  1515.                 $this->getInlineTags(substr($value0$x 3)true);
  1516.                 // strip internal from value
  1517.                 $value substr($valuestrrpos($value'}}'1);
  1518.                 // turn off internal
  1519.                 $this->_pf_internal false;
  1520.             }
  1521.         }
  1522.         if (!$value{
  1523.             return;
  1524.         }
  1525.         $dbtype  'docblock';
  1526.         $dbtype .= ($this->_pf_docblock '' 'template');
  1527.         $save    $value;
  1528.         $value   explode('{@'$value);
  1529.         $newval  array();
  1530.         // everything before the first {@ is normal text
  1531.         $this->_addDocBlockoutput($dbtype$value[0]);
  1532.         for ($i=1$i count($value)$i++{
  1533.             if (substr($value[$i]01== '}'{
  1534.                 $this->_addDocBlockoutput($dbtype'{@}' substr($value[$i]1));
  1535.             else {
  1536.                 $save      $value[$i];
  1537.                 $value[$istr_replace("\t""    "$value[$i]);
  1538.                 $value[$iexplode(" "$value[$i]);
  1539.                 $word      array_shift($value[$i]);
  1540.                 $val       join(' '$value[$i]);
  1541.                 if ($word == 'internal'{
  1542.                     $this->_pf_internal true;
  1543.                     $this->_addDocBlockoutput($dbtype'{@internal ');
  1544.                     $value[$isubstr($savestrlen('internal'1);
  1545.                     // strip internal and cycle as if it were normal text.
  1546.                     $this->_addDocBlockoutput($dbtype$value[$i]);
  1547.                     continue;
  1548.                 }
  1549.                 if (in_array(str_replace('}'''$word)$this->allowableInlineTags)
  1550.                 {
  1551.                     if (strpos($word'}')) {
  1552.                         $word str_replace('}'''$word);
  1553.                         $val  '} ' $val;
  1554.                     }
  1555.                     $val explode('}'$val);
  1556.                     if (count($val== 1{
  1557.                          //addError(PDERROR_UNTERMINATED_INLINE_TAG,
  1558.                          //    $word, '', $save);
  1559.                     }
  1560.                     $rest $val;
  1561.                     $val  array_shift($rest);
  1562.                     if ($endinternal{
  1563.                         $rest join('}'$rest);
  1564.                     else {
  1565.                         $rest join(' '$rest);
  1566.                     }
  1567.                     if (isset($this->inlineTagHandlers[$word])) {
  1568.                         $handle $this->inlineTagHandlers[$word];
  1569.                     else {
  1570.                         $handle $this->inlineTagHandlers['*'];
  1571.                     }
  1572.                     $this->$handle($word$val);
  1573.                     $this->_addDocBlockoutput($dbtype$rest);
  1574.                 else {
  1575.                     $val $word ' ' $val;
  1576.                     $this->_addDocBlockoutput($dbtype'{@' $val);
  1577.                 }
  1578.             }
  1579.         }
  1580.     }
  1581.  
  1582.    
  1583.     /**
  1584.      * Handles all inline tags
  1585.      *
  1586.      * @param string $name  the tag name
  1587.      * @param mixed  $value the tag value
  1588.      *
  1589.      * @return void 
  1590.      * @access private
  1591.      */
  1592.     function handleDefaultInlineTag($name$value)
  1593.     {
  1594.         $this->_addDocBlockoutput('inlinetag''{@' $name ' ' $value '}');
  1595.     }
  1596.  
  1597.     /**#@+
  1598.      * phpDocumentor DocBlock tag handlers
  1599.      *
  1600.      * @param string $name    tag name
  1601.      * @param array  $value   array of lines contained in the tag description
  1602.      *
  1603.      * @return void
  1604.      * @access private
  1605.      */
  1606.     /**
  1607.      * Handle normal tags
  1608.      *
  1609.      * This handler adds to outpu all comment information before the tag begins
  1610.      * as in " * " before "@todo" in " * @todo"
  1611.      *
  1612.      * Then, it highlights the tag as a regular or coretag based on $coretag.
  1613.      * Finally, it uses getInlineTags to highlight the description
  1614.      *
  1615.      * @param bool $coretag whether this tag is a core tag or not
  1616.      *
  1617.      * @uses getInlineTags() highlight a tag description
  1618.      */
  1619.     function defaultTagHandler($name$value$coretag false)
  1620.     {
  1621.         $dbtype  'docblock';
  1622.         $dbtype .= ($this->_pf_docblock '' 'template');
  1623.         foreach ($value as $line{
  1624.             $this->_addDocBlockoutput($dbtype$line[0]);
  1625.             if ($line[1=== false{
  1626.                 if (trim($line[0]!= '*/'{
  1627.                     $this->newLineNum();
  1628.                     $this->_wp->linenum++;
  1629.                 }
  1630.                 continue;
  1631.             }
  1632.             $this->_addDocBlockoutput($dbtype$line[1][0]);
  1633.             $stored '';
  1634.             if (is_array($line[1][1])) {
  1635.                 foreach ($line[1][1as $i => $tpart{
  1636.                     if ($tpart == '@' $name && $i == 0{
  1637.                         $tagname 'tag';
  1638.                         if ($coretag{
  1639.                             $tagname 'coretag';
  1640.                         }
  1641.                         $this->_addDocBlockoutput($tagname'@' $name);
  1642.                         continue;
  1643.                     }
  1644.                     $stored .= ' ' $tpart;
  1645.                 }
  1646.             else {
  1647.                 $stored $line[1];
  1648.             }
  1649.             $this->getInlineTags($stored);
  1650.             if (strpos($stored'*/'=== false{
  1651.                 $this->newLineNum();
  1652.                 $this->_wp->linenum++;
  1653.             }
  1654.         }
  1655.     }
  1656.    
  1657.     /**
  1658.      * main handler for "core" tags
  1659.      *
  1660.      * @see defaultTagHandler()
  1661.      */
  1662.     function coreTagHandler($name$value)
  1663.     {
  1664.         return $this->defaultTagHandler($name$valuetrue);
  1665.     }
  1666.    
  1667.     /**
  1668.      * Handles @global
  1669.      *
  1670.      * This handler works like {@link defaultTagHandler()} except it highlights
  1671.      * the type and variable (if present) in "@global type $variable" or
  1672.      * "@global type description"
  1673.      */
  1674.     function globalTagHandler($name$value)
  1675.     {
  1676.         $this->paramTagHandler($name$value);
  1677.     }
  1678.    
  1679.     /**
  1680.      * Handles @param
  1681.      *
  1682.      * This handler works like {@link defaultTagHandler()} except it highlights
  1683.      * the type and variable (if present) in "@param type $variable description"
  1684.      * or "@param type description"
  1685.      *
  1686.      * @param bool $checkforvar private parameter, checks for $var or not
  1687.      */
  1688.     function paramTagHandler($name$value$checkforvar true)
  1689.     {
  1690.         $dbtype  'docblock';
  1691.         $dbtype .= ($this->_pf_docblock '' 'template');
  1692.         $ret     $this->retrieveType($value0$checkforvar);
  1693.         foreach ($value as $num => $line{
  1694.             $this->_addDocBlockoutput($dbtype$line[0]);
  1695.             if ($line[1=== false{
  1696.                 if (trim($line[0]!= '*/'{
  1697.                     $this->newLineNum();
  1698.                     $this->_wp->linenum++;
  1699.                 }
  1700.                 continue;
  1701.             }
  1702.             $this->_addDocBlockoutput($dbtype$line[1][0]);
  1703.             $stored  '';
  1704.             $typeloc 1;
  1705.             $varloc  2;
  1706.             if (is_array($line[1][1])) {
  1707.                 $this->_addDocBlockoutput('coretag''@' $name ' ');
  1708.                 foreach ($ret[0as $text{
  1709.                     if (is_string($text)) {
  1710.                         $this->_addDocBlockoutput($dbtype$text);
  1711.                     }
  1712.                     if (is_array($text)) {
  1713.                         if ($text[0!= 'desc'{
  1714.                             $this->_addDocBlockoutput($text[0]$text[1]);
  1715.                         else {
  1716.                             $stored .= $text[1];
  1717.                         }
  1718.                     }
  1719.                 }
  1720.             else {
  1721.                 if (isset($ret[$num])) {
  1722.                     foreach ($ret[$numas $text{
  1723.                         if (is_string($text)) {
  1724.                             $this->_addDocBlockoutput($dbtype$text);
  1725.                         }
  1726.                         if (is_array($text)) {
  1727.                             if ($text[0!= 'desc'{
  1728.                                 $this->_addDocBlockoutput($text[0]$text[1]);
  1729.                             else {
  1730.                                 $stored .= $text[1];
  1731.                             }
  1732.                         }
  1733.                     }
  1734.                 else {
  1735.                     $stored $line[1];
  1736.                 }
  1737.             }
  1738.             $this->getInlineTags($stored);
  1739.             if (strpos($stored'*/'=== false{
  1740.                 $this->newLineNum();
  1741.                 $this->_wp->linenum++;
  1742.             }
  1743.         }
  1744.     }
  1745.    
  1746.     /**
  1747.      * handles the @staticvar tag
  1748.      *
  1749.      * @see paramTagHandler()
  1750.      */
  1751.     function staticvarTagHandler($name$value)
  1752.     {
  1753.         return $this->paramTagHandler($name$value);
  1754.     }
  1755.    
  1756.     /**
  1757.      * handles the @var tag
  1758.      *
  1759.      * @see paramTagHandler()
  1760.      */
  1761.     function varTagHandler($name$value)
  1762.     {
  1763.         return $this->paramTagHandler($name$value);
  1764.     }
  1765.    
  1766.     /**
  1767.      * Handles @return
  1768.      *
  1769.      * This handler works like {@link defaultTagHandler()} except it highlights
  1770.      * the type in "@return type description"
  1771.      */
  1772.     function returnTagHandler($name$value)
  1773.     {
  1774.         $this->paramTagHandler($name$valuefalse);
  1775.     }
  1776.  
  1777.     /**
  1778.      * Handles @property(-read or -write) and @method magic tags
  1779.      */
  1780.     function propertyTagHandler($name$value)
  1781.     {
  1782.         return $this->paramTagHandler($name$valuetrue);
  1783.     }
  1784.  
  1785.     /**#@-*/
  1786.    
  1787.     /**
  1788.      * Retrieve the type portion of a @tag type description
  1789.      *
  1790.      * Tags like @param, @return and @var all have a PHP type portion in their
  1791.      * description.  Since the type may contain the expression "object blah"
  1792.      * where blah is a classname, it makes parsing out the type field complex.
  1793.      *
  1794.      * Even more complicated is the case where a tag variable can contain
  1795.      * multiple types, such as object blah|object blah2|false, and so this
  1796.      * method handles these cases.
  1797.      *
  1798.      * @param array $value       array of words that were separated by spaces
  1799.      * @param 0|1  $state       0 = find the type, 1 = find the var, if present
  1800.      * @param bool  $checkforvar flag to determine whether to check for the end of a
  1801.      *                            type is defined by a $varname
  1802.      *
  1803.      * @return array Format: array(state (0 [find type], 1 [var], 2 [done]),
  1804.      * @access private
  1805.      */
  1806.     function retrieveType($value$state 0$checkforvar false)
  1807.     {
  1808.         $index  0;
  1809.         $result array();
  1810.         do {
  1811.             if (!isset($value[$index][1])) {
  1812.                 return $result;
  1813.             }
  1814.             $val $value[$index][1];
  1815.             if (empty($val)) {
  1816.                 return $result;
  1817.             }
  1818.             if ($index == 0{
  1819.                 $val $val[1];
  1820.                 array_shift($val);
  1821.             else {
  1822.                 $val explode(' '$val);
  1823.             }
  1824.             $ret              $this->_retrieveType($val$state$checkforvar);
  1825.             $state            $ret[0];
  1826.             $result[$index++$ret[1];
  1827.         while ((!$checkforvar && $state 1|| ($state && $checkforvar));
  1828.         return $result;
  1829.     }
  1830.  
  1831.     /**
  1832.      * used by {@link retrieveType()} in its work
  1833.      *
  1834.      * @param array $value       array of words that were separated by spaces
  1835.      * @param 0|1  $state       0 = find the type, 1 = find the var, if present
  1836.      * @param bool  $checkforvar flag to determine whether to check for the end of a
  1837.      *                            type is defined by a $varname
  1838.      *
  1839.      * @return array 
  1840.      * @access private
  1841.      */   
  1842.     function _retrieveType($value$state$checkforvar)
  1843.     {
  1844.         $result   array();
  1845.         $result[$this->_removeWhiteSpace($value0);
  1846.         if ($state == 0{
  1847.             if (!count($value)) {
  1848.                 return array(2$result);
  1849.             }
  1850.             $types '';
  1851.             $index 0;
  1852.             if (trim($value[0]== 'object'{
  1853.                 $result[array('tagphptype'$value[0' ');
  1854.                 $types   .= array_shift($value).' ';
  1855.                 $result[$this->_removeWhiteSpace($value0);
  1856.                 if (!count($value)) {
  1857.                     // was just passed "object"
  1858.                     return array(2$result);
  1859.                 }
  1860.                 if ($value[0]{0== '$' || substr($value[0]02== '&$'{
  1861.                     // was just passed "object"
  1862.                     // and the next thing is a variable name
  1863.                     if ($checkforvar{
  1864.                         $result[array('tagvarname' $value[0' ');
  1865.                         array_shift($value);
  1866.                     }
  1867.                     $result[array('desc'join(' '$value));
  1868.                     return array(2$result);
  1869.                 }
  1870.             }
  1871.             $done false;
  1872.             $loop = -1;
  1873.             do {
  1874.                 // this loop checks for type|type|type and for
  1875.                 // type|object classname|type|object classname2
  1876.                 if (strpos($value[0]'|')) {
  1877.                     $temptypes explode('|'$value[0]);
  1878.                     while (count($temptypes)) {
  1879.                         $type     array_shift($temptypes);
  1880.                         $result[array('tagphptype'$type);
  1881.                         if (count($temptypes)) {
  1882.                             $result['|';
  1883.                         }
  1884.                     }
  1885.                     if (trim($type== 'object'{
  1886.                         $result[array('tagphptype'$types ' ');
  1887.                         $result[$this->_removeWhiteSpace($value0);
  1888.                     else {
  1889.                         $done true;
  1890.                     }
  1891.                     array_shift($value);
  1892.                     if (count($value&& strlen($value[0]&& isset ($value[0]&& 
  1893.                         ($value[0]{0== '$' || substr($value[0]02== '&$')
  1894.                     {
  1895.                         // was just passed "object"
  1896.                         // and the next thing is a variable name
  1897.                         $result[array('tagvarname' $value[0' ');
  1898.                         array_shift($value);
  1899.                         $result[array('desc'join(' '$value));
  1900.                         return array(2$result);
  1901.                     }
  1902.                 else {
  1903.                     $result[array('tagphptype'$value[0' ');
  1904.                     array_shift($value);
  1905.                     $done true;
  1906.                 }
  1907.                 $loop++;
  1908.             while (!$done && count($value));
  1909.             if ($loop{
  1910.                 $result[' ';
  1911.             }
  1912.             // still searching for type
  1913.             if (!$done && !count($value)) {
  1914.                 return array(0$result);
  1915.             }
  1916.             // still searching for var
  1917.             if ($done && !count($value)) {
  1918.                 return array(1$result);
  1919.             }
  1920.         }
  1921.         $result[$this->_removeWhiteSpace($value0);
  1922.         $state    1;
  1923.         if ($checkforvar{
  1924.             if (count($value)) {
  1925.                 $state 2;
  1926.                 if (substr($value[0]01== '$' || 
  1927.                     substr($value[0]02== '&$'
  1928.                 {
  1929.                     $result[array('tagvarname' $value[0' ');
  1930.                     array_shift($value);
  1931.                 }
  1932.             else {
  1933.                 $state 1;
  1934.             }
  1935.         }
  1936.         $result[array('desc'join(' '$value));
  1937.         return array($state$result);
  1938.     }
  1939.    
  1940.     /**
  1941.      * captures trailing whitespace
  1942.      *
  1943.      * @param array &$value array of string
  1944.      * @param int   $index  index to seek non-whitespace to
  1945.      *
  1946.      * @return string whitespace
  1947.      * @access private
  1948.      */
  1949.     function _removeWhiteSpace(&$value$index)
  1950.     {
  1951.         $result '';
  1952.         if (count($value$index && empty($value[$index])) {
  1953.             $found false;
  1954.             for ($i $index$i count($value&& !strlen($value[$i])$i++{
  1955.                 $result .= ' ';
  1956.             }
  1957.             array_splice($value$index$i $index);
  1958.         }
  1959.         return $result;
  1960.     }
  1961.  
  1962.     /**#@+
  1963.      * Link generation methods
  1964.      *
  1965.      * @param string|array $word token to try to link
  1966.      *
  1967.      * @access private
  1968.      */
  1969.     /**
  1970.      * Generate a link to documentation for an element
  1971.      *
  1972.      * This method tries to link to documentation for functions, methods,
  1973.      * PHP functions, class names, and if found, adds the links to output
  1974.      * instead of plain text
  1975.      */
  1976.     function _link($word)
  1977.     {
  1978.         if (is_array($word&& $word[0== T_STRING{
  1979.             if ($this->_pf_colon_colon{
  1980.                 $this->_pf_colon_colon false;
  1981.  
  1982.                 $combo $this->_pv_last_string[1'::' $word[1'()';
  1983.                 //debug('testing ' . $combo);
  1984.                 $link $this->_converter->getLink($combo);
  1985.                 if (is_object($link)) {
  1986.                     $this->_addoutput($this->_converter->returnSee($link,
  1987.                         $word[1])true);
  1988.                     return;
  1989.                 }
  1990.                 $this->_addoutput($word);
  1991.                 return;
  1992.             }
  1993.             $link $this->_converter->getLink($word[1'()');
  1994.             if (is_object($link)) {
  1995.                 $this->_addoutput($this->_converter->returnSee($link,
  1996.                     $word[1])true);
  1997.                 return;
  1998.             elseif (is_string($link&& strpos($link'ttp://')) {
  1999.                 $this->_addoutput($this->_converter->returnLink($link,
  2000.                     $word[1])true);
  2001.                 return;
  2002.             else {
  2003.                 $link $this->_converter->getLink($word[1]);
  2004.                 if (is_object($link)) {
  2005.                     $word[1$this->_converter->returnSee($link$word[1]);
  2006.                 }
  2007.                 $this->_addoutput($wordtrue);
  2008.                 return;
  2009.             }
  2010.         }
  2011.         $this->_addoutput($word);
  2012.     }
  2013.    
  2014.     /**
  2015.      * Works like {@link _link()} except it only links to global variables
  2016.      */
  2017.     function _globallink($word)
  2018.     {
  2019.         if (!is_array($word)) {
  2020.             return $this->_addoutput($word);
  2021.         }
  2022.         if ($word[0!= T_VARIABLE{
  2023.             return $this->_addoutput($word);
  2024.         }
  2025.         if (is_array($word&& $word[0== T_VARIABLE{
  2026.             $link $this->_converter->getLink('global ' $word[1]);
  2027.             if (is_object($link)) {
  2028.                 $this->_addoutput($this->_converter->returnSee($link,
  2029.                     $word[1])true);
  2030.                 return;
  2031.             }
  2032.         }
  2033.         $this->_addoutput($word);
  2034.     }
  2035.    
  2036.     /**
  2037.      * Works like {@link _link()} except it only links to classes
  2038.      */
  2039.     function _classlink($word)
  2040.     {
  2041.         //debug("checking class " . $word[1]);
  2042.         if (is_array($word&& $word[0== T_STRING{
  2043.             $link $this->_converter->getLink($word[1]);
  2044.             if (is_object($link)) {
  2045.                 $this->_addoutput($this->_converter->returnSee($link,
  2046.                     $word[1])true);
  2047.                 return;
  2048.             }
  2049.         }
  2050.         $this->_addoutput($word);
  2051.     }
  2052.    
  2053.     /**
  2054.      * Works like {@link _link()} except it only links to methods
  2055.      */
  2056.     function _methodlink($word)
  2057.     {
  2058.         if (is_array($word&& $word[0== T_STRING{
  2059.             //debug("checking method " . $this->_pv_class . '::' . $word[1] . '()');
  2060.             if (isset($this->_pv_prev_var_type)) {
  2061.                 $link $this->_converter->getLink($this->_pv_prev_var_type '::' .
  2062.                     $word[1'()');
  2063.             else {
  2064.                 $link $this->_converter->getLink($this->_pv_class '::' 
  2065.                     $word[1'()');
  2066.             }
  2067.             if (is_object($link)) {
  2068.                 $this->_addoutput($this->_converter->returnSee($link,
  2069.                     $word[1])true);
  2070.                 return;
  2071.             }
  2072.             if (isset($this->_pv_prev_var_type)) {
  2073.                 $this->_addoutput($word);
  2074.                 return;
  2075.             }
  2076.             //debug("checking method " . $word[1] . '()');
  2077.             $link $this->_converter->getLink($word[1'()');
  2078.             if (is_object($link)) {
  2079.                 $this->_addoutput($this->_converter->returnSee($link,
  2080.                     $word[1])true);
  2081.                 return;
  2082.             }
  2083.         }
  2084.         $this->_addoutput($word);
  2085.     }
  2086.    
  2087.     /**
  2088.      * Works like {@link _link()} except it only links to class variables
  2089.      *
  2090.      * @param bool $justastring true if the $word is only a string
  2091.      */
  2092.     function _varlink($word$justastring=false)
  2093.     {
  2094.         if ($justastring{
  2095.             $word[0T_VARIABLE;
  2096.         }
  2097.         if (is_array($word&& $word[0== T_VARIABLE{
  2098.             $x ($justastring '$' '');
  2099.             //debug("checking var " . $this->_pv_class . '::' . $x . $word[1]);
  2100.             if (isset($this->_pv_prev_var_type)) {
  2101.                 //debug("checking var " . $this->_pv_prev_var_type . '::' .
  2102.                 //    $x . $word[1]);
  2103.                 $link $this->_converter->getLink($this->_pv_prev_var_type '::' .
  2104.                     $x $word[1]);
  2105.             else {
  2106.                 $link $this->_converter->getLink($this->_pv_class '::' 
  2107.                     $x $word[1]);
  2108.             }
  2109.             if (is_object($link)) {
  2110.                 $this->_addoutput($this->_converter->returnSee($link,
  2111.                     $word[1])true);
  2112.                 return;
  2113.             }
  2114.             //debug("checking var " . $x . $word[1]);
  2115.             if (isset($this->_pv_prev_var_type)) {
  2116.                 $this->_addoutput($word);
  2117.                 return;
  2118.             }
  2119.             $link $this->_converter->getLink($x $word[1]);
  2120.             if (is_object($link)) {
  2121.                 $this->_addoutput($this->_converter->returnSee($link,
  2122.                     $word[1])true);
  2123.                 return;
  2124.             }
  2125.         }
  2126.         $this->_addoutput($word);
  2127.     }
  2128.     /**#@-*/
  2129.    
  2130.     /**#@+
  2131.      * Output Methods
  2132.      * @access private
  2133.      */
  2134.     /**
  2135.      * This method adds output to {@link $_line}
  2136.      *
  2137.      * If a string with variables like "$test this" is present, then special
  2138.      * handling is used to allow processing of the variable in context.
  2139.      *
  2140.      * @param mixed $word         the string|array tag token and value
  2141.      * @param bool  $preformatted whether or not the $word is already formatted
  2142.      *
  2143.      * @return void 
  2144.      * @see _flush_save()
  2145.      */
  2146.     function _addoutput($word$preformatted false)
  2147.     {
  2148.         if ($this->_pf_no_output_yet{
  2149.             return;
  2150.         }
  2151.         if ($this->_pf_quote_active{
  2152.             if (is_array($word)) {
  2153.                 $this->_save .= $this->_converter->highlightSource($word[0],
  2154.                     $word[1]);
  2155.             else {
  2156.                 $this->_save .= $this->_converter->highlightSource(false,
  2157.                     $wordtrue);
  2158.             }
  2159.         else {
  2160.             $this->_flush_save();
  2161.             if (is_string($word&& trim($word== ''{
  2162.                 $this->_line .= $this->_converter->postProcess($word);
  2163.                 return;
  2164.             }
  2165.             if (is_array($word&& trim($word[1]== ''{
  2166.                 $this->_line .= $this->_converter->postProcess($word[1]);
  2167.                 return;
  2168.             }
  2169.             if (is_array($word)) {
  2170.                 $this->_line .= $this->_converter->highlightSource($word[0],
  2171.                     $word[1]$preformatted);
  2172.             else {
  2173.                 $this->_line .= $this->_converter->highlightSource(false,
  2174.                     $word$preformatted);
  2175.             }
  2176.         }
  2177.     }
  2178.    
  2179.     /** 
  2180.      * Like {@link _output()}, but for DocBlock highlighting
  2181.      *
  2182.      * @param mixed $dbtype       the docblock type
  2183.      * @param mixed $word         the string|array tag token and value
  2184.      * @param bool  $preformatted whether or not the $word is already formatted
  2185.      *
  2186.      * @return void 
  2187.      */
  2188.     function _addDocBlockoutput($dbtype$word$preformatted false)
  2189.     {
  2190.         if ($this->_pf_internal{
  2191.             $this->_line .= $this->_converter->highlightDocBlockSource('internal',
  2192.                 $word$preformatted);
  2193.         else {
  2194.             $this->_line .= $this->_converter->highlightDocBlockSource($dbtype,
  2195.                 $word$preformatted);
  2196.         }
  2197.     }
  2198.    
  2199.     /**
  2200.      * Flush a saved string variable highlighting
  2201.      *
  2202.      * {@source } 
  2203.      *
  2204.      * @return void 
  2205.      * @todo CS cleanup - rename to _flushSave() for camelCase rule
  2206.      */
  2207.     function _flush_save()
  2208.     {
  2209.         if (!empty($this->_save)) {
  2210.             $this->_save .= $this->_converter->flushHighlightCache();
  2211.             // clear the existing cache, reset it to the old value
  2212.             if (isset($this->_save_highlight_state)) {
  2213.                 $this->_converter->
  2214.                     _setHighlightCache($this->_save_highlight_state[0],
  2215.                          $this->_save_highlight_state[1]);
  2216.             }
  2217.             $this->_line .= $this->_converter->
  2218.                 highlightSource(T_CONSTANT_ENCAPSED_STRING$this->_savetrue);
  2219.             $this->_save  '';
  2220.         }
  2221.     }
  2222.     /**#@-*/
  2223.    
  2224.     /**
  2225.      * Give the word parser necessary data to begin a new parse
  2226.      *
  2227.      * @param array &$data all tokens separated by line number
  2228.      *
  2229.      * @return void 
  2230.      */
  2231.     function configWordParser(&$data)
  2232.     {
  2233.         $this->_wp->setup($data$this);
  2234.         $this->_wp->setWhitespace(true);
  2235.     }
  2236.  
  2237.     /**
  2238.      * Initialize all parser state variables
  2239.      *
  2240.      * @param bool         $inlinesourceparse true if we are highlighting an inline
  2241.      *                                         {@}source} tag's output
  2242.      * @param false|string$class             name of class we are going
  2243.      *                                         to start from
  2244.      *
  2245.      * @return void 
  2246.      * @uses $_wp sets to a new {@link phpDocumentor_HighlightWordParser}
  2247.      */
  2248.     function setupStates($inlinesourceparse$class)
  2249.     {
  2250.         $this->_output '';
  2251.         $this->_line   '';
  2252.         unset($this->_wp);
  2253.         $this->_wp          new phpDocumentor_HighlightWordParser;
  2254.         $this->_event_stack new EventStack;
  2255.         if ($inlinesourceparse{
  2256.             $this->_event_stack->pushEvent(PARSER_EVENT_PHPCODE);
  2257.             if ($class{
  2258.                 $this->_event_stack->pushEvent(PARSER_EVENT_CLASS);
  2259.                 $this->_pv_class $class;
  2260.             }
  2261.         else {
  2262.             $this->_pv_class null;
  2263.         }
  2264.  
  2265.         $this->_pv_define              null;
  2266.         $this->_pv_define_name         null;
  2267.         $this->_pv_define_value        null;
  2268.         $this->_pv_define_params_data  null;
  2269.         $this->_pv_dtype               null;
  2270.         $this->_pv_docblock            null;
  2271.         $this->_pv_dtemplate           null;
  2272.         $this->_pv_func                null;
  2273.         $this->_pv_global_name         null;
  2274.         $this->_pv_global_val          null;
  2275.         $this->_pv_globals             null;
  2276.         $this->_pv_global_count        null;
  2277.         $this->_pv_include_params_data null;
  2278.         $this->_pv_include_name        null;
  2279.         $this->_pv_include_value       null;
  2280.         $this->_pv_linenum             null;
  2281.         $this->_pv_periodline          null;
  2282.         $this->_pv_paren_count         0;
  2283.         $this->_pv_statics             null;
  2284.         $this->_pv_static_count        null;
  2285.         $this->_pv_static_val          null;
  2286.         $this->_pv_quote_data          null;
  2287.         $this->_pv_function_data       null;
  2288.         $this->_pv_var                 null;
  2289.         $this->_pv_varname             null;
  2290.         $this->_pf_definename_isset    false;
  2291.         $this->_pf_extends_found       false;
  2292.         $this->_pf_includename_isset   false;
  2293.         $this->_pf_get_source          false;
  2294.         $this->_pf_getting_source      false;
  2295.         $this->_pf_in_class            false;
  2296.         $this->_pf_in_define           false;
  2297.         $this->_pf_in_global           false;
  2298.         $this->_pf_in_include          false;
  2299.         $this->_pf_in_var              false;
  2300.         $this->_pf_funcparam_val       false;
  2301.         $this->_pf_quote_active        false;
  2302.         $this->_pf_reset_quote_data    true;
  2303.         $this->_pf_useperiod           false;
  2304.         $this->_pf_var_equals          false;
  2305.         $this->_pf_obj_op              false;
  2306.         $this->_pf_docblock            false;
  2307.         $this->_pf_docblock_template   false;
  2308.         $this->_pf_colon_colon         false;
  2309.         $this->_pv_last_string         false;
  2310.         $this->_pf_inmethod            false;
  2311.         $this->_pf_no_output_yet       false;
  2312.         $this->_pv_saveline            0;
  2313.         $this->_pv_next_word           false;
  2314.         $this->_save                   '';
  2315.     }
  2316.  
  2317.     /**
  2318.      * Initialize the {@link $tokenpushEvent, $wordpushEvent} arrays
  2319.      *
  2320.      * @return void 
  2321.      */
  2322.     function phpDocumentor_HighlightParser()
  2323.     {
  2324.         if (!defined('T_INTERFACE')) {
  2325.             define('T_INTERFACE'-1);
  2326.         }
  2327.         $this->allowableTags
  2328.             = $GLOBALS['_phpDocumentor_tags_allowed'];
  2329.         $this->allowableInlineTags
  2330.             = $GLOBALS['_phpDocumentor_inline_doc_tags_allowed'];
  2331.         $this->inlineTagHandlers
  2332.             = array('*' => 'handleDefaultInlineTag');
  2333.         /**************************************************************/
  2334.  
  2335.         $this->tokenpushEvent[PARSER_EVENT_NOEVENTS
  2336.             array(
  2337.                 T_OPEN_TAG => PARSER_EVENT_PHPCODE,
  2338.             );
  2339.  
  2340.         /**************************************************************/
  2341.  
  2342.         $this->tokenpushEvent[PARSER_EVENT_PHPCODE
  2343.             array(
  2344.                 T_FUNCTION      => PARSER_EVENT_FUNCTION,
  2345.                 T_CLASS         => PARSER_EVENT_CLASS,
  2346.                 T_INTERFACE     => PARSER_EVENT_CLASS,
  2347.                 T_INCLUDE_ONCE  => PARSER_EVENT_INCLUDE,
  2348.                 T_INCLUDE       => PARSER_EVENT_INCLUDE,
  2349.                 T_START_HEREDOC => PARSER_EVENT_EOFQUOTE,
  2350.                 T_REQUIRE       => PARSER_EVENT_INCLUDE,
  2351.                 T_REQUIRE_ONCE  => PARSER_EVENT_INCLUDE,
  2352.                 T_COMMENT       => PARSER_EVENT_COMMENT,
  2353.                 T_DOC_COMMENT   => PARSER_EVENT_DOCBLOCK,
  2354.             );
  2355.         $this->wordpushEvent[PARSER_EVENT_PHPCODE=
  2356.             array(
  2357.                 "define" => PARSER_EVENT_DEFINE,
  2358.                 '"'      => PARSER_EVENT_QUOTE,
  2359.                 '\''     => PARSER_EVENT_QUOTE,
  2360.             );
  2361.         /**************************************************************/
  2362.  
  2363.         $this->wordpushEvent[PARSER_EVENT_FUNCTION=
  2364.             array(
  2365.                 '{' => PARSER_EVENT_LOGICBLOCK,
  2366.                 '(' => PARSER_EVENT_FUNCTION_PARAMS,
  2367.             );
  2368.         $this->tokenpushEvent[PARSER_EVENT_FUNCTION=
  2369.             array(
  2370.                 T_COMMENT     => PARSER_EVENT_COMMENT,
  2371.                 T_DOC_COMMENT => PARSER_EVENT_DOCBLOCK,
  2372.             );
  2373.         $this->wordpopEvent[PARSER_EVENT_FUNCTION]   array("}");
  2374.         /**************************************************************/
  2375.  
  2376.         $this->tokenpopEvent[PARSER_EVENT_EOFQUOTEarray(T_END_HEREDOC);
  2377.         /**************************************************************/
  2378.  
  2379.         $this->tokenpushEvent[PARSER_EVENT_FUNCTION_PARAMS=
  2380.             array(
  2381.                 T_CONSTANT_ENCAPSED_STRING => PARSER_EVENT_QUOTE,
  2382.                 T_ARRAY                    => PARSER_EVENT_ARRAY,
  2383.                 T_COMMENT                  => PARSER_EVENT_COMMENT,
  2384.                 T_DOC_COMMENT              => PARSER_EVENT_DOCBLOCK,
  2385.             );
  2386.         $this->wordpushEvent[PARSER_EVENT_FUNCTION_PARAMS=
  2387.             array(
  2388.                 '"' => PARSER_EVENT_QUOTE,
  2389.                 "'" => PARSER_EVENT_QUOTE,
  2390.             );
  2391.         $this->wordpopEvent[PARSER_EVENT_FUNCTION_PARAMS]   array(")");
  2392.         /**************************************************************/
  2393.  
  2394.         $this->wordpushEvent[PARSER_EVENT_LOGICBLOCK
  2395.             array(
  2396.                 "{" => PARSER_EVENT_LOGICBLOCK,
  2397.                 '"' => PARSER_EVENT_QUOTE,
  2398.             );
  2399.         $this->tokenpushEvent[PARSER_EVENT_LOGICBLOCK=
  2400.             array(
  2401.                 T_GLOBAL                   => PARSER_EVENT_FUNC_GLOBAL,
  2402.                 T_STATIC                   => PARSER_EVENT_STATIC_VAR,
  2403.                 T_START_HEREDOC            => PARSER_EVENT_EOFQUOTE,
  2404.                 T_CURLY_OPEN               => PARSER_EVENT_LOGICBLOCK,
  2405.                 T_DOLLAR_OPEN_CURLY_BRACES => PARSER_EVENT_LOGICBLOCK,
  2406.             );
  2407.         $this->wordpopEvent[PARSER_EVENT_LOGICBLOCK]   array("}");
  2408.         $this->tokenpopEvent[PARSER_EVENT_LOGICBLOCKarray(T_CURLY_OPEN);
  2409.  
  2410.         /**************************************************************/
  2411.  
  2412.         $this->tokenpushEvent[PARSER_EVENT_ARRAY
  2413.             array(
  2414.                 T_COMMENT     => PARSER_EVENT_COMMENT,
  2415.                 T_DOC_COMMENT => PARSER_EVENT_DOCBLOCK,
  2416.             );
  2417.         $this->wordpopEvent[PARSER_EVENT_ARRAY]   array(")");
  2418.         /**************************************************************/
  2419.  
  2420.         $this->tokenpushEvent[PARSER_EVENT_FUNC_GLOBAL=
  2421.             array(
  2422.                 T_COMMENT     => PARSER_EVENT_COMMENT,
  2423.                 T_DOC_COMMENT => PARSER_EVENT_DOCBLOCK,
  2424.             );
  2425.         $this->wordpopEvent[PARSER_EVENT_FUNC_GLOBAL]   array(";");
  2426.         /**************************************************************/
  2427.  
  2428.         $this->tokenpushEvent[PARSER_EVENT_STATIC_VAR=
  2429.             array(
  2430.                 T_CONSTANT_ENCAPSED_STRING => PARSER_EVENT_QUOTE,
  2431.                 T_COMMENT                  => PARSER_EVENT_COMMENT,
  2432.                 T_DOC_COMMENT              => PARSER_EVENT_DOCBLOCK,
  2433.             );
  2434.         $this->wordpushEvent[PARSER_EVENT_STATIC_VAR=
  2435.             array(
  2436.                 "=" => PARSER_EVENT_STATIC_VAR_VALUE,
  2437.             );
  2438.         $this->wordpopEvent[PARSER_EVENT_STATIC_VAR]   array(";");
  2439.         /**************************************************************/
  2440.  
  2441.         $this->tokenpushEvent[PARSER_EVENT_STATIC_VAR_VALUE
  2442.             array(
  2443.                 T_CONSTANT_ENCAPSED_STRING => PARSER_EVENT_QUOTE,
  2444.                 T_COMMENT                  => PARSER_EVENT_COMMENT,
  2445.                 T_DOC_COMMENT              => PARSER_EVENT_DOCBLOCK,
  2446.                 T_ARRAY                    => PARSER_EVENT_ARRAY,
  2447.             );
  2448.         $this->wordpushEvent[PARSER_EVENT_STATIC_VAR_VALUE=
  2449.             array(
  2450.                 '"' => PARSER_EVENT_QUOTE,
  2451.                 "'" => PARSER_EVENT_QUOTE,
  2452.             );
  2453.         $this->wordpopEvent[PARSER_EVENT_STATIC_VAR_VALUE]   array(";"",");
  2454.         /**************************************************************/
  2455.         $this->tokenpushEvent[PARSER_EVENT_QUOTE
  2456.             array(
  2457.                 T_OBJECT_OPERATOR => PARSER_EVENT_CLASS_MEMBER,
  2458.                 T_CURLY_OPEN      => PARSER_EVENT_QUOTE_VAR,
  2459.             );
  2460.         $this->wordpopEvent[PARSER_EVENT_QUOTE]   array('"');
  2461.         /**************************************************************/
  2462.         $this->tokenpushEvent[PARSER_EVENT_QUOTE_VAR
  2463.             array(
  2464.                 T_OBJECT_OPERATOR => PARSER_EVENT_CLASS_MEMBER,
  2465.                 T_CURLY_OPEN      => PARSER_EVENT_QUOTE_VAR,
  2466.             );
  2467.         $this->wordpushEvent[PARSER_EVENT_QUOTE_VAR=
  2468.             array(
  2469.                 "{" => PARSER_EVENT_QUOTE_VAR,
  2470.                 '"' => PARSER_EVENT_QUOTE_VAR,
  2471.                 "'" => PARSER_EVENT_QUOTE_VAR,
  2472.             );
  2473.         $this->wordpopEvent[PARSER_EVENT_QUOTE_VAR]   array('}');
  2474.         /**************************************************************/
  2475.  
  2476.         $this->tokenpushEvent[PARSER_EVENT_DEFINE
  2477.             array(
  2478.                 T_COMMENT                  => PARSER_EVENT_COMMENT,
  2479.                 T_DOC_COMMENT              => PARSER_EVENT_DOCBLOCK,
  2480.                 T_CONSTANT_ENCAPSED_STRING => PARSER_EVENT_QUOTE,
  2481.             );
  2482.         $this->wordpushEvent[PARSER_EVENT_DEFINE
  2483.             array(
  2484.                 "(" => PARSER_EVENT_DEFINE_PARAMS,
  2485.             );
  2486.         $this->wordpopEvent[PARSER_EVENT_DEFINE]   array(";");
  2487.         /**************************************************************/
  2488.  
  2489.         $this->tokenpushEvent[PARSER_EVENT_DEFINE_PARAMS
  2490.             array(
  2491.                 T_COMMENT     => PARSER_EVENT_COMMENT,
  2492.                 T_DOC_COMMENT => PARSER_EVENT_DOCBLOCK,
  2493.             );
  2494.         $this->wordpushEvent[PARSER_EVENT_DEFINE_PARAMS
  2495.             array(
  2496.                 "(" => PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS,
  2497.                 '"' => PARSER_EVENT_QUOTE,
  2498.                 "'" => PARSER_EVENT_QUOTE,
  2499.             );
  2500.         $this->wordpopEvent[PARSER_EVENT_DEFINE_PARAMS]   array(")");
  2501.         /**************************************************************/
  2502.  
  2503.         $this->tokenpushEvent[PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS=
  2504.             array(
  2505.                 T_COMMENT     => PARSER_EVENT_COMMENT,
  2506.                 T_DOC_COMMENT => PARSER_EVENT_DOCBLOCK,
  2507.             );
  2508.         $this->wordpushEvent[PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS=
  2509.             array(
  2510.                 "(" => PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS,
  2511.                 '"' => PARSER_EVENT_QUOTE,
  2512.                 "'" => PARSER_EVENT_QUOTE,
  2513.             );
  2514.         $this->wordpopEvent[PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS]   array(")");
  2515.         /**************************************************************/
  2516.  
  2517.         $this->tokenpushEvent[PARSER_EVENT_VAR
  2518.             array(
  2519.                 T_COMMENT     => PARSER_EVENT_COMMENT,
  2520.                 T_DOC_COMMENT => PARSER_EVENT_DOCBLOCK,
  2521.                 T_ARRAY       => PARSER_EVENT_ARRAY,
  2522.             );
  2523.         $this->wordpopEvent[PARSER_EVENT_VAR]   array(";");
  2524.         /**************************************************************/
  2525.  
  2526.         $this->tokenpushEvent[PARSER_EVENT_CLASS
  2527.             array(
  2528.                 T_FUNCTION    => PARSER_EVENT_METHOD,
  2529.                 T_VAR         => PARSER_EVENT_VAR,
  2530.                 T_COMMENT     => PARSER_EVENT_DOCBLOCK,
  2531.                 T_DOC_COMMENT => PARSER_EVENT_DOCBLOCK,
  2532.                 T_CLOSE_TAG   => PARSER_EVENT_OUTPHP,
  2533.             );
  2534.         $this->wordpopEvent[PARSER_EVENT_CLASS]   array("}");
  2535.         /**************************************************************/
  2536.  
  2537.         $this->wordpushEvent[PARSER_EVENT_METHOD=
  2538.             array(
  2539.                 '{' => PARSER_EVENT_METHOD_LOGICBLOCK,
  2540.                 '(' => PARSER_EVENT_FUNCTION_PARAMS,
  2541.             );
  2542.         $this->tokenpushEvent[PARSER_EVENT_METHOD=
  2543.             array(
  2544.                 T_COMMENT     => PARSER_EVENT_COMMENT,
  2545.                 T_DOC_COMMENT => PARSER_EVENT_DOCBLOCK,
  2546.             );
  2547.         $this->wordpopEvent[PARSER_EVENT_METHOD]   array("}"";");
  2548.         /**************************************************************/
  2549.  
  2550.         $this->wordpushEvent[PARSER_EVENT_METHOD_LOGICBLOCK
  2551.             array(
  2552.                 "{" => PARSER_EVENT_METHOD_LOGICBLOCK,
  2553.                 '"' => PARSER_EVENT_QUOTE,
  2554.             );
  2555.         $this->tokenpushEvent[PARSER_EVENT_METHOD_LOGICBLOCK=
  2556.             array(
  2557.                 T_OBJECT_OPERATOR          => PARSER_EVENT_CLASS_MEMBER,
  2558.                 T_GLOBAL                   => PARSER_EVENT_FUNC_GLOBAL,
  2559.                 T_STATIC                   => PARSER_EVENT_STATIC_VAR,
  2560.                 T_CURLY_OPEN               => PARSER_EVENT_LOGICBLOCK,
  2561.                 T_DOLLAR_OPEN_CURLY_BRACES => PARSER_EVENT_LOGICBLOCK,
  2562.             );
  2563.         $this->wordpopEvent[PARSER_EVENT_METHOD_LOGICBLOCK]   array("}");
  2564.         $this->tokenpopEvent[PARSER_EVENT_METHOD_LOGICBLOCKarray(T_CURLY_OPEN);
  2565.         /**************************************************************/
  2566.  
  2567.         $this->tokenpushEvent[PARSER_EVENT_INCLUDE
  2568.             array(
  2569.                 T_COMMENT     => PARSER_EVENT_COMMENT,
  2570.                 T_DOC_COMMENT => PARSER_EVENT_DOCBLOCK,
  2571.             );
  2572.         $this->wordpushEvent[PARSER_EVENT_INCLUDE
  2573.             array(
  2574.                 "(" => PARSER_EVENT_INCLUDE_PARAMS,
  2575.             );
  2576.         $this->wordpopEvent[PARSER_EVENT_INCLUDE]   array(";");
  2577.         /**************************************************************/
  2578.  
  2579.         $this->tokenpushEvent[PARSER_EVENT_INCLUDE_PARAMS
  2580.             array(
  2581.                 T_COMMENT     => PARSER_EVENT_COMMENT,
  2582.                 T_DOC_COMMENT => PARSER_EVENT_DOCBLOCK,
  2583.             );
  2584.         $this->wordpushEvent[PARSER_EVENT_INCLUDE_PARAMS
  2585.             array(
  2586.                 "(" => PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS,
  2587.             );
  2588.         $this->wordpopEvent[PARSER_EVENT_INCLUDE_PARAMS]   array(")");
  2589.         /**************************************************************/
  2590.  
  2591.         $this->tokenpushEvent[PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS=
  2592.             array(
  2593.                 T_COMMENT     => PARSER_EVENT_COMMENT,
  2594.                 T_DOC_COMMENT => PARSER_EVENT_DOCBLOCK,
  2595.             );
  2596.         $this->wordpushEvent[PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS=
  2597.             array(
  2598.                 "(" => PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS,
  2599.             );
  2600.         $this->wordpopEvent[PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS]   array(")");
  2601.     }
  2602. }
  2603. ?>
    Поддержать сайт на родительском проекте КГБ