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 = "» ";
+ $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(
- ' ',
- '<font color="', // for PHP 4
- '<span style="color: ', // for PHP 5.0.0RC1
- '</font>',
- "\n ",
- ' '
- ),
- array(
- ' ',
- '<span class="',
- '<span class="',
- '</span>',
- "\n ",
- ' '
- ),
- 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
*/