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

Reply via email to