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