Viewing file: XMLpackagePageParser.inc (21.38 KB) -rw-rw-rw- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php /** * Parser for XML DocBook-based phpDocumentor tutorials * * phpDocumentor :: automatic documentation generator * * PHP versions 4 and 5 * * Copyright (c) 2002-2006 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 * * @package phpDocumentor * @subpackage Parsers * @author Gregory Beaver <cellog@php.net> * @copyright 2002-2006 Gregory Beaver * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @version CVS: $Id: XMLpackagePageParser.inc,v 1.10 2006/05/22 01:07:28 cellog Exp $ * @tutorial tutorials.pkg * @link http://www.phpdoc.org * @link http://pear.php.net/PhpDocumentor * @since 1.2 */ /** when <programlisting> is found */ define('PHPDOCUMENTOR_PDP_EVENT_PROGRAMLISTING', 600); /** when <programlisting> is found */ define('PHPDOCUMENTOR_PDP_STATE_PROGRAMLISTING', 700); /** when a DocBook <tag> is found */ define('PHPDOCUMENTOR_PDP_EVENT_TAG', 601); /** when a DocBook <tag> is found */ define('PHPDOCUMENTOR_PDP_STATE_TAG', 701); /** when <![CDATA[ ]]> is found */ define('PHPDOCUMENTOR_PDP_EVENT_CDATA', 602); /** when <![CDATA[ ]]> is found */ define('PHPDOCUMENTOR_PDP_STATE_CDATA', 702); /** when tag attributes name="value" are found */ define('PHPDOCUMENTOR_PDP_EVENT_ATTRIBUTES', 603); /** when tag attributes name="value" are found */ define('PHPDOCUMENTOR_PDP_STATE_ATTRIBUTES', 703); /** when tag attributes name="value" are found */ define('PHPDOCUMENTOR_PDP_EVENT_ENTITY', 604); /** when tag attributes name="value" are found */ define('PHPDOCUMENTOR_PDP_STATE_ENTITY', 704);
/** * Used to parse XML DocBook-based tutorials * @package phpDocumentor * @subpackage Parsers * @author Greg Beaver <cellog@users.sourceforge.net> * @since 1.2 */ class XMLPackagePageParser extends Parser { /** @var array */ var $eventHandlers = array( PHPDOCUMENTOR_PDP_EVENT_TAG => 'handleTag', PHPDOCUMENTOR_PDP_EVENT_ATTRIBUTES => 'handleAttributes', PHPDOCUMENTOR_PDP_EVENT_CDATA => 'handleCData', PARSER_EVENT_NOEVENTS => 'defaultHandler', PARSER_EVENT_COMMENTBLOCK => 'ignoreHandler', PARSER_EVENT_OUTPHP => 'ignoreHandler', PARSER_EVENT_QUOTE => 'handleQuote', PHPDOCUMENTOR_PDP_EVENT_ENTITY => 'handleEntity', ); /** * @var array */ var $pars = array(); var $refsect1id = false; var $refsect2id = false; var $refsect3id = false; /** * @var array the tag stack */ var $context; /**#@+ @access private */ var $_gettoc = false; var $_toc = array(); var $_cursection = 0; /**#@-*/ /** * Set up the wordparser * * {@source} * @uses ObjectWordParser */ function XMLPackagePageParser() { $this->wp = new ObjectWordParser(true); } /** * Parse a new file * * @param string $parse_data * @param array $tutorial for format, see {@link Io::getTutorials()} * @staticvar integer used for recursion limiting if a handler for an event is not found * @return bool * @uses parserTutorial using {@link Publisher::PublishEvent()}, a new tutorial * is created from the file parsed, and passed to the * Intermediate Parser */ function parse ($parse_data, $tutorial) { $tempparse = new ppageParser; $parse_data = $tempparse->parse($parse_data,true,$tutorial['package'],$tutorial['subpackage'], basename($tutorial['path']),$tutorial['category'], $tutorial['path']); unset($tempparse); static $endrecur = 0; if (!is_array($parse_data) || count($parse_data) == 0) { return false; } $this->setupStates();
// initialize variables so E_ALL error_reporting doesn't complain $pevent = 0; $word = 0; $this->p_vars['start'] = true; $this->p_vars['event_stack'] = new EventStack;
$this->wp->setup($parse_data,false); $this->wp->setWhitespace(true); $this->context = array(); if (isset($this->curtag)) unset($this->curtag);
do { $lpevent = $pevent; $pevent = $this->p_vars['event_stack']->getEvent(); if ($lpevent != $pevent) { $this->p_vars['last_pevent'] = $lpevent; }
if ($this->p_vars['last_pevent'] != $pevent) { // its a new event so the word parser needs to be reconfigured $this->configWordParser($pevent); }
$this->p_vars['last_word'] = $word; $word = $this->wp->getWord();
if (0)//PHPDOCUMENTOR_DEBUG == true) { echo "----------------\n"; echo "LAST: |" . $this->p_vars['last_word'] . "|\n"; // echo "INDEX: ".$this->p_vars['curpar']."\n"; echo "PEVENT: " . $this->getParserEventName($pevent) . "\n"; echo "LASTPEVENT: " . $this->getParserEventName($this->p_vars['last_pevent']) . "\n"; echo $this->wp->getPos() . " WORD: |$word|\n\n"; // echo '"'.$this->p_vars['quote_data']."\"\n"; } if (isset($this->eventHandlers[$pevent])) { $handle = $this->eventHandlers[$pevent]; if ($word !== false) $this->$handle($word, $pevent); } else { debug('WARNING: possible error, no XMLPackagePageParser handler for event number '.$pevent); if ($endrecur++ == 25) { die("FATAL ERROR, recursion limit reached"); } } $this->p_vars['start'] = false; } while (!($word === false)); if (count($this->_toc) && isset($this->p_vars['toc'])) { $a = $this->curtag->getTOC($this->p_vars['toc']); $a->setTOC($this->_toc); $a->setPath($tutorial['path']); $this->curtag->setTOC($this->p_vars['toc'],$a); } $this->PublishEvent(PHPDOCUMENTOR_EVENT_TUTORIAL,new parserTutorial($this->curtag, $tutorial)); return $this->curtag; } /**#@+ * @access private * @param string|parserInlineTag token * @param integer parser event */ function defaultHandler($word, $pevent) { if (is_string($word) && $this->checkEventPush($word, $pevent)) { return; } } function ignoreHandler($word, $pevent) { $this->checkEventPop($word, $pevent); } /** * handler for QUOTE. * this handler recognizes strings defined with double quotation marks (") and handles them correctly * in any place that they legally appear in php code */ function handleQuote($word, $pevent) { if ($this->p_flags['reset_quote_data'] === true) { $this->p_flags['reset_quote_data'] = false; $this->p_vars['quote_data'] = ""; } if (!is_object($word)) $this->checkEventPush( $word, $pevent); if (is_object($word)) { $this->p_vars['quote_data'] = $word; } else { if ($word != "\"") { if (!is_object($this->p_vars['quote_data'])) { $this->p_vars['quote_data'] .= $word; } } if ($word == '>') { if (is_object($this->p_vars['quote_data'])) { $this->p_vars['quote_data'] = '{@id '.$this->p_vars['quote_data']->id.'}'; } addErrorDie(PDERROR_UNTERMINATED_ATTRIB, $this->curtag->name,$this->p_vars['attrname'],$this->p_vars['quote_data']); } if ($this->checkEventPop($word,$pevent)) { $this->p_flags['reset_quote_data'] = true; } } } /** * Handles all XML DocBook tags */ function handleTag($word, $pevent) { if (isset($this->curtag) && $this->curtag->hasTitle() && $this->_gettoc && $this->_gettoc->name == $this->curtag->name) { if (isset($this->_toc[$this->_cursection])) { $this->_toc[$this->_cursection]['title'] = $this->curtag->_title; $this->_cursection++; } $this->_gettoc = false; } if ($this->p_vars['last_word'] == '<') { // get tag name $this->p_flags['begin_tag'] = true; array_push($this->context,$word); // if (isset($this->curtag)) debug("pushed ".$this->curtag->name); if (isset($this->curtag)) { array_push($this->pars,$this->curtag); } $this->curtag = new parserXMLDocBookTag($word); } elseif ($this->p_vars['last_word'] == '</' || $word == '/>') { $tag = array_pop($this->context); if ($word == '/>') { // all is OK $this->checkEventPop($word, $pevent); $word = $tag; } if ($tag != $word) { addErrorDie(PDERROR_UNMATCHED_TUTORIAL_TAG,$tag,$word,$this->curtag->getString()); } if (in_array($this->curtag->name, array('refentry', 'refsect1', 'refsect2', 'refsect3'))) { if (!isset($this->curtag->_id)) { $title = ''; if (isset($this->curtag->_title)) { $title = $this->curtag->_title->getString(); } addWarning(PDERROR_NO_DOCBOOK_ID, $this->curtag->name, $title); } } $this->p_flags['begin_tag'] = false; $curtag = @array_pop($this->pars); // debug("popped $tag ".$curtag->name.' I am '.$this->curtag->name); if ($curtag) { if ($this->curtag->name == 'refsect1') $this->refsect1id = false; if ($this->curtag->name == 'refsect2') $this->refsect2id = false; if ($this->curtag->name == 'refsect3') $this->refsect3id = false; $curtag->add($this->curtag); // debug("added ".$this->curtag->name." to ".$curtag->name.' '.$curtag->id); $this->curtag = $curtag; } else { // debug("here"); } } elseif (is_string($word)) { if (!($e = $this->checkEventPush($word, $pevent))) { if ($this->checkEventPop($word, $pevent)) { if ($this->p_flags['begin_tag']) { $this->p_vars['event_stack']->pushEvent(PHPDOCUMENTOR_PDP_EVENT_TAG); $this->p_vars['event_stack']->pushEvent(PHPDOCUMENTOR_PDP_EVENT_CDATA); $this->p_vars['last_tag'] = array_pop($this->context); array_push($this->context,$this->p_vars['last_tag']); $this->p_flags['in_cdata'] = false; } return; } } else { $this->p_flags['start_attr'] = true; $this->p_flags['end_attr'] = false; } } else addErrorDie(PDERROR_CANT_HAVE_INLINE_IN_TAGNAME); } /** * Handle CData sections */ function handleCData($word, $pevent) { if ($this->curtag->name == 'refentry' && phpDocumentor_get_class($word) == 'parsertocinlinetag') { $this->p_vars['toc'] = $this->curtag->getTOC(); } if (is_string($word) && !$this->p_flags['in_cdata']) { if ($this->checkEventPop($word, $pevent)) { return; } if ($this->checkEventPush($word, $pevent)) { return; } } if (is_string($word) && $word == '<![CDATA[') { $this->curtag->startCData(); $this->p_flags['in_cdata'] = true; } elseif ($this->p_flags['in_cdata'] && is_string($word) && $word == ']]>') { $this->curtag->endCData(); $this->p_flags['in_cdata'] = false; } else { if ($this->p_flags['in_cdata']) $this->curtag->addCData($word); else $this->curtag->add($word); } } /** * Handle Entities like ” */ function handleEntity($word, $pevent) { if (!$word) { if (!isset($this->p_vars['entity_name'])) $this->p_vars['entity_name'] = ''; addErrorDie(PDERROR_UNTERMINATED_ENTITY,$this->p_vars['entity_name']); } $e = $this->checkEventPop($word, $pevent); if ($word && !$e) $this->p_vars['entity_name'] = $word; if ($e) { $entity = new parserEntity($this->p_vars['entity_name']); unset($this->p_vars['entity_name']); $this->curtag->add($entity); } } /** * Handle Tag attributes name="value" */ function handleAttributes($word, $pevent) { if ($this->checkEventPush($word, $pevent)) return; if ($word == '=') { $this->p_flags['start_attr'] = false; $this->p_vars['end_attr'] = true; } else { if ($this->p_flags['start_attr']) { $this->p_vars['attrname'] = $word; } else { if (isset($this->p_vars['attrname'])) { $value = $this->p_vars['quote_data']; if (phpDocumentor_get_class($value) == 'parseridinlinetag') { // "inherit" the parent section's id, so // <refsect1 id="{@id test"}> <!-- id is 'test' --> // ... // <refsect2 id="{@id me}"> <!-- id is 'test.me' --> // ... // <refsect3 id="{@id out}"> <!-- id is 'test.me.out' --> // <example id="{@id withexample}"> <!-- id is 'test.me.out.withexample' --> $a = ($this->refsect1id ? $this->refsect1id . '.' : ''); $a .= ($this->refsect2id ? $this->refsect2id . '.' : ''); $a .= ($this->refsect3id ? $this->refsect3id . '.' : ''); if ($this->curtag->name == 'refsect1') { $this->refsect1id = $value->id; } if ($this->curtag->name == 'refsect2') { $this->refsect2id = $value->id; } if ($this->curtag->name == 'refsect3') { $this->refsect3id = $value->id; } // debug($value->id.' is now '.$a.$value->id); $value->id = $a . $value->id; if ($value->id != '') { if (isset($this->_toc[$this->_cursection])) { $this->_cursection++; } $this->_toc[$this->_cursection]['id'] = $value; $this->_toc[$this->_cursection]['tag'] = new parserXMLDocBookTag($this->curtag->name); // debug("set gettoc to ".$this->curtag->name .' '. $value->id); $this->_gettoc = $this->curtag; } } $this->curtag->addAttribute($this->p_vars['attrname'],$value); unset($this->p_vars['attrname']); if (is_string($word) && $this->checkEventPop($word, $pevent)) { $this->p_flags['start_attr'] = true; $this->p_flags['end_attr'] = false; $this->wp->setPos($this->wp->getPos() - strlen($word)); } else { $this->wp->setPos($this->wp->getPos() - strlen($word)); } return; } } } if (is_string($word) && $this->checkEventPop($word, $pevent)) { $this->p_flags['start_attr'] = true; $this->p_flags['end_attr'] = false; $this->wp->setPos($this->wp->getPos() - strlen($word)); } } /**#@-*/ /** * setup the parser tokens, and the pushEvent/popEvent arrays * @see $tokens, $pushEvent, $popEvent */ function setupStates() { $this->_gettoc = false; $this->_toc = array(); $this->_cursection = 0; if (isset($this->p_vars['toc'])) unset($this->p_vars['toc']); $this->tokens[STATE_NOEVENTS] = array('</','<!--','<!','<?','<'); $this->tokens[STATE_COMMENTBLOCK] = array('-->'); $this->tokens[STATE_OUTPHP] = array('?>','>'); $this->tokens[STATE_QUOTE] = array("\\\"","\\\\","\"",'>'); $this->tokens[STATE_ESCAPE] = false;// this tells the word parser to just cycle $this->tokens[PHPDOCUMENTOR_PDP_STATE_TAG] = array('>',' ','/>'); $this->tokens[PHPDOCUMENTOR_PDP_STATE_CDATA] = array('&','<!--','</','<![CDATA[','<',']]>'); $this->tokens[PHPDOCUMENTOR_PDP_STATE_ATTRIBUTES] = array('=','>','/>','"'); $this->tokens[PHPDOCUMENTOR_PDP_STATE_ENTITY] = array(';');
// For each event word to event mapings $this->pushEvent[PARSER_EVENT_NOEVENTS] = array( '<!--' => PARSER_EVENT_COMMENTBLOCK, '<!' => PARSER_EVENT_OUTPHP, "</" => PHPDOCUMENTOR_PDP_EVENT_TAG, '<?' => PARSER_EVENT_OUTPHP, "<" => PHPDOCUMENTOR_PDP_EVENT_TAG, '&' => PHPDOCUMENTOR_PDP_EVENT_ENTITY, ); ##########################
$this->pushEvent[PHPDOCUMENTOR_PDP_EVENT_TAG] = array( ' ' => PHPDOCUMENTOR_PDP_EVENT_ATTRIBUTES, ); $this->popEvent[PHPDOCUMENTOR_PDP_EVENT_TAG] = array(">","/>"); ########################## $this->pushEvent[PHPDOCUMENTOR_PDP_EVENT_ATTRIBUTES] = array( '"' => PARSER_EVENT_QUOTE, );
$this->popEvent[PHPDOCUMENTOR_PDP_EVENT_ATTRIBUTES] = array(">","/>"); ##########################
$this->popEvent[PARSER_EVENT_COMMENTBLOCK] = array("-->"); ########################## $this->pushEvent[PARSER_EVENT_QUOTE] = array( "\\" => PARSER_EVENT_ESCAPE ); $this->popEvent[PARSER_EVENT_QUOTE] = array("\""); ##########################
$this->popEvent[PARSER_EVENT_OUTPHP] = array("?>",">"); ##########################
$this->popEvent[PHPDOCUMENTOR_PDP_EVENT_ENTITY] = array(";"); ##########################
$this->pushEvent[PHPDOCUMENTOR_PDP_EVENT_CDATA] = array( "<" => PHPDOCUMENTOR_PDP_EVENT_TAG, '<!--' => PARSER_EVENT_COMMENTBLOCK, '<?' => PARSER_EVENT_OUTPHP, '&' => PHPDOCUMENTOR_PDP_EVENT_ENTITY, ); $this->popEvent[PHPDOCUMENTOR_PDP_EVENT_CDATA] = array("</"); } /** * debugging function * * {@source} * @static */ function getParserEventName ($value) { $lookup = array( PARSER_EVENT_NOEVENTS => "PARSER_EVENT_NOEVENTS", PHPDOCUMENTOR_PDP_EVENT_TAG => "PHPDOCUMENTOR_PDP_EVENT_TAG", PHPDOCUMENTOR_PDP_EVENT_ATTRIBUTES => "PHPDOCUMENTOR_PDP_EVENT_ATTRIBUTES", PHPDOCUMENTOR_PDP_EVENT_CDATA => "PHPDOCUMENTOR_PDP_EVENT_CDATA", PHPDOCUMENTOR_PDP_EVENT_LIST => "PHPDOCUMENTOR_PDP_EVENT_LIST", PARSER_EVENT_QUOTE => "PARSER_EVENT_QUOTE", PHPDOCUMENTOR_PDP_EVENT_ENTITY => "PHPDOCUMENTOR_PDP_EVENT_ENTITY", PHPDOCUMENTOR_PDP_EVENT_COMMENT => "PHPDOCUMENTOR_PDP_EVENT_COMMENT", PHPDOCUMENTOR_PDP_EVENT_PI => "PHPDOCUMENTOR_PDP_EVENT_PI", ); if (isset($lookup[$value])) return $lookup[$value]; else return $value; } } ?>
|