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  
 * @copyright  2001-2006 Gregory Beaver  
 * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL  
 * @version    CVS: $Id: Converter.inc 291278 2009-11-24 17:43:20Z 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.}}}  
 * @version $Id: Converter.inc 291278 2009-11-24 17:43:20Z 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 ";  
                        $this->package = 
$tutorial->package;  
        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();  
            for($i=
0; $i<
count($pages[$j]->elements); $i++
)  
                $a = 
$pages[$j]->elements[$i]->docblock->getKeyword('access');  
//                phpDocumentor_out("    ".$pages[$j]->elements[$i]->name."\n");  
                $pages[$j]->elements[$i]->docblock->package = 
$this->package;  
                $pages[$j]->elements[$i]->docblock->subpackage = 
$this->subpackage;  
                $this->Convert($pages[$j]->elements[$i]);  
            for($i=
0; $i<
count($pages[$j]->classelements); $i++
)  
                    if ($pages[$j]->classelements[$i]->type == 
'class')  
                        if (!$this->killclass) $this->endClass();  
                        $this->killclass = 
false;  
                        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;  
                        $a = 
$pages[$j]->classelements[$i]->docblock->getKeyword('access');  
                        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')  
                    $this->killclass = 
false;  
                    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;  
//                phpDocumentor_out("    ".$pages[$j]->classelements[$i]->name."\n");  
                $this->Convert($pages[$j]->classelements[$i]);  
            if (count($pages[$j]->classelements) && 
!$this->killclass) $this->endClass();  
     * Get a tree structure representing the hierarchy of tutorials  
     * Returns an array in format:  
     * array('tutorial' => {@link parserTutorial},  
     *       'kids' => array( // child tutorials  
     *                   array('tutorial' => child {@link parserTutorial},  
     * @param parserTutorial|array  
     * @tutorial tutorials.pkg  
            if (isset
($this->tutorial_tree[$path])) {  
                $tutorial = 
$this->tutorial_tree[$path];  
        if (isset
($tutorial['tutorial']))  
            $tree['tutorial'] = 
$tutorial['tutorial'];  
            if (isset
($tutorial['child']))  
                foreach($tutorial['child'] as $a => 
$b)  
                        'tutorial' => 
$this->tutorials  
                            [$btut->package][$btut->subpackage]  
                            [$btut->tutorial_type][$btut->name]  
                         $res['kids'] = 
$tempres['kids'];  
     * Remove tutorials one by one from $all, and transfer them into $new in the  
     * order they should be parsed  
    function generateTutorialOrder($parent,&$all,&$new)  
        // remove from the list of tutorials to process  
        foreach($all[$parent->package][$parent->subpackage][$parent->tutorial_type] as $ind => 
$t)  
            if ($t->name == 
$parent->name) {  
                unset
($all[$parent->package][$parent->subpackage][$parent->tutorial_type][$ind]); 
        // add to the new ordered list of tutorials  
        $x = 
&$new[$parent->package][$parent->subpackage][$parent->tutorial_type];  
        { // only add if the parent isn't also a child  
            $new[$parent->package][$parent->subpackage][$parent->tutorial_type][] = 
$parent;  
            // add a new branch to the tree  
        // process all child tutorials, and insert them in order  
//        debug("processing parent ".$parent->name);  
            foreach($parent->ini['Linked Tutorials'] as $child)  
                $sub = 
(empty($parent->subpackage) ? 
'' : 
$parent->subpackage . 
'/');  
                $kid = 
$parent->package . 
'/' . 
$sub . 
$child . 
'.' . 
$parent->tutorial_type;  
                $_klink = 
$this->getTutorialLink($kid,false,false,array($parent->package));  
                // remove the child from the list of remaining tutorials  
                foreach($all[$parent->package][$parent->subpackage][$parent->tutorial_type] as $ind => 
$tute)  
                    if ($klink && 
$tute->getLink($this) == 
$klink)  
                        // set up parent, next and prev links  
                        $tute->setParent($parent, $this);  
                        // remove the child from the list of tutorials to process  
                        foreach($all[$parent->package][$parent->subpackage][$parent->tutorial_type] as $ind => 
$t)  
                            if ($t->name == 
$tute->name)  
                            unset
($all[$parent->package][$parent->subpackage][$parent->tutorial_type][$ind]); 
                        // add to the new ordered list of tutorials  
                        $new[$parent->package][$parent->subpackage][$parent->tutorial_type][] = 
$tute;  
                            // add all the child's child tutorials to the list  
                            $this->generateTutorialOrder($tute,$all,$new);  
        /** Returns the path to this tutorial as a string  
         * @param parserTutorial $pkg   
         * @param parserTutorial $subpkg   
         * @param parserTutorial $namepkg   
            $subpackagename = 
($subpkg->subpackage ? 
'/' . 
$subpkg->subpackage : 
'');  
            return $pkg->package . 
$subpackagename . 
'/' . 
$namepkg->name;  
     * Creates a tree structure of tutorials  
     * array('package/subpackage/tutorial1.ext' =>  
     *          array('tutorial' => {@link parserTutorial},  
     *                    array('package/subpackage/child1tutorial.ext' => ...,  
     *                          'package/subpackage/child2tutorial.ext' => ...,  
     *       'package/subpackage/tutorial2.ext' => ...,  
     * @return array the tutorial tree  
    function _setupTutorialTree($parent = 
false)  
        if (! isset
($this->processed_tutorials)) {  
            $this->processed_tutorials = 
array();  
            foreach($this->tutorials as $package => 
$s)  
                foreach($s as $subpackage => 
$t)  
                    foreach($t as $type => 
$n)  
                        foreach($n as $name => 
$tutorial)  
                            if (isset
($this->processed_tutorials[$child_path])) {  
                            $this->processed_tutorials[$child_path] = 
$tutorial;  
                            //debug("parent ".$tutorial->name);  
                            $ret = 
$this->_setupTutorialTree($tutorial);  
        $tree[$parent_path]['tutorial'] = 
$parent;  
        // process all child tutorials, and insert them in order  
            foreach($parent->ini['Linked Tutorials'] as $child)  
                if (isset
($this->tutorials[$parent->package][$parent->subpackage]  
                                          [$parent->tutorial_type][$child . 
'.' .
  
                                           $parent->tutorial_type])) {  
                    // remove the child from the list of remaining tutorials  
                    $tute = 
$this->tutorials[$parent->package][$parent->subpackage]  
                                            [$parent->tutorial_type][$child . 
'.' .
  
                if (isset
($this->processed_tutorials[$child_path])) {  
                $this->processed_tutorials[$child_path] = 
$tute;  
                if ($tute->name != 
$child . 
'.' . 
$parent->tutorial_type) {  
                //echo "Adding [$child_path] to [$parent_path]<br>";  
                $tree[$parent_path]['child'][$this->_tutorial_path($parent,$parent,$tute)]['tutorial']  
                // add all the child's child tutorials to the list  
                if (!isset
($tree[$parent_path]['child'])) {  
                    $tree[$parent_path]['child'] = 
$this->_setupTutorialTree($tute);  
                    $tree[$parent_path]['child'] = 
array_merge($tree[$parent_path]['child'],  
                        $this->_setupTutorialTree($tute));  
     * Debugging function for dumping {@link $tutorial_tree}  
        if (phpDocumentor_get_class($tree) == 
'parsertutorial') return $tree->name.
' extends '.
($tree->parent? 
$tree->parent->name : 
'nothing');  
        foreach($tree as $ind => 
$stuff)  
            $a .= 
$indent.
'['.
$ind.
" => \n   ".
$indent.
$x.
"]\n";  
    function sort_package_elements($a,$b)  
        if (($a->type == 
$b->type) && 
(isset
($a->isConstructor) && 
$a->isConstructor)) return -
1;  
        if (($a->type == 
$b->type) && 
(isset
($b->isConstructor) && 
$b->isConstructor)) return 1;  
        if ($a->type == 
$b->type) return strnatcasecmp($a->name,$b->name);  
        if ($a->type == 
'class') return -
1;  
        if ($b->type == 
'class') return 1;  
        if ($a->type == 
'const') return -
1;  
        if ($b->type == 
'const') return 1;  
        if ($a->type == 
'var') return -
1;  
        if ($b->type == 
'var') return 1;  
        if ($a->type == 
'page') return -
1;  
        if ($b->type == 
'page') return 1;  
        if ($a->type == 
'include') return -
1;  
        if ($b->type == 
'include') return 1;  
        if ($a->type == 
'define') return -
1;  
        if ($b->type == 
'define') return 1;  
        if ($a->type == 
'global') return -
1;  
        if ($b->type == 
'global') return 1;  
        if ($a->type == 
'function') return -
1;  
        if ($b->type == 
'function') return 1;  
    function defpackagesort($a,$b)  
        if ($a == 
$GLOBALS['phpDocumentor_DefaultPackageName']) return -
1;  
        if ($b == 
$GLOBALS['phpDocumentor_DefaultPackageName']) return 0;  
     * walk over elements by package rather than page  
     * This method is designed for converters like the PDF converter that need  
     * everything passed in alphabetical order by package/subpackage and by  
     * procedural and then class information  
     * @see PDFdefaultConverter  
                    uksort($r['page'],'strnatcasecmp');  
                    foreach($r['page'] as $page => 
$oo)  
                        usort($this->package_elements[$package][$subpackage]['page'][$page],array($this,'sort_package_elements'));  
                    uksort($r['class'],'strnatcasecmp');  
                    foreach($r['class'] as $page => 
$oo)  
                        usort($r['class'][$page],array($this,'sort_package_elements'));  
            foreach($s as $subpackage => 
$r)  
                    foreach($r['page'] as $page => 
$elements)  
                            foreach($elements as $element)  
                                if ($element->type == 
'page')  
                                    $this->curfile = 
$element->parent->getFile();  
                                    $this->curname = 
$this->getPageName($element->parent);  
                                    $this->curpath = 
$element->parent->getPath();  
                                    // force all contained elements to have parent package/subpackage  
                                    $element->docblock->package = 
$this->package;  
                                    $element->docblock->subpackage = 
$this->subpackage;  
                                    $a = 
$element->docblock->getKeyword('access');  
                    foreach($r['class'] as $class => 
$elements)  
                        foreach($elements as $element)  
                            if ($element->type == 
'class')  
                                $this->class = 
$element->getName();  
                                $this->killclass = 
false;  
                                if ($this->checkKillClass($element->getName(),$element->getPath())) continue;  
                                $a = 
$element->docblock->getKeyword('access');  
                                if ($this->killclass) continue;  
                                // force all contained elements to have parent package/subpackage  
                                $element->docblock->package = 
$this->package;  
                                $element->docblock->subpackage = 
$this->subpackage;  
                            if ($this->killclass) continue;  
                } // if isset($r['class'])  
        } // foreach($this->package_elements)  
     * Convert the phpDocumentor parsing/conversion error log  
     * Convert the list of all @todo tags  
     * Sorts the @todo list - do not override or modify this function  
     * @uses _sortTodos passed to {@link usort()} to sort the todo list  
        foreach($this->todoList as $package => 
$r) {  
            usort($this->todoList[$package], array('Converter', '_sortTodoPackage'));  
            foreach ($r as $a => 
$sub) {  
                    usort($this->todoList[$package][$a][1],array('Converter', '_sortTodos'));  
    function _sortTodoPackage($a, $b)  
    function _sortTodos($a, $b)  
     * Sorts all indexes - do not override or modify this function  
     * @uses $leftindex based on the value of leftindex, sorts link arrays  
     * @uses $class_elements sorts with {@link compareLink}  
     * @uses $page_elements sorts with {@link compareLink}  
     * @uses $define_elements sorts with {@link compareLink}  
     * @uses $global_elements sorts with {@link compareLink}  
     * @uses $function_elements sorts with {@link compareLink}  
     * @uses $elements sorts with {@link elementCmp}  
     * @uses $pkg_elements sorts with {@link elementCmp} after sorting by  
     *                      package/subpackage alphabetically  
                foreach($o1 as $subpackage => 
$links)  
                foreach($o1 as $subpackage => 
$links)  
                foreach($o1 as $subpackage => 
$links)  
                foreach($o1 as $subpackage => 
$links)  
                foreach($o1 as $subpackage => 
$links)  
        foreach($this->elements as $letter => 
$nothuing)  
            foreach($this->pkg_elements[$package] as $subpackage => 
$els)  
                if (empty($els)) continue;  
                foreach($els as $letter => 
$yuh)  
                    usort($this->pkg_elements[$package][$subpackage][$letter],array($this,"elementCmp"));  
     * sorts {@link $page_contents} by element type as well as alphabetically  
     * @see $sort_page_contents_by_element_type  
                if (empty($els)) continue;  
                foreach($this->page_contents[$package][$subpackage] as $path => 
$stuff)  
                    if (!count($pages[$path]->elements)) continue;  
                    usort($pages[$path]->elements,array($this,'eltypecmp'));  
                    if (isset
($this->page_contents[$package][$subpackage][$path][0]))  
     * @see Converter::sortIndexes()  
    function compareLink($a, $b)  
     * @see Converter::sortPageContentsByElementType()  
    function eltypecmp($a, $b)  
        if ($a->type == 
'page') return -
1;  
        if ($b->type == 
'page') return 1;  
     * does a nat case sort on the specified second level value of the array  
    function elementCmp ($a, $b)  
     * Used to stop conversion of @ignored or private @access classes  
     * @uses $killclass sets killclass based on the value of {@link Classes::$killclass}  
     *        and {@link $package_output}  
    function checkKillClass($class, $path)  
        $this->killclass = 
false;  
        if (isset
($this->classes->killclass[$class]) && isset
($this->classes->killclass[$class][$path])) $this->killclass = 
true;  
            $a = 
$this->classes->getClass($class, $path);  
        if (PHPDOCUMENTOR_DEBUG && 
$this->killclass) debug("$class $path killed");  
     * @param abstractLink descendant of abstractLink  
     * @param array|parserTaglist of @todos|@todo tag  
    function addTodoLink($link, $todos)  
        $this->todoList[$link->package][] = 
array($link, $todos);  
     * Adds all elements to the {@link $elements, $pkg_elements, $links},  
     * {@link $linkswithfile} and left indexes - Do not modify or override  
     * @param parserBase any documentable element descendant of parserBase  
     * @param false|parserPageonly used to add a {@link parserPage} if the  
     *                          $element passed is a parserPage  
     * @staticvar string path of current page, used for {@link $page_contents} setup  
    function addElement(&$element,$pageel=
false)  
        if ($this->package_output)  
            if (!in_array($this->package, $this->package_output)) return;  
        if ($pageel && 
phpDocumentor_get_class($pageel) == 
'parserdata')  
            if (isset
($pageel->docblock) && 
phpDocumentor_get_class($pageel->docblock) == 
'parserdocblock')  
                $a = 
$pageel->docblock->getKeyword('todo');  
                if ($a && 
!empty($a->value[0]))  
                    $this->addTodoLink($this->addLink($element),$a);  
        if (isset
($element->docblock))  
            $a = 
$element->docblock->getKeyword('access');  
            $a = 
$element->docblock->getKeyword('todo');  
            if ($a && 
!empty($a->value[0]))  
                if ($element->type != 
'include') {  
                    $this->addTodoLink($this->addLink($element),$a);  
        $startPositionOfElementName = 
0;    // which character of the element name actually starts its textual name  
                $link = 
$this->addLink($element);  
                $curpath = 
$element->getPath();  
                $link = 
$this->addLink($element);  
                $link = 
$this->addLink($element);  
                $link = 
$this->addLink($element);  
                $link = 
$this->addLink($element);  
                $startPositionOfElementName = 
1;    // lose the leading "$" character  
                $link = 
$this->addLink($element);  
                $startPositionOfElementName = 
1;    // lose the leading "$" character  
                $link = 
$this->addLink($element);  
                $link = 
$this->addLink($element);  
                $link = 
$this->addLink($element);  
        if ($element->getType() != 
'include')  
            if ($element->getType() == 
'var' || 
$element->getType() == 
'method'|| 
$element->getType() == 
'const')  
                $this->links[$this->package][$this->subpackage][$element->getType()][$element->class][$element->getName()] = 
$link;  
                $this->linkswithfile[$this->package][$this->subpackage][$element->getType()][$element->getPath()][$element->class][$element->getName()] = 
$link;  
                if ($element->type == 
'page')  
                    $this->links[$this->package][$this->subpackage][$element->getType()][$element->getFile()] = 
$link;  
                    $this->linkswithfile[$this->package][$this->subpackage][$element->getType()][$element->getPath()][$element->getFile()] = 
$link;  
                    $this->links[$this->package][$this->subpackage][$element->getType()][$element->getName()] = 
$link;  
                    $this->linkswithfile[$this->package][$this->subpackage][$element->getType()][$element->getPath()][$element->getName()] = 
$link;  
        if ($element->type == 
'page')  
     * returns an abstract link to element.  Do not modify or override  
     * This method should only be called in process of Conversion, unless  
     * $element is a parserPage, or $page is set to true, and $element is  
     * @return abstractLink abstractLink descendant  
     * @param parserElement element to add a new link (descended from  
     *                       {@link abstractLink})to the {@link $links} array  
     * @param string classname for elements that are class-based (this may be  
     *                deprecated in the future, as the classname  
     *                should be contained within the element.  if $element is a  
     *                page, this parameter is a package name  
     * @param string subpackage name for page elements  
    function addLink(&$element,$page = 
false)  
            // create a fake parserPage to extract the fileAlias for this link  
            $fakepage->setPath($element->getPath());  
            $fakepage->setFile(basename($element->getPath()));  
            $this->curname = 
$this->getPageName($fakepage);  
                $x->addLink($element->getPath(), $this->curname, $element->name, $element->docblock->package, $element->docblock->subpackage, $element->docblock->category);  
                $x->addLink($element->getPath(), $this->curname, $element->name, $element->docblock->package, $element->docblock->subpackage, $element->docblock->category);  
                $x->addLink($element->getPath(), $this->curname, $element->name, $element->docblock->package, $element->docblock->subpackage, $element->docblock->category);  
                $x->addLink($element->getPath(), $this->curname, $element->name, $element->docblock->package, $element->docblock->subpackage, $element->docblock->category);  
                $x->addLink($this->class, $element->getPath(), $this->curname, $element->name, $element->docblock->package, $element->docblock->subpackage, $element->docblock->category);  
                $x->addLink($this->class, $element->getPath(), $this->curname, $element->name, $element->docblock->package, $element->docblock->subpackage, $element->docblock->category);  
                $x->addLink($this->class, $element->getPath(), $this->curname, $element->name, $element->docblock->package, $element->docblock->subpackage, $element->docblock->category);  
                $x->addLink($element->getPath(),$this->getPageName($element),$element->file,$element->package, $element->subpackage, $element->category);  
     * Return a tree of all classes that extend this class  
     * The data structure returned is designed for a non-recursive algorithm,  
     * and is somewhat complex.  
     * In most cases, the array returned is:  
     *         array('link' => {@link classLink} to $class,  
     *               'children' => array(array('class' => 'childclass1',  
     *                                         'package' => 'child1package'),  
     *                                    array('class' => 'childclass2',  
     *                                         'package' => 'child2package'),...  
     *       'child1package#childclass1' =>  
     *         array('link' => {@link classLink} to childclass1,  
     *               'children' => array(array('class' => 'kidclass',  
     *                                         'package' => 'kidpackage'),...  
     *       'kidpackage#kidclass' =>  
     *         array('link' => {@link classLink} to kidclass,  
     *               'parent' => 'child1package#childclass1',  
     *               'children' => array() // no children  
     * To describe this format using language, every class in the tree has an  
     * entry in the first level of the array.  The index for all child  
     * classes that extend the root class is childpackage#childclassname.  
     * Each entry in the array has 3 elements: link, parent, and children.  
     *  <li>link - a {@link classLink} to the current class</li>  
     *  <li>parent - a {@link classLink} to the class's parent, or false (except for one special case described below)</li>  
     *  <li>children - an array of arrays, each entry has a 'class' and 'package' index to the child class,  
     * used to find the entry in the big array</li>  
     * special cases are when the #root class has a parent in another package,  
     * or when the #root class extends a class not found  
     * by phpDocumentor.  In the first case, parent will be a  
     * classLink to the parent class.  In the second, parent will be the  
     * in this case, the #root entry will be array('link' => classLink to X, 'parent' => 'Y', children => array(...))  
     * The fastest way to design a method to process the array returned  
     * is to copy HTMLframesConverter::getRootTree() into  
     * your converter and to modify the html to whatever output format you are going to use  
     * @see HTMLframesConverter::getRootTree()  
     * @param string class name  
     * @return array Format: see docs  
        $root = 
$this->classes->getClassByPackage($class,$package);  
        if (!$root) return false;  
        $class_children = 
$this->classes->getDefiniteChildren($class,$root->curfile);  
            // special case: parent class is found, but is not part of this package, class has no children  
                $x = 
$root->getParent($this);  
                if ($x->docblock->package != 
$package)  
                    return array('#root' => 
array('link' => 
$v,'parent' => 
Converter::getClassLink($x->getName(),$x->docblock->package,$x->getPath()), 'children' => 
array()));  
            { // class has normal situation, no children  
                return array('#root' => 
array('link' => 
Converter::getClassLink($root->getName(),$package,$root->getPath()), 'parent' => 
$root->getExtends(),'children' => 
array()));  
                return array('#root' => 
array('link' => 
Converter::getClassLink($root->getName(),$package,$root->getPath()), 'parent' => 
false, 'children' => 
array()));  
        // special case: parent class is found, but is not part of this package, class has children  
            $x = 
$root->getParent($this);  
            if ($x->docblock->package != 
$package)  
                $my_tree = 
array('#root' => 
array('link' => 
$v, 'parent' => 
Converter::getClassLink($x->getName(),$x->docblock->package,$x->getPath()), 'children' => 
array()));  
        $my_tree = 
array('#root' => 
array('link' => 
Converter::getClassLink($root->getName(),$package,$root->getPath()), 'parent' => 
false, 'children' => 
array()));  
        // location of tree walker  
        $lastcur = 
array(array(false,0));  
        if (isset
($class_children))  
                    if (isset
($my_tree[$cur]['children'][$childpos + 
1]))  
                        $cur = 
$my_tree[$cur]['children'][$childpos + 
1];  
                        $x = 
$this->classes->getClassByPackage($cur['class'],$cur['package']);  
                        $cur = 
$cur['package'] . 
'#' . 
$cur['class'];  
                        $my_tree[$cur]['parent'] = 
$par;  
                        $my_tree[$cur]['children'] = 
array();  
                        $class_children = 
$this->classes->getDefiniteChildren($x->getName(), $x->curfile);  
                foreach($class_children as $chileclass => 
$chilefile)  
                    $ch = 
$this->classes->getClass($chileclass,$chilefile);  
                    $my_tree[$cur]['children'][] = 
array('class' => 
$ch->getName(), 'package' => 
$ch->docblock->package);  
                usort($my_tree[$cur]['children'],'rootcmp');  
                if (isset
($my_tree[$cur]['children'][$childpos]))  
                    $cur = 
$my_tree[$cur]['children'][$childpos];  
                    $x = 
$this->classes->getClassByPackage($cur['class'],$cur['package']);  
                    $cur = 
$cur['package'] . 
'#' . 
$cur['class'];  
                    $my_tree[$cur]['parent'] = 
$par;  
                    $my_tree[$cur]['children'] = 
array();  
                    $class_children = 
$this->classes->getDefiniteChildren($x->getName(), $x->curfile);  
     * @return bool true if a link to this class exists in package $package and subpackage $subpackage  
     * @param string $expr class name  
     * @param string $package package to search in  
     * @param string $subpackage subpackage to search in  
    function isLinkedClass($expr,$package,$subpackage,$file=
false)  
        return isset
($this->linkswithfile[$package][$subpackage]['class'][$file][$expr]);  
        return isset
($this->links[$package][$subpackage]['class'][$expr]);  
     * @return bool true if a link to this function exists in package $package and subpackage $subpackage  
     * @param string $expr function name  
     * @param string $package package to search in  
     * @param string $subpackage subpackage to search in  
    function isLinkedFunction($expr,$package,$subpackage,$file=
false)  
        return isset
($this->linkswithfile[$package][$subpackage]['function'][$file][$expr]);  
        return isset
($this->links[$package][$subpackage]['function'][$expr]);  
     * @return bool true if a link to this define exists in package $package and subpackage $subpackage  
     * @param string $expr define name  
     * @param string $package package to search in  
     * @param string $subpackage subpackage to search in  
    function isLinkedDefine($expr,$package,$subpackage,$file=
false)  
        return isset
($this->linkswithfile[$package][$subpackage]['define'][$file][$expr]);  
        return isset
($this->links[$package][$subpackage]['define'][$expr]);  
     * @return bool true if a link to this define exists in package $package and subpackage $subpackage  
     * @param string $expr define name  
     * @param string $package package to search in  
     * @param string $subpackage subpackage to search in  
    function isLinkedGlobal($expr,$package,$subpackage,$file=
false)  
        return isset
($this->linkswithfile[$package][$subpackage]['global'][$file][$expr]);  
        return isset
($this->links[$package][$subpackage]['global'][$expr]);  
     * @return bool true if a link to this procedural page exists in package $package and subpackage $subpackage  
     * @param string $expr procedural page name  
     * @param string $package package to search in  
     * @param string $subpackage subpackage to search in  
    function isLinkedPage($expr,$package,$subpackage,$path=
false)  
        return isset
($this->linkswithfile[$package][$subpackage]['page'][$path][$expr]);  
        return isset
($this->links[$package][$subpackage]['page'][$expr]);  
     * @return bool true if a link to this method exists in package $package, subpackage $subpackage and class $class  
     * @param string $expr method name  
     * @param string $class class name  
     * @param string $package package to search in  
     * @param string $subpackage subpackage to search in  
    function isLinkedMethod($expr,$package,$subpackage,$class,$file=
false)  
        return isset
($this->linkswithfile[$package][$subpackage]['method'][$file][$class][$expr]);  
        return isset
($this->links[$package][$subpackage]['method'][$class][$expr]);  
     * @return bool true if a link to this method exists in package $package, subpackage $subpackage and class $class  
     * @param string $expr var name  
     * @param string $class class name  
     * @param string $package package to search in  
     * @param string $subpackage subpackage to search in  
    function isLinkedVar($expr,$package,$subpackage,$class,$file=
false)  
        return isset
($this->linkswithfile[$package][$subpackage]['var'][$file][$class][$expr]);  
        return isset
($this->links[$package][$subpackage]['var'][$class][$expr]);  
     * @return bool true if a link to this method exists in package $package, subpackage $subpackage and class $class  
     * @param string $expr constant name  
     * @param string $class class name  
     * @param string $package package to search in  
     * @param string $subpackage subpackage to search in  
    function isLinkedConst($expr,$package,$subpackage,$class,$file=
false)  
        return isset
($this->linkswithfile[$package][$subpackage]['const'][$file][$class][$expr]);  
        return isset
($this->links[$package][$subpackage]['const'][$class][$expr]);  
     * return false or a {@link classLink} to $expr  
     * @param string $expr class name  
     * @param string $package package name  
     * @return mixed returns a {@link classLink} or false if the element is not found in package $package  
    function getClassLink($expr,$package,$file=
false, $text = 
false)  
        if (!isset
($this->links[$package])) return false;  
        foreach($this->links[$package] as $subpackage => 
$notused)  
            if ($this->isLinkedClass($expr,$package,$subpackage,$file))  
                    return $this->linkswithfile[$package][$subpackage]['class'][$file][$expr];  
                return $this->links[$package][$subpackage]['class'][$expr];  
     * return false or a {@link functionLink} to $expr  
     * @param string $expr function name  
     * @param string $package package name  
     * @return mixed returns a {@link functionLink} or false if the element is not found in package $package  
        if (!isset
($this->links[$package])) return false;  
        foreach($this->links[$package] as $subpackage => 
$notused)  
            if ($this->isLinkedFunction($expr,$package,$subpackage,$file))  
                    return $this->linkswithfile[$package][$subpackage]['function'][$file][$expr];  
                return $this->links[$package][$subpackage]['function'][$expr];  
     * return false or a {@link defineLink} to $expr  
     * @param string $expr constant name  
     * @param string $package package name  
     * @return mixed returns a {@link defineLink} or false if the element is not found in package $package  
    function getDefineLink($expr,$package,$file=
false, $text = 
false)  
        if (!isset
($this->links[$package])) return false;  
        foreach($this->links[$package] as $subpackage => 
$notused)  
            if ($this->isLinkedDefine($expr,$package,$subpackage,$file))  
                    return $this->linkswithfile[$package][$subpackage]['define'][$file][$expr];  
                return $this->links[$package][$subpackage]['define'][$expr];  
     * return false or a {@link globalLink} to $expr  
     * @param string $expr global variable name (with leading $)  
     * @param string $package package name  
     * @return mixed returns a {@link defineLink} or false if the element is not found in package $package  
    function getGlobalLink($expr,$package,$file=
false, $text = 
false)  
        if (!isset
($this->links[$package])) return false;  
        foreach($this->links[$package] as $subpackage => 
$notused)  
            if ($this->isLinkedGlobal($expr,$package,$subpackage,$file))  
                    return $this->linkswithfile[$package][$subpackage]['global'][$file][$expr];  
                return $this->links[$package][$subpackage]['global'][$expr];  
     * return false or a {@link pageLink} to $expr  
     * @param string $expr procedural page name  
     * @param string $package package name  
     * @return mixed returns a {@link pageLink} or false if the element is not found in package $package  
    function getPageLink($expr,$package,$path = 
false, $text = 
false, $packages = 
false)  
        if (!isset
($this->links[$package])) return false;  
        foreach($this->links[$package] as $subpackage => 
$notused)  
            if ($this->isLinkedPage($expr,$package,$subpackage,$path))  
                    return $this->linkswithfile[$package][$subpackage]['page'][$path][$expr];  
                return $this->links[$package][$subpackage]['page'][$expr];  
     * return false or a {@link methodLink} to $expr in $class  
     * @param string $expr method name  
     * @param string $class class name  
     * @param string $package package name  
     * @return mixed returns a {@link methodLink} or false if the element is not found in package $package, class $class  
    function getMethodLink($expr,$class,$package,$file=
false, $text = 
false)  
        if (!isset
($this->links[$package])) return false;  
        foreach($this->links[$package] as $subpackage => 
$notused)  
            if ($this->isLinkedMethod($expr,$package,$subpackage,$class,$file))  
                    return $this->linkswithfile[$package][$subpackage]['method'][$file][$class][$expr];  
                return $this->links[$package][$subpackage]['method'][$class][$expr];  
     * return false or a {@link varLink} to $expr in $class  
     * @param string $expr var name  
     * @param string $class class name  
     * @param string $package package name  
     * @return mixed returns a {@link varLink} or false if the element is not found in package $package, class $class  
    function getVarLink($expr,$class,$package,$file=
false, $text = 
false)  
        if (!isset
($this->links[$package])) return false;  
        foreach($this->links[$package] as $subpackage => 
$notused)  
            if ($this->isLinkedVar($expr,$package,$subpackage,$class,$file))  
                    return $this->linkswithfile[$package][$subpackage]['var'][$file][$class][$expr];  
                return $this->links[$package][$subpackage]['var'][$class][$expr];  
     * return false or a {@link constLink} to $expr in $class  
     * @param string $expr constant name  
     * @param string $class class name  
     * @param string $package package name  
     * @return mixed returns a {@link varLink} or false if the element is not found in package $package, class $class  
    function getConstLink($expr,$class,$package,$file=
false, $text = 
false)  
        if (!isset
($this->links[$package])) return false;  
        foreach($this->links[$package] as $subpackage => 
$notused)  
            if ($this->isLinkedConst($expr,$package,$subpackage,$class,$file))  
                    return $this->linkswithfile[$package][$subpackage]['const'][$file][$class][$expr];  
                return $this->links[$package][$subpackage]['const'][$class][$expr];  
     * The meat of the @tutorial tag and inline {@}tutorial} tag  
     * Take a string and return an abstract link to the tutorial it represents.  
     * Since tutorial naming literally works like the underlying filesystem, the  
     * way to reference the tutorial is similar.  Tutorials are located in a  
     * subdirectory of any directory parsed, which is named 'tutorials/' (we  
     * try to make things simple when we can :).  They are further organized by  
     * package and subpackage as:  
     * tutorials/package/subpackage  
     * and the files are named *.cls, *.pkg, or *.proc, and so a link to a tutorial  
     * named file.cls can be referenced (depending on context) as any of:  
     * * @tutorial package/subpackage/file.cls  
     * * @tutorial package/file.cls  
     * The first case will only be needed if file.cls exists in both the current  
     * package, in anotherpackage/file.cls and in anotherpackage/subpackage/file.cls  
     * and you wish to reference the one in anotherpackage/subpackage.  
     * The second case is only needed if you wish to reference file.cls in another  
     * package and it is unique in that package. the third will link to the first  
     * file.cls it finds using this search method:  
     *    <li>current package/subpackage</li>  
     *    <li>all other subpackages of current package</li>  
     *    <li>parent package, if this package has classes that extend classes in  
     *    <li>all other packages</li>  
     * @return tutorialLink|stringreturns either a link, or the original text, if not found  
     * @param string the original expression  
     * @param string package to look in first  
     * @param string subpackage to look in first  
     * @param array array of package names to search in if not found in parent packages.  
     *               This is used to limit the search, phpDocumentor automatically searches  
    function getTutorialLink($expr, $package = 
false, $subpackage = 
false, $packages = 
false)  
        // is $expr a comma-delimited list?  
            for($i=
0;$i<
count($a);$i++
)  
                // if so return each component with a link  
        if (!$package) $package = 
$this->package;  
        if (!$subpackage) $subpackage = 
$this->subpackage;  
        elseif (isset
($packages[$package])) unset
($packages[$package]);  
        $ext = 
pathinfo($expr, PATHINFO_EXTENSION);  
        if (isset
($this->tutorials[$package][$subpackage][$ext][$expr]))  
            $a = 
$this->tutorials[$package][$subpackage][$ext][$expr];  
            $link->addLink($subsection,$a->path,$a->name,$a->package,$a->subpackage,$a->getTitle($this,$subsection));  
                if (isset
($packages[$package])) unset
($packages[$package]);  
            if (isset
($this->tutorials[$package]))  
                if (isset
($this->tutorials[$package][$subpackage][$ext][$expr]))  
                    $a = 
$this->tutorials[$package][$subpackage][$ext][$expr];  
                    foreach($this->tutorials[$package] as $subpackage => 
$stuff)  
                        if (isset
($stuff[$ext][$expr]))  
                            $a = 
$stuff[$ext][$expr];  
            // look in parent package first, if found  
                // no parent package, so start with the first one that's left  
                list
($package,) = 
@each($packages); 
                if (isset
($packages[$package])) unset
($packages[$package]);  
        } while (count($packages) || 
$package);  
     * The meat of the @see tag and inline {@}link} tag  
     * $expr is a string with many allowable formats:  
     *  <li>proceduralpagename.ext</li>  
     *  <li>classname::function()</li>  
     *  <li>classname::constantname</li> (new 1.2.4)  
     *  <li>classname::$variablename</li>  
     *  <li>object classname</li>  
     *  <li>function functionname()</li>  
     *  <li>global $globalvarname</li>  
     *  <li>packagename#expr where expr is any of the above</li>  
     * New in version 1.1, you can explicitly specify a package to link to that  
     * is different from the current package.  Use the # operator  
     * to specify a new package, as in tests#bug-540368.php (which should appear  
     * as a link like: "{@link tests#bug-540368.php}").  This  
     * example links to the procedural page bug-540368.php in package  
     * tests.  Also, the "function" operator is now used to specifically  
     * link to a function instead of a method in the current class.  
     *  // from inside the class definition, use "function conflict()" to refer to procedural function "conflict()"  
     * If classname:: is not present, and the see tag is in a documentation  
     * block within a class, then the function uses the classname to  
     * search for $expr as a function or variable within classname, or any of its parent classes.  
     * given an $expr without '$', '::' or '()' getLink first searches for  
     * classes, procedural pages, constants, global variables, and then searches for  
     * methods and variables within the default class, and finally for any function  
     * @param string $expr expression to search for a link  
     * @param string $package package to start searching in  
     * @param array $packages list of all packages to search in  
     * @return mixed getLink returns a descendant of {@link abstractLink} if it finds a link, otherwise it returns a string  
     * @see getPageLink(), getDefineLink(), getVarLink(), getFunctionLink(), getClassLink()  
     * @see pageLink, functionLink, defineLink, classLink, methodLink, varLink  
    function &getLink($expr, $package = 
false, $packages = 
false)  
        // is $expr a comma-delimited list?  
            for($i=
0;$i<
count($a);$i++
)  
                // if so return each component with a link  
            { // can have exactly 1 package override, otherwise it's ignored  
                // feature 564991, link to php manual  
                if ($a[0] == 
'PHP_MANUAL') {  
                    $s = 
'http://www.php.net/'.
$a[1];  
        $a = 
&$this->_getLink($expr, $package, $packages);  
    function &_getLink($expr, $package = 
false, $packages = 
false)  
        if (!$package) $package = 
$this->package;  
        elseif (isset
($packages[$package])) unset
($packages[$package]);  
        if (strpos($expr,'function ') === 
0)  
        { // asking for a function, not a method  
        if (strpos($expr,'global ') === 
0)  
        { // asking for a global variable  
        if (strpos($expr,'object ') === 
0)  
        if (strpos($expr,'constant ') === 
0)  
            // is $expr simply a word? see if it is the class  
            if (trim($expr) == 
$class)  
            // if not, check to see if it is a method or variable of this class tree  
                // if get is neither get() nor $get, assume get is a function, add () to make get()  
                if (strpos($expr,'$') !== 
0 && 
!strpos($expr,'()')) //$get = $get.'()';  
                    if ($a = 
$this->getLinkMethod($expr,$class,$package)) return $a;  
                    if ($a = 
$this->getLinkConst($expr,$class,$package)) return $a;  
                    if ($a = 
$this->getLinkVar('$'.
$expr,$class,$package)) return $a;  
                if (strpos($expr,'()')) if ($a = 
$this->getLinkMethod($expr,$class,$package)) return $a;  
                if (is_numeric(strpos($expr,'$'))) if ($a = 
$this->getLinkVar($expr,$class,$package)) return $a;  
//        if (strpos($expr,'.'))  
            if (isset
($packages[$package])) unset
($packages[$package]);  
            // is $expr in class::method() or class::$variable format?  
            if (strpos($expr,'function ') === 
0)  
            { // asking for a function, not a method  
            $test = 
$this->_getDoubleColon($expr, $package, $packages, $class, $links);  
            if (strpos($test, 'parent::') === 
0) return $test;  
            // $expr does not have ::  
                // default to current class, whose name is contained in $this->render->parent  
            // $expr is a function? (non-method)  
                // otherwise, see if it is a method  
                // extract the function name, use it to retrieve the file that the function is in  
    //            $page = $this->func_page[str_replace('function ','',str_replace('()','',$expr))];  
            // $expr is just a word.  First, test to see if it is a function of the current package  
            // look in parent package first, if found  
                    if (isset
($packages[$package])) unset
($packages[$package]);  
            // no parent package, so start with the first one that's left  
            if ($package && isset
($packages[$package]))  
                unset
($packages[$package]); 
        } while (count($packages) || 
$package);  
        // feature 564991, link to php manual  
            $return = 
'http://www.php.net/'.
str_replace(array('(',')'),array('',''),$expr);  
     * Split up getLink to make it easier to debug  
    function _getDoubleColon(&$expr, &$package, &$packages, $class, $links)  
            $class_method = 
explode('::',$expr);  
            if ($class_method[0] == 
'parent')  
                // can only have parent in the same package as the class!  subtle bug  
                $cl = 
$this->classes->getClassByPackage($class,$package);  
                { // this is possible if an example file has parent::method()  
                $par = 
$cl->getParent($this);  
                    $package = 
$par->docblock->package;  
                    $phpparent = 
$par->getName();  
                if ($phpparent) $class_method[0] = 
$phpparent;  
            if (strpos($class_method[1],'()'))  
                // strip everything but the function name, return a link  
     * cycle through parent classes to retrieve a link to a method  
     * do not use or override, used by getLink  
    function &getLinkMethod($expr, $class, $package)  
            // is $expr in class::method() or class::$variable format?  
                $class_method = 
explode('::',$expr);  
                if ($class_method[0] == 
'parent')  
                    $cl = 
$this->classes->getClassByPackage($class,$package);  
                    $par = 
$cl->getParent($this);  
                        $package = 
$par->docblock->package;  
                        $phpparent = 
$par->getName();  
                    } else addWarning(PDERROR_CLASSPARENT_NOTFOUND,$class,$package,$class_method[1]);  
                    if ($phpparent) $class_method[0] = 
$phpparent;  
                    $cl = 
$this->classes->getClassByPackage($class,$package);  
                if (strpos($class_method[1],'()'))  
                    // strip everything but the function name, return a link  
            $cl = 
$this->classes->getClassByPackage($class,$package);  
                $par = 
$cl->getParent($this);  
                    $package = 
$par->docblock->package;  
                    $class = 
$par->getName();  
     * cycle through parent classes to retrieve a link to a var  
     * do not use or override, used by getLink  
    function &getLinkVar($expr, $class, $package)  
            // is $expr in class::method() or class::$variable format?  
                $class_method = 
explode('::',$expr);  
                if ($class_method[0] == 
'parent')  
                    $cl = 
$this->classes->getClassByPackage($class,$package);  
                    $par = 
$cl->getParent($this);  
                        $package = 
$par->docblock->package;  
                        $phpparent = 
$par->getName();  
                    } else addWarning(PDERROR_CLASSPARENT_NOTFOUND,$class,$package,$class_method[1]);  
                    if ($phpparent) $class_method[0] = 
$phpparent;  
                    $cl = 
$this->classes->getClassByPackage($class,$package);  
                if ($test = 
Converter::getVarLink('$'.
$class_method[1], $class_method[0], $package)) return $test;  
            $cl = 
$this->classes->getClassByPackage($class,$package);  
                $par = 
$cl->getParent($this);  
                    $package = 
$par->docblock->package;  
                    $class = 
$par->getName();  
     * cycle through parent classes to retrieve a link to a class constant  
     * do not use or override, used by getLink  
    function &getLinkConst($expr, $class, $package)  
            // is $expr in class::method() or class::$variable format?  
                $class_method = 
explode('::',$expr);  
                if ($class_method[0] == 
'parent')  
                    $cl = 
$this->classes->getClassByPackage($class,$package);  
                    $par = 
$cl->getParent($this);  
                        $package = 
$par->docblock->package;  
                        $phpparent = 
$par->getName();  
                    } else addWarning(PDERROR_CLASSPARENT_NOTFOUND,$class,$package,$class_method[1]);  
                    if ($phpparent) $class_method[0] = 
$phpparent;  
                    $cl = 
$this->classes->getClassByPackage($class,$package);  
            $cl = 
$this->classes->getClassByPackage($class,$package);  
                $par = 
$cl->getParent($this);  
                    $package = 
$par->docblock->package;  
                    $class = 
$par->getName();  
     * take URL $link and text $text and return a link in the format needed for the Converter  
     * @param string text to display  
     * @return string link to $link  
     * take {@link abstractLink} descendant and text $eltext and return a link  
     * in the format needed for the Converter  
     * @return string link to $element  
     * take {@link abstractLink} descendant and text $eltext and return a  
     * unique ID in the format needed for the Converter  
     * @return string unique identifier of $element  
     * Convert README/INSTALL/CHANGELOG file contents to output format  
     * @param README|INSTALL|CHANGELOG  
     * @param string contents of the file  
     * Convert all elements to output format  
     * This will call ConvertXxx where Xxx is {@link ucfirst}($element->type).  
     * It is expected that a child converter defines a handler for every  
     * element type, even if that handler does nothing.  phpDocumentor will  
     * terminate with an error if a handler doesn't exist.  
     * Since 1.2.0 beta 3, this function has been moved from child converters  
     * to the parent, because it doesn't really make sense to put it in the  
     * child converter, and we can add error handling.  
     * @throws {@link PDERROR_NO_CONVERT_HANDLER}  
     * @param mixed {@link parserElement} descendant or {@link parserPackagePage} or {@link parserData}  
        $handler = 
'convert'.
ucfirst($element->type);  
            $this->$handler($element);  
     * All of the convert* handlers set up template variables for the Smarty  
     * template.{@internal  In addition, the {@link newSmarty()} method is  
     * called to retrieve the global Smarty template}}  
     * Default Tutorial Handler  
     * Sets up the tutorial template, and its prev/next/parent links  
     * Retrieves the title using {@link parserTutorial::getTitle()} and uses the  
     * {@link parserTutorial::prev, parserTutorial::next, parserTutorial::parent}  
     * links to set up those links.}}}  
        $template->assign('contents',$x);  
        $template->assign('title',$element->getTitle($this));  
        $template->assign('nav',$element->parent || 
$element->prev || 
$element->next);  
            $template->assign('up',$this->getId($element->parent));  
            $template->assign('uptitle',$element->parent->title);  
            $template->assign('prev',$this->getId($element->prev));  
            $template->assign('prevtitle',$element->prev->title);  
            $template->assign('next',$this->getId($element->next));  
            $template->assign('nexttitle',$element->next->title);  
     * Sets up the class template.  
     * {@internal special methods  
     * {@link generateChildClassList(), generateFormattedClassTree()},  
     * {@link getFormattedConflicts, getFormattedInheritedMethods},  
     * and {@link getFormattedInheritedVars} are called to complete vital  
        $this->class = 
$element->getName();  
        $this->class_data->assign("class_name",$element->getName());  
        $this->class_data->assign("is_interface", $element->isInterface());  
        $this->class_data->assign("line_number",$element->getLineNumber());  
        $this->class_data->assign("source_location",$element->getSourceLocation($this));  
        $this->class_data->assign("sdesc",$docblock['sdesc']);  
        $this->class_data->assign("desc",$docblock['desc']);  
                $this->class_data->assign("access", $docblock['access']);  
                $this->class_data->assign("abstract", $docblock['abstract']);  
        $this->class_data->assign("tags",$docblock['tags']);  
        $this->class_data->assign("api_tags",$docblock['api_tags']);  
        $this->class_data->assign("info_tags",$docblock['info_tags']);  
        $this->class_data->assign("utags",$docblock['utags']);  
        $this->class_data->assign( "prop_tags", $docblock['property_tags'] );  
        $this->class_data->assign("class_slink",$this->getSourceAnchor($element->getPath(),$element->getLineNumber(),$element->getLineNumber(),true));  
        if (!empty($inherited_methods))  
            $this->class_data->assign("imethods",$inherited_methods);  
        if (!empty($inherited_vars))  
            $this->class_data->assign("ivars",$inherited_vars);  
        if (!empty($inherited_consts))  
            $this->class_data->assign("iconsts",$inherited_consts);  
     * Converts method for template output  
     * This function must be called by a child converter with any extra  
     * template variables needed in the parameter $addition  
        $fname = 
$element->getName();  
        if ($element->isConstructor) $returntype = 
$element->class;  
        if ($element->docblock->return)  
            $a = 
$element->docblock->return->Convert($this);  
            $returntype = 
$element->docblock->return->converted_returnType;  
        $params = 
$param_i = 
array();  
        if (count($element->docblock->params))  
        foreach($element->docblock->params as $param => 
$val)  
            $params[] = 
$param_i[$param] = 
array("var" => 
$param,"datatype" => 
$val->converted_returnType,"data" => 
$a);  
        if ($element->docblock->hasaccess) {  
            $acc = 
$docblock['access'];  
        $additions["slink"] = 
$this->getSourceAnchor($element->getPath(),$element->getLineNumber(),$element->getLineNumber(),true);  
                        'sdesc' => 
$docblock['sdesc'],  
                        'desc' => 
$docblock['desc'],  
                        'static' => 
$docblock['static'],  
                        'abstract' => 
$docblock['abstract'],  
                        'tags' => 
$docblock['tags'],  
                        'api_tags' => 
$docblock['api_tags'],  
                        'see_tags' => 
$docblock['see_tags'],  
                        'info_tags_sorted' => 
$docblock['info_tags_sorted'],  
                        'info_tags' => 
$docblock['info_tags'],  
                        'utags' => 
$docblock['utags'],  
                        'constructor' => 
$element->isConstructor,  
                        'function_name'     => 
$fname,  
                        'function_return'    => 
$returntype,  
                        'function_call'     => 
$element->getFunctionCall(),  
                        'ifunction_call'     => 
$element->getIntricateFunctionCall($this, $param_i),  
                        'line_number' => 
$element->getLineNumber(),  
                        'id' => 
$this->getId($element),  
     * Converts class variables for template output.  
     * This function must be called by a child converter with any extra  
     * template variables needed in the parameter $addition  
    function convertVar(&$element, $additions = 
array())  
        if ($element->docblock->hasaccess)  
            $acc = 
$element->docblock->tags['access'][0]->value;  
        if ($element->docblock->var)  
            $b = 
$element->docblock->var->converted_returnType;  
        $additions["slink"] = 
$this->getSourceAnchor($element->getPath(),$element->getLineNumber(),$element->getLineNumber(),true);  
                        'sdesc' => 
$docblock['sdesc'],  
                        'desc' => 
$docblock['desc'],  
                        'static' => 
$docblock['static'],  
                        'abstract' => 
$docblock['abstract'],  
                        'utags' => 
$docblock['utags'],  
                        'tags' => 
$docblock['tags'],  
                        'api_tags' => 
$docblock['api_tags'],  
                        'info_tags' => 
$docblock['info_tags'],  
                        'var_name' => 
$element->getName(),  
                        'has_default' => 
strlen($element->getValue()),  
                        'var_default' => 
$this->postProcess($element->getValue()),  
                        'line_number' => 
$element->getLineNumber(),  
                        'id' => 
$this->getId($element)  
     * Converts class constants for template output.  
     * This function must be called by a child converter with any extra  
     * template variables needed in the parameter $addition  
        if ($element->docblock->hasaccess)  
            $acc = 
$element->docblock->tags['access'][0]->value;  
        $additions["slink"] = 
$this->getSourceAnchor($element->getPath(),$element->getLineNumber(),$element->getLineNumber(),true);  
                        'sdesc' => 
$docblock['sdesc'],  
                        'desc' => 
$docblock['desc'],  
                        'access' => 
$docblock['access'],  
                        'abstract' => 
$docblock['abstract'],  
                        'utags' => 
$docblock['utags'],  
                        'tags' => 
$docblock['tags'],  
                        'api_tags' => 
$docblock['api_tags'],  
                        'info_tags' => 
$docblock['info_tags'],  
                        'const_name' => 
$element->getName(),  
                        'const_value' => 
$this->postProcess($element->getValue()),  
                        'line_number' => 
$element->getLineNumber(),  
                        'id' => 
$this->getId($element)  
     * {@internal In addition to setting up the smarty template with {@link newSmarty()},  
     * this class uses {@link getSourceLocation()} and {@link getClassesOnPage()}  
     * to set template variables.  Also used is {@link getPageName()}, to get  
     * a Converter-specific name for the page.}}}  
        $this->page = 
$this->getPageName($element->parent);  
        $this->path = 
$element->parent->getPath();  
        $this->curpage = 
&$element->parent;  
        $this->page_data->assign("source_location",$element->parent->getSourceLocation($this));  
        $this->page_data->assign("functions",array());  
        $this->page_data->assign("includes",array());  
        $this->page_data->assign("hasclasses",$element->hasClasses());  
        $this->page_data->assign("hasinterfaces",$element->hasInterfaces());  
        $this->page_data->assign("name", $element->parent->getFile());  
        if ($t = 
$element->getTutorial())  
            $this->page_data->assign("sdesc",$docblock['sdesc']);  
            $this->page_data->assign("desc",$docblock['desc']);  
            $this->page_data->assign("tags",$docblock['tags']);  
            $this->page_data->assign("api_tags",$docblock['api_tags']);  
            $this->page_data->assign("info_tags",$docblock['info_tags']);  
            $this->page_data->assign("utags",$docblock['utags']);  
     * Converts global variables for template output  
     * This function must be called by a child converter with any extra  
     * template variables needed in the parameter $addition  
     * In addition to using {@link prepareDocBlock()}, this method also  
     * uses utility functions {@link getGlobalValue(), getFormattedConflicts()}}}}  
     * @uses postProcess() on global_value template value, makes it displayable  
     * @param array any additional template variables should be in this array  
        $addition["slink"] = 
$this->getSourceAnchor($element->getPath(),$element->getLineNumber(),$element->getLineNumber(),true);  
                                            array('sdesc' => 
$docblock['sdesc'],  
                                                  'desc' => 
$docblock['desc'],  
                                                  'tags' => 
$docblock['tags'],  
                                                  'api_tags' => 
$docblock['api_tags'],  
                                                  'info_tags' => 
$docblock['info_tags'],  
                                                  'utags' => 
$docblock['utags'],  
                                                  'global_name'     => 
$element->getName(),  
                                                  'global_type' => 
$element->getDataType($this),  
                                                  'global_value'    => 
$value,  
                                                  'line_number' => 
$element->getLineNumber(),  
                                                  'id' => 
$this->getId($element)),  
     * Converts defines for template output  
     * This function must be called by a child converter with any extra  
     * template variables needed in the parameter $addition  
     * In addition to using {@link prepareDocBlock()}, this method also  
     * uses utility functions {@link getGlobalValue(), getFormattedConflicts()}}}}  
     * @uses postProcess() on define_value template value, makes it displayable  
     * @param array any additional template variables should be in this array  
        $addition["slink"] = 
$this->getSourceAnchor($element->getPath(),$element->getLineNumber(),$element->getLineNumber(),true);  
                                            array('sdesc' => 
$docblock['sdesc'],  
                                                  'desc' => 
$docblock['desc'],  
                                                  'tags' => 
$docblock['tags'],  
                                                  'api_tags' => 
$docblock['api_tags'],  
                                                  'info_tags' => 
$docblock['info_tags'],  
                                                  'utags' => 
$docblock['utags'],  
                                                  'define_name'     => 
$element->getName(),  
                                                  'line_number' => 
$element->getLineNumber(),  
                                                  'define_value'    => 
$this->postProcess($element->getValue()),  
                                                  'id' => 
$this->getId($element)),  
     * Converts includes for template output  
     * This function must be called by a child converter with any extra  
     * template variables needed in the parameter $addition  
        $addition["slink"] = 
$this->getSourceAnchor($element->getPath(),$element->getLineNumber(),$element->getLineNumber(),true);  
                                             array('sdesc' => 
$docblock['sdesc'],  
                                                   'desc' => 
$docblock['desc'],  
                                                   'tags' => 
$docblock['tags'],  
                                                   'api_tags' => 
$docblock['api_tags'],  
                                                   'info_tags' => 
$docblock['info_tags'],  
                                                   'utags' => 
$docblock['utags'],  
                                                   'include_name'     => 
$element->getName(),  
                                                   'line_number' => 
$element->getLineNumber(),  
                                                   'include_value'    => 
$per),  
     * Converts function for template output  
     * This function must be called by a child converter with any extra  
     * template variables needed in the parameter $addition  
        $fname = 
$element->getName();  
        $params = 
$param_i = 
array();  
        if (count($element->docblock->params))  
        foreach($element->docblock->params as $param => 
$val)  
            $params[] = 
$param_i[$param] = 
array("var" => 
$param,"datatype" => 
$val->converted_returnType,"data" => 
$a);  
        if ($element->docblock->return)  
            $a = 
$element->docblock->return->Convert($this);  
            $returntype = 
$element->docblock->return->converted_returnType;  
        $addition["slink"] = 
$this->getSourceAnchor($element->getPath(),$element->getLineNumber(),$element->getLineNumber(),true);  
                                              array('sdesc' => 
$docblock['sdesc'],  
                                                    'desc' => 
$docblock['desc'],  
                                                    'tags' => 
$docblock['tags'],  
                                                    'api_tags' => 
$docblock['api_tags'],  
                                                    'info_tags' => 
$docblock['info_tags'],  
                                                    'utags' => 
$docblock['utags'],  
                                                    'function_name'     => 
$fname,  
                                                    'function_return'    => 
$returntype,  
                                                    'ifunction_call'     => 
$element->getIntricateFunctionCall($this, $param_i),  
                                                    'function_call'     => 
$element->getFunctionCall(),  
                                                    'line_number' => 
$element->getLineNumber(),  
                                                    'id' => 
$this->getId($element),  
     * convert the element's DocBlock for output  
     * This function converts all tags and descriptions for output  
     * @param mixed any descendant of {@link parserElement}, or {@link parserData}  
     * @param array used to translate tagnames into other tags  
     * @param boolean set to false for pages and classes, the only elements allowed to specify @package  
     *  array('sdesc' => DocBlock summary  
     *        'desc' => DocBlock detailed description  
     *        'tags' => array('keyword' => tagname, 'data' => tag description)  
     *        'api_tags' => array('keyword' => tagname, 'data' => tag description)  
     *                  known api documentation tags  
     *        'info_tags' => array('keyword' => tagname, 'data' => tag description)  
     *                  known informational tags  
     *      [ 'utags' => array('keyword' => tagname, 'data' => tag description  
     *      [ 'vartype' => type from @var/@return tag ]  
     *      [ 'var_descrip' => description from @var/@return tag ]  
        $tagses = 
$element->docblock->listTags();  
        $tags = 
$ret = 
$api_tags = 
$info_tags = 
array();  
        $api_tags_arr = 
array("abstract", "access", "deprecated", "example", "filesource",  
                             "global", "internal", "name", "return", "see",  
                             "property", "property-read", "property-write", "method",  
                             "staticvar", "usedby", "uses", "var");  
            $tags[] = 
array('keyword' => 
'package','data' => 
$element->docblock->package);  
            if (!empty($element->docblock->subpackage)) $tags[] = 
array('keyword' => 
'subpackage','data' => 
$element->docblock->subpackage);  
        if ($element->docblock->var)  
            $a = 
$element->docblock->var->Convert($this);  
            $ret['vartype'] = 
$element->docblock->var->converted_returnType;  
                $tags[] = 
array('keyword' => 
'var', 'data' => 
$a);  
                $ret["var_descrip"] = 
$a;  
        if ($element->docblock->return)  
            $a = 
$element->docblock->return->Convert($this);  
            $ret['vartype'] = 
$element->docblock->return->converted_returnType;  
                $tags[] = 
$api_tags[] = 
array('keyword' => 
'return', 'data' => 
$a);  
                $ret["var_descrip"] = 
$a;  
        if ($element->docblock->funcglobals)  
        foreach($element->docblock->funcglobals as $global => 
$val)  
            $tags[] = 
$api_tags[] = 
array('keyword' => 
'global','data' => 
$val[0].
' '.
$global.
': '.
$val[1]->Convert($this));  
        if ($element->docblock->statics)  
        foreach($element->docblock->statics as $static => 
$val)  
            $tags[] = 
$api_tags[] = 
array('keyword' => 
'staticvar','data' => 
$val->converted_returnType.
' '.
$static.
': '.
$a);  
        $property_tags = 
array();  
        foreach ( $element->docblock->properties as $prop_name => 
$val )  
                $tags[] = 
$api_tags[] = 
array( 'keyword' => 
$val->keyword ,  
                                               'data' => 
$val->converted_returnType  . 
' ' . 
$prop_name . 
': ' . 
$a );  
                $prop['prop_name'] = 
$prop_name;  
                $prop['access'] = 
$val->keyword == 
'property-read' ? 
'read' :
  
                                    ( $val->keyword == 
'property-write' ? 
'write' : 
'read/write' );  
                $prop['prop_type'] = 
$val->converted_returnType;  
                $property_tags[ $prop_name ] = 
$prop;  
        ksort( $property_tags, SORT_STRING );  
        $info_tags_sorted = 
array();  
            if (isset
($names[$tag->keyword])) $tag->keyword = 
$names[$tag->keyword];  
            if ($tag->keyword == 
'static') {  
                $tags[] = 
array("keyword" => 
$tag->keyword,"data" => 
$tag->Convert($this));  
            if (in_array($tag->keyword, $api_tags_arr)) {  
                $api_tags[] = 
array("keyword" => 
$tag->keyword,"data" => 
$tag->Convert($this));  
                $info_tags[] = 
array("keyword" => 
$tag->keyword,"data" => 
$tag->Convert($this));  
                $info_tags_sorted[ $tag->keyword ][] = 
array( 'keyword' => 
$className, 'data' => 
$desc );  
        foreach($element->docblock->unknown_tags as $keyword => 
$tag)  
            $utags[] = 
array('keyword' => 
$keyword, 'data' => 
$t->Convert($this));  
        $ret['abstract'] = 
false;  
        $ret['access'] = 
'public';  
            if ($tag['keyword'] == 
'access') {  
                $ret['access'] = 
$tag['data'];  
            if ($tag['keyword'] == 
'abstract') {  
            if ($tag['keyword'] == 
'see' || 
$tag['keyword'] == 
'uses' ||
  
                  $tag['keyword'] == 
'usedby') {  
                $see_tags[] = 
$tag['data'];  
        $ret['sdesc'] = 
$element->docblock->getSDesc($this);  
        $ret['desc'] = 
$element->docblock->getDesc($this);  
        $ret['see_tags'] = 
$see_tags;  
        $ret['info_tags_sorted'] = 
$info_tags_sorted;  
        $ret['api_tags'] = 
$api_tags;  
        $ret['info_tags'] = 
$info_tags;  
        $ret['property_tags'] = 
$property_tags;  
     * gets a list of all classes declared on a procedural page represented by  
     * $element, a {@link parserData} class  
     * @param parserData &$element   
     * @return array links to each classes documentation  
     *  array('name' => class name,  
     *        'sdesc' => summary of the class  
     *        'link' => link to the class's documentation)  
        global $_phpDocumentor_setting;  
        $a = 
$element->getClasses($this);  
        foreach($a as $package => 
$clas)  
            if (!empty($_phpDocumentor_setting['packageoutput']))  
                $packages = 
explode(',',$_phpDocumentor_setting['packageoutput']);  
                if (!in_array($package, $packages)) continue;  
            for($i=
0; $i<
count($clas); $i++
)  
                if ($this->parseprivate || 
! ($clas[$i]->docblock && 
$clas[$i]->docblock->hasaccess && 
$clas[$i]->docblock->tags['access'][0]->value == 
'private'))  
                    $sdesc = 
$clas[$i]->docblock->getSDesc($this);  
                    if ($clas[$i]->docblock->hasaccess)  
                                            $r['access'] = 
$clas[$i]->docblock->tags['access'][0]->value;  
                                        if (isset 
($clas[$i]->docblock->tags['abstract']))  
                    $r['name'] = 
$clas[$i]->getName();  
                    $r['link'] = 
$this->getClassLink($clas[$i]->getName(),$package,$clas[$i]->getPath());  
     * returns an array containing the class inheritance tree from the root  
     * This method must be overridden, or phpDocumentor will halt with a fatal  
     * @return string Converter-specific class tree for an individual class  
     * @param parserClass    class variable  
     * returns an array containing the class inheritance tree from the root  
     * This method must be overridden, or phpDocumentor will halt with a fatal  
     * @return string Converter-specific class tree for an individual class  
     * @param parserClass    class variable  
        foreach ($el->getImplements() as $interface)  
            $link = 
$this->getLink($interface);  
                        $inter = 
new ReflectionClass($interface);  
                        if ($inter->isInternal()) {  
                            $ret[] = 
$interface . 
' (internal interface)';  
     * @param mixed {@link parserClass, parserFunction, parserDefine} or  
     * @param string type to display.  either 'class','function','define'  
     * @return array links to conflicting elements, or empty array  
     * @uses parserClass::getConflicts()  
     * @uses parserFunction::getConflicts()  
     * @uses parserDefine::getConflicts()  
     * @uses parserGlobal::getConflicts()  
        $conflicts = 
$element->getConflicts($this);  
        if (!$conflicts) return false;  
        foreach($conflicts as $package => 
$class)  
        if (!empty($r)) $r = 
array('conflicttype' => 
$type, 'conflicts' => 
$r);  
     * Get a list of methods in child classes that override this method  
     * @return array empty array or array(array('link'=>link to method,  
     *  'sdesc'=>short description of the method),...)  
     * @uses parserMethod::getOverridingMethods()  
        $meths = 
$element->getOverridingMethods($this);  
        for($i=
0; $i<
count($meths); $i++
)  
            $ms['link'] = 
$meths[$i]->getLink($this);  
            $ms['sdesc'] = 
$meths[$i]->docblock->getSDesc($this);  
     * Get a list of vars in child classes that override this var  
     * @return array empty array or array('link'=>link to var,  
     *  'sdesc'=>short description of the method  
     * @uses parserVar::getOverridingVars()  
        $vars = 
$element->getOverridingVars($this);  
        for($i=
0; $i<
count($vars); $i++
)  
            $vs['link'] = 
$vars[$i]->getLink($this);  
            $vs['sdesc'] = 
$vars[$i]->docblock->getSDesc($this);  
     * Get the method this method overrides, if any  
     * @return array|falsearray('link'=>link to overridden method,  
     *  'sdesc'=>short description  
     * @see parserMethod::getOverrides()  
        $ovr = 
$element->getOverrides($this);  
        $sdesc = 
$ovr->docblock->getSDesc($this);  
        $name = 
method_exists($ovr, 'getFunctionCall') ? 
$ovr->getFunctionCall() : 
$ovr->getName();  
        $link = 
($link = 
$ovr->getLink($this)) ? 
$link : 
$ovr->getClass() . 
'::' . 
$name;  
        return array('link' => 
$link,'sdesc' => 
$sdesc);  
     * Get the method this method(s) implemented from an interface, if any  
     * @return array|falsearray('link'=>link to implemented method,  
     *  'sdesc'=>short description  
     * @uses parserMethod::getImplements()  
        $ovr = 
$element->getImplements($this);  
        foreach ($ovr as $impl) {  
            $sdesc = 
$impl->docblock->getSDesc($this);  
            $name = 
$impl->getName();  
            $link = 
($link = 
$impl->getLink($this)) ? 
$link : 
$impl->getClass() . 
'::' . 
$name;  
            $ret[] = 
array('link' => 
$link,'sdesc' => 
$sdesc);  
     * returns a list of child classes  
     * @param parserClass class variable  
     * @uses parserClass::getChildClassList()  
        $kids = 
$class->getChildClassList($this);  
            for($i=
0; $i<
count($kids); $i++
)  
                $lt['link'] = 
$kids[$i]->getLink($this);  
                $lt['sdesc'] = 
$kids[$i]->docblock->getSDesc($this);  
                                if ($kids[$i]->docblock->hasaccess)  
                                    $lt['access'] = 
$kids[$i]->docblock->tags['access'][0]->value;  
                                    $lt['access'] = 
'public';  
                                $lt['abstract'] = isset 
($kids[$i]->docblock->tags['abstract'][0]);  
     * Return template-enabled list of inherited variables  
     * uses parserVar helper function getInheritedVars and generates a  
     * template-enabled list using getClassLink()  
     * @param parserVar $child class var  
     * @see getClassLink(), parserVar::getInheritedVars()  
     *    array('parent_class' => link to parent class's documentation,  
     *               array('name' => inherited variable name,  
     *                     'link' => link to inherited variable's documentation,  
     *                     'default' => default value of inherited variable,  
     *                     'sdesc' => summary of inherited variable),  
        $package = 
$child->docblock->package;  
        $ivars = 
$child->getInheritedVars($this);  
        if (!count($ivars)) return $results;  
        foreach($ivars as $parent => 
$vars)  
            $par = 
$this->classes->getClass($parent,$file);  
                $package = 
$par->docblock->package;  
            usort($vars,array($this,"sortVar"));  
            $result['parent_class'] = 
$this->getClassLink($parent, $package);  
            if (!$result['parent_class']) {  
                $result['parent_class'] = 
$parent . 
' (Internal Class)';  
                if ($var->docblock->hasaccess) {  
                    $info['access'] = 
$var->docblock->tags['access'][0]->value;  
                    $info['access'] = 
'public';  
                $info['abstract'] = isset 
($var->docblock->tags['abstract'][0]);  
                $info['name'] = 
$var->getName();  
                $info['link'] = 
$var->getLink($this);  
                    $info['link'] = 
$info['name'];  
                $info['default'] = 
$this->postProcess($var->getValue());  
                $info['sdesc'] = 
$var->docblock->getSDesc($this);  
                $result["ivars"][] = 
$info;  
     * Return template-enabled list of inherited methods  
     * uses parserMethod helper function getInheritedMethods and generates a  
     * template-enabled list using getClassLink()  
     * @param parserMethod $child class method  
     * @see getClassLink(), parserMethod::getInheritedMethods()  
     *    array('parent_class' => link to parent class's documentation,  
     *               array('name' => inherited variable name,  
     *                     'link' => link to inherited variable's documentation,  
     *                     'function_call' => {@link parserMethod::getIntricateFunctionCall()}  
     *                     'sdesc' => summary of inherited variable),  
        $package = 
$child->docblock->package;  
        $imethods = 
$child->getInheritedMethods($this);  
        if (!count($imethods)) return $results;  
        foreach($imethods as $parent => 
$methods)  
            $file = 
$methods['file'];  
            $methods = 
$methods['methods'];  
            $par = 
$this->classes->getClass($parent,$file);  
                $package = 
$par->docblock->package;  
            usort($methods,array($this,"sortMethod"));  
            $result['parent_class'] = 
$this->getClassLink($parent,$package);  
            if (!$result['parent_class']) {  
                $result['parent_class'] = 
$parent . 
' (Internal Class)';  
            foreach($methods as $method)  
                if ($method->docblock->hasaccess) {  
                    $info['access'] = 
$method->docblock->tags['access'][0]->value;  
                    $info['access'] = 
'public';  
                $info['abstract'] = isset 
($method->docblock->tags['abstract'][0]);  
                if ($method->isConstructor) $info['constructor'] = 
1;  
                if ($method->isConstructor) {  
                    $returntype = 
$method->getClass();  
                if ($method->docblock->return) {  
                    $a = 
$method->docblock->return->Convert($this);  
                    $returntype = 
$method->docblock->return->converted_returnType;  
                $info['function_return'] = 
$returntype;  
                $info['static'] = isset 
($method->docblock->tags['static'][0]);  
                $info['link'] = 
$method->getLink($this);  
                    $info['link'] = 
$method->getFunctionCall();  
                $info['name'] = 
$method->getName();  
                $info['sdesc'] = 
$method->docblock->getSDesc($this);  
                if (count($method->docblock->params))  
                foreach($method->docblock->params as $param => 
$val)  
                    $params[$param] = 
array("var" => 
$param,"datatype" => 
$val->converted_returnType,"data" => 
$a);  
                $info['function_call'] = 
$method->getIntricateFunctionCall($this,$params);  
                $result["imethods"][] = 
$info;  
     * Return template-enabled list of inherited class constants  
     * uses parserConst helper function getInheritedConsts and generates a  
     * template-enabled list using getClassLink()  
     * @param parserConst $child class constant  
     * @see getClassLink(), parserMethod::getInheritedConsts()  
     *    array('parent_class' => link to parent class's documentation,  
     *               array('name' => inherited constant name,  
     *                     'link' => link to inherited constant's documentation,  
     *                     'value' => constant value,  
     *                     'sdesc' => summary of inherited constant),  
        $package = 
$child->docblock->package;  
        $ivars = 
$child->getInheritedConsts($this);  
        if (!count($ivars)) return $results;  
        foreach($ivars as $parent => 
$vars)  
            $par = 
$this->classes->getClass($parent,$file);  
                $package = 
$par->docblock->package;  
            usort($vars,array($this,"sortVar"));  
            $result['parent_class'] = 
$this->getClassLink($parent,$package);  
            if (!$result['parent_class']) {  
                $result['parent_class'] = 
$parent . 
' (Internal Class)';  
                if ($var->docblock->hasaccess) {  
                    $info['access'] = 
$var->docblock->tags['access'][0]->value;  
                    $info['access'] = 
'public';  
                $info['name'] = 
$var->getName();  
                $info['link'] = 
$var->getLink($this);  
                    $info['link'] = 
$info['name'] . 
' = ' . 
$var->getValue();  
                $info['sdesc'] = 
$var->docblock->getSDesc($this);  
                $result["iconsts"][] = 
$info;  
     * Return a Smarty template object to operate with  
     * This returns a Smarty template with pre-initialized variables for use.  
     * If the method "SmartyInit()" exists, it is called.  
        $templ->use_sub_dirs = 
false;  
            // we'll delete this on finishing conversion  
            $this->_compiledDir[$this->targetDir . 
DIRECTORY_SEPARATOR . 
md5($templatename)] = 
1;  
        $templ->assign("date",date("r",time()));  
        $templ->assign("maintitle",$this->title);  
        $templ->assign('default_package',$GLOBALS['phpDocumentor_DefaultPackageName']);  
        $templ->assign("package",$this->package);  
        if (method_exists($this,'SmartyInit')) return $this->SmartyInit($templ);  
     * Finish up parsing/cleanup directories  
        foreach ($this->_compiledDir as $dir => 
$one) {  
     * Completely remove a directory and its contents  
     * @param string $directory   
            while (false !== 
($file = 
readdir($handle))) {  
                if ($file == 
'.' || 
$file == 
'..') {  
                if (is_dir($directory . 
DIRECTORY_SEPARATOR . 
$file)) {  
                    $this->_rmdir($directory . 
DIRECTORY_SEPARATOR . 
$file);  
                @unlink($directory . 
DIRECTORY_SEPARATOR . 
$file);  
     * do all necessary output  
        phpDocumentor_out("WARNING: Generic Converter::Output was used, no output will be generated");  
     * Set the template directory with a different template base directory  
     * @tutorial phpDocumentor.howto.pkg#using.command-line.templatebase  
     * @param string template base directory  
     * @param string template name  
        // remove trailing /'s from the base path, if any  
            // retrieve template options, allow array creation  
     * sets the template directory based on the {@link $outputformat} and {@link $name}  
     * Also sets {@link $templateName} to the $dir parameter  
     * @param string subdirectory  
        if (isset
($GLOBALS['_phpDocumentor_template_base'])) {  
            $templateBase = 
str_replace('\\', '/', $GLOBALS['_phpDocumentor_template_base']);  
        } else if ('@DATA-DIR@' != 
'@'.
'DATA-DIR@') {  
            $templateBase = 
str_replace('\\', '/', '@DATA-DIR@/PhpDocumentor/phpDocumentor');  
            $templateBase = 
str_replace('\\','/',$GLOBALS['_phpDocumentor_install_dir']) . 
'/phpDocumentor';  
     * Get the absolute path to the converter's base directory  
        if ('@DATA-DIR@' != 
'@' . 
'DATA-DIR@') {  
            return str_replace('\\', '/', "@DATA-DIR@/PhpDocumentor/phpDocumentor/Converters/") . 
$this->outputformat . 
"/" . 
$this->name;  
            return str_replace('\\','/',$GLOBALS['_phpDocumentor_install_dir']) .
"/phpDocumentor/Converters/" . 
$this->outputformat . 
"/" . 
$this->name;  
     * Parse a global variable's default value for class initialization.  
     * If a global variable's default value is "new class" as in:  
     * $globalvar = new Parser  
     * This method will document it not as "new Parser" but instead as  
     * "new {@link Parser}".    For examples, see {@link phpdoc.inc}.  
     * Many global variables are classes, and phpDocumentor links to their  
     * @return string default global variable value with link to class if  
     * @param string default value of a global variable.  
        if (strpos($value,'new') === 
0)  
            preg_match('/new([^(]*)((?:.|\r|\n)*)/',$value,$newval);  
                if (!isset
($newval[2])) $newval[2] = 
'';  
     * Parse an include's file to see if it is a file documented in this project  
     * Although not very smart yet, this method will try to look for the  
     * included file file.ext:  
     * If it finds it, it will return a link to the file's documentation.  As of  
     * 1.2.0rc1, phpDocumentor is smarty enough to find these cases:  
     *  <li>absolute path to file</li>  
     *  <li>./file.ext or ../file.ext</li>  
     *  <li>relpath/to/file.ext if relpath is a subdirectory of the base parse  
     * For examples, see {@link Setup.inc.php} includes.  
     * Every include auto-links to the documentation for the file that is included  
     * @return string included file with link to docs for file, if found  
     * @param string file included by include statement.  
     * @param string path of file that has the include statement  
        preg_match('/"([^"\']*\.[^"\']*)"/',$value,$match);  
        preg_match('/\'([^"\']*\.[^"\']*)\'/',$value,$match);  
            $fancy_per = 
$this->proceduralpages->pathMatchesParsedFile($match[1],$ipath);  
                $link = 
$this->addLink($fancy_per);  
     * Recursively creates all subdirectories that don't exist in the $dir path  
            $test = 
@mkdir($parent,0775);  
                $test = 
@mkdir($parent,0775);  
     * Sets the output directory for generated documentation  
     * As of 1.3.0RC6, this also sets the compiled templates directory inside  
     * @param string $dir the output directory  
            // if directory does exist create it, this should have more error checking in the future  
                echo 
"Output path: '$dir' is not a directory\n"; 
            echo 
"a target directory must be specified\n try phpdoc -h\n"; 
     * Writes a file to target dir  
     * @param boolean true if the data is binary and not text  
    function writeFile($file,$data,$binary = 
false)  
        if ($binary) $string = 
'binary file ';  
        if ($binary) $write = 
'wb';  
     * Copies a file from the template directory to the target directory  
     * thanks to Robert Hoffmann for this fix  
     * Return parserStringWithInlineTags::Convert() cache state  
     * @see parserStringWithInlineTags::Convert()  
     * Compare parserStringWithInlineTags::Convert() cache state to $state  
     * @see parserStringWithInlineTags::Convert()  
 * @see Converter::getSortedClassTreeFromClass()  
 * @global string used to make the first tutorials converted the default package tutorials  
function tutorialcmp($a, $b)  
    global $phpDocumentor_DefaultPackageName;  
    if ($a == 
$phpDocumentor_DefaultPackageName) return -
1;  
    if ($b == 
$phpDocumentor_DefaultPackageName) return 1;  
 * smart htmlentities, doesn't entity the allowed tags list  
 * Since version 1.1, this function uses htmlspecialchars instead of  
 * htmlentities, for international support  
 * This function has been replaced by functionality in {@link ParserDescCleanup.inc}  
 * @return string browser-displayable page  
 * @deprecated As of v1.2, No longer needed, as valid tags are parsed out of the source,  
 *    and everything else is {@link Converter::postProcess()} handled  
    global $phpDocumentor___html,$_phpDocumentor_html_allowed;  
    $result = 
strtr($result,$phpDocumentor___html);  
    for($i=
0;$i<
count($matches[1]);$i++
)  
    for($i=
0;$i<
count($matches[1]);$i++
)  
    for($i=
0;$i<
count($matches[1]);$i++
)  
    for($i=
0;$i<
count($matches[1]);$i++
)  
    for($i=
0;$i<
count($matches[1]);$i++
)  
    for($i=
0;$i<
count($matches[1]);$i++
)  
 * Used solely for setting up the @uses list  
    function setTemplateDir(){}  
    function setTargetDir(){}  
    function getPageName(&$element)  
        return '_'.
$element->parent->getName();  
 
 
	
		Documentation generated on Mon, 05 Dec 2011 21:53:58 -0600 by phpDocumentor 1.4.4