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

Source for file Parser.inc

Documentation is available at Parser.inc

  1. <?php
  2. /**
  3.  * Base parser for all parsers
  4.  * 
  5.  * phpDocumentor :: automatic documentation generator
  6.  * 
  7.  * PHP versions 4 and 5
  8.  *
  9.  * Copyright (c) 2000-2006 Joshua Eichorn, Gregory Beaver
  10.  * 
  11.  * LICENSE:
  12.  * 
  13.  * This library is free software; you can redistribute it
  14.  * and/or modify it under the terms of the GNU Lesser General
  15.  * Public License as published by the Free Software Foundation;
  16.  * either version 2.1 of the License, or (at your option) any
  17.  * later version.
  18.  * 
  19.  * This library is distributed in the hope that it will be useful,
  20.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  22.  * Lesser General Public License for more details.
  23.  * 
  24.  * You should have received a copy of the GNU Lesser General Public
  25.  * License along with this library; if not, write to the Free Software
  26.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  27.  *
  28.  * @package    phpDocumentor
  29.  * @subpackage Parsers
  30.  * @author     Joshua Eichorn <[email protected]>
  31.  * @author     Gregory Beaver <[email protected]>
  32.  * @copyright  2000-2006 Joshua Eichorn, Gregory Beaver
  33.  * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL
  34.  * @version    CVS: $Id: Parser.inc,v 1.6 2006/08/17 03:23:26 cellog Exp $
  35.  * @link       http://www.phpdoc.org
  36.  * @link       http://pear.php.net/PhpDocumentor
  37.  * @since      0.1
  38.  */
  39. /** used when a backslash is encountered in parsing a string or other escapable entity */ 
  40. define("PARSER_EVENT_ESCAPE"        ,    900);
  41. /** used when a backslash is encountered in parsing a string or other escapable entity */ 
  42. define("STATE_ESCAPE"            ,    1000);
  43.  
  44. /** Class published to IntermediateParser with this event */
  45. define("PHPDOCUMENTOR_EVENT_CLASS"        ,    800);
  46. /** DocBlock published to IntermediateParser with this event */
  47. define("PHPDOCUMENTOR_EVENT_DOCBLOCK"        ,    801);
  48. /** Function published to IntermediateParser with this event */
  49. define("PHPDOCUMENTOR_EVENT_FUNCTION"        ,    802);
  50. /** Class Variable published to IntermediateParser with this event */
  51. define("PHPDOCUMENTOR_EVENT_VAR"        ,    803);
  52. /** New File (page) published to IntermediateParser with this event */
  53. define("PHPDOCUMENTOR_EVENT_PAGE"        ,    804);
  54. /** Constant (define) published to IntermediateParser with this event */
  55. define("PHPDOCUMENTOR_EVENT_DEFINE"        ,    805);
  56. /** Class Constant published to IntermediateParser with this event */
  57. define("PHPDOCUMENTOR_EVENT_CONST"        ,    806);
  58. /** @deprecated */
  59. define("PHPDOCUMENTOR_EVENT_MESSAGE"        ,    807);
  60. /** use to inform IntermediateParser of a new element being parsed */
  61. define("PHPDOCUMENTOR_EVENT_NEWSTATE"        ,    808);
  62. /**
  63.  * used to inform phpDocumentor_IntermediateParser that the current file has been completely parsed.
  64.  * Render then flushes all buffers for functions/classes/defines/includes on the current page
  65.  * @see phpDocumentor_IntermediateParser::HandleEvent()
  66.  */
  67. define("PHPDOCUMENTOR_EVENT_END_PAGE"        ,    808);
  68. /** Package-level page published to IntermediateParser with this event */
  69. define("PHPDOCUMENTOR_EVENT_PACKAGEPAGE"        ,    809);
  70. /** Include (include/require/include_once/include_once) published to IntermediateParser with this event */
  71. define("PHPDOCUMENTOR_EVENT_INCLUDE"        ,    810);
  72. /** Tutorial published to IntermediateParser with this event */
  73. define("PHPDOCUMENTOR_EVENT_TUTORIAL"        ,    811);
  74. /** Contents of README/INSTALL/CHANGELOG files published to IntermediateParser with this event */
  75. define("PHPDOCUMENTOR_EVENT_README_INSTALL_CHANGELOG"        ,    812);
  76.  
  77. /** use to inform ErrorTracker of a new file being parsed */
  78. define("PHPDOCUMENTOR_EVENT_NEWFILE"    ,    811);
  79. /** use to inform ErrorTracker of the next line number being parsed */
  80. define("PHPDOCUMENTOR_EVENT_NEWLINENUM"    ,    812);
  81. /** used when a global variable definition is encountered in the source */
  82. define("PHPDOCUMENTOR_EVENT_GLOBAL"    ,    813);
  83. /** used when a docblock template is encountered in the source */
  84. define("PHPDOCUMENTOR_EVENT_DOCBLOCK_TEMPLATE"    ,    814);
  85. /** used when a docblock template is encountered in the source */
  86. define("PHPDOCUMENTOR_EVENT_END_DOCBLOCK_TEMPLATE"    ,    815);
  87. /** used when double quotation mark (") encountered in parsing */
  88. define("PARSER_EVENT_QUOTE"        ,    101);
  89. /** currently parsing a quote */
  90. define("STATE_QUOTE"            ,    201);
  91.  
  92. /** { encountered in parsing a function or php code */
  93. define("PARSER_EVENT_LOGICBLOCK"    ,    102);
  94. /** currently parsing a { } block */
  95. define("STATE_LOGICBLOCK"        ,    202);
  96.  
  97. /** used for the beginning of parsing, before first < ? php encountered */
  98. define("PARSER_EVENT_NOEVENTS"        ,    103);
  99. /** out of < ? php tag */
  100. define("STATE_NOEVENTS"            ,    203);
  101.  
  102. /** used when long comment /x x/ where x is an asterisk is encountered in parsing */
  103. define("PARSER_EVENT_COMMENTBLOCK"    ,    104);
  104. /** currently parsing a long comment /x x/ where x is an asterisk */
  105. define("STATE_COMMENTBLOCK"        ,    204);
  106.  
  107. /** used when short comment // is encountered in parsing */
  108. define("PARSER_EVENT_COMMENT"        ,    105);
  109. /** currently parsing a short comment // */
  110. define("STATE_COMMENT"            ,    205);
  111.  
  112. /** used when php code processor instruction (< ? php) is encountered in parsing */
  113. define("PARSER_EVENT_PHPCODE"        ,    106);
  114. /** currently parsing php code */
  115. define("STATE_PHPCODE"            ,    206);
  116.  
  117. /** used when a define statement is encountered in parsing */
  118. define("PARSER_EVENT_DEFINE"        ,    107);
  119. /** currently parsing a define statement */
  120. define("STATE_DEFINE"            ,    207);
  121.  
  122. /** used when a define statement opening parenthesis is encountered in parsing */
  123. define("PARSER_EVENT_DEFINE_PARAMS"    ,    108);
  124. /** currently parsing the stuff in ( ) of a define statement */
  125. define("STATE_DEFINE_PARAMS"        ,    208);
  126.  
  127. /** used when a function statement opening parenthesis is encountered in parsing */
  128. define("PARSER_EVENT_FUNCTION_PARAMS"    ,    109);
  129. /** currently parsing the stuff in ( ) of a function definition */
  130. define("STATE_FUNCTION_PARAMS"        ,    209);
  131.  
  132. /** used when a single quote (') is encountered in parsing */
  133. define("PARSER_EVENT_SINGLEQUOTE"    ,    110);
  134. /** currently parsing a string enclosed in single quotes (') */
  135. define("STATE_SINGLEQUOTE"        ,    210);
  136.  
  137. /** used when a class definition is encountered in parsing */
  138. define("PARSER_EVENT_CLASS"        ,    111);
  139. /** currently parsing a class definition */
  140. define("STATE_CLASS"            ,    211);
  141. /** used to tell Render that a class has been completely parsed, and to flush buffers */
  142. define("STATE_END_CLASS"        ,    311);
  143.  
  144. /** used when a DocBlock is encountered in parsing */
  145. define("PARSER_EVENT_DOCBLOCK"        ,    112);
  146. /** currently parsing a DocBlock */
  147. define("STATE_DOCBLOCK"            ,    212);
  148.  
  149. /** used when a @tag is encountered in DocBlock parsing */
  150. define("PARSER_EVENT_DOCKEYWORD"    ,    113);
  151. /** currently parsing a @tag in a DocBlock */
  152. define("STATE_DOCKEYWORD"        ,    213);
  153.  
  154. /** used when a <[email protected]> is encountered in parsing an @author tag*/
  155. define("PARSER_EVENT_DOCKEYWORD_EMAIL"    ,    114);
  156. /** currently parsing an email in brackets in an @author tag of a DocBlock */
  157. define("STATE_DOCKEYWORD_EMAIL"        ,    214);
  158.  
  159. /** used when an array definition is encountered in parsing */
  160. define("PARSER_EVENT_ARRAY"        ,    115);
  161. /** currently parsing an array */
  162. define("STATE_ARRAY"            ,    215);
  163.  
  164. /** used when a var statement is encountered in parsing a class definition */
  165. define("PARSER_EVENT_VAR"        ,    116);
  166. /** currently parsing a Class variable */
  167. define("STATE_VAR"            ,    216);
  168.  
  169. /** used when a function definition is encountered in parsing */
  170. define("PARSER_EVENT_FUNCTION"        ,    117);
  171. /** currently parsing a Function or Method */
  172. define("STATE_FUNCTION"            ,    217);
  173.  
  174. /** used when a ? > (with no space) is encountered in parsing */
  175. define("PARSER_EVENT_OUTPHP"        ,    118);
  176. /** currently out of php code */
  177. define("STATE_OUTPHP"            ,    218);
  178.  
  179. /** used when an inline {@tag} is encountered in parsing a DocBlock */
  180. define("PARSER_EVENT_INLINE_DOCKEYWORD"    ,    119);
  181. /** currently parsing an inline tag like { @link} in a DocBlock */
  182. define("STATE_INLINE_DOCKEYWORD"        ,    219);
  183.  
  184. /** used when a define statement's opening parenthesis is encountered in parsing */
  185. define("PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS"    ,    120);
  186. /** currently parsing an inner parenthetical statement of a define( ) */
  187. define("STATE_DEFINE_PARAMS_PARENTHESIS"        ,    220);
  188.  
  189. define("PARSER_EVENT_END_STATEMENT",    121);
  190.  
  191. /** used when a <<< is encountered in parsing */
  192. define("PARSER_EVENT_EOFQUOTE"    ,    122);
  193. /** currently parsing a string defined using Perl <<< */
  194. define("STATE_EOFQUOTE"        ,    222);
  195.  
  196. /** used when an include/require/include_once/include_once statement is encountered in parsing */
  197. define("PARSER_EVENT_INCLUDE"    ,    123);
  198. /** currently parsing an include/require/include_once/include_once */
  199. define("STATE_INCLUDE"    ,    223);
  200.  
  201. /** used when an opening parenthesis of an include/require/include_once/include_once statement is encountered in parsing */
  202. define("PARSER_EVENT_INCLUDE_PARAMS"    ,    124);
  203. /** currently parsing the stuff in ( ) of a define statement */
  204. define("STATE_INCLUDE_PARAMS"    ,    224);
  205.  
  206. /** used when an inner ( ) is encountered while parsing an include/require/include_once/include_once statement */
  207. define("PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS"    ,    125);
  208. /** currently parsing an inner parenthetical statement of an include/includeonce/require/requireonce( ) */
  209. define("STATE_INCLUDE_PARAMS_PARENTHESIS"    ,    225);
  210.  
  211. /** used when parsing the desc part of a docblock */
  212. define("PARSER_EVENT_DESC"    ,    126);
  213. /** currently parsing the desc part of a docblock */
  214. define("STATE_DESC"    ,    226);
  215.  
  216. /** used when parsing the @tag block of a docblock */
  217. define("PARSER_EVENT_TAGS"    ,    127);
  218. /** currently parsing the @tag block of a docblock */
  219. define("STATE_TAGS"    ,    227);
  220.  
  221. /** used when parsing a global variable declaration */
  222. define("PARSER_EVENT_DEFINE_GLOBAL"    ,    128);
  223. /** currently parsing a global variable declaration */
  224. define("STATE_GLOBAL"    ,    228);
  225.  
  226. /** used when parsing the default value in a global variable declaration */
  227. define("PARSER_EVENT_GLOBAL_VALUE"    ,    129);
  228. /** currently parsing the default value in a global variable declaration */
  229. define("STATE_GLOBAL_VALUE"    ,    229);
  230.  
  231. /** used when parsing a "global $var1, $var2;" declaration in a function */
  232. define("PARSER_EVENT_FUNC_GLOBAL"    ,    130);
  233. /** currently parsing a "global $var1, $var2;" declaration in a function */
  234. define("STATE_FUNC_GLOBAL"    ,    230);
  235.  
  236. /** used when parsing a "static $var1, $var2;" declaration in a function */
  237. define("PARSER_EVENT_STATIC_VAR"    ,    131);
  238. /** currently parsing a "static $var1, $var2;" declaration in a function */
  239. define("STATE_STATIC_VAR"    ,    231);
  240.  
  241. /** used when parsing the value in a "static $var1 = x" declaration in a function */
  242. define("PARSER_EVENT_STATIC_VAR_VALUE"    ,    132);
  243. /** currently parsing the value in a "static $var1 = x" declaration in a function */
  244. define("STATE_STATIC_VAR_VALUE"    ,    232);
  245.  
  246. /** used when encountering a /**#@+ comment marking a new docblock template */
  247. define("PARSER_EVENT_DOCBLOCK_TEMPLATE"    ,    133);
  248. /** currently parsing the value in a "static $var1 = x" declaration in a function */
  249. define("STATE_DOCBLOCK_TEMPLATE"    ,    233);
  250.  
  251. /** used when encountering a /**#@-* / comment (no space) marking the end of using a docblock template */
  252. define("PARSER_EVENT_END_DOCBLOCK_TEMPLATE"    ,    134);
  253. /** currently parsing the value in a "static $var1 = x" declaration in a function */
  254. define("STATE_END_DOCBLOCK_TEMPLATE"    ,    234);
  255.  
  256. /** used by the {@link HighlightParser} only, when a method starts */
  257. define("PARSER_EVENT_METHOD"    ,    135);
  258. /** currently parsing a method using the {@link HighlightParser} */
  259. define("STATE_METHOD"    ,    235);
  260.  
  261. /** used by the {@link HighlightParser} only, when a method body is parsed */
  262. define("PARSER_EVENT_METHOD_LOGICBLOCK"    ,    136);
  263. /** currently parsing the method body using the {@link HighlightParser} */
  264. define("STATE_METHOD_LOGICBLOCK"    ,    236);
  265.  
  266. /** used by the {@link HighlightParser} only, when ->var or ->function() is encountered in a method */
  267. define("PARSER_EVENT_CLASS_MEMBER"    ,    137);
  268. /** currently parsing a class member using the {@link HighlightParser} */
  269. define("STATE_CLASS_MEMBER"    ,    237);
  270.  
  271. /** used by the {@link HighlightParser} only, when {$var  is encountered in a string */
  272. define("PARSER_EVENT_QUOTE_VAR"    ,    138);
  273. /** currently parsing a {$encapsed_var} using the {@link HighlightParser} */
  274. define("STATE_QUOTE_VAR"    ,    238);
  275.  
  276. /** used when parsing an access modifier */
  277. define("PARSER_EVENT_ACCESS_MODIFIER"    ,    139);
  278. /** currently parsing an access modifier */
  279. define("STATE_ACCESS_MODIFIER"    ,    239);
  280.  
  281. /** used when a class implements interfaces */
  282. define("PARSER_EVENT_IMPLEMENTS"    ,    140);
  283. /** currently parsing an implements clause */
  284. define("STATE_IMPLEMENTS"    ,    240);
  285.  
  286. /** used when a class implements interfaces */
  287. define("PARSER_EVENT_CLASS_CONSTANT"    ,    141);
  288. /** currently parsing a class constant */
  289. define("STATE_CLASS_CONSTANT"    ,    241);
  290.  
  291. /** used when a variable value is an array */
  292. define("PARSER_EVENT_VAR_ARRAY"    ,    142);
  293. /** currently parsing a variable value is an array */
  294. define("STATE_VAR_ARRAY"    ,    242);
  295.  
  296. /** used when a comment is found in a variable array value */
  297. define("PARSER_EVENT_VAR_ARRAY_COMMENT"    ,    143);
  298. /** currently parsing a comment in a variable array value */
  299. define("STATE_VAR_ARRAY_COMMENT"    ,    243);
  300.  
  301. /** used when a $param is encountered in a function definition */
  302. define("PARSER_EVENT_FUNCTION_PARAM_VAR"144);
  303. /** currently parsing a $param in a function definition */
  304. define("STATE_FUNCTION_PARAM_VAR"244);
  305.  
  306. if (!defined('T_INTERFACE'))
  307. {
  308.     define('T_INTERFACE''foo');
  309.     if (!defined('T_CONST')) {
  310.         define('T_CONST''foo');
  311.     }
  312.     define('T_ABSTRACT''foo');
  313.     define('T_PRIVATE''foo');
  314.     define('T_PUBLIC''foo');
  315.     define('T_PROTECTED''foo');
  316.     define('T_FINAL''foo');
  317.     define('T_IMPLEMENTS''foo');
  318. }
  319. if (!defined('T_ML_COMMENT'))
  320. {
  321.     define('T_ML_COMMENT'T_COMMENT);
  322. }
  323. if (!defined('T_DOC_COMMENT'))
  324. {
  325.     define('T_DOC_COMMENT'T_ML_COMMENT);
  326. }
  327. /**
  328.  * PHP Parser for PHP 4.2.3-
  329.  *
  330.  * This parser is slower than the tokenizer-based parser, and is deprecated.
  331.  * @author    Joshua Eichorn <[email protected]>
  332.  * @author    Gregory Beaver <[email protected]>
  333.  * @version    $Id: Parser.inc,v 1.6 2006/08/17 03:23:26 cellog Exp $
  334.  * @package     phpDocumentor
  335.  * @subpackage Parsers
  336.  * @deprecated in favor of {@link phpDocumentorTParser}
  337.  */
  338. class Parser extends Publisher
  339. {
  340.     /**#@+
  341.      * @access private
  342.      */
  343.     /**
  344.      * Word parser
  345.      * @see WordParser
  346.      */
  347.     var $wp;
  348.     
  349.     /**
  350.      * temporary parser variables
  351.      */
  352.     var $p_vars array('func' => false'function_data' => '''quote_data' => '''event_stack' => false'last_pevent' => 0,
  353.                         'two_words_ago' => '''temp_word' => '''docblock' => false'line' => array()'linecount' => 0'startword' => '',
  354.                         'periodline' => 0'shortdesc' => '''docblock_desc' => '''class' => false'source_location' => '',
  355.                         'define_params_data' => '''define' => false'define_name' => '''define_value' => '''var' => false,
  356.                         'oldtoken' => false'comment_data' => '''function_param' => NULL'inline_dockeyword_type' => false,
  357.                         'inline_dockeyword_data' => false'dockeyword_type' => false'dockeyword_data' =>false'param_var' => false,
  358.                         'include_name' => '''include_value' => '','include' => false'return_type' => '''cur_class' => '',
  359.                         'function_data' => false'varname' => '''returntype' => false'vartype' => false'paramtype' => false,
  360.                         'tagname' => '''find_global' => '''global_type' => '''paramname' => false'statics' => array(),
  361.                         'static_count' => 0'static_val' => array()'docblock_type' => 'docblock''seelement' => false);
  362.     
  363.     /**
  364.      * parser flags, for states that don't warrant a new event (like new line in a docblock)
  365.      */
  366.     var $p_flags array('docblocknewline' => false'docblockintags' => false'useperiod' => false,
  367.                         'definename_isset' => false'define_parens' => false'reset_quote_data' => false,
  368.                         'in_desc' => true'in_tag' => false'newline' => true'tempnewline' => false,
  369.                         'start_docblock' => false'includename_isset' => false'return_isset' => false,
  370.                         'is_return' => false'in_class' => false'asterisk' => false'var_equals' => false,
  371.                         'arrayinvarname' => false'valid_newline' => true'startline' => false,
  372.                         'function_global' => false'define_global' => false'static_value' => false,'funcparam_val' => false,
  373.                         'get_source' => false'getting_source' => false);
  374.  
  375.     /**
  376.      * lookup table for event handler methods
  377.      * @see Parser::parse()
  378.      */
  379.     var $eventHandlers array(
  380.                                 'handleArray' => PARSER_EVENT_ARRAY,
  381.                                 'handleClass' => PARSER_EVENT_CLASS,
  382.                                 'handleComment' => PARSER_EVENT_COMMENT,
  383.                                 'handleDocBlockTemplate' => PARSER_EVENT_DOCBLOCK_TEMPLATE,
  384.                                 'handleEndDocBlockTemplate' => PARSER_EVENT_END_DOCBLOCK_TEMPLATE,
  385.                                 'handleEscape' => PARSER_EVENT_ESCAPE,
  386.                                 'handleLogicBlock' => PARSER_EVENT_LOGICBLOCK,
  387.                                 'defaultHandler' => PARSER_EVENT_NOEVENTS,
  388. //                                'defaultHandler' => PARSER_EVENT_COMMENTBLOCK, (set in constructor below)
  389. //                                'defaultHandler' => PARSER_EVENT_OUTPHP,
  390.                                                                 'handleDefine' => PARSER_EVENT_DEFINE,
  391.                                 'handleDefineParams' => PARSER_EVENT_DEFINE_PARAMS,
  392.                                 'handleDefineParamsParenthesis' => PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS,
  393.                                 'handleIncludeParamsParenthesis' => PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS,
  394. //                                'handleDocBlock' => PARSER_EVENT_DOCBLOCK,
  395.                                                                 'BetterhandleDocBlock' => PARSER_EVENT_DOCBLOCK,
  396.                                 'handleTags' => PARSER_EVENT_TAGS,
  397.                                 'handleDesc' => PARSER_EVENT_DESC,
  398. //                                'handleDockeyword' => PARSER_EVENT_DOCKEYWORD,
  399.                                                                 'handleTag' => PARSER_EVENT_DOCKEYWORD,
  400.                                 'handleDockeywordEmail' => PARSER_EVENT_DOCKEYWORD_EMAIL,
  401.                                 'handleEOFQuote' => PARSER_EVENT_EOFQUOTE,
  402.                                 'handleFunction' => PARSER_EVENT_FUNCTION,
  403.                                 'handleFunctionParams' => PARSER_EVENT_FUNCTION_PARAMS,
  404.                                 'handleFuncGlobal' => PARSER_EVENT_FUNC_GLOBAL,
  405.                                 'handleGlobal' => PARSER_EVENT_DEFINE_GLOBAL,
  406.                                 'handleGlobalValue' => PARSER_EVENT_GLOBAL_VALUE,
  407.                                 'handleInlineDockeyword' => PARSER_EVENT_INLINE_DOCKEYWORD,
  408.                                 'handleInclude' => PARSER_EVENT_INCLUDE,
  409.                                 'handleIncludeParams' => PARSER_EVENT_INCLUDE_PARAMS,
  410.                                 'handleQuote' => PARSER_EVENT_QUOTE,
  411.                                 'handlePhpCode' => PARSER_EVENT_PHPCODE,
  412.                                 'handleSingleQuote' => PARSER_EVENT_SINGLEQUOTE,
  413.                                 'handleStaticVar' => PARSER_EVENT_STATIC_VAR,
  414.                                 'handleStaticValue' => PARSER_EVENT_STATIC_VAR_VALUE,
  415.                                 'handleVar' => PARSER_EVENT_VAR,
  416.     );
  417.     
  418.     /**
  419.      * event handlers for @tags
  420.      * @tutorial tags.pkg
  421.      */
  422.     var $tagHandlers array(
  423.                                 '*' => 'defaultTagHandler',
  424.                                 'category' => 'categoryTagHandler',
  425.                                 'example' => 'exampleTagHandler',
  426.                                 'filesource' => 'invalidTagHandler',
  427.                                 'return' => 'returnTagHandler',
  428.                                 'returns' => 'returnTagHandler',
  429.                                 'var' => 'varTagHandler',
  430.                                 'package' => 'packageTagHandler',
  431.                                 'param' => 'paramTagHandler',
  432.                                 'parameter' => 'paramTagHandler',
  433.                                 'global' => 'globalTagHandler',
  434.                                 'staticvar' => 'staticvarTagHandler',
  435.                                 'uses' => 'usesTagHandler'
  436.                             );
  437.  
  438.     var $laststart false;
  439.  
  440.     /**
  441.      * An array of allowable @tags
  442.      */
  443.     var $allowableTags;
  444.  
  445.  
  446.     /**
  447.      * An array of allowed inline @tags
  448.      */
  449.     var $allowableInlineTags;
  450.     
  451.     /**
  452.      * Sets the states up, and creates a new WordParser
  453.      */
  454.     
  455.     /**
  456.      * an array of parsing tokens organized by event number.
  457.      * A token is defined as the smallest group of characters that separates or
  458.      * defines a new parser element.  In English, a space or punctuation are
  459.      * tokens that separate words.  in PHP, tokens may be //, or even "
  460.      * Format: array(eventnum =>array(token1, token2, token3, ...),...)
  461.      * @var array 
  462.      */
  463.     var $tokens;
  464.     
  465.     /**
  466.      * array of events that are raised, organized by the tokens that raise them.
  467.      * Format: array(eventnum => array(token => neweventnum, token2 => neweventnum2,...),...)
  468.      * @var array 
  469.      */
  470.     var $pushEvent;
  471.     
  472.     /**
  473.      * array of tokens that end an event, organized by event
  474.      * Format: array(eventnum => array(token => neweventnum, token2 => neweventnum2,...),...)
  475.      * @var array 
  476.      */
  477.     var $popEvent;
  478.     /**#@-*/
  479.     
  480.     /**
  481.      * Set up invariant parsing variables
  482.      */
  483.     function Parser()
  484.     {
  485.         $this->allowableTags $GLOBALS['_phpDocumentor_tags_allowed'];
  486.         $this->allowableInlineTags $GLOBALS['_phpDocumentor_inline_doc_tags_allowed'];
  487.         $this->wp new WordParser;
  488.         // strange PHP 4.0.6 behavior: it converts constants to strings without warning if it's an array index
  489.         $this->eventHandlers array_flip($this->eventHandlers);
  490.         $this->eventHandlers[PARSER_EVENT_COMMENTBLOCK'defaultHandler';
  491.         $this->eventHandlers[PARSER_EVENT_OUTPHP'defaultHandler';
  492.         $this->subscribe(PHPDOCUMENTOR_EVENT_NEWLINENUM,$GLOBALS['phpDocumentor_errors']);
  493.         $this->subscribe(PHPDOCUMENTOR_EVENT_NEWFILE,$GLOBALS['phpDocumentor_errors']);
  494.     }
  495.  
  496.     /**
  497.      * Parse a new file
  498.      *
  499.      * @param    string    $parse_data 
  500.      * @param    string    $path 
  501.      * @param    int    $base    number of directories to drop off the bottom when creating names using path
  502.      * @staticvar    integer    used for recursion limiting if a handler for an event is not found
  503.      * @return    bool 
  504.      */
  505.     function parse (&$parse_data$path$base 0$packages false)
  506.     {
  507.         global $_phpDocumentor_options;
  508.         static $endrecur 0;
  509.         $this->p_vars array('func' => false'function_data' => '''quote_data' => '''event_stack' => false'last_pevent' => 0,
  510.                         'two_words_ago' => '''temp_word' => '''docblock' => false'line' => array()'linecount' => 0'startword' => '',
  511.                         'periodline' => 0'shortdesc' => '''docblock_desc' => '''class' => false'source_location' => '',
  512.                         'define_params_data' => '''define' => false'define_name' => '''define_value' => '''var' => false,
  513.                         'oldtoken' => false'comment_data' => '''function_param' => NULL'inline_dockeyword_type' => false,
  514.                         'inline_dockeyword_data' => false'dockeyword_type' => false'dockeyword_data' =>false'param_var' => false,
  515.                         'include_name' => '''include_value' => '','include' => false'return_type' => '''cur_class' => '',
  516.                         'function_data' => false'varname' => '''returntype' => false'vartype' => false'paramtype' => false,
  517.                         'tagname' => '''find_global' => '''global_type' => '''paramname' => false'statics' => array(),
  518.                         'static_count' => 0'static_val' => array()'docblock_type' => 'docblock''linenum' => false,
  519.                         'seelement' => false);
  520.     
  521.         $this->p_flags array('docblocknewline' => false'docblockintags' => false'useperiod' => false,
  522.                         'definename_isset' => false'define_parens' => false'reset_quote_data' => false,
  523.                         'in_desc' => true'in_tag' => false'newline' => true'tempnewline' => false,
  524.                         'start_docblock' => false'includename_isset' => false'return_isset' => false,
  525.                         'is_return' => false'in_class' => false'asterisk' => false'var_equals' => false,
  526.                         'arrayinvarname' => false'valid_newline' => true'startline' => false,
  527.                         'function_global' => false'define_global' => false'static_value' => false,'funcparam_val' => false,
  528.                         'get_source' => false'getting_source' => false'in_define' => false'in_include' => false,
  529.                         'in_var' => false'in_global' => false);
  530.         $this->p_vars['parsepath'$path;
  531.         $this->setupStates();
  532.         if (strlen($parse_data== 0)
  533.         {
  534.             return false;
  535.         }
  536.  
  537.         // initialize variables so E_ALL error_reporting doesn't complain
  538.         $pevent 0;
  539.         $word 0;
  540.         $this->p_vars['event_stack'new EventStack;
  541.  
  542.         $this->wp->setup($parse_data);
  543.         
  544.  
  545.         $page new ParserPage;
  546.         $page->setPath($path);
  547.         $page->setPackageOutput($packages);
  548.         $page->setFile(basename($path));
  549.         $this->publishEvent(PHPDOCUMENTOR_EVENT_NEWFILE,basename($path));
  550.         //$name = str_replace("/","_",dirname($path)) . "_" . array_shift(explode(".",$page->getFile()));
  551.         // [email protected] 11/29/2001
  552.         $name str_replace':'''dirname($pathPATH_DELIMITER $page->getFile() );
  553.         $tmp explodePATH_DELIMITER$name );
  554.         $name implode"---"array_slice$tmp$base ) );
  555.         // if base is '', drive letter is present in windows
  556.  
  557.         $page->setName($name);
  558.         $temploc $_phpDocumentor_options['Program_Root'PATH_DELIMITERimplode(PATH_DELIMITER,
  559.             array_slice(explode(PATH_DELIMITER,$path),$base));
  560.         
  561.         if ($temploc == $_phpDocumentor_options['Program_Root'PATH_DELIMITER$temploc .= $path;
  562.         
  563.         $this->p_vars['source_location'$source_location $temploc;
  564.         $page->setSourceLocation($source_location);
  565.  
  566.         $this->publishEvent(PHPDOCUMENTOR_EVENT_PAGE,$page);
  567.         unset($page);
  568.         $this->p_flags['reset_quote_data'true;
  569.  
  570.         do
  571.         {
  572.             $lpevent $pevent;
  573.             $pevent $this->p_vars['event_stack']->getEvent();
  574.             if ($lpevent != $pevent)
  575.             {
  576.                 $this->p_vars['last_pevent'$lpevent;
  577.             }
  578.  
  579.             if ($this->p_vars['last_pevent'!= $pevent)
  580.             {
  581.                 // its a new event so the word parser needs to be reconfigured 
  582.                 $this->configWordParser($pevent);
  583.             }
  584.         
  585.             $this->publishEvent(PHPDOCUMENTOR_EVENT_NEWSTATE,($pevent 100));
  586.  
  587.             if ($pevent == PARSER_EVENT_GLOBAL_VALUE || $pevent == PARSER_EVENT_DOCBLOCK || $pevent == PARSER_EVENT_DOCBLOCK_TEMPLATE)
  588.             {
  589.                 $this->wp->setWhitespace(true);
  590.             }
  591.  
  592.             $this->p_vars['last_word'$word;
  593.             $word $this->wp->getWord();
  594.             // in wordparser, have to keep track of lines
  595.             $this->publishEvent(PHPDOCUMENTOR_EVENT_NEWLINENUM$this->wp->linenum);
  596.  
  597.             if (0)//PHPDOCUMENTOR_DEBUG == true)
  598.             {
  599.                 echo "\nLAST: |" $this->p_vars['last_word'"|\n";
  600.                 echo "PEVENT: " $this->getParserEventName($pevent"\n";
  601.                 echo "LASTPEVENT: " $this->getParserEventName($this->p_vars['last_pevent']"\n";
  602.                 echo $this->wp->getPos(": |$word|\n--------------------------\n\n";
  603.             }
  604.             if ($this->p_flags['get_source'])
  605.             {
  606.                 if ($pevent == PARSER_EVENT_FUNCTION)
  607.                 {
  608.                     $this->wp->retrievesource("function $word");
  609.                     $this->p_flags['get_source'false;
  610.                     $this->p_flags['getting_source'true;
  611.                 }
  612.             }
  613.             if (false)//$this->p_flags['getting_source'] && ($pevent == PARSER_EVENT_DOCBLOCK) || ($pevent == PARSER_EVENT_NOEVENTS))
  614.             {
  615.                 addError(PDERROR_SOURCE_TAG_FUNCTION_NOT_FOUND);
  616.                 // throw away source
  617.                 $this->wp->getSource();
  618.             }
  619.             if (isset($this->eventHandlers[$pevent]))
  620.             {
  621.                 $handle $this->eventHandlers[$pevent];
  622.                 $this->$handle($word$pevent);
  623.             else
  624.             {
  625.                 debug('WARNING: possible error, no handler for event number '.$pevent);
  626.                 if ($endrecur++ == 25)
  627.                 {
  628.                     die("FATAL ERROR, recursion limit reached");
  629.                 }
  630.             }
  631.         while (!($word === false));
  632.     }
  633.     
  634.     /**#@+
  635.      * @access private
  636.      * @param string token parsed from source
  637.      * @param integer parser constant from {@link Parser.inc}
  638.      */
  639.     /**
  640.      * handler for NOEVENTS, OUTPHP, COMMENTBLOCK
  641.      */
  642.     
  643.     function defaultHandler($word$pevent)
  644.     {
  645.         $this->checkEventPush$word$pevent);
  646.         $this->checkEventPop($word,$pevent);
  647.     }
  648.     
  649.     /**
  650.      * handler for LOGICBLOCK
  651.      *
  652.      * Logic Blocks are the stuff between { and } in a function/method.  A
  653.      * logic block can clearly contain other logic blocks, as in:
  654.      *
  655.      * <code>
  656.      * function test($a)
  657.      * {
  658.      *    if (testcondition)
  659.      *    { // nested logic block
  660.      *    }
  661.      * }
  662.      * </code>
  663.      *
  664.      * So, the exit portion of the logic block handler must check to see if the
  665.      * logic block being exited is the top-level, and it does this by retrieving
  666.      * the last event from the stack.  If it is a function (and not a logic block)
  667.      * then it backs up the word parser so that the function will exit properly.
  668.      *
  669.      * {@source 11}
  670.      */
  671.     
  672.     function handleLogicBlock($word$pevent)
  673.     {
  674.         $a $this->checkEventPush$word$pevent);
  675.         if ($a == PARSER_EVENT_FUNC_GLOBAL || $a == PARSER_EVENT_STATIC_VAR)
  676.         {
  677.             if (substr($this->p_vars['last_word'],strlen($this->p_vars['last_word']1,1!= ' ' && substr($this->p_vars['last_word'],strlen($this->p_vars['last_word']1,1!= "\t" && substr($this->p_vars['last_word'],strlen($this->p_vars['last_word']1,1!= "\n" && substr($this->p_vars['last_word'],strlen($this->p_vars['last_word']1,1!= ";" && substr($this->p_vars['last_word'],strlen($this->p_vars['last_word']1,1!= "}" && substr($this->p_vars['last_word'],strlen($this->p_vars['last_word']1,1!= "{")
  678.             {
  679.                 $this->p_vars['event_stack']->popEvent();
  680.             }
  681.         }
  682.         if ($this->checkEventPop($word,$pevent))
  683.         {
  684.             $e $this->p_vars['event_stack']->popEvent();
  685.             $this->p_vars['event_stack']->pushEvent($e);
  686.             if ($e == PARSER_EVENT_FUNCTION)
  687.             {
  688.                 $this->wp->backupPos($word)
  689.             }
  690.         }
  691.     }
  692.     
  693.     /**
  694.      * handler for ESCAPE.
  695.      * this event handler parses <code>"this string \"with its escape backslashes\""</code> and returns:
  696.      * <code>this string "with its escape backslashes"</code>
  697.      * to make it human-readable
  698.      */
  699.     
  700.     function handleEscape($word$pevent)
  701.     {
  702.         $this->p_vars['event_stack']->popEvent();
  703.     }
  704.     
  705.     /**
  706.      * handler for COMMENT.
  707.      * this event handler parses single-line comments like:
  708.      * // this one
  709.      */
  710.     
  711.     function handleComment($word$pevent)
  712.     {
  713.         $this->checkEventPush$word$pevent);
  714.     
  715.         if (!isset($this->p_vars['comment_data'])) $this->p_vars['comment_data''';
  716.         $this->p_vars['comment_data'.= $word;
  717.     
  718.         $this->checkEventPop($word,$pevent);
  719.     }
  720.  
  721.     /**
  722.      * handler for ARRAY.
  723.      * this event handler parses arrays in default values of function and var definitions
  724.      */
  725.     
  726.     function handleArray($word$pevent)
  727.     {
  728.         $e $this->checkEventPush$word$pevent)
  729.         if (($e == PARSER_EVENT_COMMENTBLOCK||
  730.             ($e == PARSER_EVENT_COMMENT)) return;
  731.  
  732.         if (!isset($this->p_vars['function_data']|| (isset($this->p_vars['function_data']&& empty($this->p_vars['function_data'])))
  733.         {
  734.             $this->p_vars['function_data'"array";
  735.         }
  736.  
  737.         if ( ($this->p_vars['last_word'== "'"))
  738.         {
  739.             $this->p_vars['function_data'.= $this->p_vars['quote_data']."'";
  740.         }
  741.         if ( ($this->p_vars['last_word'== "\""))
  742.         {
  743.             $this->p_vars['function_data'.= $this->p_vars['quote_data']."\"";
  744.         }
  745.  
  746.         $this->p_vars['function_data'.= $word;
  747.         //echo "function_data = |$this->p_vars['function_data']|\n";
  748.  
  749.         if ($this->checkEventPop($word,$pevent))
  750.         {
  751.         }
  752.     }
  753.  
  754.     /**
  755.      * handler for DEFINE.
  756.      * handles define(constant, value); statements
  757.      */
  758.     
  759.     function handleDefine($word$pevent)
  760.     {
  761.         if (!$this->p_flags['in_define'])
  762.         {
  763.             $this->p_vars['linenum'$this->wp->linenum;
  764.         }
  765.         $this->p_flags['in_define'true;
  766.         $this->checkEventPush$word$pevent);
  767.  
  768.         $this->p_flags['definename_isset'false;
  769.         $this->p_vars['define_params_data''';
  770.         unset($this->p_vars['quote_data']);
  771.         if ($this->checkEventPop($word,$pevent))
  772.         {
  773.             $this->p_flags['in_define'false;
  774.             $this->p_vars['define'new parserDefine;
  775.             $this->p_vars['define']->setLineNumber($this->p_vars['linenum']);
  776.             $this->p_vars['define']->setName($this->p_vars['define_name']);
  777.             $this->p_vars['define']->setValue($this->p_vars['define_value']);
  778.             $this->publishEvent(PHPDOCUMENTOR_EVENT_DEFINE,$this->p_vars['define']);
  779.             $this->p_flags['definename_isset'false;
  780.             unset($this->p_vars['define']);
  781.             unset($this->p_vars['define_name']);
  782.             unset($this->p_vars['define_value']);
  783.             $this->p_flags['in_define'false;
  784.             $this->p_vars['define_params_data''';
  785.         }
  786.     }
  787.     
  788.     /**
  789.      * handler for DEFINE_PARAMS.
  790.      * handles the parsing of constant and value in define(constant, value);
  791.      */
  792.     
  793.     function handleDefineParams($word$pevent)
  794.     {
  795.         if ($this->checkEventPush$word$pevent))
  796.         {
  797.             if ($word == '(')
  798.             {
  799.                 $this->p_vars['define_params_data'.= $word;
  800.             }
  801.             return;
  802.         }
  803.         
  804.         $this->p_flags['define_parens'true;
  805.         if(!isset($this->p_vars['define_params_data'])) $this->p_vars['define_params_data''';
  806.         
  807.         if ($this->checkEventPop($word,$pevent))
  808.         {
  809.             if (!empty($this->p_vars['quote_data']))
  810.             {
  811.                 $this->p_vars['define_params_data'.= $this->p_vars['quote_data'];
  812.             }
  813.             if (!empty($this->p_vars['define_params_data']))
  814.             {
  815.                 //echo $this->p_vars['define_params_data']."\n";
  816.                 $this->p_vars['define_value'$this->p_vars['define_params_data'];
  817.             }
  818.             else
  819.             {
  820.                 if (    $this->p_vars['last_word'!= "/*" && 
  821.                     $this->p_vars['last_word'!= "//" && $this->p_vars['last_word'!= "#")
  822.                 {
  823.                     $this->p_vars['define_value'trim($this->p_vars['last_word']);
  824.                 }
  825.                 else
  826.                 {
  827.                     $this->p_vars['define_value'"";
  828.                 }
  829.             }
  830.         }
  831.         if ($this->p_flags['definename_isset'])
  832.         {
  833.             if (isset($this->p_vars['quote_data']))
  834.             {
  835.                 $this->p_vars['define_params_data'.= '"'.$this->p_vars['quote_data'].'"';
  836.                 unset($this->p_vars['quote_data']);
  837.             }
  838.             $this->p_vars['define_params_data'.= $word;
  839.         else
  840.         {
  841.             if ($word != ",")
  842.             {
  843.                 if (isset($this->p_vars['quote_data']))
  844.                 {
  845.                     $this->p_vars['define_params_data'.= $this->p_vars['quote_data'];
  846.                     unset($this->p_vars['quote_data']);
  847.                 }
  848.                 $this->p_vars['define_params_data'.= $word;
  849.             else
  850.             {
  851.                 if (isset($this->p_vars['quote_data']&& !$this->p_flags['definename_isset'])
  852.                 {
  853.                     $this->p_vars['define_params_data'.= $this->p_vars['quote_data'];
  854.                     unset($this->p_vars['quote_data']);
  855.                 }
  856.                 $this->p_flags['definename_isset'true;
  857.                 $this->p_vars['define_name'$this->p_vars['define_params_data'];
  858.                 unset($this->p_vars['quote_data']);
  859.                 $this->p_vars['define_params_data''';
  860.             }
  861.         }
  862.     }
  863.     
  864.     /**
  865.      * handler for DEFINE_PARAMS_PARENTHESIS.
  866.      * this handler takes all parenthetical statements within constant or value in:
  867.      * define(constant, value) of a define statement, and handles them properly
  868.      */
  869.     
  870.     function handleDefineParamsParenthesis($word$pevent)
  871.     {
  872.         if (isset($this->p_vars['quote_data']))
  873.         {
  874.             $this->p_vars['define_params_data'.= '"'.$this->p_vars['quote_data'].'"';
  875.             unset($this->p_vars['quote_data']);
  876.         }
  877.         $this->p_vars['define_params_data'.= $word;
  878.         $this->checkEventPush$word$pevent);
  879.         $this->checkEventPop$word$pevent);
  880.     }
  881.  
  882.     /**
  883.      * handler for CLASS.
  884.      * this handler parses a class statement
  885.      */
  886.     
  887.     function handleClass($word$pevent)
  888.     {
  889.         $this->p_flags['in_class'true;
  890.         $a $this->checkEventPush$word$pevent);
  891.         if ($a == PARSER_EVENT_DOCBLOCK || $a == PARSER_EVENT_DOCBLOCK_TEMPLATE)
  892.         {
  893.             $this->wp->setWhitespace(true);
  894.         }
  895.  
  896.         if (!isset($this->p_vars['class'])) $this->p_vars['class'false;
  897.         if (!is_subclass_of($this->p_vars['class'],"parserBase"))
  898.         {
  899.             $this->p_vars['class'new parserClass;
  900.             $this->p_vars['class']->setLineNumber($this->wp->linenum);
  901.             $this->p_vars['class']->setname($word);
  902.             $this->p_vars['cur_class'$word;
  903.             $this->p_vars['class']->setSourceLocation($this->p_vars['source_location']);
  904.         }
  905.  
  906.         if (strtolower($this->p_vars['last_word']== "extends")
  907.         {
  908.             $this->p_vars['class']->setExtends($word);
  909.         }
  910.  
  911.         if ($word == "{")
  912.         {
  913.             $this->publishEvent(PHPDOCUMENTOR_EVENT_CLASS,$this->p_vars['class']);
  914.         }
  915.         //echo $this->wp->getPos() . ": |$word|\n";
  916.         if ($this->checkEventPop($word,$pevent))
  917.         {
  918.             $this->p_flags['in_class'false;
  919.             // throw an event when class is done
  920.             $this->p_vars['class'false;
  921.         }
  922.     }
  923.  
  924.     /**
  925.      * handler for VAR.
  926.      * handle a var $varname = default_value; or var $varname; statement in a class definition
  927.      */
  928.     
  929.     function handleVar($word$pevent)
  930.     {
  931.         if (!$this->p_flags['in_var'])
  932.         {
  933.             $this->p_vars['linenum'$this->wp->linenum;
  934.         }
  935.         $this->p_flags['in_var'true;
  936.         //echo $word."\n";
  937.         $e $this->checkEventPush$word$pevent);
  938.         
  939.         if (!isset($this->p_vars['var'])) $this->p_vars['var'false;
  940.         if ($word == '=' || $word == ';'$this->p_flags['var_equals'true;
  941.         if (!$this->p_flags['var_equals'])
  942.         {
  943.             // if we haven't parsed the = yet, no arrays are possible!
  944.             if ($e == PARSER_EVENT_ARRAY)
  945.             {
  946.                 $this->p_flags['arrayinvarname'true;
  947.                 $this->p_vars['event_stack']->popEvent();
  948.             }
  949.             if (!$e || ($e == PARSER_EVENT_ARRAY))
  950.             $this->p_vars['varname'.= $word;
  951.         }
  952.  
  953.         if (!$this->p_flags['var_equals'])
  954.         {
  955.             if ($word != "/*" && $word != "//" && $word != "#")
  956.             {
  957.                 $this->p_vars['var'new parserVar($this->p_vars['cur_class']);
  958.                 $this->p_vars['var']->setName($this->p_vars['varname']);
  959.             }
  960.         }
  961.         if ($this->p_vars['last_word'== "=")
  962.         {
  963.             if ($word != "/*" && $word != "//" && $word != "#")
  964.             {
  965.                 $this->p_vars['var']->setValue($word);
  966.             }
  967.         }
  968.         // fix 1202772
  969.         if (isset($this->p_vars['quote_data']&& ($this->p_vars['last_pevent'== PARSER_EVENT_QUOTE || $this->p_vars['last_pevent'== PARSER_EVENT_SINGLEQUOTE))
  970.         {
  971.             $this->p_vars['var']->setValue($this->p_vars['quote_data']);
  972.             unset($this->p_vars['quote_data']);
  973.         }
  974.         if ($this->p_vars['last_pevent'== PARSER_EVENT_ARRAY)
  975.         {
  976.             $this->p_vars['var']->setValue($this->p_vars['function_data']);
  977.             $this->p_vars['function_data'false;
  978.         }
  979.             
  980.         if ($this->checkEventPop($word,$pevent))
  981.         {
  982.             $this->p_vars['var']->setLineNumber($this->p_vars['linenum']);
  983.             $this->publishEvent(PHPDOCUMENTOR_EVENT_VAR,$this->p_vars['var']);
  984.             unset($this->p_vars['var']);
  985.             $this->p_flags['in_var'false;
  986.             $this->p_flags['var_equals'false;
  987.             $this->p_flags['arrayinvarname'false;
  988.             $this->p_vars['varname''';
  989.         }
  990.     }
  991.  
  992.     /**
  993.      * handler for QUOTE.
  994.      * this handler recognizes strings defined with double quotation marks (") and handles them correctly
  995.      * in any place that they legally appear in php code
  996.      */
  997.     
  998.     function handleQuote($word$pevent)
  999.     {
  1000.         if ($this->p_flags['reset_quote_data'=== true)
  1001.         {
  1002.             $this->p_flags['reset_quote_data'false;
  1003.             $this->p_vars['quote_data'"";
  1004.         }
  1005.         $this->checkEventPush$word$pevent);
  1006.         if ($word != "\"")
  1007.         {
  1008.             $this->p_vars['quote_data'.= $word;
  1009.         }
  1010.         if ($this->checkEventPop($word,$pevent))
  1011.         {
  1012.             $this->p_flags['reset_quote_data'true;
  1013.         }
  1014.     }
  1015.     
  1016.     /**
  1017.      * handler for SINGLEQUOTE.
  1018.      * this handler recognizes strings defined with single quotation marks (') and handles them correctly
  1019.      * in any place that they legally appear in php code
  1020.      */
  1021.     
  1022.     function handleSingleQuote($word$pevent)
  1023.     {
  1024.         $this->checkEventPush$word$pevent);
  1025.         if ($this->checkEventPop($word,$pevent))
  1026.         {
  1027.             if ($this->p_vars['last_word'!= "'")
  1028.             {
  1029.                 $this->p_vars['quote_data'$this->p_vars['last_word'];
  1030.             else {
  1031.                 $this->p_vars['quote_data'"";
  1032.             }
  1033.         }
  1034.     }
  1035.  
  1036.     /**
  1037.      * handler for EOFQUOTE.
  1038.      * this handler recognizes strings defined with perl-style <<< EOF quotes, and handles them correctly
  1039.      * in any place that they legally appear in php code
  1040.      *
  1041.      * an example:
  1042.      * <code>$var <<< EOF
  1043.      * blah blah blah
  1044.      * EOF;</code>
  1045.      */
  1046.     
  1047.     function handleEOFQuote($word$pevent)
  1048.     {
  1049.         //    echo $this->wp->getPos() . ": word=|$word|\t\t\tlastword=|$this->p_vars['last_word']|\n";
  1050.         if (trim($this->p_vars['last_word']== "<<<")
  1051.         {
  1052.             // ok we found the keyword
  1053.             //echo "Keyword == $word\n";
  1054.             $this->p_vars['oldtoken'$this->tokens[STATE_EOFQUOTE];
  1055.             $this->tokens[STATE_EOFQUOTEarray($word);
  1056.         
  1057.         else if ($this->p_vars['last_pevent'|| PARSER_EVENT_EOFQUOTE
  1058.         {
  1059.             // i don't think anything will ever use this so were not going to set it
  1060.             //$this->p_vars['quote_data'] = $this->p_vars['last_word']; 
  1061.             $this->p_vars['event_stack']->popEvent();
  1062.             $this->tokens[STATE_EOFQUOTE$this->p_vars['oldtoken'];
  1063.         }
  1064.     }
  1065.     /**#@-*/
  1066.  
  1067.     /**
  1068.      * Tells the parser to search for a global variable definition as
  1069.      * defined by a @global type $name tag.
  1070.      *
  1071.      * The parser is fooled into looking for the entire global variable as a
  1072.      * single token by amending the {@link $tokens} array.
  1073.      *
  1074.      * {@source } 
  1075.      * @access private
  1076.      * @param string name of global variable as it appears in the source code
  1077.      */
  1078.     function findGlobal($name)
  1079.     {
  1080.         if (!isset($this->p_vars['globaltofind']))
  1081.         {
  1082.             $this->p_vars['globaltofind'$name;
  1083.             $this->pushEvent[PARSER_EVENT_PHPCODE][strtolower($name)PARSER_EVENT_DEFINE_GLOBAL;
  1084.             $this->tokens[STATE_PHPCODE][$name;
  1085.         else
  1086.         {
  1087.             addError(PDERROR_MULTIPLE_GLOBAL_TAGS,$this->p_vars['globaltofind'],$name);
  1088.         }
  1089.     }
  1090.     
  1091.     /**#@+
  1092.      * @access private
  1093.      * @param string token parsed from source
  1094.      * @param integer parser constant from {@link Parser.inc}
  1095.      */
  1096.     /**
  1097.      * handler for PHPCODE.
  1098.      * this handler recognizes the <code><?</code> php processor directive, and begins parsing php code
  1099.      */
  1100.     
  1101.     function handlePhpCode($word$pevent)
  1102.     {
  1103.         $e $this->checkEventPush$word$pevent);
  1104.         if ($e == PARSER_EVENT_DOCBLOCK || $e == PARSER_EVENT_DOCBLOCK_TEMPLATE)
  1105.         {
  1106.             $this->wp->setWhitespace(true);
  1107.         }
  1108.         if (isset($this->p_vars['globaltofind']&& $e)
  1109.         {
  1110.             if ($e != PARSER_EVENT_DEFINE_GLOBAL && $e != PARSER_EVENT_ARRAY && $e != PARSER_EVENT_QUOTE && $e != PARSER_EVENT_SINGLEQUOTE && $e != PARSER_EVENT_COMMENT && $e != PARSER_EVENT_COMMENTBLOCK)
  1111.             {
  1112.                 addError(PDERROR_GLOBAL_NOT_FOUND,$this->p_vars['globaltofind']);
  1113.                 unset($this->pushEvent[PARSER_EVENT_PHPCODE][strtolower($this->p_vars['globaltofind'])]);
  1114.                 foreach($this->tokens[STATE_PHPCODEas $i => $notme)
  1115.                 if ($this->tokens[STATE_PHPCODE][$i== $this->p_vars['globaltofind'])
  1116.                 unset($this->tokens[STATE_PHPCODE][$i]);
  1117.                 unset($this->p_vars['globaltofind']);
  1118.             }
  1119.         }
  1120.     }
  1121.     
  1122.     /**
  1123.      * handler for global variables
  1124.      */
  1125.     function handleGlobal($word$pevent)
  1126.     {
  1127.         if (!$this->p_flags['in_global'])
  1128.         {
  1129.             $this->p_vars['linenum'$this->wp->linenum;
  1130.         }
  1131.         $this->p_flags['in_global'true;
  1132.         $e $this->checkEventPush($word$pevent);
  1133.         if ($this->checkEventPop($word$pevent))
  1134.         {
  1135.             $this->p_flags['in_global'false;
  1136.             $a new parserGlobal;
  1137.             $a->setDataType($this->p_vars['global_type']);
  1138.             $this->p_vars['global_type''';
  1139.             $a->setLineNumber($this->p_vars['linenum']);
  1140.             $a->setName($this->p_vars['globaltofind']);
  1141.             if (isset($this->p_vars['global_val']))
  1142.             $a->setValue(trim($this->p_vars['global_val']));
  1143.             unset($this->p_vars['global_val']);
  1144.             $this->publishEvent(PHPDOCUMENTOR_EVENT_GLOBAL,$a);
  1145.             unset($this->pushEvent[PARSER_EVENT_PHPCODE][strtolower($this->p_vars['globaltofind'])]);
  1146.             foreach($this->tokens[STATE_PHPCODEas $i => $notme)
  1147.             if ($this->tokens[STATE_PHPCODE][$i== $this->p_vars['globaltofind'])
  1148.             unset($this->tokens[STATE_PHPCODE][$i]);
  1149.             unset($this->p_vars['globaltofind']);
  1150.         }
  1151.     }
  1152.     
  1153.     /**
  1154.      * Handles the stuff after the = in <code>$globalvar = value</code>
  1155.      */
  1156.     function handleGlobalValue($word$pevent)
  1157.     {
  1158.         if ($this->checkEventPush($word$pevent))
  1159.         {
  1160.             $this->wp->setWhitespace(false);
  1161.             return;
  1162.         }
  1163.         if (!isset($this->p_vars['global_val'])) $this->p_vars['global_val''';
  1164.         if ($this->p_vars['last_pevent'== PARSER_EVENT_QUOTE || $this->p_vars['last_pevent'== PARSER_EVENT_SINGLEQUOTE)
  1165.         {
  1166.             if (!isset($this->p_vars['quote_data'])) $this->p_vars['quote_data''';
  1167.             $this->p_vars['global_val'.= '"'.$this->p_vars['quote_data'].'"';
  1168.             unset($this->p_vars['quote_data']);
  1169.             $this->p_vars['last_pevent'PARSER_EVENT_GLOBAL_VALUE;
  1170.         }
  1171.         if ($this->p_vars['last_pevent'== PARSER_EVENT_ARRAY)
  1172.         {
  1173.             $this->p_vars['global_val'.= $this->p_vars['function_data'];
  1174.             $this->p_vars['function_data'false;
  1175.         }
  1176.         if ($word != ';')
  1177.         $this->p_vars['global_val'.= $word;
  1178.         if ($this->checkEventPop($word$pevent))
  1179.         {
  1180.             $this->wp->setWhitespace(false);
  1181.             $this->wp->backupPos($word);
  1182.         }
  1183.     }
  1184.     
  1185.     /**
  1186.      * handler for FUNC_GLOBAL.
  1187.      * this handler recognizes "global $var1, $var2" declarations in a function, and parses them
  1188.      */
  1189.     
  1190.     function handleFuncGlobal($word$pevent)
  1191.     {
  1192.         if ((substr(trim($word),0,1!= '$'&& ($word != ','&& ($word != ';'))
  1193.         // not a global declaration, using a variable named "$global"
  1194.             $this->p_vars['event_stack']->popEvent();
  1195.             return;
  1196.         }
  1197.         if ($this->checkEventPop($word$pevent))
  1198.         {
  1199.             return;
  1200.         }
  1201.         if (!$this->checkEventPush($word$pevent))
  1202.         {
  1203.             if ($word == ',')
  1204.             // another variable
  1205.                 $this->p_vars['global_count']++;
  1206.             else
  1207.             {
  1208.                 if (!isset($this->p_vars['globals'][$this->p_vars['global_count']]))
  1209.                 $this->p_vars['globals'][$this->p_vars['global_count']] '';
  1210.                 if (!empty($this->p_vars['globals'][$this->p_vars['global_count']])) $this->p_vars['global_count']++;
  1211.                 $this->p_vars['globals'][$this->p_vars['global_count']] trim($word);
  1212.             }
  1213.         }
  1214.     }
  1215.     
  1216.     /**
  1217.      * handler for STATIC_VAR.
  1218.      * this handler recognizes "static $var1, $var2 = 6" declarations in a function, and parses them
  1219.      */
  1220.     
  1221.     function handleStaticVar($word$pevent)
  1222.     {
  1223.         if ($this->checkEventPop($word$pevent))
  1224.         {
  1225.             $this->p_vars['static_count']++;
  1226.             return;
  1227.         }
  1228.         if (!$this->checkEventPush($word$pevent))
  1229.         {
  1230.             if ($word == ',')
  1231.             {
  1232.                 $this->p_vars['static_count']++;
  1233.                 return;
  1234.             }
  1235.             if (!isset($this->p_vars['statics'][$this->p_vars['static_count']]))
  1236.             $this->p_vars['statics'][$this->p_vars['static_count']] '';
  1237.             if (!empty($this->p_vars['statics'][$this->p_vars['static_count']])) $this->p_vars['static_count']++;
  1238.             $this->p_vars['statics'][$this->p_vars['static_count']] trim($word);
  1239.         }
  1240.     }
  1241.     
  1242.     /**
  1243.      * handler for STATIC_VAR_VALUE.
  1244.      * this handler parses the 6 in "static $var1, $var2 = 6"
  1245.      */
  1246.     
  1247.     function handleStaticValue($word$pevent)
  1248.     {
  1249.         if ($this->checkEventPush($word$pevent))
  1250.         {
  1251.             return;
  1252.         }
  1253.         if (!isset($this->p_vars['static_val'][$this->p_vars['static_count']])) $this->p_vars['static_val'][$this->p_vars['static_count']] '';
  1254.         if ($this->p_vars['last_pevent'== PARSER_EVENT_QUOTE || $this->p_vars['last_pevent'== PARSER_EVENT_SINGLEQUOTE)
  1255.         {
  1256.             $this->p_vars['static_val'][$this->p_vars['static_count']] .= '"'.$this->p_vars['quote_data'].'"';
  1257.             unset($this->p_vars['quote_data']);
  1258.         }
  1259.         if ($this->p_vars['last_pevent'== PARSER_EVENT_ARRAY)
  1260.         {
  1261.             $this->p_vars['static_val'][$this->p_vars['static_count']] .= $this->p_vars['function_data'];
  1262.             $this->p_vars['function_data'false;
  1263.         }
  1264.         if ($this->checkEventPop($word$pevent))
  1265.         {
  1266.             $this->p_vars['static_val'][$this->p_vars['static_count']] trim($this->p_vars['static_val'][$this->p_vars['static_count']]);
  1267.             $this->wp->backupPos($word);
  1268.             return;
  1269.         else $this->p_vars['static_val'][$this->p_vars['static_count']] .= $word;
  1270.     }
  1271.     
  1272.     /**
  1273.      * handler for FUNCTION.
  1274.      * this handler recognizes function declarations, and parses them.  The body
  1275.      * of the function is parsed by handleLogicBlock()
  1276.      * @see handleLogicBlock()
  1277.      */
  1278.     
  1279.     function handleFunction($word$pevent)
  1280.     {
  1281.         if ($e $this->checkEventPush$word$pevent))
  1282.         {
  1283.             if ($e == PARSER_EVENT_COMMENT || $e == PARSER_EVENT_COMMENTBLOCKreturn;
  1284.         }
  1285.     
  1286.         if (!isset($this->p_vars['func'])) $this->p_vars['func'false;
  1287.         if (is_subclass_of($this->p_vars['func'],"parserBase")) 
  1288.         {
  1289.             $this->p_vars['globals'array();
  1290.             $this->p_vars['global_count'0;
  1291.             if ($this->p_flags['in_class'])
  1292.             $this->p_vars['func'new parserMethod($this->p_vars['cur_class'])
  1293.             else
  1294.             $this->p_vars['func'new parserFunction;
  1295.             $this->p_vars['func']->setLineNumber($this->wp->linenum);
  1296.             if (trim($word!= '&')
  1297.             $this->p_vars['func']->setName(trim($word));
  1298.             else
  1299.             $this->p_vars['func']->setReturnsReference();
  1300.         else
  1301.         {
  1302.             if ($this->p_vars['func']->getReturnsReference())
  1303.             {
  1304.                 if ($this->p_vars['last_word'== '&')
  1305.                 {
  1306.                     $this->p_vars['func']->setName(trim($word));
  1307.                 }
  1308.             }
  1309.         }
  1310.         if ($this->checkEventPop($word,$pevent)) 
  1311.         
  1312.             $this->p_vars['func']->addGlobals($this->p_vars['globals']);
  1313.             $this->p_vars['func']->addStatics($this->p_vars['statics'],$this->p_vars['static_val']);
  1314.             $this->p_vars['globals'array();
  1315.             $this->p_vars['global_count'0;
  1316.             if ($this->p_flags['getting_source'])
  1317.             {
  1318.                 $x $this->wp->getSource();
  1319.                 $this->p_vars['func']->addSource($x);
  1320.                 $this->p_flags['get_source'false;
  1321.                 $this->p_flags['getting_source'false;
  1322.             }
  1323.             $this->publishEvent(PHPDOCUMENTOR_EVENT_FUNCTION,$this->p_vars['func'])
  1324.             $this->p_vars['func'false
  1325.         
  1326.     }
  1327.  
  1328.     /**#@-*/
  1329.     /**
  1330.      * Helper function for {@link handleFunctionParams()}
  1331.      *
  1332.      * This function adds a new parameter to the parameter list
  1333.      * @access private
  1334.      * @param string 
  1335.      */
  1336.     function endFunctionParam($word)
  1337.     {
  1338.         if (isset($this->p_vars['quote_data']&& ($this->p_vars['last_pevent'== PARSER_EVENT_SINGLEQUOTE))
  1339.         {
  1340.             $this->p_vars['function_data'.= "'".$this->p_vars['quote_data']."'";
  1341.             unset($this->p_vars['quote_data']);
  1342.         }
  1343.         if (isset($this->p_vars['quote_data']&& ($this->p_vars['quote_data'!= ''&& ($this->p_vars['last_pevent'== PARSER_EVENT_QUOTE))
  1344.         {
  1345.             $this->p_vars['function_data'.= '"'.$this->p_vars['quote_data'].'"';
  1346.             unset($this->p_vars['quote_data']);
  1347.         }
  1348.         if (isset($this->p_vars['function_param']))
  1349.         {
  1350.             $this->p_vars['func']->addParam($this->p_vars['function_param'],$this->p_vars['function_data']$this->p_flags['funcparam_val']);
  1351.             unset($this->p_vars['function_param']);
  1352.             $this->p_vars['function_data''';
  1353.             $this->p_flags['funcparam_val'false;
  1354.         }
  1355.     }
  1356.     /**#@+
  1357.      * @access private
  1358.      * @param string token parsed from source
  1359.      * @param integer parser constant from {@link Parser.inc}
  1360.      */
  1361.     /**
  1362.      * handler for FUNCTION_PARAMS.
  1363.      * this handler recognizes the parameters of a function within parentheses like function(param, param = default_value)
  1364.      * and parses them
  1365.      * @see endFunctionParam()
  1366.      */
  1367.     
  1368.     function handleFunctionParams($word$pevent)
  1369.     {
  1370.         //echo $this->wp->getPos() . ": word=|$word|\t\t\tlastword=|".$this->p_vars['last_word']."|\n";
  1371.         //echo "function_param = '".$this->p_vars['function_param']."'\n";
  1372.         //echo "function_data = '".$this->p_vars['function_data']."'\n";
  1373.         $e1 $this->checkEventPush$word$pevent)
  1374.  
  1375.         if (!$e1)
  1376.         {
  1377.             if ($word == ',' || $this->checkEventPop($word,$pevent))
  1378.             {
  1379.                 $this->endFunctionParam($word);
  1380.             elseif ($word == '=')
  1381.             {
  1382.                 $this->p_flags['funcparam_val'true;
  1383.             else
  1384.             {
  1385.                 if ($this->p_flags['funcparam_val'])
  1386.                 {
  1387.                     if (isset($this->p_vars['quote_data']&& ($this->p_vars['last_pevent'== PARSER_EVENT_SINGLEQUOTE))
  1388.                     {
  1389.                         $this->p_vars['function_data'.= "'".$this->p_vars['quote_data']."'";
  1390.                         unset($this->p_vars['quote_data']);
  1391.                     }
  1392.                     if (isset($this->p_vars['quote_data']&& ($this->p_vars['last_pevent'== PARSER_EVENT_QUOTE))
  1393.                     {
  1394.                         $this->p_vars['function_data'.= '"'.$this->p_vars['quote_data'].'"';
  1395.                         unset($this->p_vars['quote_data']);
  1396.                     }
  1397.                     $this->p_vars['function_data'.= $word;
  1398.                 else
  1399.                 {
  1400.                     $this->p_vars['function_param'$word;
  1401.                 }
  1402.             }
  1403.         }
  1404.     }
  1405.  
  1406.     
  1407.     /**
  1408.      * javadoc-desc-compliant handler for DOCBLOCK.
  1409.      * this handler recognizes @tags in DocBlocks and parses them for display.
  1410.      * It also parses out unknown tags into their own array for use by the docblock
  1411.      */
  1412.     
  1413.     function JavaDochandleDocblock($word$pevent)
  1414.     {
  1415.         $e1 $this->checkEventPush$word$pevent);
  1416.         if (!isset($this->p_vars[$this->p_vars['docblock_type']]|| !$this->p_vars[$this->p_vars['docblock_type']])
  1417.         {
  1418.             $this->p_vars[$this->p_vars['docblock_type']] new parserDocBlock();
  1419.             $this->p_vars['returntype'false;
  1420.             $this->p_vars['vartype'false;
  1421.             $this->p_flags['startdocblock'true;
  1422.             $this->p_flags['valid_newline'true;
  1423.             $this->p_flags['startline'true;
  1424.             $this->p_flags['newline'true;
  1425.             $this->p_flags['in_desc'true;
  1426.             $this->p_flags['in_tag'false;
  1427.             $this->p_flags['useperiod'false;
  1428.             $this->p_vars['line'array();
  1429.             $this->p_vars['linecount'0;
  1430.         }
  1431.         $e $this->checkEventPop$word$pevent);
  1432.         if (!$e1 && !$e)
  1433.         {
  1434.             if ($this->p_flags['in_desc']$this->JavaDochandleDesc($word$pevent);
  1435.             else $this->handleTags($word$pevent);
  1436.         }
  1437.         if ($e)
  1438.         {
  1439.             if (!isset($this->p_vars['periodline'])) $this->p_vars['periodline'0;
  1440.             if ($this->p_vars['periodline'3)
  1441.             {
  1442.                 $this->p_flags['useperiod'false;
  1443.             }
  1444.  
  1445.             $this->p_vars['docblock_desc'new parserDesc;
  1446. //            echo "i = ".$this->p_vars['periodline']."; i < " . count($this->p_vars['line']) . "\n";
  1447.             if ($this->p_vars['docblock_type'== 'docblock')
  1448.             {
  1449.                 if (isset($this->p_vars['docblock_template']))
  1450.                 {
  1451.                     // copy template values if not overridden
  1452.                     if (!$this->p_vars['docblock']->getExplicitPackage())
  1453.                     {
  1454.                         if ($p $this->p_vars['docblock_template']->getKeyword('package'))
  1455.                         {
  1456.                             $this->p_vars['docblock']->addKeyword('package',$p);
  1457.                             $this->p_vars['docblock']->setExplicitPackage();
  1458.                         }
  1459.                         if ($p $this->p_vars['docblock_template']->getKeyword('category'))
  1460.                         {
  1461.                             $this->p_vars['docblock']->addKeyword('category',$p);
  1462.                             $this->p_vars['docblock']->setExplicitCategory();
  1463.                         }
  1464.                         if ($p $this->p_vars['docblock_template']->getKeyword('subpackage'))
  1465.                         {
  1466.                             $this->p_vars['docblock']->addKeyword('subpackage',$p);
  1467.                         }
  1468.                     }
  1469.                     $tags $this->p_vars['docblock_template']->listTags();
  1470.                     foreach($tags as $tag)
  1471.                     {
  1472.                         $this->p_vars['docblock']->addKeyword($tag->keyword,$tag->value);
  1473.                     }
  1474.                     $this->p_vars['docblock_desc']->add($this->p_vars['docblock_template']->desc);
  1475.                     if (!count($this->p_vars['docblock']->params)) $this->p_vars['docblock']->params $this->p_vars['docblock_template']->params;
  1476.                 }
  1477.                 if ($a strpos(trim($this->p_vars['shortdesc']),'<p>'=== 0)
  1478.                 $this->p_vars['shortdesc'substr($this->p_vars['shortdesc'],strpos($this->p_vars['shortdesc'],'<p>'4);
  1479.                 $this->p_vars[$this->p_vars['docblock_type']]->setShortDesc($this->p_vars['shortdesc']);
  1480.             }
  1481.             for($i 0$i count($this->p_vars['line'])$i++)
  1482.             {
  1483.                 // the line will not be set if it doesn't start with a *
  1484.                 if (isset($this->p_vars['line'][$i]))
  1485.                 $this->p_vars['docblock_desc']->add($this->p_vars['line'][$i]);
  1486.             }
  1487.  
  1488.  
  1489.             $this->p_vars[$this->p_vars['docblock_type']]->setDesc($this->p_vars['docblock_desc']);
  1490.             unset($this->p_vars['docblock_desc']);
  1491. //            var_dump($this->p_vars[$this->p_vars['docblock_type']]);
  1492. //            exit;
  1493.             if ($this->p_vars['docblock_type'== 'docblock')
  1494.             {
  1495.                 $this->publishEvent(PHPDOCUMENTOR_EVENT_DOCBLOCK,$this->p_vars[$this->p_vars['docblock_type']]);
  1496.                 unset($this->p_vars[$this->p_vars['docblock_type']]);
  1497.                 $this->p_vars[$this->p_vars['docblock_type']] new parserDocBlock();
  1498.             }
  1499.             $this->p_flags['in_desc'true;
  1500.             $this->p_flags['in_tag'false;
  1501.             $this->p_flags['useperiod'false;
  1502.             $this->p_vars['line'array();
  1503.             $this->p_vars['linecount'0;
  1504.             $this->p_flags['start_docblock'true;
  1505.             $this->p_flags['valid_newline'true;
  1506.             $this->wp->setWhitespace(false);
  1507.         }
  1508.     }
  1509.  
  1510.     /**
  1511.      * handler for DOCKEYWORD_DESC.
  1512.      * this handler parses the short and long description of a dockeyword
  1513.      */
  1514.     
  1515.     function JavaDochandleDesc($word$pevent)
  1516.     {
  1517.         if ($this->p_flags['valid_newline'])
  1518.         {
  1519.             if ($word == '@' && $this->p_flags['startline'])
  1520.             {
  1521.                 return $this->handleTag($word$pevent);
  1522.             }
  1523.             if (!isset($this->p_vars['line'][$this->p_vars['linecount']]))
  1524.             {
  1525.                 $this->p_vars['line'][$this->p_vars['linecount']] new parserStringWithInlineTags;
  1526.             }
  1527.             if ($this->p_vars['last_word'== "." && $this->p_flags['useperiod'== false)
  1528.             {
  1529.                 $this->p_vars['periodline'$this->p_vars['linecount'];
  1530.                 $this->p_vars['shortdesc'new parserDesc;
  1531.                 for($i 0($i <= $this->p_vars['periodline']&& ($i count($this->p_vars['line']))$i++)
  1532.                 {
  1533.                     if (isset($this->p_vars['line'][$i]))
  1534.                     $this->p_vars['shortdesc']->add($this->p_vars['line'][$i]);
  1535.                 }
  1536.                 $this->p_flags['useperiod'true;
  1537.             }
  1538.             $this->p_vars['line'][$this->p_vars['linecount']]->add($word);
  1539. //            debug("DESC $word");
  1540.         }
  1541.         $this->handleCR($word);
  1542.     }
  1543.     
  1544.     /**
  1545.      * handler for DOCBLOCK.
  1546.      * this handler recognizes @tags in DocBlocks and parses them for display.
  1547.      * It also parses out unknown tags into their own array for use by the docblock
  1548.      */
  1549.     
  1550.     function BetterhandleDocblock($word$pevent)
  1551.     {
  1552.         $e1 $this->checkEventPush$word$pevent);
  1553.         if (!$this->wp->returnWhiteSpace)
  1554.         {
  1555.             addErrorDie(PDERROR_NEED_WHITESPACE);
  1556.         }
  1557.         if (!isset($this->p_vars[$this->p_vars['docblock_type']]|| !$this->p_vars[$this->p_vars['docblock_type']])
  1558.         {
  1559.             $this->p_vars[$this->p_vars['docblock_type']] new parserDocBlock();
  1560.             $this->p_vars['returntype'false;
  1561.             $this->p_vars['vartype'false;
  1562.             $this->p_flags['startdocblock'true;
  1563.             $this->p_flags['valid_newline'true;
  1564.             $this->p_flags['startline'true;
  1565.             $this->p_flags['newline'true;
  1566.             $this->p_flags['in_desc'true;
  1567.             $this->p_flags['in_tag'false;
  1568.             $this->p_flags['useperiod'false;
  1569.             $this->p_vars['line'array();
  1570.             $this->p_vars['linecount'0;
  1571.         }
  1572.         $e $this->checkEventPop$word$pevent);
  1573.         if (!$e1 && !$e)
  1574.         {
  1575.             if ($this->p_flags['in_desc']$this->handleDesc($word$pevent);
  1576.             else $this->handleTags($word$pevent);
  1577.         }
  1578.         if ($e)
  1579.         {
  1580.             if (!isset($this->p_vars['periodline'])) $this->p_vars['periodline'0;
  1581.             if ($this->p_vars['periodline'3)
  1582.             {
  1583.                 $this->p_flags['useperiod'false;
  1584.             else
  1585.             {
  1586.                 for($i 0$i $this->p_vars['periodline']$i++)
  1587.                 {
  1588.                     if (isset($this->p_vars['line'][$i]))
  1589.                     {
  1590.                         if ($this->p_vars['line'][$i]->trimmedStrlen(== && isset($this->p_vars['line'][$i 1]&& $this->p_vars['line'][$i 1]->trimmedStrlen())
  1591.                         {
  1592.                             $this->p_vars['periodline'$i;
  1593.                         }
  1594.                     }
  1595.                 }
  1596.             }
  1597.             // figure out the shortdesc
  1598.             if ($this->p_flags['useperiod'=== false)
  1599.             {
  1600.                 // use the first non blank line for short desc
  1601.                 for($i 0$i count($this->p_vars['line'])$i++)
  1602.                 {
  1603.                     if (!isset($this->p_vars['line'][$i]))
  1604.                     $this->p_vars['line'][$inew parserStringWithInlineTags;
  1605.                     if ($this->p_vars['line'][$i]->trimmedStrlen(0)
  1606.                     {
  1607.                         $this->p_vars['periodline'$i;
  1608.                         $i count($this->p_vars['line']);
  1609.                     }
  1610.                 }
  1611.                         
  1612.                 // check to see if we are going to use a blank line to end the shortdesc
  1613.                 // this can only be in the first 4 lines
  1614.                 if (count($this->p_vars['line']4)
  1615.                 {
  1616.                     $max 4;
  1617.                 else {
  1618.                     $max count($this->p_vars['line']);
  1619.                 }
  1620.  
  1621.                 for($i $this->p_vars['periodline']$i $max$i++)
  1622.                 {
  1623.                     if (isset($this->p_vars['line'][$i]))
  1624.                     if ($this->p_vars['line'][$i]->trimmedStrlen(== 0)
  1625.                     {
  1626.                         $this->p_vars['periodline'$i;
  1627.                         $i $max;
  1628.                     }
  1629.                 }
  1630.             }
  1631.  
  1632.             if ($this->p_vars['docblock_type'== 'docblock')
  1633.             {
  1634.                 $this->p_vars['shortdesc'new parserDesc;
  1635.                 for($i 0($i <= $this->p_vars['periodline']&& ($i count($this->p_vars['line']))$i++)
  1636.                 {
  1637.                     if (isset($this->p_vars['line'][$i]))
  1638.                     $this->p_vars['shortdesc']->add($this->p_vars['line'][$i]);
  1639.                 }
  1640.                 $this->p_vars['periodline']++;
  1641.     
  1642.                 $this->p_vars['docblock_desc'new parserDesc;
  1643.                 if (isset($this->p_vars['docblock_template']))
  1644.                 {
  1645.                     // copy template values if not overridden
  1646.                     if (!$this->p_vars['docblock']->getExplicitPackage())
  1647.                     {
  1648.                         if ($p $this->p_vars['docblock_template']->getKeyword('package'))
  1649.                         {
  1650.                             $this->p_vars['docblock']->addKeyword('package',$p);
  1651.                             $this->p_vars['docblock']->setExplicitPackage();
  1652.                         }
  1653.                         if ($p $this->p_vars['docblock_template']->getKeyword('category'))
  1654.                         {
  1655.                             $this->p_vars['docblock']->addKeyword('category',$p);
  1656.                             $this->p_vars['docblock']->setExplicitCategory();
  1657.                         }
  1658.                         if ($p $this->p_vars['docblock_template']->getKeyword('subpackage'))
  1659.                         {
  1660.                             $this->p_vars['docblock']->addKeyword('subpackage',$p);
  1661.                         }
  1662.                     }
  1663.                     $tags $this->p_vars['docblock_template']->listTags();
  1664.                     foreach($tags as $tag)
  1665.                     {
  1666.                         $this->p_vars['docblock']->addKeyword($tag->keyword,$tag->value);
  1667.                     }
  1668.                     if (!count($this->p_vars['docblock']->params)) $this->p_vars['docblock']->params $this->p_vars['docblock_template']->params;
  1669.                     $this->p_vars['docblock_desc']->add($this->p_vars['docblock_template']->desc);
  1670.                 }
  1671.     //            echo "i = ".$this->p_vars['periodline']."; i < " . count($this->p_vars['line']) . "\n";
  1672.                 for($i $this->p_vars['periodline']$i count($this->p_vars['line'])$i++)
  1673.                 {
  1674.                     // the line will not be set if it doesn't start with a *
  1675.                     if (isset($this->p_vars['line'][$i]))
  1676.                     $this->p_vars['docblock_desc']->add($this->p_vars['line'][$i]);
  1677.                 }
  1678.             else
  1679.             {
  1680.                 $this->p_vars['shortdesc'new parserDesc;
  1681.                 for($i 0($i <= $this->p_vars['periodline']&& ($i count($this->p_vars['line']))$i++)
  1682.                 {
  1683.                     if (isset($this->p_vars['line'][$i]))
  1684.                     $this->p_vars['shortdesc']->add($this->p_vars['line'][$i]);
  1685.                 }
  1686.                 $this->p_vars['periodline']++;
  1687.     
  1688.                 $this->p_vars['docblock_desc'new parserDesc;
  1689.                 for($i=$this->p_vars['periodline']$i count($this->p_vars['line'])$i++)
  1690.                 {
  1691.                     if (isset($this->p_vars['line'][$i]))
  1692.                     $this->p_vars['docblock_desc']->add($this->p_vars['line'][$i]);
  1693.                 }
  1694.             }
  1695.  
  1696.  
  1697.             $this->p_vars[$this->p_vars['docblock_type']]->setShortDesc($this->p_vars['shortdesc']);
  1698.             $this->p_vars[$this->p_vars['docblock_type']]->setDesc($this->p_vars['docblock_desc']);
  1699.             unset($this->p_vars['docblock_desc']);
  1700. //            var_dump($this->p_vars[$this->p_vars['docblock_type']]);
  1701. //            exit;
  1702.             if ($this->p_vars['docblock_type'== 'docblock')
  1703.             {
  1704.                 $this->publishEvent(PHPDOCUMENTOR_EVENT_DOCBLOCK,$this->p_vars[$this->p_vars['docblock_type']]);
  1705.                 unset($this->p_vars[$this->p_vars['docblock_type']]);
  1706.                 $this->p_vars[$this->p_vars['docblock_type']] new parserDocBlock();
  1707.             else
  1708.             {
  1709.                 $this->publishEvent(PHPDOCUMENTOR_EVENT_DOCBLOCK_TEMPLATE,$this->p_vars[$this->p_vars['docblock_type']]);
  1710.             }
  1711.             $this->p_flags['in_desc'true;
  1712.             $this->p_flags['in_tag'false;
  1713.             $this->p_flags['useperiod'false;
  1714.             $this->p_vars['line'array();
  1715.             $this->p_vars['linecount'0;
  1716.             $this->p_flags['start_docblock'true;
  1717.             $this->p_flags['valid_newline'true;
  1718.             $this->wp->setWhitespace(false);
  1719.             $this->p_vars['docblock_type''docblock';
  1720.         }
  1721.     }
  1722.     
  1723.     /**
  1724.      * Handles docblock templates
  1725.      * @tutorial phpDocumentor.howto.pkg#basics.docblocktemplate
  1726.      */
  1727.     function handleDocBlockTemplate($word$pevent)
  1728.     {
  1729.         $this->p_vars['docblock_type''docblock_template';
  1730.         $this->p_vars['event_stack']->popEvent();
  1731.         $this->p_vars['event_stack']->pushEvent(PARSER_EVENT_DOCBLOCK);
  1732.         // fool the docblock handler into thinking everything is totally normal
  1733.         $this->p_vars['last_word''/**';
  1734.         $pevent PARSER_EVENT_DOCBLOCK;
  1735.         $this->BetterhandleDocBlock($word$pevent);
  1736.     }
  1737.     
  1738.     /**
  1739.      * Handles closing docblock templates /**#@-* /
  1740.      * @tutorial phpDocumentor.howto.pkg#basics.docblocktemplate
  1741.      */
  1742.     function handleEndDocBlockTemplate($word$pevent)
  1743.     {
  1744.         unset($this->p_vars['docblock_template']);
  1745.         $this->p_vars['event_stack']->popEvent();
  1746.     }
  1747.     /**#@-*/
  1748.     /**
  1749.      * Handles a new line in a DocBlock
  1750.      * @param string token containing a newline \n
  1751.      * @access private
  1752.      */
  1753.     function handleCR($word)
  1754.     {
  1755.         $this->laststart $this->p_flags['startline'];
  1756.         if ($word == "\n" || $word == ".\n")
  1757.         {
  1758.             $this->p_flags['start_docblock'false;
  1759.             $this->p_flags['newline'true;
  1760.             $this->p_flags['valid_newline'false;
  1761.             if ($this->p_flags['in_desc'&& !$this->p_flags['useperiod'])
  1762.             {
  1763.                 if ($word == ".\n")
  1764.                 {
  1765.                     $this->p_flags['useperiod'true;
  1766.                     $this->p_vars['periodline'$this->p_vars['linecount'];
  1767.                 }
  1768.             }
  1769.         else
  1770.         {
  1771.             if ($this->p_flags['valid_newline'&& strlen(trim($word)))
  1772.             {
  1773.                 $this->p_flags['startline'false;
  1774.             }
  1775.             if ($this->p_flags['newline'&& ($word == '*' || $this->p_flags['start_docblock']))
  1776.             {
  1777.                 $this->p_flags['newline'false;
  1778.                 $this->p_flags['valid_newline'true;
  1779.                 if (!$this->p_flags['start_docblock'])
  1780.                 $this->p_vars['linecount']++;
  1781.                 $this->p_flags['startline'true;
  1782.                 $justset true;
  1783. //                debug('valid newline');
  1784.             }
  1785.         }
  1786.     }
  1787.     
  1788.     /**
  1789.      * handler for DOCKEYWORD_DESC.
  1790.      * this handler parses the short and long description of a dockeyword
  1791.      * @access private
  1792.      */
  1793.     
  1794.     function handleDesc($word$pevent)
  1795.     {
  1796. //        echo "|$word|\n";
  1797.         if ($this->p_flags['valid_newline'])
  1798.         {
  1799.             if ($word == '@' && $this->p_flags['startline'])
  1800.             {
  1801.                 return $this->handleTag($word$pevent);
  1802.             }
  1803.             if ($this->p_vars['last_word'== ". " || $this->p_vars['last_word'== ".\t")
  1804.             {
  1805.                 $this->p_flags['useperiod'true;
  1806.                 $this->p_vars['periodline'$this->p_vars['linecount'];
  1807.                 $this->p_vars['linecount']++;
  1808.             }
  1809.             if (!isset($this->p_vars['line'][$this->p_vars['linecount']]))
  1810.             {
  1811.                 $this->p_vars['line'][$this->p_vars['linecount']] new parserStringWithInlineTags;
  1812.             }
  1813.             if ($this->p_flags['startline'])
  1814.             {
  1815.                 if ($word[0== ' '$word substr($word,1);
  1816. //                $word = ltrim($word," \t");
  1817.             }
  1818.             if ($word != ''$this->p_vars['line'][$this->p_vars['linecount']]->add($word);
  1819. //            debug("DESC $word");
  1820.         }
  1821.         $this->handleCR($word);
  1822.     }
  1823.     
  1824.     /**#@+
  1825.      * @access private
  1826.      * @param string token parsed from source
  1827.      * @param integer parser constant from {@link Parser.inc}
  1828.      */
  1829.     /**
  1830.      * handler for DOCKEYWORD_TAGS.
  1831.      * this handler recognizes @tags in DocBlocks and parses them for display
  1832.      * I think this may be unused.  We'll delete from 1.1 if so
  1833.      */
  1834.     function handleTags($word$pevent)
  1835.     {
  1836.         if ($this->p_flags['valid_newline'])
  1837.         {
  1838. //            debug("TAGS $word");
  1839.         }
  1840.         $this->handleCR($word);
  1841.     }
  1842.     
  1843.     /**
  1844.      * handler for DOCKEYWORD.
  1845.      * this handler recognizes @tags in DocBlocks and parses them for display
  1846.      */
  1847.     function handleTag($word$pevent)
  1848.     {
  1849.         if ($this->p_flags['in_desc'&& !$this->p_flags['valid_newline'])
  1850.         {
  1851.             $this->p_vars['event_stack']->popEvent();
  1852.             return $this->handleDesc($word$pevent);
  1853.         }
  1854. //        if ($this->p_vars['last_word'] == '@') fancy_debug('here'.$word,$this->p_flags['startline'],$this->p_flags['in_tag']);
  1855.         if ($this->p_vars['tagname'== 'author')
  1856.         {
  1857.             if ($word == '<')
  1858.             {
  1859.                 $this->p_vars['event_stack']->pushEvent(PARSER_EVENT_DOCKEYWORD_EMAIL);
  1860.                 return $this->handleDockeywordEmail($word$pevent);
  1861.             }
  1862.         }
  1863.         if ($this->checkEventPush$word$pevent)) return;
  1864.         if ($this->p_vars['last_word'== '@' && !$this->p_flags['startline'&& $this->p_flags['in_desc'])
  1865.         {
  1866.             // fix 1203445
  1867.             if (!isset($this->p_vars['line'][$this->p_vars['linecount']]))
  1868.             {
  1869.                 $this->p_vars['line'][$this->p_vars['linecount']] new parserStringWithInlineTags;
  1870.             }
  1871.             $this->p_vars['event_stack']->popEvent();
  1872.             $this->p_vars['line'][$this->p_vars['linecount']]->add('@');
  1873.             return $this->handleDesc($word$pevent);
  1874.         elseif($this->p_vars['last_word'== '@' && !strlen(trim($word)) && empty($this->p_vars['tagname']&& $this->p_flags['in_desc'])
  1875.         {
  1876.             // fix 1203445
  1877.             if (!isset($this->p_vars['line'][$this->p_vars['linecount']]))
  1878.             {
  1879.                 $this->p_vars['line'][$this->p_vars['linecount']] new parserStringWithInlineTags;
  1880.             }
  1881.             $pevent $this->p_vars['event_stack']->popEvent();
  1882.             $this->p_vars['line'][$this->p_vars['linecount']]->add('@');
  1883.             return $this->handleDesc($word$pevent);
  1884.         }
  1885.         if ($word == '@' && $this->p_flags['startline'&& $this->p_flags['in_tag'])
  1886.         {
  1887.             $this->wp->backupPos($word);
  1888.             $white $this->wp->returnWhiteSpace;
  1889.             $this->wp->setWhitespace(true);
  1890.             $word1 $this->wp->getWord();
  1891.             $this->wp->backupPos($word1);
  1892.             if (strlen(trim($word1)))
  1893.             {
  1894.                 $this->endTag();
  1895.             }
  1896.             $this->wp->getWord();
  1897.             $this->wp->setWhitespace($white);
  1898.         }
  1899.         $this->p_flags['in_tag'true;
  1900.         $e $this->checkEventPop($word$pevent);
  1901.         if (!$e)
  1902.         {
  1903.             if ($this->p_flags['valid_newline'])
  1904.             {
  1905.                 if (($this->p_flags['startline'|| $this->laststart&& $word != '@')
  1906.                 {
  1907.                     if ($this->p_vars['last_word'== '@')
  1908.                     {
  1909. //                        debug("TAGSTART $word");
  1910.                         $this->p_flags['in_tag'true;
  1911.                         $this->p_vars['tagname'$word;
  1912.                         $this->p_flags['startline'false;
  1913.                         $this->p_vars['tag_value'new parserStringWithInlineTags;
  1914.                     else
  1915.                     {
  1916. //                        debug("TAG1 $word");
  1917.                         if (isset($this->tagHandlers[$this->p_vars['tagname']]))
  1918.                         $handler $this->tagHandlers[$this->p_vars['tagname']];
  1919.                         else $handler $this->tagHandlers['*'];
  1920.                         $this->$handler($word);
  1921.                     }
  1922.                 else
  1923.                 {
  1924.                     if (empty($this->p_vars['tagname']))
  1925.                     {
  1926.                         if ($this->p_flags['in_desc'])
  1927.                         {
  1928.                             $this->p_flags['in_tag'false;
  1929.                             // fix 1203445
  1930.                             if (!isset($this->p_vars['line'][$this->p_vars['linecount']]))
  1931.                             {
  1932.                                 $this->p_vars['line'][$this->p_vars['linecount']] =
  1933.                                     new parserStringWithInlineTags;
  1934.                             }
  1935.                             $this->p_vars['line'][$this->p_vars['linecount']]->add('@');
  1936.                             $this->p_vars['event_stack']->popEvent();
  1937.                             $this->handleCR($word);
  1938.                             return $this->handleDesc($word$pevent);
  1939.                         }
  1940.                     }
  1941. //                    debug("TAG2 $word");
  1942.                     if (isset($this->tagHandlers[$this->p_vars['tagname']]))
  1943.                     $handler $this->tagHandlers[$this->p_vars['tagname']];
  1944.                     else $handler $this->tagHandlers['*'];
  1945.                     $this->$handler($word);
  1946.                 }
  1947.             }
  1948.             $this->handleCR($word);
  1949.         }
  1950.         $this->p_flags['in_desc'false;
  1951.         if ($e)
  1952.         {
  1953.             $this->endTag();
  1954.             $this->wp->setWhitespace(false);
  1955.             // walk back a word
  1956.             $this->wp->backupPos($word);
  1957.             $this->wp->setWhitespace(true);
  1958.         }
  1959.     }
  1960.     /**#@-*/
  1961.     /**
  1962.      * Called to clean up at the end of parsing a @tag in a docblock
  1963.      */
  1964.     function endTag()
  1965.     {
  1966.         if (isset($this->tagHandlers[$this->p_vars['tagname']]))
  1967.         $handler $this->tagHandlers[$this->p_vars['tagname']];
  1968.         else $handler $this->tagHandlers['*'];
  1969.         $this->$handler(false);
  1970.         $this->p_vars['tagname''';
  1971.         $this->p_flags['startline'true;
  1972. //        debug("ENDTAG");
  1973.     }
  1974.     
  1975.     /**#@+
  1976.      * Tag Handlers
  1977.      * @param string 
  1978.      */
  1979.     /**
  1980.      * Handles all standard tags that only have a description
  1981.      */
  1982.     function defaultTagHandler($word)
  1983.     {
  1984.         if ($word !== false)
  1985.         {
  1986.             $this->p_vars['tag_value']->add($word);
  1987.         else
  1988.         {
  1989.             $this->p_vars[$this->p_vars['docblock_type']]->addKeyword($this->p_vars['tagname'],$this->p_vars['tag_value']);
  1990.         }
  1991.     }
  1992.     
  1993.     /**
  1994.      * Handles tags like '@filesource' that only work in PHP 4.3.0+
  1995.      */
  1996.     function invalidTagHandler($word)
  1997.     {
  1998.         if ($word === false)
  1999.         {
  2000.             addError(PDERROR_TAG_NOT_HANDLED,$this->p_vars['tagname']);
  2001.         }
  2002.     }
  2003.     
  2004.     /**
  2005.      * handles @package
  2006.      * @tutorial tags.package.pkg
  2007.      */
  2008.     function packageTagHandler($word)
  2009.     {
  2010.         if ($word !== false)
  2011.         {
  2012.             $this->p_vars['tag_value']->add($word);
  2013.         else
  2014.         {
  2015.             $this->p_vars[$this->p_vars['docblock_type']]->addKeyword($this->p_vars['tagname'],$this->p_vars['tag_value']);
  2016.             $this->p_vars[$this->p_vars['docblock_type']]->setExplicitPackage();
  2017.         }
  2018.     }
  2019.     
  2020.     /**
  2021.      * handles @example
  2022.      * @tutorial tags.example.pkg
  2023.      */
  2024.     function exampleTagHandler($word)
  2025.     {
  2026.         if ($word !== false)
  2027.         {
  2028.             $this->p_vars['tag_value']->add($word);
  2029.         else
  2030.         {
  2031.             $this->p_vars[$this->p_vars['docblock_type']]->addExample($this->p_vars['tag_value']$this->p_vars['parsepath']);
  2032.         }
  2033.     }
  2034.     
  2035.     /**
  2036.      * handles @category
  2037.      * @tutorial tags.category.pkg
  2038.      */
  2039.     function categoryTagHandler($word)
  2040.     {
  2041.         if ($word !== false)
  2042.         {
  2043.             $this->p_vars['tag_value']->add($word);
  2044.         else
  2045.         {
  2046.             $this->p_vars[$this->p_vars['docblock_type']]->addKeyword($this->p_vars['tagname'],$this->p_vars['tag_value']);
  2047.             $this->p_vars[$this->p_vars['docblock_type']]->setExplicitCategory();
  2048.         }
  2049.     }
  2050.     
  2051.     /**
  2052.      * handles @global
  2053.      * @tutorial tags.global.pkg
  2054.      */
  2055.     function globalTagHandler($word)
  2056.     {
  2057.         if ($word !== false)
  2058.         {
  2059.             // no data yet
  2060.             $a trim($this->p_vars['tag_value']->getString());
  2061.             if (empty($a))
  2062.             {
  2063.                 // not an empty word
  2064.                 if (trim($word!= '')
  2065.                 {
  2066.                     if (!empty($this->p_vars['global_type']))
  2067.                     {
  2068.                         if (!$this->p_flags['define_global'&& !$this->p_flags['function_global'])
  2069.                         {
  2070.                             // @global type $GLOBALVARNAME ?
  2071.                             if (substr($word,0,1== '$')
  2072.                             {
  2073.                                 $this->p_flags['define_global'true;
  2074.                                 $this->p_flags['function_global'false;
  2075.                                 $this->p_vars['find_global'$word;
  2076.                             else
  2077.                             // function @global type description
  2078.                                 $this->p_flags['function_global'true;
  2079.                                 $this->p_flags['define_global'false;
  2080.                                 $this->p_vars['tag_value']->add($word);
  2081.                             }
  2082.                         else
  2083.                         {
  2084.                             if ($this->p_flags['define_global'])
  2085.                             {
  2086.                                 $this->p_vars['find_global'.= $word;
  2087.                             elseif($this->p_flags['function_global'])
  2088.                             {
  2089.                                 // description, to be added to the tag
  2090.                                 $this->p_vars['tag_value']->add($word);
  2091.                             }
  2092.                         }
  2093.                     else
  2094.                     {
  2095.                         $this->p_vars['global_type'$word;
  2096.                     
  2097.                 else $this->p_vars['tag_value']->add($word)// add whitespace to the tag description
  2098.             else
  2099.             // tag_value has data, must be a function @global
  2100.                 $this->p_vars['tag_value']->add($word);
  2101.             }
  2102.         else
  2103.         // endtag
  2104.             if ($this->p_flags['define_global'])
  2105.             {
  2106.                 $this->findGlobal($this->p_vars['find_global']);
  2107.             }
  2108.             elseif ($this->p_flags['function_global'])
  2109.             {
  2110.                 $this->p_vars[$this->p_vars['docblock_type']]->addFuncGlobal($this->p_vars['global_type'],$this->p_vars['tag_value']);
  2111.                 $this->p_vars['global_type''';
  2112.             }
  2113.             else
  2114.             {
  2115.                 addError(PDERROR_MALFORMED_GLOBAL_TAG);
  2116.             }
  2117.             $this->p_vars['find_global''';
  2118.             $this->p_flags['define_global'false;
  2119.             $this->p_flags['function_global'false;
  2120.         }
  2121.     }
  2122.     
  2123.     /**
  2124.      * handles @staticvar
  2125.      * @tutorial tags.staticvar.pkg
  2126.      */
  2127.     function staticvarTagHandler($word)
  2128.     {
  2129.         if ($word !== false)
  2130.         {
  2131.             if (!$this->p_vars['returntype']$this->p_vars['returntype'trim($word);
  2132.             else
  2133.             {
  2134.                 if (!$this->p_vars['paramname'])
  2135.                 {
  2136.                     if (substr(trim($word),0,1== "$")
  2137.                     $this->p_vars['paramname'trim($word);
  2138.                     else $this->p_vars['tag_value']->add($word);
  2139.                 else
  2140.                 {
  2141.                     if (0)//strtolower($this->p_vars['paramtype']) == 'object')
  2142.                     {
  2143.                         if (strlen(trim($word)))
  2144.                         $this->p_vars['paramname'trim($word);
  2145.                     else $this->p_vars['tag_value']->add($word);
  2146.                 }
  2147.             }
  2148.         else
  2149.         {
  2150.             if (!$this->p_vars['paramname'])
  2151.             $this->p_vars[$this->p_vars['docblock_type']]->addStaticVar(null,$this->p_vars['returntype'],$this->p_vars['tag_value']);
  2152.             else
  2153.             $this->p_vars[$this->p_vars['docblock_type']]->addStaticVar($this->p_vars['paramname'],$this->p_vars['returntype'],$this->p_vars['tag_value']);
  2154.             $this->p_vars['paramname'false;
  2155.             $this->p_vars['returntype'false;
  2156.         }
  2157.     }
  2158.     
  2159.     /**
  2160.      * handles @uses
  2161.      * @tutorial tags.uses.pkg
  2162.      */
  2163.     function usesTagHandler($word)
  2164.     {
  2165.         if ($word !== false)
  2166.         {
  2167.             if (!$this->p_vars['seelement']$this->p_vars['seelement'trim($word);
  2168.             else
  2169.             {
  2170.                 $this->p_vars['tag_value']->add($word);
  2171.             }
  2172.         else
  2173.         {
  2174.             $see new parserStringWithInlineTags;
  2175.             $see->add($this->p_vars['seelement']);
  2176.             $this->p_vars[$this->p_vars['docblock_type']]->addUses($see,$this->p_vars['tag_value']);
  2177.             $this->p_vars['seelement'false;
  2178.         }
  2179.     }
  2180.     
  2181.     /**
  2182.      * handles @param
  2183.      * @tutorial tags.param.pkg
  2184.      */
  2185.     function paramTagHandler($word)
  2186.     {
  2187.         if ($word !== false)
  2188.         {
  2189.             if (!$this->p_vars['returntype']$this->p_vars['returntype'trim($word);
  2190.             else
  2191.             {
  2192.                 if (!$this->p_vars['paramname'])
  2193.                 {
  2194.                     if (substr(trim($word),0,1== "$|| substr(trim($word),0,2== "&$")
  2195.                     $this->p_vars['paramname'trim($word);
  2196.                     else $this->p_vars['tag_value']->add($word);
  2197.                 else
  2198.                 {
  2199.                     if (0)//strtolower($this->p_vars['paramtype']) == 'object')
  2200.                     {
  2201.                         if (strlen(trim($word)))
  2202.                         $this->p_vars['paramname'trim($word);
  2203.                     else $this->p_vars['tag_value']->add($word);
  2204.                 }
  2205.             }
  2206.         else
  2207.         {
  2208.             if (!$this->p_vars['paramname'])
  2209.             $this->p_vars[$this->p_vars['docblock_type']]->addParam(null,$this->p_vars['returntype'],$this->p_vars['tag_value']);
  2210.             else
  2211.             $this->p_vars[$this->p_vars['docblock_type']]->addParam($this->p_vars['paramname'],$this->p_vars['returntype'],$this->p_vars['tag_value']);
  2212.             $this->p_vars['paramname'false;
  2213.             $this->p_vars['returntype'false;
  2214.         }
  2215.     }
  2216.     
  2217.     /**
  2218.      * handles @return
  2219.      * @tutorial tags.return.pkg
  2220.      */
  2221.     function returnTagHandler($word)
  2222.     {
  2223.         if ($word !== false)
  2224.         {
  2225.             if (!$this->p_vars['returntype']$this->p_vars['returntype'trim($word);
  2226.             else
  2227.             {
  2228.                 if (strtolower($this->p_vars['returntype']== 'object')
  2229.                 {
  2230.                     if (strlen(trim($word)))
  2231.                     $this->p_vars['returntype'trim($word);
  2232.                 else $this->p_vars['tag_value']->add($word);
  2233.             }
  2234.         else
  2235.         {
  2236.             $this->p_vars[$this->p_vars['docblock_type']]->addReturn($this->p_vars['returntype'],$this->p_vars['tag_value']);
  2237.             $this->p_vars['returntype'false;
  2238.         }
  2239.     }
  2240.     
  2241.     /**
  2242.      * handles @var
  2243.      * @tutorial tags.var.pkg
  2244.      */
  2245.     function varTagHandler($word)
  2246.     {
  2247.         if ($word)
  2248.         {
  2249.             if (!$this->p_vars['vartype']$this->p_vars['vartype'trim($word);
  2250.             else
  2251.             {
  2252.                 if (strtolower($this->p_vars['vartype']== 'object')
  2253.                 {
  2254.                     if (strlen(trim($word)))
  2255.                     $this->p_vars['vartype'trim($word);
  2256.                 }
  2257.                 else $this->p_vars['tag_value']->add($word);
  2258.             }
  2259.         elseif ($word === false)
  2260.         {
  2261.             $this->p_vars[$this->p_vars['docblock_type']]->addVar($this->p_vars['vartype'],$this->p_vars['tag_value']);
  2262.             $this->p_vars['vartype'false;
  2263.         }
  2264.     }
  2265.     /**#@-*/
  2266.     /** @access private */
  2267.     function getSource()
  2268.     {
  2269.         $this->p_flags['get_source'true;
  2270.     }
  2271.     /**#@+
  2272.      * @access private
  2273.      * @param string token parsed from source
  2274.      * @param integer parser constant from {@link Parser.inc}
  2275.      */
  2276.     /**
  2277.      * handler for DOCKEYWORD_EMAIL.
  2278.      * this handler recognizes angle brackets < and > surrounding an email address in an @author tag,
  2279.      * and returns a mailto: hyperlink
  2280.      */
  2281.     
  2282.     function handleDockeywordEmail($word$pevent)
  2283.     {
  2284.         //echo $this->wp->getPos() . ": |$word|\n";
  2285.         if (!$this->checkEventPop($word,$pevent&& $word != "<")
  2286.         {
  2287.             if (strstr($word,"@"))
  2288.             {
  2289.                 $this->p_vars['tag_value']->add('<');
  2290.                 $this->p_vars['tag_value']->add(new parserLinkInlineTag("mailto:$word",$word));
  2291.                 $this->p_vars['tag_value']->add('>');
  2292.             else {
  2293.                 $this->p_vars['tag_value']->add("<$word>");
  2294.             }
  2295.         }
  2296.     }
  2297.  
  2298.     /**
  2299.      * handler for INLINE_DOCKEYWORD.
  2300.      * this handler recognizes {@inline tags} like link, and parses them, replacing them directly
  2301.      * in the text flow with their output.
  2302.      */
  2303.     
  2304.     function handleInlineDockeyword($word$pevent)
  2305.     {
  2306.         //        echo $this->wp->getPos() . ": |$word|\n";
  2307.  
  2308.         //        echo "docktype: $this->p_vars['inline_dockeyword_type']\n";
  2309.         if (!isset($this->p_vars['inline_dockeyword_type'])) $this->p_vars['inline_dockeyword_type'false;
  2310.         if (!isset($this->p_vars['inline_dockeyword_data'])) $this->p_vars['inline_dockeyword_data''';
  2311.         if (!$this->p_vars['inline_dockeyword_type'])
  2312.         {
  2313.             if (in_array($word,$this->allowableInlineTags))
  2314.             {
  2315.                 if ($word == '}')
  2316.                 $this->p_vars['inline_dockeyword_type''';
  2317.                 else
  2318.                 $this->p_vars['inline_dockeyword_type'strtolower($word);
  2319.                 $this->p_vars['whitesp'$this->wp->returnWhiteSpace;
  2320.                 $this->wp->setWhiteSpace(true);
  2321.             else {
  2322.                 if ($this->p_flags['in_desc'])
  2323.                 {
  2324.                     // fix 1203445
  2325.                     if (!isset($this->p_vars['line'][$this->p_vars['linecount']]))
  2326.                     {
  2327.                         $this->p_vars['line'][$this->p_vars['linecount']] =
  2328.                             new parserStringWithInlineTags;
  2329.                     }
  2330.                     if ($word == '}')
  2331.                     {
  2332.                         $this->p_vars['line'][$this->p_vars['linecount']]->add('{@');
  2333.                     else
  2334.                     {
  2335.                         $this->p_vars['line'][$this->p_vars['linecount']]->add('{@'.$word);
  2336.                     }
  2337.                 elseif($this->p_flags['in_tag'])
  2338.                 {
  2339.                     if ($word == '}')
  2340.                     $this->p_vars['tag_value']->add('{@'.$word);
  2341.                     else
  2342.                     $this->p_vars['tag_value']->add('{@'.$word);
  2343.                 }
  2344.                 $this->p_vars['event_stack']->popEvent();
  2345.                 $this->p_vars['inline_dockeyword_type'false;
  2346.                 $this->p_vars['inline_dockeyword_data''';
  2347.                 return;
  2348.             }
  2349.         else
  2350.         {
  2351.             if ($word != "}")
  2352.             {
  2353.                 $this->p_vars['inline_dockeyword_data'.= $word;
  2354.             }
  2355.         }
  2356.         if ($this->checkEventPop($word,$pevent))
  2357.         {
  2358.             $this->wp->setWhiteSpace($this->p_vars['whitesp']);
  2359.             if ($this->p_vars['inline_dockeyword_type']=='link')
  2360.             {
  2361.                 // support hyperlinks of any protocol
  2362.                 if (is_numeric(strpos($this->p_vars['inline_dockeyword_data'],'://')) || (strpos(trim($this->p_vars['inline_dockeyword_data']),'mailto:'=== 0))
  2363.                 {
  2364.                     // if there is more than 1 parameter, the stuff after the space is the hyperlink text
  2365.                     if (strpos(trim($this->p_vars['inline_dockeyword_data']),' '))
  2366.                     {
  2367.                         $i1 strpos(trim($this->p_vars['inline_dockeyword_data']),' '1;
  2368.                         $link substr(trim($this->p_vars['inline_dockeyword_data']),0,$i1 1);
  2369.                         $text substr(trim($this->p_vars['inline_dockeyword_data']),$i1);
  2370.                         $this->p_vars['inline_dockeyword_data'new parserLinkInlineTag($link,$text);
  2371. //                        '<a href="'.$link.'">'.$text.'</a>';
  2372.                     }
  2373.                     else
  2374.                     {
  2375.                         $this->p_vars['inline_dockeyword_data'new parserLinkInlineTag($this->p_vars['inline_dockeyword_data'],$this->p_vars['inline_dockeyword_data']);
  2376.                     }
  2377. //                    '<a href="'.$this->p_vars['inline_dockeyword_data'].'">'.$this->p_vars['inline_dockeyword_data'].'</a>';
  2378.                 else
  2379.                 {
  2380.                     if (!strpos($this->p_vars['inline_dockeyword_data'],','))
  2381.                     {
  2382.                         $testp explode('#',$this->p_vars['inline_dockeyword_data']);
  2383.                         if (count($testp1)
  2384.                         $this->p_vars['inline_dockeyword_data'new parserLinkInlineTag($this->p_vars['inline_dockeyword_data'],$testp[1]);
  2385.                         else
  2386.                         $this->p_vars['inline_dockeyword_data'new parserLinkInlineTag($this->p_vars['inline_dockeyword_data'],$this->p_vars['inline_dockeyword_data']);
  2387.                     else
  2388.                     $this->p_vars['inline_dockeyword_data'new parserLinkInlineTag($this->p_vars['inline_dockeyword_data'],$this->p_vars['inline_dockeyword_data']);
  2389.                 }
  2390.             }
  2391.             if ($this->p_vars['inline_dockeyword_type'== 'tutorial')
  2392.             {
  2393.                 $this->p_vars['inline_dockeyword_data'new parserTutorialInlineTag($this->p_vars['inline_dockeyword_data'],$this->p_vars['inline_dockeyword_data']);
  2394.             }
  2395.             if ($this->p_vars['inline_dockeyword_type'== 'source')
  2396.             {
  2397.                 $this->getSource();
  2398.                 $this->p_vars['inline_dockeyword_data'new parserSourceInlineTag($this->p_vars['inline_dockeyword_data']);
  2399.             }
  2400.             if ($this->p_vars['inline_dockeyword_type'== 'inheritdoc')
  2401.             {
  2402.                 $this->p_vars['inline_dockeyword_data'new parserInheritdocInlineTag();
  2403.             }
  2404.             if ($word == '*/')
  2405.             {
  2406.                 if (!isset($this->p_vars['inline_dockeyword_type'])) $this->p_vars['inline_dockeyword_type''';
  2407.                 if (!isset($this->p_vars['tagname'])) $this->p_vars['tagname''';
  2408.                 if (!isset($this->p_vars['tag_value']|| !is_object($this->p_vars['tag_value'])) $this->p_vars['tag_value'new parserStringWithInlineTags;
  2409.                 addError(PDERROR_UNTERMINATED_INLINE_TAG,$this->p_vars['inline_dockeyword_type'],$this->p_vars['tagname'],'@'.$this->p_vars['tagname'].' '.$this->p_vars['tag_value']->getString());
  2410.         // when we add the error class, raise error here: we reached the end of the docblock
  2411.                 $this->wp->backupPos($word)
  2412.             }
  2413.             if ($this->p_flags['in_desc'])
  2414.             {
  2415.                 $this->p_vars['line'][$this->p_vars['linecount']]->add($this->p_vars['inline_dockeyword_data']);
  2416.                 $this->p_vars['inline_dockeyword_type'false;
  2417.                 $this->p_vars['inline_dockeyword_data''';
  2418.             }
  2419.             elseif ($this->p_flags['in_tag'])
  2420.             {
  2421.                 $this->p_vars['tag_value']->add($this->p_vars['inline_dockeyword_data']);
  2422.                 $this->p_vars['inline_dockeyword_type'false;
  2423.                 $this->p_vars['inline_dockeyword_data''';
  2424.             }
  2425.         }
  2426.     }
  2427.  
  2428.     /**
  2429.      * handler for INCLUDE.
  2430.      * this handler recognizes include/require/include_once/include_once statements, and publishes the
  2431.      * data to Render
  2432.      */
  2433.     
  2434.     function handleInclude($word$pevent)
  2435.     {
  2436.         if (!$this->p_flags['in_include'])
  2437.         {
  2438.             $this->p_vars['linenum'$this->wp->linenum;
  2439.         }
  2440.         $this->p_flags['in_include'true;
  2441.         $a $this->checkEventPush$word$pevent);
  2442.         if (!$this->p_flags['includename_isset'])
  2443.         {
  2444.             $this->p_flags['includename_isset'true;
  2445.             $this->p_vars['include_name'$this->p_vars['last_word'];
  2446.             if ($a)
  2447.             $this->p_vars['include_value''';
  2448.             else
  2449.             $this->p_vars['include_value'$word;
  2450.             unset($this->p_vars['quote_data']);
  2451.         else
  2452.         {
  2453.             if (!$a)
  2454.             {
  2455.                 if (empty($this->p_vars['include_params_data']))
  2456.                 {
  2457.                     if (isset($this->p_vars['quote_data']))
  2458.                     {
  2459.                         $this->p_vars['include_value'.= '"'.$this->p_vars['quote_data'].'"';
  2460.                         unset($this->p_vars['quote_data']);
  2461.                     }
  2462.                     if ($word != ';')
  2463.                     $this->p_vars['include_value'.= $word;
  2464.                 }
  2465.             else
  2466.             {
  2467.                 $this->p_vars['include_params_data''';
  2468.             }
  2469.         }
  2470.  
  2471.         if ($this->checkEventPop($word,$pevent))
  2472.         {
  2473.             $this->p_vars['include'new parserInclude;
  2474.             $this->p_vars['include']->setLineNumber($this->p_vars['linenum']);
  2475.             $this->p_flags['in_include'false;
  2476.             $this->p_vars['include']->setName($this->p_vars['include_name']);
  2477.             $this->p_vars['include']->setValue($this->p_vars['include_value']);
  2478.             $this->publishEvent(PHPDOCUMENTOR_EVENT_INCLUDE,$this->p_vars['include']);
  2479.             $this->p_flags['includename_isset'false;
  2480.             unset($this->p_vars['include']);
  2481.             unset($this->p_vars['include_name']);
  2482.             unset($this->p_vars['include_value']);
  2483.             unset($this->p_vars['include_params_data']);
  2484.         }
  2485.     }
  2486.     
  2487.     /**
  2488.      * handler for INCLUDE_PARAMS.
  2489.      * this handler parses the contents of ( ) in include/require/include_once/include_once statements
  2490.      */
  2491.     
  2492.     function handleIncludeParams($word$pevent)
  2493.     {
  2494.         $this->checkEventPush$word$pevent);
  2495.         
  2496.         $this->p_flags['include_parens'true;
  2497.         if(!isset($this->p_vars['include_params_data'])) $this->p_vars['include_params_data''';
  2498.         
  2499.         if ($this->checkEventPop($word,$pevent))
  2500.         {
  2501.             if (isset($this->p_vars['quote_data']))
  2502.             {
  2503.                 $this->p_vars['include_value'$this->p_vars['include_params_data'].'"'.$this->p_vars['quote_data'].'"';
  2504.                 unset($this->p_vars['quote_data']);
  2505.             else {
  2506.                 if (!empty($this->p_vars['include_params_data']))
  2507.                 $this->p_vars['include_value'$this->p_vars['include_params_data'];
  2508.                 else
  2509.                 $this->p_vars['include_value'trim($this->p_vars['last_word']);
  2510.             }
  2511.         }
  2512.         if (isset($this->p_vars['quote_data']))
  2513.         {
  2514.             $this->p_vars['include_params_data'.= '"'.$this->p_vars['quote_data'].'"';
  2515.             unset($this->p_vars['quote_data']);
  2516.         }
  2517.         if (($word != "'"&& ($word != '"'))
  2518.         $this->p_vars['include_params_data'.= $word;
  2519.     }
  2520.     
  2521.     /**
  2522.      * handler for INCLUDE_PARAMS_PARENTHESIS.
  2523.      * this handler takes all parenthetical statements within file in:
  2524.      * include statement include(file), and handles them properly
  2525.      */
  2526.     
  2527.     function handleIncludeParamsParenthesis($word$pevent)
  2528.     {
  2529.         if (isset($this->p_vars['quote_data']))
  2530.         {
  2531.             $this->p_vars['include_params_data'.= '"'.$this->p_vars['quote_data'].'"';
  2532.             unset($this->p_vars['quote_data']);
  2533.         }
  2534.         $this->p_vars['include_params_data'.= $word;
  2535.         $this->checkEventPush$word$pevent);
  2536.         $this->checkEventPop$word$pevent);
  2537.     }
  2538.     /**#@-*/
  2539.     /**
  2540.      * this function checks whether parameter $word is a token for pushing a new event onto the Event Stack.
  2541.      * @return mixed    returns false, or the event number
  2542.      */
  2543.     
  2544.     function checkEventPush($word,$pevent)
  2545.     {
  2546.         $e false;
  2547.         if (isset($this->pushEvent[$pevent]))
  2548.         {
  2549.             if (isset($this->pushEvent[$pevent][strtolower($word)]))
  2550.             $e $this->pushEvent[$pevent][strtolower($word)];
  2551.         }
  2552.         if ($e)
  2553.         {
  2554.             $this->p_vars['event_stack']->pushEvent($e);
  2555.             return $e;
  2556.         else {
  2557.             return false;
  2558.         }
  2559.     }
  2560.  
  2561.     /**
  2562.      * this function checks whether parameter $word is a token for popping the current event off of the Event Stack.
  2563.      * @return mixed    returns false, or the event number popped off of the stack
  2564.      */
  2565.     
  2566.     function checkEventPop($word,$pevent)
  2567.     {
  2568.         if (!isset($this->popEvent[$pevent])) return false;
  2569.         if (in_array(strtolower($word),$this->popEvent[$pevent]))
  2570.         {
  2571.             return $this->p_vars['event_stack']->popEvent();
  2572.         else {
  2573.             return false;
  2574.         }
  2575.     }
  2576.  
  2577.     /**
  2578.      * setup the parser tokens, and the pushEvent/popEvent arrays
  2579.      * @see $tokens, $pushEvent, $popEvent
  2580.      */
  2581.     
  2582.     function setupStates()
  2583.     {
  2584.         $this->tokens[STATE_PHPCODE]            array(" ""\t",";","?>","</script>","/**#@+","/**#@-*/","/**""//","/*","#","\r\n","\n","\r","(",'<<<','"',"'");
  2585.         $this->tokens[STATE_QUOTE]            array("\\\"","\\\\","\"");
  2586.         $this->tokens[STATE_LOGICBLOCK]            array("{","}","\"","'","/*","//","#","?>","</script>",'<<<','global','static');
  2587.         $this->tokens[STATE_FUNC_GLOBAL]        array("\"","'","/*","//","#",";",",");
  2588.         $this->tokens[STATE_STATIC_VAR]        array("\"","'","/*","//","#",";",",",'=','array');
  2589.         $this->tokens[STATE_STATIC_VAR_VALUE]        array("/*","//","#"," ","\t",";","=","\"","'","array",",");
  2590.         $this->tokens[STATE_NOEVENTS]            array("<?php","<?",'<script language="php">');
  2591.         $this->tokens[STATE_COMMENTBLOCK]        array("*/","\n");
  2592.         $this->tokens[STATE_COMMENT]            array("\r\n","\r","\n");
  2593.         $this->tokens[STATE_DEFINE]            array(" ","(",";");
  2594.         $this->tokens[STATE_DEFINE_PARAMS]        array("/*","//","#",",",")"," ","'","\"","(");
  2595.         $this->tokens[STATE_DEFINE_PARAMS_PARENTHESIS]    array("(","'","\"",")");
  2596.         $this->tokens[STATE_FUNCTION_PARAMS]        array("/*","//","#","\"",",",")","="," ","'","(");
  2597.         $this->tokens[STATE_SINGLEQUOTE]        array("'","\\'","\\\\");
  2598.         $this->tokens[STATE_CLASS]            array(" ""\t""?>""</script>"";""}""{",
  2599.                                                       "/**#@+""/**#@-*/""/**""//""/*""#",
  2600.                                                       "\r\n""\n""\r","(");
  2601.         $this->tokens[STATE_DOCBLOCK]            array("*/","*","@","\r\n","\n","\r",". ",".\n",".\t",'{@');
  2602.         $this->tokens[STATE_DOCBLOCK_TEMPLATE]            array("*/","*","@","\r\n","\n","\r",". ",".\n",".\t",'{@');
  2603.         $this->tokens[STATE_DOCKEYWORD]            array("@","*/","*","\n","\r\n","\r","\t"," ","<",">",'{@');
  2604.         $this->tokens[STATE_INLINE_DOCKEYWORD]        array("{@","}","\t"," ","*/");
  2605.         $this->tokens[STATE_DOCKEYWORD_EMAIL]        array(">","\n","\r\n","\r");
  2606.         $this->tokens[STATE_VAR]            array("/*","//","#"," ","\t",";","=",",","\"","'","array");
  2607.         $this->tokens[STATE_GLOBAL]            array("/*","//","#"," ","\t",";","=","\"","'");
  2608.         $this->tokens[STATE_GLOBAL_VALUE]            array("/*","//","#"," ","\t",";","=","\"","'","array");
  2609.         $this->tokens[STATE_ARRAY]            array("/*","//","#","(",")","\"","'","array");
  2610.         $this->tokens[STATE_FUNCTION]            array("(","{","}"," ","\t","&","/*","//","#");
  2611.         $this->tokens[STATE_OUTPHP]            array("<?php","<?",'<script language="php">');
  2612.         $this->tokens[STATE_EOFQUOTE]            array(" ","\t","\n");
  2613.         $this->tokens[STATE_ESCAPE]            false;// this tells the word parser to just cycle
  2614.         $this->tokens[STATE_INCLUDE]            array(" ","(",";","'",'"');
  2615.         $this->tokens[STATE_INCLUDE_PARAMS]        array("/*",")"," ","'","\"","(");
  2616.         $this->tokens[STATE_INCLUDE_PARAMS_PARENTHESIS]    array("(","'","\"",")");
  2617.  
  2618.         // For each event word to event mapings
  2619.         $this->pushEvent[PARSER_EVENT_QUOTE
  2620.             array(
  2621.                 "\\"    => PARSER_EVENT_ESCAPE
  2622.             );
  2623.         $this->popEvent[PARSER_EVENT_QUOTEarray("\"");
  2624. ##########################
  2625.          
  2626.         $this->pushEvent[PARSER_EVENT_LOGICBLOCK
  2627.             array(
  2628.                 "\""    => PARSER_EVENT_QUOTE,
  2629.                 "'"    => PARSER_EVENT_SINGLEQUOTE,
  2630.                 "//"     => PARSER_EVENT_COMMENT,
  2631.                 "#"     => PARSER_EVENT_COMMENT,
  2632.                 "global"    => PARSER_EVENT_FUNC_GLOBAL,
  2633.                 "static"    => PARSER_EVENT_STATIC_VAR,
  2634.                 "/*"     => PARSER_EVENT_COMMENTBLOCK,
  2635.                 "{"    => PARSER_EVENT_LOGICBLOCK,
  2636.                 "?>"    => PARSER_EVENT_OUTPHP,
  2637.                 "</script>"    => PARSER_EVENT_OUTPHP,
  2638.                 "<<<"    => PARSER_EVENT_EOFQUOTE
  2639.             );
  2640.         $this->popEvent[PARSER_EVENT_LOGICBLOCKarray("}");
  2641. ##########################
  2642.  
  2643.         $this->pushEvent[PARSER_EVENT_FUNC_GLOBAL=
  2644.             array(
  2645.                 "\""    => PARSER_EVENT_QUOTE,
  2646.                 "'"    => PARSER_EVENT_SINGLEQUOTE,
  2647.                 "//"     => PARSER_EVENT_COMMENT,
  2648.                 "#"     => PARSER_EVENT_COMMENT,
  2649.                 "/*"     => PARSER_EVENT_COMMENTBLOCK,
  2650.             );
  2651.         $this->popEvent[PARSER_EVENT_FUNC_GLOBALarray(";");
  2652. ##########################
  2653.  
  2654.         $this->pushEvent[PARSER_EVENT_STATIC_VAR=
  2655.             array(
  2656.                 "\""    => PARSER_EVENT_QUOTE,
  2657.                 "'"    => PARSER_EVENT_SINGLEQUOTE,
  2658.                 "//"     => PARSER_EVENT_COMMENT,
  2659.                 "#"     => PARSER_EVENT_COMMENT,
  2660.                 "/*"     => PARSER_EVENT_COMMENTBLOCK,
  2661.                 "="        => PARSER_EVENT_STATIC_VAR_VALUE,
  2662.             );
  2663.         $this->popEvent[PARSER_EVENT_STATIC_VARarray(";");
  2664. ##########################
  2665.  
  2666.         $this->pushEvent[PARSER_EVENT_STATIC_VAR_VALUE
  2667.             array(
  2668.                 "\""    => PARSER_EVENT_QUOTE,
  2669.                 "'"    => PARSER_EVENT_SINGLEQUOTE,
  2670.                 "array" => PARSER_EVENT_ARRAY,
  2671.                 "/*"     => PARSER_EVENT_COMMENTBLOCK,
  2672.                 "//"     => PARSER_EVENT_COMMENT,
  2673.                 "#"     => PARSER_EVENT_COMMENT
  2674.             );
  2675.         $this->popEvent[PARSER_EVENT_STATIC_VAR_VALUEarray(";",",");
  2676. ##########################
  2677.  
  2678.         $this->pushEvent[PARSER_EVENT_NOEVENTS
  2679.             array(
  2680.                 "<?php" => PARSER_EVENT_PHPCODE,
  2681.                 "<?" => PARSER_EVENT_PHPCODE,
  2682.                 '<script language="php">' => PARSER_EVENT_PHPCODE,
  2683.             );
  2684. ##########################
  2685.  
  2686.         $this->pushEvent[PARSER_EVENT_PHPCODE
  2687.             array(
  2688.                 "function"     => PARSER_EVENT_FUNCTION,
  2689.                 "class"     => PARSER_EVENT_CLASS,
  2690.                 "define"     => PARSER_EVENT_DEFINE,
  2691.                 "include_once" => PARSER_EVENT_INCLUDE,
  2692.                 "require_once" => PARSER_EVENT_INCLUDE,
  2693.                 "include"    => PARSER_EVENT_INCLUDE,
  2694.                 "require"    => PARSER_EVENT_INCLUDE,
  2695.                 "//"         => PARSER_EVENT_COMMENT,
  2696.                 "#"         => PARSER_EVENT_COMMENT,
  2697.                 "/*"         => PARSER_EVENT_COMMENTBLOCK,
  2698.                 "/**"         => PARSER_EVENT_DOCBLOCK,
  2699.                 "/**#@+"    => PARSER_EVENT_DOCBLOCK_TEMPLATE,
  2700.                 "/**#@-*/"    => PARSER_EVENT_END_DOCBLOCK_TEMPLATE,
  2701.                 "\""        => PARSER_EVENT_QUOTE,
  2702.                 "'"        => PARSER_EVENT_SINGLEQUOTE,
  2703.                 "<<<"        => PARSER_EVENT_EOFQUOTE,
  2704.                 "?>"         => PARSER_EVENT_OUTPHP,
  2705.                 "</script>"         => PARSER_EVENT_OUTPHP,
  2706.             );
  2707. ##########################
  2708.  
  2709.         $this->pushEvent[PARSER_EVENT_FUNCTION
  2710.             array(
  2711.                 "("     => PARSER_EVENT_FUNCTION_PARAMS,
  2712.                 "//"     => PARSER_EVENT_COMMENT,
  2713.                 "#"     => PARSER_EVENT_COMMENT,
  2714.                 "/*"     => PARSER_EVENT_COMMENTBLOCK,
  2715.                 "{"     => PARSER_EVENT_LOGICBLOCK
  2716.             );
  2717.         $this->popEvent[PARSER_EVENT_FUNCTIONarray("}");
  2718. ##########################
  2719.  
  2720.         $this->pushEvent[PARSER_EVENT_DOCBLOCK
  2721.             array(
  2722.                 "@"     => PARSER_EVENT_DOCKEYWORD,
  2723.                 "{@"    => PARSER_EVENT_INLINE_DOCKEYWORD
  2724.             );
  2725.         $this->popEvent[PARSER_EVENT_DOCBLOCKarray("*/");
  2726. ##########################
  2727.  
  2728.         $this->pushEvent[PARSER_EVENT_DOCBLOCK_TEMPLATE
  2729.             array(
  2730.                 "@"     => PARSER_EVENT_DOCKEYWORD,
  2731.                 "{@"    => PARSER_EVENT_INLINE_DOCKEYWORD
  2732.             );
  2733.         $this->popEvent[PARSER_EVENT_DOCBLOCK_TEMPLATEarray("*/");
  2734. ##########################
  2735.  
  2736.         $this->pushEvent[PARSER_EVENT_CLASS
  2737.             array(
  2738.                 "function"     => PARSER_EVENT_FUNCTION,
  2739.                 "var"         => PARSER_EVENT_VAR,
  2740.                 "/**"         => PARSER_EVENT_DOCBLOCK,
  2741.                 "/**#@+"    => PARSER_EVENT_DOCBLOCK_TEMPLATE,
  2742.                 "/**#@-*/"    => PARSER_EVENT_END_DOCBLOCK_TEMPLATE,
  2743.                 "//"         => PARSER_EVENT_COMMENT,
  2744.                 "/*"         => PARSER_EVENT_COMMENTBLOCK,
  2745.                 "#"         => PARSER_EVENT_COMMENT,
  2746.                 "?>"        => PARSER_EVENT_OUTPHP,
  2747.                 "</script>"    => PARSER_EVENT_OUTPHP,
  2748.             );
  2749.         $this->popEvent[PARSER_EVENT_CLASSarray("}");
  2750. ##########################
  2751.  
  2752.         $this->pushEvent[PARSER_EVENT_DEFINE
  2753.             array(
  2754.                 "/*"     => PARSER_EVENT_COMMENTBLOCK,
  2755.                 "("     => PARSER_EVENT_DEFINE_PARAMS
  2756.             );
  2757.         $this->popEvent[PARSER_EVENT_DEFINEarray(";");
  2758. ##########################
  2759.  
  2760.         $this->pushEvent[PARSER_EVENT_INCLUDE
  2761.             array(
  2762.                 "/*"     => PARSER_EVENT_COMMENTBLOCK,
  2763.                 "("     => PARSER_EVENT_INCLUDE_PARAMS,
  2764.                 "'"        => PARSER_EVENT_SINGLEQUOTE,
  2765.                 '"'        => PARSER_EVENT_QUOTE,
  2766.             );
  2767.         $this->popEvent[PARSER_EVENT_INCLUDEarray(";");
  2768. ##########################
  2769.  
  2770.         $this->pushEvent[PARSER_EVENT_DEFINE_PARAMS
  2771.             array(
  2772.                 "("    =>    PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS,
  2773.                 "'"        => PARSER_EVENT_SINGLEQUOTE,
  2774.                 '"' =>    PARSER_EVENT_QUOTE,
  2775.                 "/*"     => PARSER_EVENT_COMMENTBLOCK,
  2776.                 "//"     => PARSER_EVENT_COMMENT,
  2777.                 "#"     => PARSER_EVENT_COMMENT
  2778.             );
  2779.         $this->popEvent[PARSER_EVENT_DEFINE_PARAMSarray(")");
  2780. ##########################
  2781.  
  2782.         $this->pushEvent[PARSER_EVENT_INCLUDE_PARAMS
  2783.             array(
  2784.                 "("    =>    PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS,
  2785.                 "'" =>    PARSER_EVENT_SINGLEQUOTE,
  2786.                 '"' =>    PARSER_EVENT_QUOTE,
  2787.             );
  2788.         $this->popEvent[PARSER_EVENT_INCLUDE_PARAMSarray(")");
  2789. ##########################
  2790.  
  2791.             array(
  2792.                 "("    =>    PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS,
  2793.                 "'" =>    PARSER_EVENT_SINGLEQUOTE,
  2794.                 '"' =>    PARSER_EVENT_QUOTE,
  2795.             );
  2796.         $this->popEvent[PARSER_EVENT_DEFINE_PARAMS_PARENTHESISarray(")");
  2797. ##########################
  2798.  
  2799.             array(
  2800.                 "("    =>    PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS,
  2801.                 "'" =>    PARSER_EVENT_SINGLEQUOTE,
  2802.                 '"' =>    PARSER_EVENT_QUOTE,
  2803.             );
  2804.         $this->popEvent[PARSER_EVENT_INCLUDE_PARAMS_PARENTHESISarray(")");
  2805. ##########################
  2806.  
  2807.         $this->pushEvent[PARSER_EVENT_VAR
  2808.             array(
  2809.                 "\""    => PARSER_EVENT_QUOTE,
  2810.                 "'"    => PARSER_EVENT_SINGLEQUOTE,
  2811.                 "array" => PARSER_EVENT_ARRAY,
  2812.                 "/*"     => PARSER_EVENT_COMMENTBLOCK,
  2813.                 "//"     => PARSER_EVENT_COMMENT,
  2814.                 "#"     => PARSER_EVENT_COMMENT
  2815.             );
  2816.         $this->popEvent[PARSER_EVENT_VARarray(";");
  2817. ##########################
  2818.  
  2819.         $this->pushEvent[PARSER_EVENT_DEFINE_GLOBAL
  2820.             array(
  2821.                 "="    => PARSER_EVENT_GLOBAL_VALUE,
  2822.                 "\""    => PARSER_EVENT_QUOTE,
  2823.                 "'"    => PARSER_EVENT_SINGLEQUOTE,
  2824.                 "/*"     => PARSER_EVENT_COMMENTBLOCK,
  2825.                 "//"     => PARSER_EVENT_COMMENT,
  2826.                 "#"     => PARSER_EVENT_COMMENT
  2827.             );
  2828.         $this->popEvent[PARSER_EVENT_DEFINE_GLOBALarray(";");
  2829. ##########################
  2830.  
  2831.         $this->pushEvent[PARSER_EVENT_GLOBAL_VALUE
  2832.             array(
  2833.                 "\""    => PARSER_EVENT_QUOTE,
  2834.                 "'"    => PARSER_EVENT_SINGLEQUOTE,
  2835.                 "array" => PARSER_EVENT_ARRAY,
  2836.                 "/*"     => PARSER_EVENT_COMMENTBLOCK,
  2837.                 "//"     => PARSER_EVENT_COMMENT,
  2838.                 "#"     => PARSER_EVENT_COMMENT
  2839.             );
  2840.         $this->popEvent[PARSER_EVENT_GLOBAL_VALUEarray(";");
  2841. ##########################
  2842.  
  2843.         $this->pushEvent[PARSER_EVENT_COMMENT
  2844.             array(
  2845.                 "\\"    => PARSER_EVENT_ESCAPE
  2846.             );
  2847.         $this->popEvent[PARSER_EVENT_COMMENTarray("\n");
  2848. ##########################
  2849.  
  2850.         $this->popEvent[PARSER_EVENT_COMMENTBLOCKarray("*/");
  2851. ##########################
  2852.         $this->pushEvent[PARSER_EVENT_SINGLEQUOTE
  2853.             array(
  2854.                 "\\"    => PARSER_EVENT_ESCAPE
  2855.             );
  2856.  
  2857.         $this->popEvent[PARSER_EVENT_SINGLEQUOTEarray("'");
  2858. ##########################
  2859.         $this->pushEvent[PARSER_EVENT_FUNCTION_PARAMS
  2860.             array(
  2861.                 "\""    => PARSER_EVENT_QUOTE,
  2862.                 "'"    => PARSER_EVENT_SINGLEQUOTE,
  2863.                 "array" => PARSER_EVENT_ARRAY,
  2864.                 "/*"     => PARSER_EVENT_COMMENTBLOCK,
  2865.                 "//"     => PARSER_EVENT_COMMENT,
  2866.                 "#"     => PARSER_EVENT_COMMENT
  2867.             );
  2868.         $this->popEvent[PARSER_EVENT_FUNCTION_PARAMSarray(")");
  2869. ##########################
  2870.         $this->pushEvent[PARSER_EVENT_DOCKEYWORD
  2871.             array(
  2872. //                "<"    => PARSER_EVENT_DOCKEYWORD_EMAIL,
  2873.                 "{@" => PARSER_EVENT_INLINE_DOCKEYWORD,
  2874.             );
  2875.  
  2876.         $this->popEvent[PARSER_EVENT_DOCKEYWORDarray("*/");
  2877. ##########################
  2878.  
  2879.         $this->popEvent[PARSER_EVENT_INLINE_DOCKEYWORDarray("}","*/");
  2880. ##########################
  2881.  
  2882.         $this->popEvent[PARSER_EVENT_OUTPHParray("<?php","<?",'<script language="php">');
  2883. ##########################
  2884.  
  2885.         $this->popEvent[PARSER_EVENT_DOCKEYWORD_EMAILarray(">","\n");
  2886.  
  2887. ##########################
  2888.         $this->pushEvent[PARSER_EVENT_ARRAY
  2889.             array(
  2890.                 "\""    => PARSER_EVENT_QUOTE,
  2891.                 "'"    => PARSER_EVENT_SINGLEQUOTE,
  2892.                 "array" => PARSER_EVENT_ARRAY,
  2893.                 "/*"     => PARSER_EVENT_COMMENTBLOCK,
  2894.                 "//"     => PARSER_EVENT_COMMENT,
  2895.                 "#"     => PARSER_EVENT_COMMENT
  2896.             );
  2897.         $this->popEvent[PARSER_EVENT_ARRAYarray(")");
  2898. ##########################
  2899.     }
  2900.  
  2901.     /**
  2902.      * tell the parser's WordParser {@link $wp} to set up tokens to parse words by.
  2903.      * tokens are word separators.  In English, a space or punctuation are examples of tokens.
  2904.      * In PHP, a token can be a ;, a parenthesis, or even the word "function"
  2905.      * @param    $value integer an event number
  2906.      * @see WordParser
  2907.      */
  2908.     
  2909.     function configWordParser($e)
  2910.     {
  2911.         $this->wp->setSeperator($this->tokens[($e 100)]);
  2912.     }
  2913.  
  2914.     /**
  2915.      * Debugging function, takes an event number and attempts to return its name
  2916.      * @param    $value integer an event number
  2917.      */
  2918.     
  2919.  
  2920.     function getParserEventName ($value)
  2921.     {    
  2922.         $lookup array(
  2923.             PARSER_EVENT_NOEVENTS         => "PARSER_EVENT_NOEVENTS",
  2924.             PARSER_EVENT_PHPCODE        => "PARSER_EVENT_PHPCODE",
  2925.             PARSER_EVENT_DOCBLOCK        => "PARSER_EVENT_DOCBLOCK",
  2926.             PARSER_EVENT_FUNCTION        => "PARSER_EVENT_FUNCTION",
  2927.             PARSER_EVENT_CLASS        => "PARSER_EVENT_CLASS",
  2928.             PARSER_EVENT_DEFINE        => "PARSER_EVENT_DEFINE",
  2929.             PARSER_EVENT_DEFINE_PARAMS    => "PARSER_EVENT_DEFINE_PARAMS",
  2930.             PARSER_EVENT_COMMENT        => "PARSER_EVENT_COMMENT",
  2931.             PARSER_EVENT_COMMENTBLOCK    => "PARSER_EVENT_COMMENTBLOCK",
  2932.             PARSER_EVENT_ESCAPE        => "PARSER_EVENT_ESCAPE",
  2933.             PARSER_EVENT_QUOTE        => "PARSER_EVENT_QUOTE",
  2934.             PARSER_EVENT_FUNCTION_PARAMS    => "PARSER_EVENT_FUNCTION_PARAMS",
  2935.             PARSER_EVENT_SINGLEQUOTE    => "PARSER_EVENT_SINGLEQUOTE",
  2936.             PARSER_EVENT_VAR        => "PARSER_EVENT_VAR",
  2937.             PARSER_EVENT_LOGICBLOCK        => "PARSER_EVENT_LOGICBLOCK",
  2938.             PARSER_EVENT_OUTPHP        => "PARSER_EVENT_OUTPHP",
  2939.             PARSER_EVENT_DOCKEYWORD        => "PARSER_EVENT_DOCKEYWORD",
  2940.             PARSER_EVENT_DOCKEYWORD_EMAIL    => "PARSER_EVENT_DOCKEYWORD_EMAIL",
  2941.             PARSER_EVENT_ARRAY        => "PARSER_EVENT_ARRAY",
  2942.             PARSER_EVENT_INLINE_DOCKEYWORD    =>    "PARSER_EVENT_INLINE_DOCKEYWORD",
  2943.             PARSER_EVENT_EOFQUOTE    =>    "PARSER_EVENT_EOFQUOTE",
  2944.             PARSER_EVENT_INCLUDE    =>    "PARSER_EVENT_INCLUDE",
  2945.             PARSER_EVENT_INCLUDE_PARAMS    =>    "PARSER_EVENT_INCLUDE_PARAMS",
  2946.             PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS    => "PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS",
  2947.             PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS => "PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS",
  2948.             PARSER_EVENT_DEFINE_GLOBAL => "PARSER_EVENT_DEFINE_GLOBAL",
  2949.             PARSER_EVENT_GLOBAL_VALUE => "PARSER_EVENT_GLOBAL_VALUE",
  2950.             PARSER_EVENT_FUNC_GLOBAL => "PARSER_EVENT_FUNC_GLOBAL",
  2951.             PARSER_EVENT_STATIC_VAR => "PARSER_EVENT_STATIC_VAR",
  2952.             PARSER_EVENT_DOCBLOCK_TEMPLATE => "PARSER_EVENT_DOCBLOCK_TEMPLATE",
  2953.             PARSER_EVENT_END_DOCBLOCK_TEMPLATE => "PARSER_EVENT_END_DOCBLOCK_TEMPLATE",
  2954.             PARSER_EVENT_METHOD_LOGICBLOCK => 'PARSER_EVENT_METHOD_LOGICBLOCK',
  2955.             PARSER_EVENT_CLASS_MEMBER => 'PARSER_EVENT_CLASS_MEMBER',
  2956.             PARSER_EVENT_METHOD => 'PARSER_EVENT_METHOD',
  2957.             PARSER_EVENT_QUOTE_VAR => 'PARSER_EVENT_QUOTE_VAR',
  2958.             PARSER_EVENT_ACCESS_MODIFIER => 'PARSER_EVENT_ACCESS_MODIFIER',
  2959.             PARSER_EVENT_IMPLEMENTS => 'PARSER_EVENT_IMPLEMENTS',
  2960.             PARSER_EVENT_CLASS_CONSTANT => 'PARSER_EVENT_CLASS_CONSTANT',
  2961.             PARSER_EVENT_VAR_ARRAY => 'PARSER_EVENT_VAR_ARRAY',
  2962.             PARSER_EVENT_VAR_ARRAY_COMMENT =>'PARSER_EVENT_VAR_ARRAY_COMMENT',
  2963.         );
  2964.         if (isset($lookup[$value]))
  2965.         return $lookup[$value];
  2966.         else return $value;
  2967.     }
  2968. }
  2969.  
  2970. /**
  2971.  * Global package page parser
  2972.  *
  2973.  * @deprecated in favor of tutorials
  2974.  * @tutorial tutorials.pkg
  2975.  * @package phpDocumentor
  2976.  * @subpackage Parsers
  2977.  */
  2978. class ppageParser extends Parser
  2979. {
  2980.     /** @var string */
  2981.     var $package = false;
  2982.     /** @var string */
  2983.     var $subpackage = '';
  2984.     /**
  2985.      * set up invariant Parser variables
  2986.      */
  2987.     function ppageParser()
  2988.     {
  2989.         Parser::Parser();
  2990.         $this->allowableInlineTags $GLOBALS['_phpDocumentor_inline_tutorial_tags_allowed'];
  2991.         $this->eventHandlers array();
  2992.         $this->eventHandlers[PARSER_EVENT_NOEVENTS'defaultHandler';
  2993.         $this->eventHandlers[PARSER_EVENT_INLINE_DOCKEYWORD'handleInlineDocKeyword';
  2994.     }
  2995.     
  2996.     /**
  2997.      * set up invariant Parser variables
  2998.      */
  2999.     function setupStates()
  3000.     {
  3001.         $this->tokens[STATE_NOEVENTS]        array("{@","}");
  3002.         $this->tokens[STATE_INLINE_DOCKEYWORD]        array("{@","}","\t"," ");
  3003.  
  3004. ##########################
  3005.  
  3006.         $this->pushEvent[PARSER_EVENT_NOEVENTS
  3007.             array(
  3008.                 "{@" => PARSER_EVENT_INLINE_DOCKEYWORD
  3009.             );
  3010. ##########################
  3011.  
  3012.         $this->popEvent[PARSER_EVENT_INLINE_DOCKEYWORDarray("}");
  3013.     }
  3014.     
  3015.     /**
  3016.      * Parse a new file
  3017.      *
  3018.      * @param    string    $parse_data 
  3019.      * @param    string    $package 
  3020.      * @param    int    $subpackage 
  3021.      * @return    mixed    false or parsed data
  3022.      */
  3023.     function parse (&$parse_data,$xml,$package 'default',$subpackage '',$tutorial '',
  3024.                     $category='default'$path='')
  3025.     {
  3026.         $this->setupStates();
  3027.         $this->p_vars['total'new parserPackagePage($package,$xml);
  3028.         $this->p_vars['tutorial'$tutorial;
  3029.         $this->_path $path;
  3030.         $this->category $category;
  3031.         $this->package = $package;
  3032.         if (!isset($subpackage|| !$subpackage$subpackage '';
  3033.         $this->subpackage = $subpackage;
  3034.         if (strlen($parse_data== 0)
  3035.         {
  3036.             return false;
  3037.         }
  3038.  
  3039.         // initialize variables so E_ALL error_reporting doesn't complain
  3040.         $pevent 0;
  3041.         $word 0;
  3042.         $this->p_vars['event_stack'new EventStack;
  3043.         // change this to a new ParserStringWithInlineTags, and change all $total .= blah to $total->add(blah)
  3044.         // then modify phpDocumentor_IntermediateParser->Convert to convert all package pages (the package page handler in phpDocumentor_IntermediateParser should
  3045.         // save them all in a variable) to perform the linking.  then, remove the legacy code from handleDocBlock
  3046.         // and handleClass in Render.inc, and do a loop that converts each package page, and passes it to handleEvent
  3047.         // just like Converter::walk does with the other elements.  The only other addition that might be good is a
  3048.         // new descendant of parserElement parserPackagePage that contains the data and stuff.  Hope this helps :)
  3049.         $total '';
  3050.  
  3051.         $this->wp->setup($parse_data);
  3052.  
  3053.         $this->p_flags['reset_quote_data'true;
  3054.  
  3055.         do
  3056.         {
  3057.             $lpevent $pevent;
  3058.             $pevent $this->p_vars['event_stack']->getEvent();
  3059.             if ($lpevent != $pevent)
  3060.             {
  3061.                 $this->p_vars['last_pevent'$lpevent;
  3062.             }
  3063.  
  3064.             if ($this->p_vars['last_pevent'!= $pevent)
  3065.             {
  3066.                 // its a new event so the word parser needs to be reconfigured 
  3067.                 $this->configWordParser($pevent);
  3068.             }
  3069.  
  3070.             if (!$xml)
  3071.             $this->publishEvent(PHPDOCUMENTOR_EVENT_NEWSTATE,($pevent 100));
  3072.  
  3073.  
  3074.             $this->p_vars['last_word'$word;
  3075.             $word $this->wp->getWord();
  3076.  
  3077.             if (0)//PHPDOCUMENTOR_DEBUG == true)
  3078.             {
  3079.                 echo "LAST: |" $this->p_vars['last_word'"|\n";
  3080.                 echo "PEVENT: " $this->getParserEventName($pevent"\n";
  3081.                 echo $this->wp->getPos(": |$word|\n";
  3082.             }
  3083.             if (isset($this->eventHandlers[$pevent]))
  3084.             {
  3085.                 $handle $this->eventHandlers[$pevent];
  3086.                 $this->$handle($word$pevent);
  3087.             }
  3088.         while (!($word === false));
  3089.         if (!$xml)
  3090.         $this->PublishEvent(PHPDOCUMENTOR_EVENT_PACKAGEPAGE,$this->p_vars['total']);
  3091.         else
  3092.         return $this->p_vars['total']->value;
  3093.     }
  3094.     
  3095.     /**
  3096.      * Handles all non-inline tags
  3097.      * 
  3098.      * @param string token
  3099.      * @param integer parser event
  3100.      */
  3101.     function defaultHandler($word$pevent)
  3102.     {
  3103.         if (!$this->checkEventPush$word$pevent))
  3104.         {
  3105.             if ($word$this->p_vars['total']->add($word);
  3106.         }
  3107.     }
  3108.  
  3109.     /**
  3110.      * handler for INLINE_DOCKEYWORD.
  3111.      * this handler recognizes {@inline tags} like link, and parses them, replacing them directly
  3112.      * in the text flow with their output.
  3113.      * @param string token
  3114.      * @param integer parser event
  3115.      */
  3116.     
  3117.     function handleInlineDockeyword($word$pevent)
  3118.     {
  3119.         //        echo $this->wp->getPos() . ": |$word|\n";
  3120.  
  3121.         //        echo "docktype: $this->p_vars['inline_dockeyword_type']\n";
  3122.         if (!isset($this->p_vars['inline_dockeyword_type'])) $this->p_vars['inline_dockeyword_type'false;
  3123.         if (!isset($this->p_vars['inline_dockeyword_data'])) $this->p_vars['inline_dockeyword_data''';
  3124.         if (!$this->p_vars['inline_dockeyword_type'])
  3125.         {
  3126.             if (in_array($word,$this->allowableInlineTags))
  3127.             {
  3128.                 $this->p_vars['inline_dockeyword_type'strtolower($word);
  3129.                 $this->p_vars['whitesp'$this->wp->returnWhiteSpace;
  3130.                 $this->wp->setWhiteSpace(true);
  3131.             else {
  3132.                 if ($word == '}')
  3133.                 $this->p_vars['total']->add('{@');
  3134.                 else
  3135.                 {
  3136.                     $this->p_vars['total']->add('{@'.$word);
  3137.                     $this->p_vars['event_stack']->popEvent();
  3138.                 }
  3139.                 $this->p_vars['inline_dockeyword_type'false;
  3140.                 $this->p_vars['inline_dockeyword_data''';
  3141.             }
  3142.         else
  3143.         {
  3144.             if ($word != "}")
  3145.             {
  3146.                 $this->p_vars['inline_dockeyword_data'.= $word;
  3147.             }
  3148.         }
  3149.         if ($this->checkEventPop($word,$pevent))
  3150.         {
  3151.             $this->wp->setWhiteSpace($this->p_vars['whitesp']);
  3152.             if ($this->p_vars['inline_dockeyword_type']=='link')
  3153.             {
  3154.                 // support hyperlinks of any protocol
  3155.                 if (is_numeric(strpos($this->p_vars['inline_dockeyword_data'],'://')) || (strpos(trim($this->p_vars['inline_dockeyword_data']),'mailto:'=== 0))
  3156.                 {
  3157.                     // if there is more than 1 parameter, the stuff after the space is the hyperlink text
  3158.                     if (strpos(trim($this->p_vars['inline_dockeyword_data']),' '))
  3159.                     {
  3160.                         $i1 strpos(trim($this->p_vars['inline_dockeyword_data'])