gwynne Mon Jul 30 09:48:08 2007 UTC Added files: (Branch: GWYNNE_PLAYS_HERE) /phd/themes/default theme.php /phd/themes/phd theme.php /phd/themes/php theme.php /phd/themes/phpinternals theme.php
Modified files: /phd build.php /phd/formats xhtml.php /phd/include PhDReader.class.php Log: Paradigm shift. Formats and themes are no longer subclasses of PhDReader, since it doesn't really make sense in terms of object-oriented design ("is a" versus "has a"). Also changed the way format mappings are done almost completely; I didn't yet show how a theme would really modify things, but the beginnings of the flexibility idea are here. What's here right now produces a messy and invalid bigxhtml file when given .manual.xml, but the transformations that *are* implemented do work. The test data in build.php is a better example of the functionality that currently exists. More work to come soon, but once I got this far I decided to take a break; it feels like my neurons are melting.
http://cvs.php.net/viewvc.cgi/phd/build.php?r1=1.4.2.1&r2=1.4.2.2&diff_format=u Index: phd/build.php diff -u phd/build.php:1.4.2.1 phd/build.php:1.4.2.2 --- phd/build.php:1.4.2.1 Sun Jul 29 14:31:54 2007 +++ phd/build.php Mon Jul 30 09:48:07 2007 @@ -2,29 +2,33 @@ error_reporting( E_ALL | E_STRICT ); require_once 'config.php'; -require_once 'formats/xhtml.php'; +require_once 'include/PhDReader.class.php'; file_put_contents( dirname( __FILE__ ) . "/temp.xml", <<<~XML <?xml version="1.0" encoding="utf-8"?> <book> - <part id="part1"> - <chapter id="chap1"> - Using the application <application>autoconf</application>, we can do some - fun stuff, since <command>php</command> does other fun things, and dolor - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod - tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, - quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo - consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse - cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat - non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + <part xml:id="part1"> + <chapter xml:id="chap1"> + <sect1 xml:id="part1.chap1.sect1"> + <title>First section!</title> + Using the application <application>autoconf</application>, we can do some + fun stuff, since <command>php</command> does other fun things, and dolor + Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim + veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea + commodo consequat. Duis aute irure dolor in reprehenderit in voluptate + velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat + cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id + est laborum. + </sect1> </chapter> </part> </book> XML ); -$phd = new PhDReader_XHTML( dirname( __FILE__ ) . "/temp.xml", NULL, 2 ); +$phd = new PhDReader( $OPTIONS[ 'xml_root' ] . "/.manual.xml", NULL, 2 ); while ( $phd->transformChunk( $chunk ) ) { print "{$chunk}\n"; http://cvs.php.net/viewvc.cgi/phd/formats/xhtml.php?r1=1.7.2.2&r2=1.7.2.3&diff_format=u Index: phd/formats/xhtml.php diff -u phd/formats/xhtml.php:1.7.2.2 phd/formats/xhtml.php:1.7.2.3 --- phd/formats/xhtml.php:1.7.2.2 Sun Jul 29 14:31:54 2007 +++ phd/formats/xhtml.php Mon Jul 30 09:48:07 2007 @@ -1,6 +1,6 @@ <?php -/* $Id: xhtml.php,v 1.7.2.2 2007/07/29 14:31:54 gwynne Exp $ +/* $Id: xhtml.php,v 1.7.2.3 2007/07/30 09:48:07 gwynne Exp $ +-------------------------------------------------------------------------+ | Copyright(c) 2007 | | Authors: | @@ -12,18 +12,76 @@ | http://phd.php.net/LICENSE | +-------------------------------------------------------------------------+ | The XHTML output format class. This should not be instantiated | - | directly; it is intended for extension by a theme class. | - | XXX This is temporarily untrue for "let's get it started" purposes. | + | directly; it is intended for use only by PHDReader. | +-------------------------------------------------------------------------+ */ /* Grab the PhDReader parent class. */ require_once 'include/PhDReader.class.php'; -class PhDReader_XHTML extends PhDReader { +class PhD_xhtml_Format implements PhD_OutputFormat { + + protected $reader = NULL; + protected $handlerMap = array(); + protected $IDStack = array(); + protected $nameStack = array(); + + protected function translationSpec( $name ) { + return array( "<{$name} class=\"%n%\">", "</{$name}>", FALSE ); + } + + public function __construct( $reader ) { + + $this->reader = $reader; + + $span = $this->translationSpec( 'span' ); + $div = $this->translationSpec( 'div' ); + + $this->handlerMap = array( + 'application' => $span, + 'classname' => $span, + 'code' => $this->translationSpec( 'code' ), + 'collab' => $span, + 'collabname' => $span, + 'command' => $span, + 'computerOutput' => $span, + 'constant' => $span, + 'emphasis' => $this->translationSpec( 'em' ), + 'enumname' => $span, + 'envar' => $span, + 'filename' => $span, + 'glossterm' => $span, + 'holder' => $span, + 'informaltable' => $this->translationSpec( 'table' ), + 'itemizedlist' => $this->translationSpec( 'ul' ), + 'listitem' => $this->translationSpec( 'li' ), + 'literal' => $span, + 'mediaobject' => $div, + 'methodparam' => $span, + 'member' => $this->translationSpec( 'li' ), + 'note' => $div, + 'option' => $span, + 'orderedlist' => $this->translationSpec( 'ol' ), + 'para' => $this->translationSpec( 'p' ), + 'parameter' => $span, + 'partintro' => $div, + 'productname' => $span, + 'propname' => $span, + 'property' => $span, + 'proptype' => $span, + 'section' => array( '<div class="%n%" id="%i%" xml:id="%i%">', '</div>', TRUE ), + 'sect1' => array( '%push=i%%push=n%<div class="%n%" id="%i%" xml:id="%i%">', '</div>%pop=n%%pop=i%', TRUE ), + 'title' => array( '<h1 class="%top=n%"><a name="%top=i%">', '</a></h1>', FALSE ), + 'simplelist' => $this->translationSpec( 'ul' ), + 'simpara' => $this->translationSpec( 'p' ), + 'year' => $span, + 'refentry' => array( '<div id="%i%">', '</div>', TRUE ), + 'reference' => $div, + 'function' => array( '<b>', '</b>', FALSE ), + 'refsect1' => $div, + '__default' => array( $this, 'unknownElement' ), + ); - public function __construct( $file, $encoding = 'utf-8', $options = NULL ) { - parent::__construct( $file, $encoding, $options ); } public function __destruct() { @@ -35,7 +93,7 @@ } - protected function transformNode( $name, $type, &$output ) { + public function transformNode( $name, $type, &$output ) { switch ( $type ) { @@ -45,11 +103,11 @@ break; case XMLReader::TEXT: - $output = $this->value; + $output = $this->reader->value; return FALSE; case XMLReader::CDATA: - $output = $this->processCDATA( $this->value ); + $output = $this->processCDATA( $this->reader->value ); return FALSE; case XMLReader::ENTITY_REF: @@ -61,84 +119,16 @@ } protected function processElement( $name, $isOpen, &$output ) { - static $handlerMap = NULL; - if ( is_null( $handlerMap ) ) { - $spanName = array( '<span class="%n%">', FALSE, '</span>', FALSE ); - $divName = array( '<div class="%n%">', FALSE, '</div>', FALSE ); - $divNameChunked = array( '<div class="%n%">', FALSE, '</div>', TRUE ); - $oneToOne = array( '<%n%>', FALSE, '</%n%>', FALSE ); - - $handlerMap = array( - 'application' => $spanName, - 'classname' => $spanName, - 'code' => $oneToOne, - 'collab' => $spanName, - 'collabname' => $spanName, - 'command' => $spanName, - 'computerOutput' => $spanName, - 'constant' => $spanName, - 'emphasis' => $oneToOne, - 'enumname' => $spanName, - 'envar' => $spanName, - 'filename' => $spanName, - 'glossterm' => $spanName, - 'holder' => $spanName, - 'informatlable' => array( '<table>', FALSE, '</table>', FALSE ), - 'itemizedlist' => array( '<ul>', FALSE, '</ul>', FALSE ), - 'listitem' => array( '<li>', FALSE, '</li>', FALSE ), - 'literal' => $spanName, - 'mediaobject' => $divName, - 'methodparam' => $spanName, - 'member' => array( '<li>', FALSE, '</li>', FALSE ), - 'note' => $divName, - 'option' => $spanName, - 'orderedlist' => array( '<ol>', FALSE, '</ol>', FALSE ), - 'para' => array( '<p>', FALSE, '</p>', FALSE ), - 'parameter' => $spanName, - 'partintro' => $divName, - 'productname' => $spanName, - 'propname' => $spanName, - 'property' => $spanName, - 'proptype' => $spanName, - 'section' => $divNameChunked, - 'simplelist' => array( '<ul>', FALSE, '</ul>', FALSE ), - 'simpara' => array( '<p>', FALSE, '</p>', FALSE ), - 'title' => array( 'checkparentname', array( '__default' => 'h1', 'refsect1' => 'h3', 'example' => 'h4' ) ), - 'year' => $spanName, - 'refentry' => array( '<div id="%i%" class="refentry">', FALSE, '</div>', TRUE, TRUE ), - 'reference' => array( $this, 'format_reference' ), - 'function' => array( '<a href="function.%v%.html">', FALSE, '</a>', FALSE ), - 'refsect1' => array( '<div class="refsect_%r%">', FALSE, '</div>', FALSE ), - '__default' => array( $this, 'unknownElement' ), - ); - } + $mapping = isset( $this->handlerMap[ $name ] ) ? $this->handlerMap[ $name ] : $this->handlerMap[ '__default' ]; + + if ( is_callable( $mapping ) ) { + return call_user_func( $mapping, $name, $isOpen, &$output ); + + } else if ( is_array( $mapping ) ) { + $output = $this->formatMappingString( $name, $this->reader->getID(), $isOpen ? $mapping[ 0 ] : $mapping[ 1 ] ); + return ( $isOpen ? FALSE : $mapping[ 2 ] ); - $mapping = isset( $handlerMap[ $name ] ) ? $handlerMap[ $name ] : $handlerMap[ '__default' ]; - if ( is_array( $mapping ) ) { - if ( is_string( $mapping[ 0 ] ) ) { - switch ( $mapping[ 0 ] ) { - case 'checkparentname': - $output = '<div class="warning">NOT IMPLEMENTED YET.</div>'; - return FALSE; - default: - $id = $this->getID(); - $output = $this->formatMappingString( $name, $id, $isOpen ? $mapping[ 0 ] : $mapping[ 2 ] ); - if ( !empty( $mapping[ 4 ] ) ) { - $this->pushStack( $id ); - } - return ( $isOpen ? $mapping[ 1 ] : $mapping[ 3 ] ); - } - } else if ( is_callable( $mapping ) ) { - return call_user_func( $mapping, $name, $isOpen, &$output ); - } - } else if ( is_string( $mapping ) ) { - if ( $isOpen ) { - $output = $this->formatMappingString( $name, $this->getID(), $mapping ); - } else { - $output = ''; - } - return FALSE; } $output = '<div class="warning">Bad handler string for '.$name.'!</div>'; return FALSE; @@ -147,31 +137,53 @@ protected function processCDATA( $content ) { - return '<div class="phpcode">' . highlight_string( $content ) . '</div>'; + return "<div>{$content}</div>"; } - protected function formatMappingString( $name, $id, $string ) { + protected function mappingFormatter( $matches ) { + + if ( empty( $matches[ 1 ] ) ) { + if ( $matches[ 4 ] == 'n' ) { + return $this->_mapping_name; + } else if ( $matches[ 4 ] == 'i' ) { + return $this->_mapping_id; + } + } else { + if ( $matches[ 3 ] == 'n' ) { + $a = &$this->nameStack; + $v = $this->_mapping_name; + } else if ( $matches[ 3 ] == 'i' ) { + $a = &$this->IDStack; + $v = $this->_mapping_id; + } + + if ( $matches[ 2 ] == 'push' ) { + array_push( $a, $v ); + return ''; + } else if ( $matches[ 2 ] == 'pop' ) { + array_pop( $a ); + return ''; + } else if ( $matches[ 2 ] == 'top' ) { + return $a[ 0 ]; + } + } + return 'INVALID MAPPING DATA:' . var_export($matches,1); + + } - // XXX Yes, this needs heavy optimization, it's example for now. - return str_replace( array( '%n%', '%i%', '%v%', '%r' ), - array( $name, $id, $this->readInnerXML(), $this->getAttribute( 'role' ) ), - $string ); - } + protected function formatMappingString( $name, $id, $string ) { + + $sc = 'ni'; // sc == stack chars + $fc = 'ni'; // fc == formatted chars + $this->_mapping_name = $name; + $this->_mapping_id = $id; + $s = preg_replace_callback( "/%(?:((push|pop|top)=([{$sc}]))|([{$fc}]))%/", array( $this, 'mappingFormatter' ), $string ); + unset( $this->_mapping_name ); + unset( $this->_mapping_id ); + return $s; - protected function format_reference( $name, $isOpen, $output ) { - if ( $isOpen ) { - $output = sprintf( '<div id="%s" class="reference">', $this->getID() ); - return FALSE; - } - $output = '</div>' . - '<ul class="funclist">'; - foreach ( $this->popStack() as $func => $desc ) { - $output .= sptrinf( '<li><a href="function.%1$s.html" class="refentry">%1$s</a></li>', $func ); - } - $output .= '</ul>'; - return TRUE; } protected function unknownElement( $name, $isOpen, $output ) { http://cvs.php.net/viewvc.cgi/phd/include/PhDReader.class.php?r1=1.6.2.2&r2=1.6.2.3&diff_format=u Index: phd/include/PhDReader.class.php diff -u phd/include/PhDReader.class.php:1.6.2.2 phd/include/PhDReader.class.php:1.6.2.3 --- phd/include/PhDReader.class.php:1.6.2.2 Sun Jul 29 14:31:54 2007 +++ phd/include/PhDReader.class.php Mon Jul 30 09:48:07 2007 @@ -1,6 +1,6 @@ <?php -/* $Id: PhDReader.class.php,v 1.6.2.2 2007/07/29 14:31:54 gwynne Exp $ +/* $Id: PhDReader.class.php,v 1.6.2.3 2007/07/30 09:48:07 gwynne Exp $ +-------------------------------------------------------------------------+ | Copyright(c) 2007 | | Authors: | @@ -11,25 +11,110 @@ | world-wide-web at the following url: | | http://phd.php.net/LICENSE | +-------------------------------------------------------------------------+ - | The base class for reading the giant XML blob. This is intended for | - | extension by output formats, and then for further extension by output | - | themes. This class should not be instantiated directly. | + | The base class for reading the giant XML blob. This is intended to have | + | a format and theme plugged into it. | +-------------------------------------------------------------------------+ */ -abstract class PhDReader extends XMLReader { +// *** +// Output format classes must implement this interface. +// THIS IS THE OFFICIAL OUTPUT FORMAT INTERFACE. +interface PhD_OutputFormat { + + // proto string getFormatName( void ) + // Return the name of the format. + public function getFormatName(); + + // proto string transformNode( string name, int type, string &output ) + // Transform a given node, returning the string output. Binary strings ARE + // handled safely. This function will be called for all element, text, + // cdata, entity reference, and end element nodes. It is NOT valid for + // this method to advance the parser's input. Return TRUE to create a + // chunk boundary, FALSE otherwise. + public function transformNode( $name, $type, &$output ); + +} + +// *** +// Output theme classes must implement this interface. +// THIS IS THE OFFICIAL OUTPUT THEME INTERFACE. +interface PhD_OutputTheme { + + // proto string getThemeName( void ) + // Return the name of the theme. + public function getThemeName(); + + // proto string transformNode( string name, int type, PhD_OutputFormat formatter, string &output ) + // Transform a given node, returning the string output. Call the given + // formatter for all inputs, altering its output as appropriate, unless + // the theme handles the entire transformation by itself. + public function transformNode( $name, $type, $formatter, &$output ); + + // proto string chunkHeader( void ) + // Return a header for a chunk. The current node will be the first node in + // the chunk. + public function chunkHeader(); + + // proto string chunkFooter( void ) + // Return a footer for a chunk. The current node will be the END_ELEMENT + // of the chunk's first node. + public function chunkFooter(); + +} + + +class PhDReader extends XMLReader { + const XMLNS_XML = "http://www.w3.org/XML/1998/namespace"; - const XMLNS_XLINK = "http://www.w3.org/1999/xlinK"; + const XMLNS_XLINK = "http://www.w3.org/1999/xlink"; const XMLNS_PHD = "http://www.php.net/ns/phd"; + protected $outputFormat = NULL; + protected $outputTheme = NULL; + protected $stack = array(); + protected $state = array(); + + // *** + // Debugging functions + public function debuggingOn() { return $GLOBALS[ 'OPTIONS' ][ 'debug' ]; } + public function debugMessage( $msg ) { + if ( $this->debuggingOn() ) { + fwrite( STDERR, date( DATE_RFC2822 ) . ": {$msg}\n" ); + } + } + public function debugAssert( $condition, $desc ) { + if ( $this->debuggingOn() && $condition == FALSE ) { + $this->debugMessage( "ASSERTION FAILURE for '{$desc}'.\nBacktrace:" ); + $this->debugMessage( print_r( array_slice( debug_backtrace(), 1 ), 1 ) ); + exit( 1 ); + } + } + + // *** + // Constructor and destructor + public function __construct( $file ) { + global $OPTIONS; - public function __construct( $file, $encoding = "utf-8", $options = NULL ) { - - if ( !parent::open( $file, $encoding, $options ) ) { + if ( !parent::open( $file, NULL, 0 ) ) { throw new Exception(); } + // Position the reader at the first node. $this->read(); + + // Grab the output format. + require dirname( __FILE__ ) . "/../formats/{$OPTIONS[ 'output_format' ]}.php"; + $formatClassName = "PhD_" . str_replace( '-', '_', $OPTIONS[ 'output_format' ] ) . '_Format'; + $this->outputFormat = new $formatClassName( $this ); + $this->debugMessage( "Loaded output format '{$OPTIONS[ 'output_format' ]}' using class '{$formatClassName}'." ); + + // Grab the output theme. + require dirname( __FILE__ ) . "/../themes/{$OPTIONS[ 'output_theme' ]}/theme.php"; + $themeClassName = "PhD_" . str_replace( '-', '_', $OPTIONS[ 'output_theme' ] ) . '_Theme'; + $this->outputTheme = new $themeClassName( $this ); + $this->debugMessage( "Loaded output theme '{$OPTIONS[ 'output_theme' ]}' using class '{$themeClassName}'." ); + + // TODO: Set up the output encoding if necessary. } @@ -37,31 +122,18 @@ } // *** - // Format subclasses must implement these to make them real formats. - // THIS IS THE OFFICIAL OUTPUT FORMAT INTERFACE. - - // proto string getFormatName( void ) - // Return the name of the format. - abstract public function getFormatName(); - - // proto string transformNode( string name, int type, string &output ) - // Transform a given node, returning the binary string output. Binary - // strings ARE handled safely. This function will be called for all - // element, text, cdata, entity reference, and end element nodes. It - // is always valid for this method to make the parser move around in - // the file. Return TRUE to create a chunk boundary, FALSE otherwise. - abstract protected function transformNode( $name, $type, &$output ); - - // *** // Protected methods (intended for internal and subclass use only) + // *** + // Public methods + // proto array getAllAttributes( void ) // Return all the attributes in the current element node as name:ns => // value pairs. Prefer the getAttribute*() methods defined by XMLReader // when possible; use this only when you really do need all the // attributes. An element without any attributes will result in an empty // array, while a non-element node will result in a return of FALSE. - protected function getAttributes() { + public function getAttributes() { $type = $this->nodeType; if ( $type != XMLReader::ELEMENT && $type != XMLReader::END_ELEMENT ) { @@ -83,7 +155,7 @@ // proto string getID( void ) // Get the ID of the current element. Works on element and end element // nodes only, returning an empty string in all other cases. - protected function getID() { + public function getID() { if ( $this->hasAttributes && $this->moveToAttributeNs( "id", self::XMLNS_XML ) ) { $id = $this->value; @@ -93,49 +165,23 @@ return ""; } - - // protected void pushStack( mixed value ) - // Push a value of any kind onto the parser stack. The stack is not used - // by the parser; it is intended as a cheap data store for formats and - // themes. - protected function pushStack( $value ) { - - array_push( $this->stack, $value ); - - } - - // protected mixed stackTop( void ) - // Return the top value on the stack. - protected function stackTop() { - - return count( $this->stack ) ? $this->stack[ 0 ] : NULL; - - } - - // protected mixed popStack( void ) - // Pop the top value off the stack and return it. - protected function popStack() { - - return array_pop( $this->stack ); - - } - - // *** - // Public methods - + // proto bool seek( string id ) // Seek to an ID. This is used to start the parser somewhere that isn't at // the beginning (duh). Be careful; this does not cause the parser to halt // at the closing element of a successful seek. Don't forget to check the // return value. public function seek( $id ) { - + + $this->debugMessage( "Starting seek to {$id}..." ); while( parent::read() ) { if ( $this->nodeType === XMLREADER::ELEMENT && $this->hasAttributes && $this->moveToAttributeNs( "id", self::XMLNS_XML ) && $this->value === $id ) { + $this->debugMessage( "Seek complete." ); return $this->moveToElement(); } } + $this->debugMessage( "Seek failed." ); return FALSE; } @@ -145,11 +191,11 @@ // format's chunker. Returns the tree, or FALSE on error. public function transform() { - $allData = ''; - while ( ( $data = $this->transformChunk() ) !== FALSE ) { + $allData = $this->outputTheme->chunkHeader(); + while ( $this->transformChunk( $data, FALSE ) ) { $allData .= $data; } - return $allData; + return $allData . $this->outputTheme->chunkFooter(); } @@ -157,26 +203,27 @@ // Transform nodes until the output format says it's time to output a // chunking boundary or the parser runs out of data. Returns TRUE on // success, FALSE on EOF. $data contains the transformed data, if any. - public function transformChunk( &$outData ) { + public function transformChunk( &$outData, $applyHeaderFooter = TRUE ) { global $OPTIONS; $hasMore = TRUE; $data = fopen( "php://temp/maxmemory:{$OPTIONS[ 'chunking_memory_limit' ]}", "r+" ); + fwrite( $data, $this->outputTheme->chunkHeader() ); $isChunk = FALSE; do { $nodeName = $this->name; $nodeType = $this->nodeType; switch ( $nodeType ) { - case XMLReader::NONE: - break; - case XMLReader::ELEMENT: case XMLReader::END_ELEMENT: case XMLReader::TEXT: case XMLReader::CDATA: case XMLReader::ENTITY_REF: - $isChunk = $this->transformNode( $nodeName, $nodeType, $output ); + $isChunk = $this->outputTheme->transformNode( $nodeName, $nodeType, $this->outputFormat, $output ); fwrite( $data, $output ); + if ( $isChunk ) { + fwrite( $data, $this->outputTheme->chunkFooter() ); + } break; case XMLReader::ENTITY: @@ -189,8 +236,12 @@ case XMLReader::SIGNIFICANT_WHITESPACE: case XMLReader::END_ENTITY: case XMLReader::XML_DECLARATION: + case XMLReader::COMMENT: // Eat it for lunch. break; + + default: + die( "Unknown node type {$nodeType} while transforming. Can not continue." ); } $hasMore = $this->read(); } while ( !$isChunk && $hasMore ); @@ -203,43 +254,25 @@ } /* - public function getID() { - if ( $this->hasAttributes && $this->moveToAttributeNs("id", self::XMLNS_XML) ) { - $id = $this->value; - $this->moveToElement(); - return $id; - } - return ""; - } - public function nextNode() { - while( $this->read() ) { switch( $this->nodeType ) { - case XMLReader::ELEMENT: if ( $this->isEmptyElement ) { continue; } - case XMLReader::TEXT: case XMLReader::CDATA: case XMLReader::END_ELEMENT: return TRUE; } } - return FALSE; - + return FALSE; } - public function readNode( $nodeName ) { - return $this->read() && !( $this->nodeType == XMLReader::END_ELEMENT && $this->name == $nodeName ); - } - public function readContent( $node = NULL ) { - $retval = ""; if ( !$node ) { $node = $this->name; @@ -249,28 +282,9 @@ $this->read(); // Jump over END_ELEMENT too } return $retval; - } - public function readAttribute( $attr ) { - return $this->moveToAttribute( $attr ) ? $this->value : ""; - - } - - public function __call( $func, $args ) { - - if ( $this->nodeType == XMLReader::END_ELEMENT ) { - /* ignore * return; - } - trigger_error( "No mapper for $func", E_USER_WARNING ); - - /* NOTE: - * The _content_ of the element will get processed even though we dont - * know how to handle the elment itself - * - return ""; - } public function notXPath( $tag ) { $depth = $this->depth; @@ -284,54 +298,6 @@ return $tag; } - - public function transform() { - - $type = $this->nodeType; - $name = $this->name; - - switch( $type ) { - - case XMLReader::ELEMENT: - $this->STACK[ $this->depth ] = $name; - - case XMLReader::END_ELEMENT: - $funcname = "format_$name"; - if ( isset( $this->map[ $name ] ) ) { - $tag = $this->map[ $name ]; - if ( is_array( $tag ) ) { - $tag = $this->notXPath( $tag ); - } - if ( strncmp( $tag, "format_", 7 ) ) { - return $this->transormFromMap( $type == XMLReader::ELEMENT, $tag, $name ); - } - $funcname = $tag; - } - return call_user_func( array( $this, $funcname ), $type == XMLReader::ELEMENT ); - break; - - case XMLReader::TEXT: - return $this->value; - break; - - case XMLReader::CDATA: - return $this->highlight_php_code( $this->value ); - break; - - case XMLReader::COMMENT: - case XMLReader::WHITESPACE: - case XMLReader::SIGNIFICANT_WHITESPACE: - // swallow it - // XXX This could lead to a recursion overflow if a lot of comment nodes get strung together. - $this->read(); - return $this->transform(); - - default: - trigger_error( "Dunno what to do with {$this->name} {$this->nodeType}", E_USER_ERROR ); - return ""; - } - - } */ } http://cvs.php.net/viewvc.cgi/phd/themes/default/theme.php?view=markup&rev=1.1 Index: phd/themes/default/theme.php +++ phd/themes/default/theme.php http://cvs.php.net/viewvc.cgi/phd/themes/phd/theme.php?view=markup&rev=1.1 Index: phd/themes/phd/theme.php +++ phd/themes/phd/theme.php http://cvs.php.net/viewvc.cgi/phd/themes/php/theme.php?view=markup&rev=1.1 Index: phd/themes/php/theme.php +++ phd/themes/php/theme.php http://cvs.php.net/viewvc.cgi/phd/themes/phpinternals/theme.php?view=markup&rev=1.1 Index: phd/themes/phpinternals/theme.php +++ phd/themes/phpinternals/theme.php