Source for file Converter.inc
Documentation is available at Converter.inc
* Base class for all Converters
* phpDocumentor :: automatic documentation generator
* Copyright (c) 2001-2006 Gregory Beaver
* This library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser General
* Public License as published by the Free Software Foundation;
* either version 2.1 of the License, or (at your option) any
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* @author Greg Beaver <cellog@php.net>
* @copyright 2001-2006 Gregory Beaver
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @version CVS: $Id: Converter.inc 287891 2009-08-30 08:08:00Z ashnazg $
* @link http://www.phpdoc.org
* @link http://pear.php.net/PhpDocumentor
* @see parserDocBlock, parserInclude, parserPage, parserClass
* @see parserDefine, parserFunction, parserMethod, parserVar
include_once("phpDocumentor/Smarty-2.6.0/libs/Smarty.class.php");
* Base class for all output converters.
* The Converter marks the final stage in phpDocumentor. phpDocumentor works
* <pre>Parsing => Intermediate Parsing organization => Conversion to output</pre>
* A Converter takes output from the {@link phpDocumentor_IntermediateParser} and
* converts it to output. With version 1.2, phpDocumentor includes a variety
* <li>{@link HTMLframesConverter}</li>
* <li>{@link HTMLSmartyConverter}</li>
* <li>{@link PDFdefaultConverter}</li>
* <li>{@link CHMdefaultConverter}</li>
* <li>{@link CSVdia2codeConverter}</li>
* <li>{@link XMLDocBookConverter}</li>
* The converter takes output directly from {@link phpDocumentor_IntermediateParser}
* and using {@link walk()} or {@link walk_everything} (depending on the value of
* {@link $sort_absolutely_everything}) it "walks" over an array of phpDocumentor elements.}}}
* @author Greg Beaver <cellog@php.net>
* @version $Id: Converter.inc 287891 2009-08-30 08:08:00Z ashnazg $
* This converter knows about the new root tree processing
* In order to fix PEAR Bug #6389
* output format of this converter
* in Child converters, this will match the first part of the -o command-line
* as in -o HTML:frames:default "HTML"
* @tutorial phpDocumentor.howto.pkg#using.command-line.output
* package name currently being converted
* subpackage name currently being converted
* set to a classname if currently parsing a class, false if not
* the workhorse of linking.
* This array is an array of link objects of format:
* [package][subpackage][eltype][elname] = descendant of {@link abstractLink}
* eltype can be page|function|define|class|method|var
* if eltype is method or var, the array format is:
* [package][subpackage][eltype][class][elname]
* @see functionLink, pageLink, classLink, defineLink, methodLink, varLink, globalLink
* the workhorse of linking, with allowance for support of multiple
* elements in different files.
* This array is an array of link objects of format:
* [package][subpackage][eltype][file][elname] = descendant of {@link abstractLink}
* eltype can be function|define|class|method|var
* if eltype is method or var, the array format is:
* [package][subpackage][eltype][file][class][elname]
* @see functionLink, pageLink, classLink, defineLink, methodLink, varLink, globalLink
var $linkswithfile =
array();
* set to value of -po commandline
* @tutorial phpDocumentor.howto.pkg#using.command-line.packageoutput
* name of current page being converted
* path of current page being converted
* template for the procedural page currently being processed
* template for the class currently being processed
* current procedural page being processed
* alphabetical index of all elements sorted by package, subpackage, page,
* @var array Format: array(package => array(subpackage => array('page'|'class' => array(path|classname => array(element, element,...)))))
* @uses $sort_absolutely_everything if true, then $package_elements is used,
* otherwise, the {@link ParserData::$classelements} and
* {@link ParserData::$pageelements} variables are used
* alphabetical index of all elements
* @var array Format: array(first letter of element name => array({@link parserElement} or {@link parserPage},...))
* @see formatIndex(), HTMLframesConverter::formatIndex()
* alphabetized index of procedural pages by package
* @var array Format: array(package => array(subpackage => array({@link pageLink} 1,{@link pageLink} 2,...)
* alphabetized index of defines by package
* @var array Format: array(package => array(subpackage => array({@link defineLink} 1,{@link defineLink} 2,...)
* alphabetized index of classes by package
* @var array Format: array(package => array(subpackage => array({@link classLink} 1,{@link classLink} 2,...)
* alphabetized index of global variables by package
* @var array Format: array(package => array(subpackage => array({@link globalLink} 1,{@link globalLink} 2,...)
* alphabetized index of functions by package
* @var array Format: array(package => array(subpackage => array({@link functionLink} 1,{@link functionLink} 2,...)
* alphabetical index of all elements, indexed by package/subpackage
* @var array Format: array(first letter of element name => array({@link parserElement} or {@link parserPage},...))
* @see formatPkgIndex(), HTMLframesConverter::formatPkgIndex()
* alphabetical index of all elements on a page by package/subpackage
* The page itself has a link under ###main
* @var array Format: array(package => array(subpackage => array(path => array({@link abstractLink} descendant 1, ...)))
* This determines whether the {@link $page_contents} array should be sorted by element type as well as alphabetically by name
* @see sortPageContentsByElementType()
* This is used if the content must be passed in the order it should be read, i.e. by package, procedural then classes
* This fixes bug 637921, and is used by {@link PDFdefaultConverter}
* alphabetical index of all methods and vars in a class by package/subpackage
* The class itself has a link under ###main
* array({@link abstractLink} descendant 1, ...
* controls processing of elements marked private with @access private
* defaults to false. Set with command-line --parseprivate or -pp
* controls display of progress information while parsing.
* defaults to false. Set to true for cron jobs or other situations where no visual output is necessary
* directory that output is sent to. -t command-line sets this.
* @tutorial phpDocumentor.howto.pkg#using.command-line.target
* Directory that the template is in, relative to phpDocumentor root directory
* Directory that the smarty templates are in
* Name of the template, from last part of -o
* @tutorial phpDocumentor.howto.pkg#using.command-line.output
* full path of the current file being converted
* All class information, organized by path, and by package
* Flag used to help converters determine whether to do special source highlighting
* Every package that contains classes may have parent or child classes
* in other packages. In other words, this code is legal:
* class two extends one {}
* In this case, package one is a parent of package two
* @see phpDocumentor_IntermediateParser::$package_parents
* Packages associated with categories
* Used by the XML:DocBook/peardoc2 converter, and available to others, to
* group many packages into categories
* @see phpDocumentor_IntermediateParser::$packagecategories
* All packages encountered in parsing
* @see phpDocumentor_IntermediateParser::$all_packages
* A list of files that have had source code generated
* Controls which of the one-element-only indexes are generated.
* Generation of these indexes for large packages is time-consuming. This is an optimization feature. An
* example of how to use this is in {@link HTMLframesConverter::$leftindex}, and in {@link HTMLframesConverter::formatLeftIndex()}.
* These indexes are intended for use as navigational aids through documentation, but can be used for anything by converters.
* @see $class_elements, $page_elements, $function_elements, $define_elements, $global_elements
var $leftindex =
array('classes' =>
true, 'pages' =>
true, 'functions' =>
true, 'defines' =>
true, 'globals' =>
true);
* @see phpDocumentor_IntermediateParser::$title
var $title =
'Generated Documentation';
* Options for each template, parsed from the options.ini file in the template base directory
* @tutorial phpDocumentor/tutorials.pkg#conversion.ppage
* Tutorials and Extended Documentation parsed from a tutorials/package[/subpackage] directory
* @tutorial tutorials.pkg
var $tutorials =
array();
* tree-format structure of tutorials and their child tutorials, if any
var $tutorial_tree =
false;
* list of tutorials that have already been processed. Used by @link _setupTutorialTree()
var $processed_tutorials;
* List of all @todo tags and a link to the element with the @todo
* Format: array(package => array(link to element, array(todo {@link parserTag},...)),...)
* @tutorial tags.todo.pkg
* Directory where compiled templates go - will be deleted on exit
var $_compiledDir =
array();
* Initialize Converter data structures
* @param array {@link $all_packages} value
* @param array {@link $package_parents} value
* @param Classes {@link $classes} value
* @param ProceduralPages {@link $proceduralpages} value
* @param array {@link $package_output} value
* @param boolean {@link $parseprivate} value
* @param boolean {@link $quietmode} value
* @param string {@link $targetDir} value
* @param string {@link $templateDir} value
* @param string (@link $title} value
function Converter(&$allp, &$packp, &$classes, &$procpages, $po, $pp, $qm, $targetDir, $template, $title)
$this->package =
$GLOBALS['phpDocumentor_DefaultPackageName'];
$this->proceduralpages =
&$procpages;
$this->setTargetdir($targetDir);
* Called by IntermediateParser after creation
function setTutorials($tutorials)
$this->tutorials =
$tutorials;
* @param pkg|cls|procthe tutorial type to search for
* @param string package name
* @param string subpackage name, if any
* @return false|parserTutorialif the tutorial exists, return it
function hasTutorial($type, $name, $package, $subpackage =
'')
if (isset
($this->tutorials[$package][$subpackage][$type][$name .
'.' .
$type]))
return $this->tutorials[$package][$subpackage][$type][$name .
'.' .
$type];
* Called by {@link walk()} while converting, when the last class element
* A Converter can use this method in any way it pleases. HTMLframesConverter
* uses it to complete the template for the class and to output its
* @see HTMLframesConverter::endClass()
* Called by {@link walk()} while converting, when the last procedural page
* element has been parsed.
* A Converter can use this method in any way it pleases. HTMLframesConverter
* uses it to complete the template for the procedural page and to output its
* @see HTMLframesConverter::endClass()
* Called by {@link walk()} while converting.
* This method is intended to be the place that {@link $pkg_elements} is
* @see HTMLframesConverter::formatPkgIndex()
* Called by {@link walk()} while converting.
* This method is intended to be the place that {@link $elements} is
* @see HTMLframesConverter::formatIndex()
* Called by {@link walk()} while converting.
* This method is intended to be the place that any of
* {@link $class_elements, $function_elements, $page_elements},
* {@link $define_elements}, and {@link $global_elements} is formatted for
* output, depending on the value of {@link $leftindex}
* @see HTMLframesConverter::formatLeftIndex()
* Called by {@link parserSourceInlineTag::stringConvert()} to allow
* converters to format the source code the way they'd like.
* default returns it unchanged (html with xhtml tags)
* @param string output from highlight_string() - use this function to
* reformat the returned data for Converter-specific output
* @deprecated in favor of tokenizer-based highlighting. This will be
* Initialize highlight caching
$this->_highlightCache =
array(false, false);
$this->_appendHighlight =
'';
return $this->_highlightCache;
$test =
($this->_highlightCache[0] ===
$type &&
$this->_highlightCache[1] ==
$token);
$this->_appendHighlight =
'';
$this->_highlightCache =
array($type, $token);
* Return the close text for the current token
$hc =
$this->_highlightCache;
$this->_highlightCache =
array(false, false);
* Used to allow converters to format the source code the way they'd like.
* default returns it unchanged. Mainly used by the {@link HighlightParser}
* The method takes information from options.ini, the template options
* file, specifically the [highlightSourceTokens] and [highlightSource]
* sections, and uses them to enclose tokens.
* @param integer token value from {@link PHP_MANUAL#tokenizer tokenizer constants}
* @param string contents of token
* @param boolean whether the contents are preformatted or need modification
$e =
$this->_appendHighlight;
$e =
$this->_appendHighlight;
$newword =
($preformatted ?
$word :
$this->postProcess($word));
$e =
$this->_appendHighlight;
$e =
$this->_appendHighlight;
return $e .
($preformatted ?
$word :
$this->postProcess($word));
* Used to allow converters to format the source code of DocBlocks the way
* default returns it unchanged. Mainly used by the {@link HighlightParser}
* The method takes information from options.ini, the template options
* file, specifically the [highlightDocBlockSourceTokens] section, and uses
* @param string name of docblock token type
* @param string contents of token
* @param boolean whether the contents are preformatted or need modification
$e =
$this->_appendHighlight;
$e =
$this->_appendHighlight;
return $e .
$this->template_options['highlightDocBlockSourceTokens'][$token] .
$word;
$e =
$this->_appendHighlight;
return $e .
($preformatted ?
$word :
$this->postProcess($word));
* Used to allow converters to format the source code of Tutorial XML the way
* default returns it unchanged. Mainly used by the {@link HighlightParser}
* The method takes information from options.ini, the template options
* file, specifically the [highlightDocBlockSourceTokens] section, and uses
* @param string name of docblock token type
* @param string contents of token
* @param boolean whether the contents are preformatted or need modification
$e =
$this->_appendHighlight;
$e =
$this->_appendHighlight;
return $e .
$this->template_options['highlightTutorialSourceTokens'][$token] .
$word;
$e =
$this->_appendHighlight;
return $e .
($preformatted ?
$word :
$this->postProcess($word));
* Called by {@link parserReturnTag::Convert()} to allow converters to
* change type names to desired formatting
* Used by {@link XMLDocBookConverter::type_adjust()} to change true and
* false to the peardoc2 values
* Used to convert the {@}example} inline tag in a docblock.
* By default, this just wraps ProgramExample
* @see XMLDocBookpeardoc2Converter::exampleProgramExample
* @param boolean true if this is to highlight a tutorial <programlisting>
$class =
null/*false*/, $linenum =
null/*false*/, $filesourcepath =
null/*false*/)
return $this->ProgramExample($example, $tutorial, $inlinesourceparse, $class, $linenum, $filesourcepath);
* Used to convert the <<code>> tag in a docblock
* @param boolean true if this is to highlight a tutorial <programlisting>
function ProgramExample($example, $tutorial =
false, $inlinesourceparse =
null/*false*/,
$class =
null/*false*/, $linenum =
null/*false*/, $filesourcepath =
null/*false*/)
$e =
$obj->getFileSource();
foreach ($e as $ke =>
$ee)
foreach ($ee as $kee =>
$eee)
if ((int)
$e[$ke][$kee][0] ==
T_OPEN_TAG)
$example =
"<?php\n".
$example;
$e =
$obj->getFileSource();
$saveclass =
$this->class;
if (!isset
($inlinesourceparse))
$example =
$parser->parse($e, $this, true); // force php mode
if (isset
($filesourcepath))
$example =
$parser->parse($e, $this, $inlinesourceparse, $class, $linenum, $filesourcepath);
} elseif (isset
($linenum))
$example =
$parser->parse($e, $this, $inlinesourceparse, $class, $linenum);
$example =
$parser->parse($e, $this, $inlinesourceparse, $class);
$example =
$parser->parse($e, $this, $inlinesourceparse);
$this->class =
$saveclass;
$x =
$parse->parse($example, $this);
* Used to convert the contents of <<li>> in a docblock
* Used to convert the contents of <<ol>> or <<ul>> in a docblock
$listname =
($ordered ?
'ol' :
'ul');
if (!isset
($this->template_options['desctranslate']['/'.
$listname])) return $list;
* Used to convert the contents of <<pre>> in a docblock
* Used to enclose a paragraph in a docblock
* Used to convert the contents of <<b>> in a docblock
* Used to convert the contents of <<i>> in a docblock
* Used to convert the contents of <<var>> in a docblock
* Used to convert the contents of <<kbd>> in a docblock
* Used to convert the contents of <<samp>> in a docblock
* Used to convert <<br>> in a docblock
* This version does nothing
* Perform necessary post-processing of string data. For example, the HTML
* Converters should escape < and > to become < and >
* Creates a table of contents for a {@}toc} inline tag in a tutorial
* This function should return a formatted table of contents. By default, it
* does nothing, it is up to the converter to format the TOC
* @return string table of contents formatted for use in the current output format
* @param array format: array(array('tagname' => section, 'link' => returnsee link, 'id' => anchor name, 'title' => from title tag),...)
* Write out the formatted source code for a php file
* This function provides the primary functionality for the
* {@tutorial tags.filesource.pkg} tag.
* @param string full path to the file
* @param string fully highlighted/linked source code of the file
* Write out the formatted source code for an example php file
* This function provides the primary functionality for the
* {@tutorial tags.example.pkg} tag.
* @param string example title
* @param string example filename (no path)
* @param string fully highlighted/linked source code of the file
/** Translate the path info into a unique file name for the highlighted
* @param string $pathinfo
global $_phpDocumentor_options;
$pathinfo =
$this->proceduralpages->getPathInfo($path, $this);
$pathinfo['source_loc'] =
str_replace($_phpDocumentor_options['Program_Root'].
'/','',$pathinfo['source_loc']);
$pathinfo['source_loc'] =
str_replace('/','_',$pathinfo['source_loc']);
return "fsource_{$pathinfo['package']}_{$pathinfo['subpackage']}_{$pathinfo['source_loc']}";
/** Return the fixed path to the source-code file folder.
* @param string $base Path is relative to this folder
return $base .
'__filesource';
/** Return the path to the current
* @param string $pathinfo
* @return string an output-format dependent link to phpxref-style highlighted
* @return string Link to the current page being parsed.
* Should return {@link $curname} and a converter-specific extension.
* Return a line of highlighted source code with formatted line number
* If the $path is a full path, then an anchor to the line number will be
* @param integer line number
* @param string highlighted source code line
* @param false|stringfull path to @filesource file this line is a part of,
* if this is a single line from a complete file.
* @return string formatted source code line with line number
function sourceLine($linenumber, $line, $path =
false)
return $this->getSourceAnchor($path, $linenumber) .
* Determine whether an element's file has generated source code, used for
* linking to line numbers of source.
* Wrapper for {@link $sourcePaths} in this version
* {@internal since file paths get stored with most/all slashes
* set to forward slash '/', we need to doublecheck that
* we're not given a backslashed path to search for...
* if we are, it's likely that it was originally stored
* with a forward slash. Further, I'm not convinced it's safe
* to just check the {@link PHPDOCUMENTOR_WINDOWS} flag, so I'm checking
* specifically for backslashes intead.}}}
* @param string full path to the source code file
if (strpos($path, '\\') > -
1) {
* Mark a file as having had source code highlighted
* @param string full path of source file
* Used to translate an XML DocBook entity like ” from a tutorial by
* reading the options.ini file for the template.
* @param string entity name
* Used to translate an XML DocBook tag from a tutorial by reading the
* options.ini file for the template.
* @param string any attributes Format: array(name => value)
* @param string the tag contents, if any
* @param string the tag contents, if any, unpost-processed
return '<'.
$name.
$this->AttrToString($name,$attr,true).
'>'.
$cdata.
'</'.
$name.
'>'.
"\n";
// make sure this template transforms the tag into something
// test for global attribute transforms like $attr$role = class, changing
// all role="*" attributes to class="*" in html, for example
foreach($attr as $att =>
$val)
{// if the close tag isn't specified, we put opening and closing tags around it, with translated attributes
{ // if close tag is specified, use the open and close as literal
if ($name ==
'programlisting' && isset
($attr['role']) &&
($attr['role'] ==
'php' ||
$attr['role'] ==
'tutorial' ||
$attr['role'] ==
'html'))
{ // highlight PHP source
// var_dump($unconvertedcdata, $cdata);exit;
if ($attr['role'] ==
'php') {
} elseif ($attr['role'] ==
'tutorial') {
} elseif ($attr['role'] ==
'html') {
$cdata =
$unconvertedcdata;
return '<'.
$name.
$this->AttrToString($name,$attr,true).
'>' .
$cdata .
* Convert the attribute of a Tutorial docbook tag's attribute list
* to a string based on the template options.ini
* @param boolean if true, returns attrname="value"...
foreach($attr as $n =>
$v)
$ret .=
$n.
' = "'.
$v.
'"';
// no_attr tells us to ignore all attributes
// tagname! tells us to ignore all attributes for this tag
if (count($attr)) $ret =
' ';
// pass 1, check to see if any attributes add together
foreach($attr as $n =>
$v)
foreach($attr as $n =>
$v)
{ // only 1 attribute translated for this one
// this is useful for equivalent value names
{ // more than 1 attribute combines to make the new attribute
$teststrtemp[] =
$oldattr.
'+'.
$attr[$oldattr];
for($j=
$i;!$started ||
$j !=
$i;$j =
($j +
$i) %
$num)
if (!empty($a)) $a .=
'|';
foreach($teststrs as $test)
$ret .=
$n.
' = "'.
$v.
'"';
* Convert the title of a Tutorial docbook tag section
* to a string based on the template options.ini
* @param string title text
} else $cdata =
$title.
$cdata;
return array($attr,$cdata);
* Return a converter-specific id to distinguish tutorials and their
return $package.
$subpackage.
$tutorial.
$id;
* Create the {@link $elements, $pkg_elements} and {@link $links} arrays
* @todo version 2.0 - faulty package_output logic should be removed
* in this version, if the parent file isn't in the package, all
* the procedural elements are simply shunted to another package!
function _createPkgElements(&$pages)
foreach($pages as $j =>
$flub)
$this->package =
$pages[$j]->parent->package;
$this->subpackage =
$pages[$j]->parent->subpackage;
$this->curfile =
$pages[$j]->parent->getFile();
$this->curname =
$this->getPageName($pages[$j]->parent);
$this->curpath =
$pages[$j]->parent->getPath();
$this->addElement($pages[$j]->parent,$pages[$j]);
if (count($pages[$j]->classelements))
$pages[$j]->parent->subpackage =
'';
$this->addElement($pages[$j]->parent,$pages[$j]);
$this->addElement($pages[$j]->parent,$pages[$j]);
for($i=
0; $i<
count($pages[$j]->elements); $i++
)
$pages[$j]->elements[$i]->docblock->package =
$this->package;
$pages[$j]->elements[$i]->docblock->subpackage =
$this->subpackage;
$this->proceduralpages->replaceElement($pages[$j]->elements[$i]);
$this->addElement($pages[$j]->elements[$i]);
for($i=
0; $i<
count($pages[$j]->classelements); $i++
)
if ($pages[$j]->classelements[$i]->type ==
'class')
if ($this->checkKillClass($pages[$j]->classelements[$i]->getName(),$pages[$j]->classelements[$i]->getPath())) continue;
$this->package =
$pages[$j]->classelements[$i]->docblock->package;
$this->subpackage =
$pages[$j]->classelements[$i]->docblock->subpackage;
$this->class =
$pages[$j]->classelements[$i]->name;
if ($this->killclass) continue;
// force all contained elements to have parent package/subpackage
$pages[$j]->classelements[$i]->docblock->package =
$this->package;
$pages[$j]->classelements[$i]->docblock->subpackage =
$this->subpackage;
if ($pages[$j]->classelements[$i]->type ==
'class')
if ($this->checkKillClass($pages[$j]->classelements[$i]->getName(),$pages[$j]->classelements[$i]->getPath())) continue;
$this->package =
$pages[$j]->classelements[$i]->docblock->package;
$this->subpackage =
$pages[$j]->classelements[$i]->docblock->subpackage;
$this->class =
$pages[$j]->classelements[$i]->name;
if (!$this->killclass) $this->addElement($pages[$j]->classelements[$i]);
* Process the {@link $tutorials} array
* Using the tutorialname.ext.ini files, this method sets up tutorial
* hierarchy. There is some minimal error checking to make sure that no
* tutorial links to itself, even two levels deep as in tute->next->tute.
* If all tests pass, it creates the hierarchy
* @uses generateTutorialOrder()
* @uses _setupTutorialTree()
function _processTutorials()
$parents =
$all =
array();
foreach($this->tutorials as $package =>
$els)
unset
($this->tutorials[$package]);
unset
($this->tutorials[$package]);
foreach($els as $subpackage =>
$els2)
foreach($els2 as $type =>
$tutorials)
foreach($tutorials as $tutorial)
if (isset
($tutorial->ini['Linked Tutorials']))
foreach($tutorial->ini['Linked Tutorials'] as $child)
$sub =
(empty($tutorial->subpackage) ?
'' :
$tutorial->subpackage .
'/');
$kid =
$tutorial->package .
'/' .
$sub .
$child .
'.' .
$tutorial->tutorial_type;
// parent includes self as a linked tutorial?
$kidlink =
$this->getTutorialLink($kid,false,false,array($tutorial->package));
$all[$package][$subpackage][$type][] =
$tutorial;
// loop error-checking, use this to eliminate possibility of accidentally linking to a parent as a child
foreach($parents as $parent)
$testlinks[$parent->name]['links'][] =
$parent->getLink($this);
$testlinks[$parent->name]['name'][$parent->getLink($this)] =
$parent->name;
// generate the order of tutorials, and link them together
foreach($parents as $parent)
foreach($parent->ini['Linked Tutorials'] as $child)
$sub =
(empty($parent->subpackage) ?
'' :
$parent->subpackage .
'/');
$kid =
$parent->package .
'/' .
$sub .
$child .
'.' .
$parent->tutorial_type;
// child tutorials must be in the same package AND subpackage
// AND have the same extension as the parent, makes things clearer for both ends
addErrorDie(PDERROR_TUTORIAL_IS_OWN_GRANDPA,$testlinks[$parent->name][$this->returnSee($this->getTutorialLink($kid,false,false,array($parent->package)))],$kid->name,$testlinks[$parent->name][$this->returnSee($this->getTutorialLink($kid,false,false,array($parent->package)))],$kid->name.
'.ini');
$new =
$tree =
$roots =
array();
// build a list of all 'root' tutorials (tutorials without parents).
foreach($parents as $i =>
$parent)
if (! $parent->isChildOf($parents)) {
// add the parents and all child tutorials in order to the list of tutorials to process
foreach($parents as $parent)
$this->generateTutorialOrder($parent,$all,$new);
// add the leftover tutorials
foreach($all as $package =>
$els)
foreach($els as $subpackage =>
$els2)
foreach($els2 as $type =>
$tutorials)
foreach($tutorials as $tutorial)
$new[$package][$subpackage][$type][] =
$tutorial;
// remove the old, unprocessed tutorials, and set it up with the next code
$this->tutorials =
array();
// reset integrity of the tutorial list
// debug($this->vardump_tree($new));exit;
foreach($new as $package =>
$els)
foreach($els as $subpackage =>
$els2)
foreach($els2 as $type =>
$tutorials)
foreach($tutorials as $tutorial)
$this->tutorials[$prevpackage][$prevsubpackage][$prevtype][$prevname]->setNext($tutorial,$this);
$tutorial->setPrev($prev,$this);
$this->tutorials[$package][$subpackage][$type][$tutorial->name] =
$tutorial;
$prev =
$tutorial->getLink($this,true);
$prevsubpackage =
$subpackage;
$prevname =
$tutorial->name;
$this->tutorial_tree =
$this->_setupTutorialTree();
* called by {@link phpDocumentor_IntermediateParser::Convert()} to traverse
* the array of pages and their elements, converting them to the output format
* The walk() method should be flexible enough such that it never needs
* modification. walk() sets up all of the indexes, and sorts everything in
* logical alphabetical order. It then passes each element individually to
* {@link Convert()}, which then passes to the Convert*() methods. A child
* Converter need not override any of these unless special functionality must
* be added. see {@tutorial Converters/template.vars.cls} for details.
* walk() first creates all of the indexes {@link $elements, $pkg_elements}
* and the left indexes specified by {@link $leftindexes},
* and then sorts them by calling {@link sortIndexes()}.
* Next, it converts all README/CHANGELOG/INSTALL-style files, using
* passes all package-level docs to Convert(). Then, it calls the index
* sorting functions {@link formatPkgIndex(), formatIndex()} and
* {@link formatLeftIndex()}.
* Finally, it converts each procedural page in alphabetical order. This
* stage passes elements from the physical file to Convert() in alphabetical
* order. First, procedural page elements {@link parserDefine, parserInclude}
* {@link parserGlobal}, and {@link parserFunction} are passed to Convert().
* Then, class elements are passed in this order: {@link parserClass}, then
* all of the {@link parserVar}s in the class and all of the
* {@link parserMethod}s in the class. Classes are in alphabetical order,
* and both vars and methods are in alphabetical order.
* Finally, {@link ConvertErrorLog()} is called and the data walk is complete.}}}
* @param array Format: array(fullpath => {@link parserData} structure with full {@link parserData::$elements}
* and {@link parserData::$class_elements}.
* @param array Format: array({@link parserPackagePage} 1, {@link parserPackagePage} 2,...)
* @uses Converter::_createPkgElements() sets up {@link $elements} and
* {@link $pkg_elements} array, as well as {@link $links}
function walk(&$pages,&$package_pages)
die("<b>ERROR</b>: nothing parsed");
$this->_createPkgElements($pages);
foreach($this->ric as $name =>
$contents)
foreach($package_pages as $i =>
$perp)
phpDocumentor_out('Converting package page for package '.
$package_pages[$i]->package.
'... ');
$this->package =
$package_pages[$i]->package;
$this->Convert($package_pages[$i]);
// get tutorials into the order they will display, and set next/prev links
$new =
$this->_processTutorials();
foreach($this->tutorials as $package =>
$els)
foreach($els as $subpackage =>
$els2)
foreach($els2 as $type =>
$tutorials)
foreach($tutorials as $tutorial)
if (!empty($tutorial->subpackage))
$ptext =
"Converting ${a}Package-level tutorial ".
$tutorial->name.
'...';
$ptext =
"Converting ${a}Class-level tutorial " .
$tutorial->name .
" and associating...";
$addend =
'unsuccessful ';
if (isset
($this->package_elements[$tutorial->package][$tutorial->subpackage]['class'][$link->name]))
$this->package_elements[$tutorial->package][$tutorial->subpackage]['class'][$link->name][0]->addTutorial($tutorial,$this);
$addend =
'unsuccessful ';
foreach($pages as $j =>
$inf)
foreach($inf->classelements as $i =>
$class)
if ($class->type ==
'class' &&
$class->name ==
str_replace('.cls','',$tutorial->name) &&
$class->path ==
$link->path)
$pages[$j]->classelements[$i]->addTutorial($tutorial,$this);
} else $ptext .=
"unsuccessful ";
$ptext =
"Converting ${a}Procedural-level tutorial ".
$tutorial->name.
" and associating...";
$addend =
'unsuccessful ';
if (isset
($this->package_elements[$tutorial->package][$tutorial->subpackage]['page'][$link->path]))
$this->package_elements[$tutorial->package][$tutorial->subpackage]['page'][$link->path][0]->addTutorial($tutorial,$this);
foreach($pages as $j =>
$info)
$pages[$j]->addTutorial($tutorial,$this);
} else $ptext .=
"unsuccessful ";