bjori           Sun Aug  5 14:49:55 2007 UTC

  Added files:                 
    /phd        mktoc.php 
    /phd/include        PhDFormat.class.php 
    /phd/formats        php.php 
    /phd/themes phpweb.php 

  Modified files:              
    /phd        build.php 
    /phd/include        PhDReader.class.php 
    /phd/formats        xhtml.php 
  Log:
  Import PhD rev2
  
  
http://cvs.php.net/viewvc.cgi/phd/build.php?r1=1.4&r2=1.5&diff_format=u
Index: phd/build.php
diff -u phd/build.php:1.4 phd/build.php:1.5
--- phd/build.php:1.4   Fri Jul 27 23:09:27 2007
+++ phd/build.php       Sun Aug  5 14:49:55 2007
@@ -1,15 +1,109 @@
+#!/home/bjori/.apps/bin/php
 <?php
-require_once 'config.php';
-require_once 'formats/xhtml.php';
+/*  $Id: build.php,v 1.5 2007/08/05 14:49:55 bjori Exp $ */
 
-$phd = new PhDXHTMLReader( "${OPTIONS[ 'xml_root' ]}/.manual.xml" );
-$phd->seek( "function.dotnet-load" );
-echo date( DATE_RSS )." done seeking\n";
-
-ob_start();
-while( $phd->nextNode() ) {
-       print $phd->transform();
+function err($no, $str, $file, $line) {
+       global $notify;
+       if (strpos($str, "No mapper") !== false) {
+//             $notify->update("Another missing function", strstr($str, 
"'"))->show();
+               return false;
+       }
+
+       $err = new PHNotify("Something wrong!", "$str\n$file:$line\n", 
"dialog-error");
+       $err
+               ->urgency(PHNotify::URGENCY_CRITICAL)
+               ->timeout(PHNotify::EXPIRES_NEVER)
+               ->hint("x", 1680/2)->hint("y", 1050/2)
+               ->show();
+       return false;
+}
+
+if ($err = extension_loaded("phnotify")) {
+       $notify = new PHNotify("Starting build");
+       $notify->urgency(PHNotify::URGENCY_LOW)->hint("x", 1680)->hint("y", 
10)->show();
+       $start = microtime(true);
+       set_error_handler("err");
+}
+
+require "include/PhDReader.class.php";
+require "include/PhDFormat.class.php";
+require "formats/xhtml.php";
+require "formats/php.php";
+require "themes/phpweb.php";
+require "mktoc.php";
+
+if ($err) {
+       $mktoc = microtime(true);
+       $notify
+               ->update("mktoc finished", sprintf("mktoc ran for <b>%d</b> 
sec", $mktoc-$start))
+               ->show();
+}
+
+$reader = new PhDReader("/home/bjori/php/doc/.manual.xml");
+$format = new phpweb($reader, $IDs, $IDMap);
+
+$map = $format->getMap();
+
+while($reader->read()) {
+    $type = $reader->nodeType;
+    $name = $reader->name;
+
+    switch($type) {
+    case XMLReader::ELEMENT:
+    case XMLReader::END_ELEMENT:
+        $open = $type == XMLReader::ELEMENT;
+
+        $funcname = "format_$name";
+        if (isset($map[$name])) {
+            $tag = $map[$name];
+            if (is_array($tag)) {
+                $tag = $reader->notXPath($tag);
+            }
+            if (strncmp($tag, "format_", 7)) {
+                $retval = $format->transformFromMap($open, $tag, $name);
+                break;
+            }
+            $funcname = $tag;
+        }
+
+        $retval = $format->{$funcname}($open, $name);
+        break;
+
+    case XMLReader::TEXT:
+        $retval = htmlspecialchars($reader->value, ENT_QUOTES);
+        break;
+
+    case XMLReader::CDATA:
+        $retval = $format->CDATA($reader->value);
+        break;
+
+    case XMLReader::COMMENT:
+    case XMLReader::WHITESPACE:
+    case XMLReader::SIGNIFICANT_WHITESPACE:
+    case XMLReader::DOC_TYPE:
+        /* swallow it */
+        continue 2;
+
+    default:
+        trigger_error("Don't know how to handle {$name} {$type}", 
E_USER_ERROR);
+        return;
+    }
+    $format->appendData($retval, $reader->isChunk);
+}
+
+copy("cache/manual.php", "cache/index.php");
+$reader->close();
+
+if ($err) {
+       $end = microtime(true);
+       $notify
+               ->update(
+                               "PhD build finished",
+                               sprintf("mktoc build: <b>%d</b> sec\nPhD build  
 : <b>%d</b> sec\n--\nTotal time: <b>%d</b> seconds\n", $mktoc-$start, 
$end-$mktoc, $end-$start))
+               ->show();
 }
-$phd->close();
+/*
+* vim600: sw=4 ts=4 fdm=syntax syntax=php et
+* vim<600: sw=4 ts=4
+*/
 
-?>
http://cvs.php.net/viewvc.cgi/phd/include/PhDReader.class.php?r1=1.6&r2=1.7&diff_format=u
Index: phd/include/PhDReader.class.php
diff -u phd/include/PhDReader.class.php:1.6 phd/include/PhDReader.class.php:1.7
--- phd/include/PhDReader.class.php:1.6 Sat Jul 28 23:58:06 2007
+++ phd/include/PhDReader.class.php     Sun Aug  5 14:49:55 2007
@@ -1,165 +1,224 @@
 <?php
+/*  $Id: PhDReader.class.php,v 1.7 2007/08/05 14:49:55 bjori Exp $ */
+//6271
 
-/*  $Id: PhDReader.class.php,v 1.6 2007/07/28 23:58:06 gwynne Exp $
-    +-------------------------------------------------------------------------+
-    | Copyright(c) 2007                                                       |
-    | Authors:                                                                |
-    |    Gwynne Raskind <[EMAIL PROTECTED]>                                    
  |
-    |    Hannes Magnusson <[EMAIL PROTECTED]>                                  
   |
-    | This source file is subject to the license that is bundled with this    |
-    | package in the file LICENSE, and is available through the               |
-    | 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.                 |
-    +-------------------------------------------------------------------------+
-*/
-
-abstract class PhDReader extends XMLReader {
-
-       protected $map = array();
-
-       public function __construct( $file, $encoding = "utf-8", $options = 
NULL ) {
-
-               if ( !parent::open( $file, $encoding, $options ) ) {
-                       throw new Exception();
-               }
-
-       }
-    
-    public function __destruct() {
+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_PHD   = "http://www.php.net/ns/phd";;
+    const OPEN_CHUNK  = 0x01;
+    const CLOSE_CHUNK = 0x02;
+
+    private $STACK    = array();
+    private $LAST_DEPTH = -1;
+    private $lastChunkDepth = -1;
+
+    public $isChunk = false;
+
+    protected $CHUNK_ME = array( /* {{{ */
+        'article'               => true,
+        'appendix'              => true,
+        'bibliography'          => array(
+                       /* DEFAULT */          false,
+            'article'           => true,
+            'book'              => true,
+            'part'              => true,
+       ),
+        'book'                  => true,
+        'chapter'               => true,
+        'colophon'              => true,
+        'glossary'              => array(
+                       /* DEFAULT */          false,
+            'article'           => true,
+            'book'              => true,
+            'part'              => true,
+       ),
+        'index'                 => array(
+                       /* DEFAULT */          false,
+            'article'           => true,
+            'book'              => true,
+            'part'              => true,
+       ),
+        'part'                  => true,
+        'preface'               => true,
+        'refentry'              => true,
+        'reference'             => true,
+        'sect1'                 => 'isSectionChunk',
+        /*
+        'sect2'                 => 'format_section_chunk',
+        'sect3'                 => 'format_section_chunk',
+        'sect4'                 => 'format_section_chunk',
+        'sect5'                 => 'format_section_chunk',
+        */
+        'section'               => 'isSectionChunk',
+        'set'                   => true,
+        'setindex'              => true,
+   ); /* }}} */
+
+    public function __construct($file, $encoding = "UTF-8", $options = NULL) {
+        if (!XMLReader::open($file, $encoding, $options)) {
+            throw new Exception();
+        }
     }
-    
-    /* Format subclasses must implement these to make them real formats. */
-    abstract public function getFormatName();
-    abstract protected function transformFromMap( $open, $name );
-    
-    /* These are new functions, extending XMLReader. */
-    
-    /* Seek to an ID within the file. */
-       public function seek( $id ) {
-
-               while( parent::read() ) {
-                       if ( $this->nodeType == XMLREADER::ELEMENT && 
$this->hasAttributes &&
-                               $this->moveToAttributeNs( "id", 
"http://www.w3.org/XML/1998/namespace"; ) && $this->value == $id ) {
-                               return $this->moveToElement();
-                       }
-               }
-               return FALSE;
 
-       }
-    
-    /* Go to the next useful node in the file. */
-       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;
-
-       }
-    
-    /* Read a node with the right name? */
-       public function readNode( $nodeName ) {
-
-               return $this->read() && !( $this->nodeType == 
XMLReader::END_ELEMENT && $this->name == $nodeName );
+   public function notXPath($tag) {
+       $depth = $this->depth;
+       do {
+           if (isset($tag[$this->STACK[--$depth]])) {
+               $tag = $tag[$this->STACK[$depth]];
+           } else {
+               $tag = $tag[0];
+           }
+       } while (is_array($tag));
+       return $tag;
+   }
 
-       }
-
-    /* Get the content of a named node, or the current node. */
-       public function readContent( $node = NULL ) {
+    /* Seek to an ID within the file. */
+    public function seek($id) {
+        while(XMLReader::read()) {
+            if ($this->nodeType === XMLREADER::ELEMENT && $this->hasAttributes 
&& XMLReader::moveToAttributeNs("id", self::XMLNS_XML) && $this->value === $id) 
{
+                return XMLReader::moveToElement();
+            }
+        }
+        return false;
+    }
 
-               $retval = "";
-               if ( !$node ) {
-                       $node = $this->name;
-               }
-               if ( $this->readNode( $node ) ) {
-                       $retval = $this->value;
-                       $this->read(); // Jump over END_ELEMENT too
-               }
-               return $retval;
+    /* Get the ID of current node */
+    public function getID() {
+        if ($this->hasAttributes && XMLReader::moveToAttributeNs("id", 
self::XMLNS_XML)) {
+            $id = $this->value;
+            XMLReader::moveToElement();
+            return $id;
+        }
+        return "";
+    }
 
-       }
-    
+    public function read() {
+        $this->isChunk = false;
+        if(XMLReader::read()) {
+            $type = $this->nodeType;
+            switch($type) {
+            case XMLReader::ELEMENT:
+                $name = $this->name;
+                $depth = $this->depth;
+                if ($this->LAST_DEPTH >= $depth) {
+                    $this->PREVIOUS_SIBLING = $this->STACK[$depth];
+                }
+                $this->STACK[$depth] = $name;
+                $isChunk = $this->isChunk($name);
+                if ($isChunk) {
+                    $this->isChunk = PhDReader::OPEN_CHUNK;
+                    $this->chunkDepths[] = $this->lastChunkDepth = $depth;
+                }
+                break;
+
+            case XMLReader::END_ELEMENT:
+                $depth = $this->depth;
+                if ($this->lastChunkDepth == $depth) {
+                    array_pop($this->chunkDepths);
+                    $this->lastChunkDepth = end($this->chunkDepths);
+                    $this->isChunk = PhDReader::CLOSE_CHUNK;
+                }
+                $this->LAST_DEPTH = $depth;
+                break;
+            }
+            return true;
+        }
+        return false;
+    }
+   
     /* Get the attribute value by name, if exists. */
-       public function readAttribute( $attr ) {
+    public function readAttribute($attr) {
+        $retval = XMLReader::moveToAttribute($attr) ? $this->value : "";
+        XMLReader::moveToElement();
+        return $retval;
+    }
+    public function readAttributeNs($attr, $ns) {
+        $retval = XMLReader::moveToAttributeNs($attr, $ns) ? $this->value : "";
+        XMLReader::moveToElement();
+        return $retval;
+    }
+    /* Get all attributes of current node */
+    public function getAttributes() {
+        if ($this->hasAttributes) {
+            $attrs = array();
+            XMLReader::moveToFirstAttribute();
+            do {
+                $attrs[$this->name] = $this->value;
+            } while (XMLReader::moveToNextAttribute());
+            XMLReader::moveToElement();
+            return $attrs;
+        }
+        return array();
+    }
 
-               return $this->moveToAttribute( $attr ) ? $this->value : "";
 
-       }
+    /* Get the content of a named node, or the current node. */
+    public function readContent($node = null) {
+        $retval = "";
 
-    /* Handle unmapped nodes. */
-       public function __call( $func, $args ) {
+        if($this->isEmptyElement) {
+            return $retval;
+        }
+        if (!$node) {
+            $node = $this->name;
+        }
+        $retval = "";
+        while (PhDReader::readNode($node)) {
+            $retval .= $this->value;
+        }
+        return $retval;
+    }
+    /* Read $nodeName until END_ELEMENT */
+    public function readNode($nodeName) {
+        return XMLReader::read() && !($this->nodeType === 
XMLReader::END_ELEMENT && $this->name == $nodeName);
+    }
 
-               if ( $this->nodeType == XMLReader::END_ELEMENT ) {
-                   /* ignore */ return;
+  
+       public function isChunk($tag) {
+               if (isset($this->CHUNK_ME[$tag])) {
+                       $isChunk = $this->CHUNK_ME[$tag];
+                       if (is_array($isChunk)) {
+                               $isChunk = $this->notXPath($isChunk);
+                       }
+                       if (!is_bool($isChunk)) {
+                               return call_user_func(array($this, $isChunk), 
$tag);
+                       }
+            return $isChunk;
                }
-               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 "";
-
+               return false;
        }
-
-    /* Perform a transformation. */
-       public function transform() {
-
-               $type = $this->nodeType;
-               $name = $this->name;
-
-               switch( $type ) {
-
-               case XMLReader::ELEMENT:
-               case XMLReader::END_ELEMENT:
-                       if( isset( $this->map[ $name ] ) ) {
-                               return $this->transformFromMap( $type == 
XMLReader::ELEMENT, $name );
-                       }
-                       return call_user_func( array( $this, "format_${name}" 
), $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 "";
-               }
-
+    public function isSectionChunk($tag) {
+        if ($this->PREVIOUS_SIBLING == $tag && $this->checkSectionDepth()) {
+            return true;
+        }
+        return false;
+    }
+    protected function checkSectionDepth() {
+        static $allowedParents = array("section", "sect2", "sect3", "sect4", 
"sect5");
+        static $chunkers       = array(
+            "sect1", "preface", "chapter", "appendix", "article", "part", 
"reference", "refentry",
+            "index", "bibliography", "glossary", "colopone", "book", "set", 
"setindex", "legalnotice",
+       );
+        
+        $nodeDepth = $this->depth;
+        $i = 1;
+        do {
+            if (in_array($this->STACK[$nodeDepth-$i], $allowedParents)) {
+                ++$i;
+                continue;
+            }
+            break;
+        } while(true);
+        if ($i <= 1 && in_array($this->STACK[$nodeDepth-$i], $chunkers)) {
+            return true;
+        }
+        return false;
     }
-
 }
 
 /*
 * vim600: sw=4 ts=4 fdm=syntax syntax=php et
 * vim<600: sw=4 ts=4
 */
-?>
+
http://cvs.php.net/viewvc.cgi/phd/formats/xhtml.php?r1=1.7&r2=1.8&diff_format=u
Index: phd/formats/xhtml.php
diff -u phd/formats/xhtml.php:1.7 phd/formats/xhtml.php:1.8
--- phd/formats/xhtml.php:1.7   Sat Jul 28 23:58:06 2007
+++ phd/formats/xhtml.php       Sun Aug  5 14:49:55 2007
@@ -1,196 +1,382 @@
 <?php
+/*  $Id: xhtml.php,v 1.8 2007/08/05 14:49:55 bjori Exp $ */
 
-/*  $Id: xhtml.php,v 1.7 2007/07/28 23:58:06 gwynne Exp $
-    +-------------------------------------------------------------------------+
-    | Copyright(c) 2007                                                       |
-    | Authors:                                                                |
-    |    Gwynne Raskind <[EMAIL PROTECTED]>                                    
  |
-    |    Hannes Magnusson <[EMAIL PROTECTED]>                                  
   |
-    | This source file is subject to the license that is bundled with this    |
-    | package in the file LICENSE, and is available through the               |
-    | world-wide-web at the following url:                                    |
-    | 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.     |
-    +-------------------------------------------------------------------------+
-*/
-
-/* Grab the PhDReader parent class. */
-require_once 'include/PhDReader.class.php';
-
-class PhDXHTMLReader extends PhDReader {
+class XHTMLPhDFormat extends PhDFormat {
+    protected $map = array( /* {{{ */
+        'article'               => 'format_container_chunk',
+        'author'                => 'div',
+        'authorgroup'           => 'div', /* DocBook-xsl prints out "by" (i.e. 
"PHP Manual by ...") */
+        'appendix'              => 'format_container_chunk',
+        'application'           => 'span',
+        'bibliography'          => array(
+            /* DEFAULT */          'div',
+            'article'           => 'format_chunk',
+            'book'              => 'format_chunk',
+            'part'              => 'format_chunk',
+        ),
+        'book'                  => 'format_container_chunk',
+        'chapter'               => 'format_container_chunk',
+        'colophon'              => 'format_chunk',
+        'firstname'             => 'span',
+        'surname'               => 'span',
+        'othername'             => 'span',
+        'honorific'             => 'span',
+        'glossary'              => array(
+            /* DEFAULT */          'div',
+            'article'           => 'format_chunk',
+            'book'              => 'format_chunk',
+            'part'              => 'format_chunk',
+        ),
+        'classname'             => 'span',
+        'code'                  => 'code',
+        'collab'                => 'span',
+        'collabname'            => 'span',
+        'command'               => 'span',
+        'computeroutput'        => 'span',
+        'constant'              => 'span',
+        'emphasis'              => 'em',
+        'enumname'              => 'span',
+        'entry'                 => array(
+            /* DEFAULT */          'format_entry',
+            'row'               => array(
+                /* DEFAULT */      'format_row_entry',
+                'thead'         => 'format_thead_entry',
+                'tfoot'         => 'format_tfoot_entry',
+                'tbody'         => 'format_tbody_entry',
+            ),
+        ),
+        'envar'                 => 'span',
+        'filename'              => 'span',
+        'glossterm'             => 'span',
+        'holder'                => 'span',
+        'index'                 => array(
+            /* DEFAULT */          'div',
+            'article'           => 'format_chunk',
+            'book'              => 'format_chunk',
+            'part'              => 'format_chunk',
+        ),
+        'info'                  => 'div',
+        'informaltable'         => 'table',
+        'itemizedlist'          => 'ul',
+        'listitem'              => array(
+            /* DEFAULT */          'li',
+            'varlistentry'      => 'format_varlistentry_listitem',
+        ),
+        'literal'               => 'span',
+        'mediaobject'           => 'div',
+        'methodparam'           => 'span',
+        'member'                => 'li',
+        'note'                  => 'div',
+        'option'                => 'span',    
+        'orderedlist'           => 'ol',
+        'para'                  => 'p',
+        'parameter'             => 'tt',
+        'part'                  => 'format_container_chunk',
+        'partintro'             => 'div',
+        'personname'            => 'span',
+        'preface'               => 'format_chunk',
+        'productname'           => 'span',
+        'propname'              => 'span',
+        'property'              => 'span',
+        'proptype'              => 'span',
+        'refentry'              => 'format_chunk',
+        'reference'             => 'format_container_chunk',
+        'sect1'                 => 'format_chunk',
+        'sect2'                 => 'format_chunk',
+        'sect3'                 => 'format_chunk',
+        'sect4'                 => 'format_chunk',
+        'sect5'                 => 'format_chunk',
+        'section'               => 'format_chunk',
+        'set'                   => 'format_chunk',
+        'setindex'              => 'format_chunk',
+        'simplelist'            => 'ul',
+        'simpara'               => 'p',
+        'systemitem'            => 'format_systemitem',
+        'table'                 => 'format_table',
+        'term'                  => 'span',
+        'title'                 => array(
+            /* DEFAULT */          'h1',
+            'legalnotice'       => 'h4',
+            'section'           => 'h2',
+            'sect1'             => 'h2',
+            'sect2'             => 'h3',
+            'sect3'             => 'h4',
+            'refsect1'          => 'h3',
+            'example'           => 'h4',
+            'note'              => 'h4',
+        ),
+        'type'                  => 'format_type',
+        'userinput'             => 'format_userinput',
+        'variablelist'          => 'format_variablelist',
+        'varlistentry'          => 'format_varlistentry',
+        'varname'               => 'var',
+        'xref'                  => 'format_link',
+        'year'                  => 'span',
+    ); /* }}} */
 
-       protected $map = array(
-               'application'           => 'span',
-               'classname'             => 'span',
-               'code'                  => 'code',
-               'collab'                => 'span',
-               'collabname'            => 'span',
-               'command'               => 'span',
-               'computeroutput'        => 'span',
-               'constant'              => 'span',
-               'emphasis'              => 'em',
-               'enumname'              => 'span',
-               'envar'                 => 'span',
-               'filename'              => 'span',
-               'glossterm'             => 'span',
-               'holder'                => 'span',
-               'informaltable'         => 'table',
-               'itemizedlist'          => 'ul',
-               'listitem'              => 'li',
-               'literal'               => 'span',
-               'mediaobject'           => 'div',
-               'methodparam'           => 'span',
-               'member'                => 'li',
-               'note'                  => 'div',
-               'option'                => 'span',    
-               'orderedlist'           => 'ol',
-               'para'                  => 'p',
-               'parameter'             => 'span',
-               'productname'           => 'span',
-               'propname'              => 'span',
-               'property'              => 'span',
-               'proptype'              => 'span',
-               'simplelist'            => 'ul',
-               'simpara'               => 'p',
-               'title'                 => 'h1',
-               'year'                  => 'span',
-       );
+    protected $CURRENT_ID  = "";
+    protected $ext         = "html";
     
-    public function __construct( $file, $encoding = 'utf-8', $options = NULL ) 
{
-        parent::__construct( $file, $encoding, $options );
+    public function __construct(PhDReader $reader, array $IDs, array $IDMap, 
$ext = "html") {
+        parent::__construct($reader, $IDs, $IDMap, $ext);
     }
-    
-    public function __destruct() {
+    /* Overwrite PhDFormat::readContent() to convert special HTML chars */
+    public function readContent($content = null) {
+        return htmlspecialchars(PhDFormat::readContent($content), ENT_QUOTES, 
"UTF-8");
     }
-    
-    public function getFormatName() {
+    public function __call($func, $args) {
+        if ($args[0]) {
+            trigger_error("No mapper found for '{$func}'", E_USER_WARNING);
+            return "<font color='red' size='+3'>{$args[1]}</font>";
+        }
+        return "<font color='red' size='+3'>/{$args[1]}</font>";
+    }
+    public function transformFromMap($open, $tag, $name) {
+        if ($open) {
+            return sprintf('<%s class="%s">', $tag, $name);
+        }
+        return "</$tag>";
+    }
+    public function CDATA($str) {
+        return sprintf('<div class="phpcode">%s</div>', highlight_string($str, 
1));
+    }
+
+    public function format_container_chunk($open, $name) {
+        $this->CURRENT_ID = $id = PhDFormat::getID();
+        if ($open) {
+            return sprintf('<div id="%s" class="%s">', $id, $name);
+        }
+        return "</div>";
+    }
+    public function format_chunk($open, $name) {
+        $this->CURRENT_ID = $id = PhDFormat::getID();
+        if ($open) {
+            return sprintf('<div id="%s" class="%s">', $id, $name);
+        }
+        return "</div>";
+    }
+    public function format_function($open, $name) {
+        return sprintf('<a href="function.%s.html">%1$s</a>', 
$this->readContent());
+    }
+    public function format_refsect1($open, $name) {
+        if ($open) {
+            return sprintf('<div class="refsect %s">', 
PhDFormat::readAttribute("role"));
+        }
+        return "</div>\n";
+    }
+    public function format_link($open, $name) {
+        $content = $fragment = "";
+        $class = $name;
+        if($linkto = PhDFormat::readAttribute("linkend")) {
+            $id = $href = PhDFormat::getFilename($linkto);
+            if ($id != $linkto) {
+                $fragment = "#$linkto";
+            }
+            $href .= ".".$this->ext;
+        } elseif($href = PhDFormat::readAttributeNs("href", 
PhDReader::XMLNS_XLINK)) {
+            $content = "&raquo; ";
+            $class .= " external";
+        }
+        $content .= $name == "xref" ? PhDFormat::getDescription($id, false) : 
$this->readContent($name);
+        return sprintf('<a href="%s%s" class="%s">%s</a>', $href, $fragment, 
$class, $content);
+    }
+    public function format_methodsynopsis($open, $root) {
+        /* We read this element to END_ELEMENT so $open is useless */
+        $content = '<div class="methodsynopsis">';
+
+        while($child = PhDFormat::getNextChild($root)) {
+            if ($child["type"] == XMLReader::END_ELEMENT) {
+                $content .= "</span>\n";
+                continue;
+            }
+            $name = $child["name"];
+            switch($name) {
+            case "type":
+            case "parameter":
+            case "methodname":
+                $content .= sprintf('<span class="%s">%s</span>', $name, 
$this->readContent($name));
+                break;
+
+            case "methodparam":
+                $content .= '<span class="methodparam">';
+                break;
+            }
+        }
+        $content .= "</div>";
+        return $content;
+    }
+    public function format_refnamediv($open, $root) {
+        while ($child = PhDFormat::getNextChild($root)) {
+            $name = $child["name"];
+            switch($name) {
+            case "refname":
+                $refname = $this->readContent($name);
+                break;
+            case "refpurpose":
+                $refpurpose = $this->readContent($name);
+                break;
+            }
+        }
         
-        return 'XHTML 1.0 Transitional';
-    
+        return sprintf('<div class="refnamediv"><span 
class="refname">%s</span><span class="refpurpose">%s</span></div>', $refname, 
$refpurpose);
+    }
+    public function format_variablelist($open, $name) {
+        if ($open) {
+            return "<dl>\n";
+        }
+        return "</dl>\n";
+    }
+    public function format_varlistentry($open, $name) {
+        if ($open) {
+            $id = PhDFormat::getID();
+            if ($id) {
+                return sprintf('<dt id="%s">', $id);
+            }
+            return "<dt>\n";
+        }
+        return "</dt>\n";
+    }
+    public function format_varlistentry_listitem($open, $name) {
+        if ($open) {
+            return "<dd>\n";
+        }
+        return "</dd>\n";
+    }
+    public function format_userinput($open, $name) {
+        if ($open) {
+            return sprintf('<strong class="%s"><code>', $name);
+        }
+        return "</code></strong>\n";
+    }
+    public function format_systemitem($open, $name) {
+        if ($open) {
+            switch($this->readAttribute("role")) {
+            case "directive":
+            /* FIXME: Different roles should probably be handled differently */
+            default:
+                return sprintf('<code class="systemitem %s">', $name);
+            }
+        }
+        return "</code>\n";
+    }
+    public function format_type($open, $name) {
+        $type = $this->readContent($name);
+        $t = strtolower($type);
+        $href = $fragment = "";
+
+        switch($t) {
+        case "bool":
+            $href = "language.types.boolean";
+            break;
+        case "int":
+            $href = "language.types.integer";
+            break;
+        case "double":
+            $href = "language.types.float";
+            break;
+        case "boolean":
+        case "integer":
+        case "float":
+        case "string":
+        case "array":
+        case "object":
+        case "resource":
+        case "null":
+            $href = "language.types.$t";
+            break;
+        case "mixed":
+        case "number":
+        case "callback":
+            $href = "language.pseudo-types";
+            $fragment = "language.types.$t";
+            break;
+        }
+        if ($href) {
+            return sprintf('<a href="%s.%s%s" class="%s %s">%5$s</a>', $href, 
$this->ext, ($fragment ? "#$fragment" : ""), $name, $type);
+        }
+        return sprintf('<span class="%s %s">%2$s</span>', $name, $type);
     }
-    
-       public function format_refentry( $open ) {
 
-               if ( $open ) {
-                       return '<div>';
-               }
-
-               echo "</div>";
-               if ( $this->hasAttributes && $this->moveToAttributeNs( "id", 
"http://www.w3.org/XML/1998/namespace"; ) ) {
-                       $id = $this->value;
-               }
-               $content = ob_get_contents();
-               ob_clean();
-               file_put_contents( "cache/$id.html", $content );
-
-       }
-
-       public function format_function( $open ) {
-
-               return sprintf( '<a href="function.%1$s.html">%1$s</a>', 
$this->readContent() );
-
-       }
-
-       public function format_refsect1( $open ) {
-
-               if ( $open ) {
-                       return sprintf( '<div class="refsect %s">', 
$this->readAttribute( "role" ) );
-               }
-               return "</div>\n";
-
-       }
-
-       public function format_link( $open ) {
-
-               $this->moveToNextAttribute();
-               $href = $this->value;
-               $class = $this->name;
-               $content = $this->readContent( "link" );
-               return sprintf( '<a href="%s" class="%s">%s</a>', $href, 
$class, $content );
-
-       }
-
-       public function format_methodsynopsis( $open ) {
-
-               /* We read this element to END_ELEMENT so $open is useless */
-               $content = '<div class="methodsynopsis">';
-               $root = $this->name;
-
-               while( $this->readNode( $root ) ) {
-                       if ( $this->nodeType == XMLReader::END_ELEMENT ) {
-                               $content .= "</span>\n";
-                               continue;
-                       }
-                       $name = $this->name;
-                       switch($name) {
-                       case "type":
-                       case "parameter":
-                       case "methodname":
-                               $content .= sprintf( '<span 
class="%s">%s</span>', $name, $this->readContent( $name ) );
-                               break;
-
-                       case "methodparam":
-                               $content .= '<span class="methodparam">';
-                               break;
-                       }
-               }
-               $content .= "</div>";
-               return $content;
-
-       }
-
-       protected function transformFromMap( $open, $name ) {
-
-               $tag = $this->map[ $name ];
-               if($open) {
-                       return sprintf( '<%s class="%s">', $tag, $name );
-               }
-               return "</$tag>";
-
-       }
-
-       public function format_listing_hyperlink_function( $matches ) {
-
-               $link = str_replace( '_', '-', $matches[ 1 ] );
-               $link = "function${link}.html";
-               return '<a class="phpfunc" href="'.$link.'">'.$matches[ 1 
].'</a></span>'.$matches[ 2 ];
-
-       }
-
-       public function highlight_php_code( $str ) { /* copy&paste from 
livedocs */
-
-               if ( is_array( $str ) ) {
-                       $str = $str[ 0 ];
-               }
-       
-               $tmp = str_replace(
-                       array(
-                               '&nbsp;',
-                               '<font color="',        // for PHP 4
-                               '<span style="color: ', // for PHP 5.0.0RC1
-                               '</font>',
-                               "\n ",
-                               '  '
-                       ),
-                       array(
-                               ' ',
-                               '<span class="',
-                               '<span class="',
-                               '</span>',
-                               "\n&nbsp;",
-                               ' &nbsp;'
-                       ),
-                       highlight_string( $str, TRUE )
-               );
-       
-               $tmp = preg_replace_callback( 
'{([\w_]+)\s*</span>(\s*<span\s+class="keyword">\s*\()}m',
-                   array( $this, 'format_listing_hyperlink_function' ), $tmp );
-               return sprintf( '<div class="phpcode">%s</div>', $tmp );
 
-       }
+    /* TODO: Move the logic to PhDFormat? */
+    /* NOTE: This is not a full implementation, just a proof-of-concept */
+    public function format_table($open, $name) {
+        if ($open) {
+            return '<table border="5">';
+        }
+        return "</table>\n";
+    }
+    public function format_tgroup($open, $name) {
+        if ($open) {
+            $this->TABLE_COLS = $this->readAttribute("cols");
+            $this->COLSPEC = array();
+            return "<colgroup>\n";
+        }
+        return "</colgroup>\n";
+    }
+    public function format_colspec($open, $name) {
+        if ($open) {
+            $colname = $this->readAttribute("colname");
+            if ($colnum = $this->readAttribute("colnum")) {
+                $this->COLSPEC[$colnum] = $colname;
+            } else {
+                $count = count($this->COLSPEC);
+                $this->COLSPEC[$count] = $colname;
+            }
+            return "<col />"; // Probably throw in couple of width and align 
attributes
+        }
+        /* noop */
+    }
+    public function format_thead($open, $name) {
+        if ($open) {
+            return "<thead>";
+        }
+        return "</thread>\n";
+    }
+    public function format_tbody($open, $name) {
+        if ($open) {
+            return "<tbody>";
+        }
+        return "</tbody>";
+    }
+    public function format_row($open, $name) {
+        if ($open) {
+            return "<tr>\n";
+        }
+        return "</tr>\n";
+    }
+    public function format_thead_entry($open, $name) {
+        if ($open) {
+            if ($start = $this->readAttribute("namest")) {
+                $from = array_search($start, $this->COLSPEC);
+                $end = $this->readAttribute("nameend");
+                $to = array_search($end, $this->COLSPEC);
+                return sprintf('<th colspan="%d">', $end-$to);
+            }
+            return '<th>';
+        }
+        return '</th>';
+    }
+    public function format_tfoot_entry($open, $name) {
+        return $this->format_thead_entry($open, $name);
+    }
+    public function format_tbody_entry($open, $name) {
+        if ($open) {
+            $colspan = 1;
+            $rows = 1;
+            if ($start = $this->readAttribute("namest")) {
+                $from = array_search($start, $this->COLSPEC);
+                $end = $this->readAttribute("nameend");
+                $to = array_search($end, $this->COLSPEC);
+                $colspan = $to-$from+1;
+            }
+            if ($morerows = $this->readAttribute("morerows")) {
+                $rows += $morerows;
+            }
+            return sprintf('<td colspan="%d" rowspan="%d">', $colspan, $rows);
+        }
+        return "</td>";
+    }
 
 }
 
@@ -198,4 +384,4 @@
 * vim600: sw=4 ts=4 fdm=syntax syntax=php et
 * vim<600: sw=4 ts=4
 */
-?>
+

http://cvs.php.net/viewvc.cgi/phd/mktoc.php?view=markup&rev=1.1
Index: phd/mktoc.php
+++ phd/mktoc.php
<?php
/*  $Id: mktoc.php,v 1.1 2007/08/05 14:49:55 bjori Exp $ */

$r = new PhDReader("/home/bjori/php/doc/.manual.xml");
$FILENAMES = $IDs = $IDMap = array();
$CURRENT_FILENAME = $LAST_CHUNK = "";
$PARENTS = array(-1 => "");
$lastid = 0;

/* someone really needs to fix this messed up logic */
while($r->read()) {
    if (!($id = $r->getID())) {
        $name = $r->name;
        if (in_array($name, array("refname", "titleabbrev")) && 
empty($IDs[$lastid]["sdesc"])) {
            switch($name) {
            case "refname":
                $IDs[$lastid]["sdesc"] = trim($r->readContent($name));
                continue 2;
            case "titleabbrev":
                $IDs[$lastid]["sdesc"] = trim($r->readContent($name));
                continue 2;
            }
        } else if (in_array($name, array("title", "refpurpose")) && 
empty($IDs[$lastid]["ldesc"])) {
            switch($name) {
            case "title":
                $IDs[$lastid]["ldesc"] = trim($r->readContent($name));
                continue 2;
            case "refpurpose":
                $IDs[$lastid]["ldesc"] = trim($r->readContent($name));
                continue 2;
            }
        }
        continue;
    }
    switch($r->isChunk) {
    case PhDReader::OPEN_CHUNK:
        $FILENAMES[] = $id;
        $CURRENT_FILENAME = $id;
        $PARENTS[$r->depth] = $id;

        $IDMap[$id] = array("parent" => $PARENTS[$r->depth-1]);
        
        break;

    case PhDReader::CLOSE_CHUNK:
        $LAST_CHUNK = array_pop($FILENAMES);
        $CURRENT_FILENAME = end($FILENAMES);

        $IDMap[$CURRENT_FILENAME][$id] =& $IDMap[$LAST_CHUNK];
        continue 2;
    }

    if ($r->nodeType != XMLReader::ELEMENT) {
        continue;
    }
 
    $IDs[$id] = array("filename" => $CURRENT_FILENAME, "sdesc" => null, "ldesc" 
=> null);
    $lastid = $id;
}
#print_r($IDs);
#var_dump($IDs["funcref"]);
/*
foreach($IDMap[$IDMap["function.strpos"]["parent"]] as $id => $junk) {
    if ($id == "parent") {
        continue;
    }
    printf("%s (%s): %s\n", $id, $IDs[$id]["sdesc"], $IDs[$id]["ldesc"]);
}
*/
/*
* vim600: sw=4 ts=4 fdm=syntax syntax=php et
* vim<600: sw=4 ts=4
*/


http://cvs.php.net/viewvc.cgi/phd/include/PhDFormat.class.php?view=markup&rev=1.1
Index: phd/include/PhDFormat.class.php
+++ phd/include/PhDFormat.class.php
<?php
/*  $Id: PhDFormat.class.php,v 1.1 2007/08/05 14:49:55 bjori Exp $ */

abstract class PhDFormat {
    private $reader;
    private $IDs            = array();
    private $IDMap          = array();
    protected $ext = "";
    /* abstract */ protected $map          = array();

    public function __construct(PhDReader $reader, array $IDs, array $IDMap, 
$ext) {
        $this->reader = $reader;
        $this->IDs = $IDs;
        $this->IDMap = $IDMap;
        $this->ext = $ext;
    }
    final public function getFilename($id) {
        return isset($this->IDs[$id]) ? $this->IDs[$id]["filename"] : false;
    }
    final public function getDescription($id, $long = false) {
        return $long ?
            ($this->IDs[$id]["ldesc"] ? $this->IDs[$id]["ldesc"] : 
$this->IDs[$id]["sdesc"]) :
            ($this->IDs[$id]["sdesc"] ? $this->IDs[$id]["sdesc"] : 
$this->IDs[$id]["ldesc"]);
    }
    final public function getContainer($id) {
        return $this->IDMap[$id];
    }
    final public function getParent($id) {
        return $this->IDMap[$id]["parent"];
    }
    final public function getMap() {
        return $this->map;
    }

    /* PhDReader wrapper functions */
    public function getID() {
        return $this->reader->getID();
    }
    public function readContent($node = null) {
        return $this->reader->readContent($node);
    }
    public function readAttribute($attr) {
        return $this->reader->readAttribute($attr);
    }
    public function readAttributeNs($attr, $ns) {
        return $this->reader->readAttributeNs($attr, $ns);
    }
    public function getAttributes() {
        return $this->reader->getAttributes();
    }
    public function getNextChild($node) {
        return $this->reader->readNode($node) ? array("type" => 
$this->reader->nodeType, "name" => $this->reader->name) : false;
    }
    /* abstract functions */
    abstract public function transformFromMap($open, $tag, $name);
    abstract public function CDATA($data);
    abstract public function __call($func, $args);
}
/*
* vim600: sw=4 ts=4 fdm=syntax syntax=php et
* vim<600: sw=4 ts=4
*/


http://cvs.php.net/viewvc.cgi/phd/formats/php.php?view=markup&rev=1.1
Index: phd/formats/php.php
+++ phd/formats/php.php
<?php
/*  $Id: php.php,v 1.1 2007/08/05 14:49:55 bjori Exp $ */

class PHPPhDFormat extends XHTMLPhDFormat {
    protected $CURRENT_ID = "";
    protected $ext;

    public function __construct(PhDReader $reader, array $IDs, array $IDMap, 
$ext = "php") {
        parent::__construct($reader, $IDs, $IDMap, $ext);
    }
    public function format_function($open, $name) {
        $func = $this->readContent($name);
        $link = str_replace(array("_", "::", "->"), "-", $func);

        if (!substr_compare($this->CURRENT_ID, $link, -strlen($link)) || 
!($filename = PhDFormat::getFilename("function.$link"))) {
            return sprintf("<b>%s()</b>", $func);
        }

        return sprintf('<a href="%s.%s" class="function">%s()</a>', $filename, 
$this->ext, $func);
    }
    public function format_container_chunk($open, $name) {
        $this->CURRENT_ID = $id = PhDFormat::getID();
        if ($open) {
            return "<div>";
        }
        $chunks = PhDFormat::getContainer($id);
        $content = "";
        if (count($chunks) > 1) {
            $content = '<ul class="chunklist chunklist_'.$name.'">';
            if ($name == "reference") {
                foreach($chunks as $chunkid => $junk) {
                    if ($chunkid == "parent") { continue; }
                    $content .= sprintf('<li><a href="%s.%s">%s</a> — 
%s</li>', $chunkid, $this->ext, PhDFormat::getDescription($chunkid, false), 
PhDFormat::getDescription($chunkid, true));
                }
            } else {
                foreach($chunks as $chunkid => $junk) {
                    if ($chunkid == "parent") { continue; }
                    $content .= sprintf('<li><a href="%s.%s">%s</a></li>', 
$chunkid, $this->ext, PhDFormat::getDescription($chunkid, true));
                }
            }
            $content .= "</ul>\n";
        }
        $content .= "</div>\n";
        
        return $content;
    }
}
/*
* vim600: sw=4 ts=4 fdm=syntax syntax=php et
* vim<600: sw=4 ts=4
*/


http://cvs.php.net/viewvc.cgi/phd/themes/phpweb.php?view=markup&rev=1.1
Index: phd/themes/phpweb.php
+++ phd/themes/phpweb.php
<?php
/*  $Id: phpweb.php,v 1.1 2007/08/05 14:49:55 bjori Exp $ */

class phpweb extends PHPPhDFormat {
    protected $streams = array();
    protected $writeit = false;
        protected $CURRENT_ID = "";

    public function writeChunk($id, $stream) {
        rewind($stream);
        file_put_contents("cache/$id.php", $this->header($id));
        file_put_contents("cache/$id.php", $stream, FILE_APPEND);
        file_put_contents("cache/$id.php", $this->footer($id), FILE_APPEND);
    }
    public function appendData($data, $isChunk) {
        switch($isChunk) {
        case PhDReader::CLOSE_CHUNK:
            $id = $this->CURRENT_ID;
            $stream = array_pop($this->streams);
            $retval = fwrite($stream, $data);
            $this->writeChunk($id, $stream);
            fclose($stream);
            return $retval;
            break;

        case PhDReader::OPEN_CHUNK:
            $this->streams[] = fopen("php://temp/maxmemory", "r+");

        default:
            $stream = end($this->streams);
            $retval = fwrite($stream, $data);
            return $retval;
        }
    }
    public function header($id) {
        $toc = "";
        $parent = PhDFormat::getParent($id);
        foreach(PhDFormat::getContainer($parent) as $k => $v) {
            if ($k == "parent") { continue; }
            $toc .= sprintf("array('%s.php', '%s'),\n", $k, 
addslashes(PhDFormat::getDescription($k, false)));
        }

        /* Yes. This is scary. I know. */
        return '<?php
include_once $_SERVER[\'DOCUMENT_ROOT\'] . \'/include/shared-manual.inc\';
manual_setup(
    array(
        "home" => array("index.php", "PHP Manual"),
        "head" => array("UTF-8", "en"),
        "this" => array("'.$id.'.php", 
"'.addslashes(PhDFormat::getDescription($id)).'"),
        "prev" => array("function.previous.php", "prevous"),
        "next" => array("function.next.php", "next"),
        "up"   => array("'.$this->getFilename($parent).'.'.$this->ext.'", 
"'.addslashes(PhDFormat::getDescription($parent, true)). '"),
        "toc"  => array('.$toc.'),
    )
);

manual_header();
?>
';
    }
    public function footer($id) {
        return "<?php manual_footer(); ?>";
    }
}

/*
* vim600: sw=4 ts=4 fdm=syntax syntax=php et
* vim<600: sw=4 ts=4
*/

Reply via email to