+++ /dev/null
-<?php\r
-/**\r
- * Source Code Highlighting\r
- *\r
- * The classes in this file are responsible for the dynamic @example, and\r
- * <programlisting role="tutorial"> tags output. Using the\r
- * WordParser, the phpDocumentor_TutorialHighlightParser\r
- * retrieves PHP tokens one by one from the array generated by\r
- * {@link WordParser} source retrieval functions\r
- * and then highlights them individually.\r
- *\r
- * It accomplishes this highlighting through the assistance of methods in\r
- * the output Converter passed to its parse() method, and then returns the\r
- * fully highlighted source as a string\r
- * \r
- * phpDocumentor :: automatic documentation generator\r
- * \r
- * PHP versions 4 and 5\r
- *\r
- * Copyright (c) 2003-2007 Gregory Beaver\r
- * \r
- * LICENSE:\r
- * \r
- * This library is free software; you can redistribute it\r
- * and/or modify it under the terms of the GNU Lesser General\r
- * Public License as published by the Free Software Foundation;\r
- * either version 2.1 of the License, or (at your option) any\r
- * later version.\r
- * \r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * Lesser General Public License for more details.\r
- * \r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
- *\r
- * @category ToolsAndUtilities\r
- * @package phpDocumentor\r
- * @subpackage Parsers\r
- * @author Gregory Beaver <cellog@php.net>\r
- * @copyright 2003-2007 Gregory Beaver\r
- * @license http://www.opensource.org/licenses/lgpl-license.php LGPL\r
- * @version CVS: $Id: TutorialHighlightParser.inc,v 1.7 2007/11/14 01:57:04 ashnazg Exp $\r
- * @tutorial tags.example.pkg, tags.filesource.pkg\r
- * @link http://www.phpdoc.org\r
- * @link http://pear.php.net/PhpDocumentor\r
- * @since 1.3.0\r
- * @todo CS cleanup - change package to PhpDocumentor\r
- * @todo CS cleanup - PHPCS needs to ignore CVS Id length\r
- */\r
-\r
-/**\r
- * Highlights source code using {@link parse()}\r
- *\r
- * @category ToolsAndUtilities\r
- * @package phpDocumentor\r
- * @subpackage Parsers\r
- * @author Gregory Beaver <cellog@php.net>\r
- * @copyright 2003-2007 Gregory Beaver\r
- * @license http://www.opensource.org/licenses/lgpl-license.php LGPL\r
- * @version Release: 1.4.1\r
- * @link http://www.phpdoc.org\r
- * @link http://pear.php.net/PhpDocumentor\r
- * @todo CS cleanup - change package to PhpDocumentor\r
- * @todo CS cleanup - change classname to PhpDocumentor_*\r
- */\r
-class phpDocumentor_TutorialHighlightParser extends Parser\r
-{\r
- /**#@+ @access private */\r
- /**\r
- * Highlighted source is built up in this string\r
- * @var string\r
- */\r
- var $_output;\r
- /**\r
- * contents of the current source code line as it is parsed\r
- * @var string\r
- */\r
- var $_line;\r
- /**\r
- * Used to retrieve highlighted tokens\r
- * @var Converter a descendant of Converter\r
- */\r
- var $_converter;\r
- /**\r
- * Path to file being highlighted, if this is from a @filesource tag\r
- * @var false|string full path\r
- */\r
- var $_filesourcepath;\r
- /**\r
- * @var array\r
- */\r
- var $eventHandlers = array(\r
- TUTORIAL_EVENT_NOEVENTS => 'defaultHandler',\r
- TUTORIAL_EVENT_ITAG => 'defaultHandler',\r
- TUTORIAL_EVENT_ATTRIBUTE => 'attrHandler',\r
- TUTORIAL_EVENT_OPENTAG => 'defaultHandler',\r
- TUTORIAL_EVENT_CLOSETAG => 'defaultHandler',\r
- TUTORIAL_EVENT_ENTITY => 'defaultHandler',\r
- TUTORIAL_EVENT_COMMENT => 'defaultHandler',\r
- TUTORIAL_EVENT_SINGLEQUOTE => 'defaultHandler',\r
- TUTORIAL_EVENT_DOUBLEQUOTE => 'defaultHandler',\r
- );\r
- /**#@-*/\r
- \r
- /**\r
- * advances output to a new line\r
- *\r
- * @return void\r
- * @uses Converter::SourceLine() encloses {@link $_line} in a\r
- * converter-specific format\r
- */\r
- function newLineNum()\r
- {\r
- $this->_line .= $this->_converter->flushHighlightCache();\r
- $this->_output .= $this->_converter->SourceLine($this->_pv_curline + 1, \r
- $this->_line, $this->_path);\r
- $this->_line = '';\r
- }\r
- \r
- /**\r
- * Start the parsing at a certain line number\r
- *\r
- * @param int $num the line number\r
- *\r
- * @return void\r
- */\r
- function setLineNum($num)\r
- {\r
- $this->_wp->linenum = $num;\r
- }\r
- \r
- /**\r
- * Parse a new file\r
- *\r
- * The parse() method is a do...while() loop that retrieves tokens one by\r
- * one from the {@link $_event_stack}, and uses the token event array set up\r
- * by the class constructor to call event handlers.\r
- *\r
- * The event handlers each process the tokens passed to them, and use the\r
- * {@link _addoutput()} method to append the processed tokens to the\r
- * {@link $_line} variable. The word parser calls {@link newLineNum()}\r
- * every time a line is reached.\r
- *\r
- * In addition, the event handlers use special linking functions\r
- * {@link _link()} and its cousins (_classlink(), etc.) to create in-code\r
- * hyperlinks to the documentation for source code elements that are in the\r
- * source code.\r
- *\r
- * @param string $parse_data blah\r
- * @param Converter &$converter blah\r
- * @param false|string $filesourcepath full path to file with @filesource tag,\r
- * if this is a @filesource parse\r
- * @param false|integer $linenum starting line number from\r
- * {@}source linenum}\r
- *\r
- * @staticvar integer used for recursion limiting if a handler for\r
- * an event is not found\r
- * @return bool\r
- * @uses setupStates() initialize parser state variables\r
- * @uses configWordParser() pass $parse_data to prepare retrieval of tokens\r
- * @todo CS cleanup - unable to get function signature below 85char wide\r
- */\r
- function parse($parse_data, &$converter, $filesourcepath = false, $linenum = false)\r
- {\r
- static $endrecur = 0;\r
- $parse_data = \r
- str_replace(array("\r\n", "\t"), array("\n", ' '), $parse_data);\r
- $this->_converter = &$converter;\r
- $converter->startHighlight();\r
- $this->_path = $filesourcepath;\r
- $this->setupStates($parse_data);\r
-\r
- $this->configWordParser(TUTORIAL_EVENT_NOEVENTS);\r
- if ($linenum !== false) {\r
- $this->setLineNum($linenum);\r
- }\r
- // initialize variables so E_ALL error_reporting doesn't complain\r
- $pevent = 0;\r
- $word = 0;\r
-\r
- do {\r
- $lpevent = $pevent;\r
- $pevent = $this->_event_stack->getEvent();\r
- if ($lpevent != $pevent) {\r
- $this->_last_pevent = $lpevent;\r
- $this->configWordParser($pevent);\r
- }\r
- $this->_wp->setWhitespace(true);\r
-\r
- $dbg_linenum = $this->_wp->linenum;\r
- $dbg_pos = $this->_wp->getPos();\r
- $this->_pv_last_word = $word;\r
- $this->_pv_curline = $this->_wp->linenum;\r
- $word = $this->_wp->getWord();\r
-\r
- if (PHPDOCUMENTOR_DEBUG == true) {\r
- echo "LAST: ";\r
- echo "|" . $this->_pv_last_word;\r
- echo "|\n";\r
- echo "PEVENT: " . $this->getParserEventName($pevent) . "\n";\r
- echo "LASTPEVENT: " . \r
- $this->getParserEventName($this->_last_pevent) . "\n";\r
- //DEBUG echo "LINE: " . $this->_line . "\n";\r
- //DEBUG echo "OUTPUT: " . $this->_output . "\n";\r
- echo $dbg_linenum.'-'.$dbg_pos . ": ";\r
- echo '|'.htmlspecialchars($word);\r
- echo "|\n";\r
- echo "-------------------\n\n\n";\r
- flush();\r
- }\r
- if (isset($this->eventHandlers[$pevent])) {\r
- $handle = $this->eventHandlers[$pevent];\r
- $this->$handle($word, $pevent);\r
- } else {\r
- debug('WARNING: possible error, no handler for event number '\r
- . $pevent);\r
- if ($endrecur++ == 25) {\r
- die("FATAL ERROR, recursion limit reached");\r
- }\r
- }\r
- } while (!($word === false));\r
- if (strlen($this->_line)) {\r
- $this->newLineNum();\r
- }\r
- return $this->_output;\r
- }\r
- \r
- /**#@+\r
- * Event Handlers\r
- *\r
- * All Event Handlers use {@link checkEventPush()} and\r
- * {@link checkEventPop()} to set up the event stack and parser state.\r
- *\r
- * @param string|array $word token value\r
- * @param integer $pevent parser event from {@link Parser.inc}\r
- *\r
- * @return void\r
- * @access private\r
- */\r
- /**\r
- * Most tokens only need highlighting, and this method handles them\r
- *\r
- * @todo CS cleanup - PHPCS needs to recognize docblock template tags\r
- */\r
- function defaultHandler($word, $pevent)\r
- {\r
- if ($word == "\n") {\r
- $this->newLineNum();\r
- return;\r
- }\r
- if ($this->checkEventPush($word, $pevent)) {\r
- $this->_wp->backupPos($word);\r
- return;\r
- }\r
- $this->_addoutput($word);\r
- $this->checkEventPop($word, $pevent);\r
- }\r
-\r
- /**\r
- * Most tokens only need highlighting, and this method handles them\r
- *\r
- * @todo CS cleanup - PHPCS needs to recognize docblock template tags\r
- */\r
- function attrHandler($word, $pevent)\r
- {\r
- if ($word == "\n") {\r
- $this->newLineNum();\r
- return;\r
- }\r
- if ($e = $this->checkEventPush($word, $pevent)) {\r
- if ($e == TUTORIAL_EVENT_SINGLEQUOTE \r
- || $e == TUTORIAL_EVENT_DOUBLEQUOTE\r
- ) {\r
- $this->_addoutput($word);\r
- }\r
- return;\r
- }\r
- if ($this->checkEventPop($word, $pevent)) {\r
- $this->_wp->backupPos($word);\r
- return;\r
- }\r
- $this->_addoutput($word);\r
- }\r
- /**#@-*/\r
- \r
- /**#@+\r
- * Output Methods\r
- * @access private\r
- */\r
- /**\r
- * This method adds output to {@link $_line}\r
- *\r
- * If a string with variables like "$test this" is present, then special\r
- * handling is used to allow processing of the variable in context.\r
- *\r
- * @param string $word the output to add\r
- * @param bool $preformatted whether or not its preformatted\r
- *\r
- * @return void\r
- * @see _flush_save()\r
- */\r
- function _addoutput($word, $preformatted = false)\r
- {\r
- $type = array(\r
- TUTORIAL_EVENT_ATTRIBUTE => 'attribute',\r
- TUTORIAL_EVENT_SINGLEQUOTE => 'attributevalue',\r
- TUTORIAL_EVENT_DOUBLEQUOTE => 'attributevalue',\r
- TUTORIAL_EVENT_CLOSETAG => 'closetag',\r
- TUTORIAL_EVENT_ENTITY => 'entity',\r
- TUTORIAL_EVENT_ITAG => 'itag',\r
- TUTORIAL_EVENT_OPENTAG => 'opentag',\r
- TUTORIAL_EVENT_COMMENT => 'comment',\r
- );\r
-\r
- $a = $this->_event_stack->getEvent();\r
- if (in_array($a, array_keys($type))) {\r
- $this->_line .= \r
- $this->_converter->highlightTutorialSource($type[$a], $word);\r
- } else {\r
- $this->_line .= $this->_converter->flushHighlightCache();\r
- $this->_line .= $this->_converter->postProcess($word);\r
- }\r
- }\r
- /**#@-*/\r
-\r
- /**\r
- * Tell the parser's WordParser {@link $wp} to set up tokens to parse words by.\r
- *\r
- * Tokens are word separators. In English, a space or punctuation are\r
- * examples of tokens. In PHP, a token can be a ;, a parenthesis, or \r
- * even the word "function"\r
- *\r
- * @param integer $e an event number\r
- *\r
- * @return void\r
- * @see WordParser\r
- */\r
- function configWordParser($e)\r
- {\r
- $this->_wp->setSeperator($this->tokens[($e + 100)]);\r
- }\r
-\r
- /**#@+\r
- * @param string|array $word token value\r
- * @param integer $pevent parser event from {@link Parser.inc}\r
- *\r
- * @return mixed returns false, or the event number\r
- */\r
- /**\r
- * This function checks whether parameter $word is a token \r
- * for pushing a new event onto the Event Stack.\r
- *\r
- * @todo CS cleanup - PHPCS needs to recognize docblock template tags\r
- */\r
- function checkEventPush($word, $pevent)\r
- {\r
- $e = false;\r
- if (isset($this->pushEvent[$pevent])) {\r
- if (isset($this->pushEvent[$pevent][strtolower($word)])) {\r
- $e = $this->pushEvent[$pevent][strtolower($word)];\r
- }\r
- }\r
- if ($e) {\r
- $this->_event_stack->pushEvent($e);\r
- return $e;\r
- } else {\r
- return false;\r
- }\r
- }\r
-\r
- /**\r
- * This function checks whether parameter $word is a token \r
- * for popping the current event off of the Event Stack.\r
- *\r
- * @todo CS cleanup - PHPCS needs to recognize docblock template tags\r
- */\r
- function checkEventPop($word, $pevent)\r
- {\r
- if (!isset($this->popEvent[$pevent])) {\r
- return false;\r
- }\r
- if (in_array(strtolower($word), $this->popEvent[$pevent])) {\r
- return $this->_event_stack->popEvent();\r
- } else {\r
- return false;\r
- }\r
- }\r
- /**#@-*/\r
-\r
- /**\r
- * Initialize all parser state variables\r
- *\r
- * @param bool|string $parsedata true if we are highlighting an inline {@}source}\r
- * tag's output, or the name of class we are going \r
- * to start from\r
- *\r
- * @return void\r
- * @uses $_wp sets to a new {@link phpDocumentor_HighlightWordParser}\r
- */\r
- function setupStates($parsedata)\r
- {\r
- $this->_output = '';\r
- $this->_line = '';\r
-\r
- unset($this->_wp);\r
- $this->_wp = new WordParser;\r
- $this->_wp->setup($parsedata);\r
-\r
- $this->_event_stack = new EventStack;\r
- $this->_event_stack->popEvent();\r
- $this->_event_stack->pushEvent(TUTORIAL_EVENT_NOEVENTS);\r
-\r
- $this->_pv_linenum = null;\r
- $this->_pv_next_word = false;\r
- }\r
-\r
- /**\r
- * Initialize the {@link $tokenpushEvent, $wordpushEvent} arrays\r
- */\r
- function phpDocumentor_TutorialHighlightParser()\r
- {\r
- $this->allowableInlineTags = \r
- $GLOBALS['_phpDocumentor_inline_tutorial_tags_allowed']\r
- ;\r
- $this->inlineTagHandlers = \r
- array('*' => 'handleDefaultInlineTag')\r
- ;\r
- $this->tokens[STATE_TUTORIAL_NOEVENTS] = \r
- array("\n",'{@', '<!--', '</', '<', '&');\r
- $this->tokens[STATE_TUTORIAL_ITAG] = array("\n","}");\r
- $this->tokens[STATE_TUTORIAL_OPENTAG] = array("\n","\t"," ", '>', '/>');\r
- $this->tokens[STATE_TUTORIAL_CLOSETAG] = array("\n",'>');\r
- $this->tokens[STATE_TUTORIAL_COMMENT] = array("\n",'-->');\r
- $this->tokens[STATE_TUTORIAL_ENTITY] = array("\n",';');\r
- $this->tokens[STATE_TUTORIAL_ATTRIBUTE] = array("\n",'"',"'",'>','/>');\r
- $this->tokens[STATE_TUTORIAL_DOUBLEQUOTE] = array("\n",'"','&','{@');\r
- $this->tokens[STATE_TUTORIAL_SINGLEQUOTE] = array("\n","'",'&','{@');\r
- /**************************************************************/\r
-\r
- $this->pushEvent[TUTORIAL_EVENT_NOEVENTS] = array(\r
- "{@" => TUTORIAL_EVENT_ITAG,\r
- '<' => TUTORIAL_EVENT_OPENTAG,\r
- '</' => TUTORIAL_EVENT_CLOSETAG,\r
- '&' => TUTORIAL_EVENT_ENTITY,\r
- '<!--' => TUTORIAL_EVENT_COMMENT,\r
- );\r
- /**************************************************************/\r
-\r
- $this->pushEvent[TUTORIAL_EVENT_OPENTAG] = array(\r
- " " => TUTORIAL_EVENT_ATTRIBUTE,\r
- "\n" => TUTORIAL_EVENT_ATTRIBUTE,\r
- );\r
- /**************************************************************/\r
-\r
- $this->pushEvent[TUTORIAL_EVENT_ATTRIBUTE] = array(\r
- "'" => TUTORIAL_EVENT_SINGLEQUOTE,\r
- '"' => TUTORIAL_EVENT_DOUBLEQUOTE,\r
- );\r
- /**************************************************************/\r
-\r
- $this->pushEvent[TUTORIAL_EVENT_SINGLEQUOTE] = array(\r
- '&' => TUTORIAL_EVENT_ENTITY,\r
- '{@' => TUTORIAL_EVENT_ITAG,\r
- );\r
- /**************************************************************/\r
-\r
- $this->pushEvent[TUTORIAL_EVENT_DOUBLEQUOTE] = array(\r
- '&' => TUTORIAL_EVENT_ENTITY,\r
- '{@' => TUTORIAL_EVENT_ITAG,\r
- );\r
- /**************************************************************/\r
-\r
- $this->popEvent[TUTORIAL_EVENT_ENTITY] = array(';');\r
- /**************************************************************/\r
-\r
- $this->popEvent[TUTORIAL_EVENT_SINGLEQUOTE] = array("'");\r
- /**************************************************************/\r
-\r
- $this->popEvent[TUTORIAL_EVENT_DOUBLEQUOTE] = array('"');\r
- /**************************************************************/\r
-\r
- $this->popEvent[TUTORIAL_EVENT_OPENTAG] = array('>', '/>');\r
- /**************************************************************/\r
-\r
- $this->popEvent[TUTORIAL_EVENT_CLOSETAG] = array('>');\r
- /**************************************************************/\r
-\r
- $this->popEvent[TUTORIAL_EVENT_COMMENT] = array('-->');\r
- /**************************************************************/\r
-\r
- $this->popEvent[TUTORIAL_EVENT_ATTRIBUTE] = array('>','/>');\r
- /**************************************************************/\r
-\r
- $this->popEvent[TUTORIAL_EVENT_ITAG] = array('}');\r
- /**************************************************************/\r
- }\r
-\r
- /**\r
- * searches for a parser event name based on its number\r
- *\r
- * @param int $value the event number\r
- *\r
- * @return string|int the event name, or the original value\r
- */\r
- function getParserEventName ($value)\r
- { \r
- $lookup = array(\r
- TUTORIAL_EVENT_NOEVENTS => "TUTORIAL_EVENT_NOEVENTS",\r
- TUTORIAL_EVENT_ITAG => "TUTORIAL_EVENT_ITAG",\r
- TUTORIAL_EVENT_OPENTAG => "TUTORIAL_EVENT_OPENTAG",\r
- TUTORIAL_EVENT_ATTRIBUTE => "TUTORIAL_EVENT_ATTRIBUTE",\r
- TUTORIAL_EVENT_CLOSETAG => "TUTORIAL_EVENT_CLOSETAG",\r
- TUTORIAL_EVENT_ENTITY => "TUTORIAL_EVENT_ENTITY",\r
- TUTORIAL_EVENT_COMMENT => "TUTORIAL_EVENT_COMMENT",\r
- TUTORIAL_EVENT_SINGLEQUOTE => "TUTORIAL_EVENT_SINGLEQUOTE",\r
- TUTORIAL_EVENT_DOUBLEQUOTE => "TUTORIAL_EVENT_DOUBLEQUOTE",\r
- );\r
- if (isset($lookup[$value])) {\r
- return $lookup[$value];\r
- } else {\r
- return $value;\r
- }\r
- }\r
-}\r
-\r
-\r
-/**\r
- * starting state\r
- */\r
-define("TUTORIAL_EVENT_NOEVENTS", 1);\r
-\r
-/**\r
- * currently in starting state\r
- */\r
-define("STATE_TUTORIAL_NOEVENTS", 101);\r
-\r
-/**\r
- * used when an {@}inline tag} is found\r
- */\r
-define("TUTORIAL_EVENT_ITAG", 2);\r
-\r
-/**\r
- * currently parsing an {@}inline tag}\r
- */\r
-define("STATE_TUTORIAL_ITAG", 102);\r
-\r
-/**\r
- * used when an open <tag> is found\r
- */\r
-define("TUTORIAL_EVENT_OPENTAG", 3);\r
-\r
-/**\r
- * currently parsing an open <tag>\r
- */\r
-define("STATE_TUTORIAL_OPENTAG", 103);\r
-\r
-/**\r
- * used when a <tag attr="attribute"> is found\r
- */\r
-define("TUTORIAL_EVENT_ATTRIBUTE", 4);\r
-\r
-/**\r
- * currently parsing an open <tag>\r
- */\r
-define("STATE_TUTORIAL_ATTRIBUTE", 104);\r
-\r
-/**\r
- * used when a close </tag> is found\r
- */\r
-define("TUTORIAL_EVENT_CLOSETAG", 5);\r
-\r
-/**\r
- * currently parsing a close </tag>\r
- */\r
-define("STATE_TUTORIAL_CLOSETAG", 105);\r
-\r
-/**\r
- * used when an &entity; is found\r
- */\r
-define("TUTORIAL_EVENT_ENTITY", 6);\r
-\r
-/**\r
- * currently parsing an &entity;\r
- */\r
-define("STATE_TUTORIAL_ENTITY", 106);\r
-\r
-/**\r
- * used when a <!-- comment --> is found\r
- */\r
-define("TUTORIAL_EVENT_COMMENT", 7);\r
-\r
-/**\r
- * currently parsing a <!-- comment -->\r
- */\r
-define("STATE_TUTORIAL_COMMENT", 107);\r
-\r
-/**\r
- * used when a <!-- comment --> is found\r
- */\r
-define("TUTORIAL_EVENT_SINGLEQUOTE", 8);\r
-\r
-/**\r
- * currently parsing a <!-- comment -->\r
- */\r
-define("STATE_TUTORIAL_SINGLEQUOTE", 108);\r
-\r
-/**\r
- * used when a <!-- comment --> is found\r
- */\r
-define("TUTORIAL_EVENT_DOUBLEQUOTE", 9);\r
-\r
-/**\r
- * currently parsing a <!-- comment -->\r
- */\r
-define("STATE_TUTORIAL_DOUBLEQUOTE", 109);\r
-\r
-?>\r