diff options
| author | xue <> | 2006-06-19 18:38:29 +0000 | 
|---|---|---|
| committer | xue <> | 2006-06-19 18:38:29 +0000 | 
| commit | 588727c7e2b8954ec3dbde293cf4c4d68b119f9b (patch) | |
| tree | fdcc16181a20335547953ccf1550e0006c11bf28 /buildscripts/PhpDocumentor/phpDocumentor/TutorialHighlightParser.inc | |
| parent | 127f78a4db3cc0fbbbb92f5b1abcfdce4a9af93b (diff) | |
Merge from 3.0 branch till 1185.
Diffstat (limited to 'buildscripts/PhpDocumentor/phpDocumentor/TutorialHighlightParser.inc')
| -rw-r--r-- | buildscripts/PhpDocumentor/phpDocumentor/TutorialHighlightParser.inc | 491 | 
1 files changed, 491 insertions, 0 deletions
diff --git a/buildscripts/PhpDocumentor/phpDocumentor/TutorialHighlightParser.inc b/buildscripts/PhpDocumentor/phpDocumentor/TutorialHighlightParser.inc new file mode 100644 index 00000000..ff7160ce --- /dev/null +++ b/buildscripts/PhpDocumentor/phpDocumentor/TutorialHighlightParser.inc @@ -0,0 +1,491 @@ +<?php
 +//
 +// +------------------------------------------------------------------------+
 +// | phpDocumentor                                                          |
 +// +------------------------------------------------------------------------+
 +// | Copyright (c) 2000-2004 Joshua Eichorn, Gregory Beaver                 |
 +// | Email         jeichorn@phpdoc.org, cellog@phpdoc.org                   |
 +// | Web           http://www.phpdoc.org                                    |
 +// | Mirror        http://phpdocu.sourceforge.net/                          |
 +// | PEAR          http://pear.php.net/package-info.php?pacid=137           |
 +// +------------------------------------------------------------------------+
 +// | This source file is subject to version 3.00 of the PHP License,        |
 +// | that is available at http://www.php.net/license/3_0.txt.               |
 +// | If you did not receive a copy of the PHP license and are unable to     |
 +// | obtain it through the world-wide-web, please send a note to            |
 +// | license@php.net so we can mail you a copy immediately.                 |
 +// +------------------------------------------------------------------------+
 +//
 +/**
 + * 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
 + * @tutorial tags.example.pkg, tags.filesource.pkg
 + * @package phpDocumentor
 + * @subpackage Parsers
 + * @since 1.3.0
 + */
 +
 +/**
 + * Highlights source code using {@link parse()}
 + * @package phpDocumentor
 + * @subpackage Parsers
 + */
 +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',
 +    );
 +    /**#@-*/
 +    
 +    /**
 +     * @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
 +     */
 +    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.
 +     *
 +     * @uses setupStates() initialize parser state variables
 +     * @uses configWordParser() pass $parse_data to prepare retrieval of tokens
 +     * @param    string
 +     * @param    Converter
 +     * @param    false|string full path to file with @filesource tag, if this
 +     *           is a @filesource parse
 +     * @param    false|integer starting line number from {@}source linenum}
 +     * @staticvar    integer    used for recursion limiting if a handler for
 +     *                          an event is not found
 +     * @return    bool
 +     */
 +    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 (0)//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";
 +//                echo "LINE: ".$this->_line."\n";
 +//                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.
 +     * @access private
 +     * @param string|array token value
 +     * @param integer parser event from {@link Parser.inc}
 +     */
 +    /**
 +     * Most tokens only need highlighting, and this method handles them
 +     */
 +    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
 +     */
 +    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.
 +     * @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 .= $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    $value integer an event number
 +     * @see WordParser
 +     */
 +    
 +    function configWordParser($e)
 +    {
 +        $this->_wp->setSeperator($this->tokens[($e + 100)]);
 +    }
 +    /**
 +     * this function checks whether parameter $word is a token for pushing a new event onto the Event Stack.
 +     * @return mixed    returns false, or the event number
 +     */
 +    
 +    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.
 +     * @return mixed    returns false, or the event number popped off of the stack
 +     */
 +    
 +    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 boolean true if we are highlighting an inline {@}source} tag's
 +     *                output
 +     * @param false|string name of class we are going to start from
 +     * @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('}');
 +/**************************************************************/
 +    }
 +
 +    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);
 +?>
  | 
