home *** CD-ROM | disk | FTP | other *** search
/ Enter 2004 June / ENTER.ISO / files / xampp-win32-1.4.5-installer.exe / xampp / XMLDocBookpeardoc2Converter.inc < prev    next >
Encoding:
Text File  |  2004-03-24  |  62.1 KB  |  1,524 lines

  1. <?php
  2. //
  3. // +------------------------------------------------------------------------+
  4. // | phpDocumentor                                                          |
  5. // +------------------------------------------------------------------------+
  6. // | Copyright (c) 2000-2003 Joshua Eichorn, Gregory Beaver                 |
  7. // | Email         jeichorn@phpdoc.org, cellog@phpdoc.org                   |
  8. // | Web           http://www.phpdoc.org                                    |
  9. // | Mirror        http://phpdocu.sourceforge.net/                          |
  10. // | PEAR          http://pear.php.net/package-info.php?pacid=137           |
  11. // +------------------------------------------------------------------------+
  12. // | This source file is subject to version 3.00 of the PHP License,        |
  13. // | that is available at http://www.php.net/license/3_0.txt.               |
  14. // | If you did not receive a copy of the PHP license and are unable to     |
  15. // | obtain it through the world-wide-web, please send a note to            |
  16. // | license@php.net so we can mail you a copy immediately.                 |
  17. // +------------------------------------------------------------------------+
  18. //
  19. /**
  20.  * XML output converter for DocBook.
  21.  * This Converter takes output from the {@link Parser} and converts it to DocBook output
  22.  *
  23.  * @package Converters
  24.  * @subpackage XMLDocBook
  25.  * @see parserDocBlock, parserInclude, parserPage, parserClass, parserDefine, parserFunction, parserMethod, parserVar
  26.  * @author Greg Beaver <cellog@users.sourceforge.net>
  27.  * @since 1.2
  28.  * @version $Id: XMLDocBookpeardoc2Converter.inc,v 1.29.2.10 2003/10/13 03:44:06 CelloG Exp $
  29.  */
  30. /**
  31.  * XML DocBook converter.
  32.  * This Converter takes output from the {@link Parser} and converts it to DocBook
  33.  * output for PEAR documentation.
  34.  *
  35.  * This Converter differs from the parent DocBook Converter in that it does not
  36.  * recognize the possibility of procedural pages or of functions!  All functions
  37.  * must be defined as static methods for namespace purposes.  In addition, all
  38.  * constants and global variables for a package are grouped together as per
  39.  * peardoc2 requirements.  Include statements are not documented.  If you want
  40.  * to document a normal project, don't use the peardoc2 converter, use the
  41.  * DocBook converter.
  42.  * @package Converters
  43.  * @subpackage XMLDocBook
  44.  * @author Greg Beaver <cellog@users.sourceforge.net>
  45.  * @since 1.2
  46.  * @version $Id: XMLDocBookpeardoc2Converter.inc,v 1.29.2.10 2003/10/13 03:44:06 CelloG Exp $
  47.  */
  48. class XMLDocBookpeardoc2Converter extends Converter
  49. {
  50.     /**
  51.      * XMLDocBookConverter wants elements sorted by type as well as alphabetically
  52.      * @see Converter::$sort_page_contents_by_type
  53.      * @var boolean
  54.      */
  55.     var $sort_page_contents_by_type = true;
  56.     /** @var string */
  57.     var $outputformat = 'XML';
  58.     /** @var string */
  59.     var $name = 'DocBook/peardoc2';
  60.     /**
  61.      * indexes of elements by package that need to be generated
  62.      * @var array
  63.      */
  64.     var $leftindex = array('classes' => true, 'pages' => false, 'functions' => false, 'defines' => true, 'globals' => true);
  65.     /**
  66.      * whether a @see is going to be in the {@link $base_dir}, or in a package/subpackage subdirectory of $base_dir
  67.      * @var boolean
  68.      */
  69.     var $local = true;
  70.     
  71.     /**
  72.      * name of current page being converted
  73.      * @var string
  74.      */
  75.     var $page;
  76.     
  77.     /**
  78.      * path of current page being converted
  79.      * @var string
  80.      */
  81.     var $path;
  82.     
  83.     /**
  84.      * name of current class being converted
  85.      * @var string
  86.      */
  87.     var $class;
  88.     
  89.     /**
  90.      * template for the procedural page currently being processed
  91.      * @var Template
  92.      */
  93.     var $page_data;
  94.     
  95.     /**
  96.      * output directory for the current procedural page being processed
  97.      * @var string
  98.      */
  99.     var $page_dir;
  100.  
  101.     /**
  102.      * Constants, used for constants.tpl
  103.      * @var array
  104.      */
  105.     var $_peardoc2_constants = false;
  106.     
  107.     /**
  108.      * Global Variables, used for globals.tpl
  109.      * @var array
  110.      */
  111.     var $_peardoc2_globals = false;
  112.     
  113.     /**
  114.      * target directory passed on the command-line.
  115.      * {@link $targetDir} is malleable, always adding package/ and package/subpackage/ subdirectories onto it.
  116.      * @var string
  117.      */
  118.     var $base_dir;
  119.     
  120.     /**
  121.      * output directory for the current class being processed
  122.      * @var string
  123.      */
  124.     var $class_dir;
  125.     
  126.     /**
  127.      * template for the class currently being processed
  128.      * @var Template
  129.      */
  130.     var $class_data;
  131.     
  132.     /**
  133.      * array of converted package page names.
  134.      * Used to link to the package page in the left index
  135.      * @var array Format: array(package => 1)
  136.      */
  137.     var $package_pages = array();
  138.     
  139.     /**
  140.      * Contents of the packagename.xml file are stored in this template variable
  141.      * @var Smarty
  142.      */
  143.     var $packagexml;
  144.     /**
  145.      * controls formatting of parser informative output
  146.      * 
  147.      * Converter prints:
  148.      * "Converting /path/to/file.php... Procedural Page Elements... Classes..."
  149.      * Since HTMLdefaultConverter outputs files while converting, it needs to send a \n to start a new line.  However, if there
  150.      * is more than one class, output is messy, with multiple \n's just between class file output.  This variable prevents that
  151.      * and is purely cosmetic
  152.      * @var boolean
  153.      */
  154.     var $juststarted = false;
  155.     
  156.     /**
  157.      * contains all of the template procedural page element loop data needed for the current template
  158.      * @var array
  159.      */
  160.     var $current;
  161.     
  162.     /**
  163.      * contains all of the template class element loop data needed for the current template
  164.      * @var array
  165.      */
  166.     var $currentclass;
  167.     
  168.     /** 
  169.      * Pass elements by package, simplifies generation of package.xml/category.xml
  170.      */
  171.     var $sort_absolutely_everything = true;
  172.     /**
  173.      * template options.  Currently only 1 recognized option usepear
  174.      *
  175.      * usepear tells the getLink() function to return a package link to PEAR and PEAR_ERROR if possible, and to link directly
  176.      * to the fully-delimited link package#class.method or package#file.method in PEAR style, if possible, even if the
  177.      * package is not parsed.  This will allow parsing of separate PEAR packages without parsing the entire thing at once!
  178.      * @var array
  179.      */
  180.     var $template_options = array('usepear' => false);
  181.     
  182.     var $function_data = array();
  183.     var $method_data = array();
  184.     var $_write_constants_xml = array();
  185.     var $_write_globals_xml = array();
  186.     var $sourceloc = '';
  187.     /**
  188.      * peardoc2 Category
  189.      * @var string
  190.      */
  191.     var $category;
  192.     /**
  193.      * sets {@link $base_dir} to $targetDir
  194.      * @see Converter()
  195.      */
  196.     function XMLDocBookpeardoc2Converter(&$allp, &$packp, &$classes, &$procpages, $po, $pp, $qm, $targetDir, $templateDir, $title)
  197.     {
  198.         Converter::Converter($allp, $packp, $classes, $procpages,$po, $pp, $qm, $targetDir, $templateDir, $title);
  199.         $this->base_dir = $targetDir;
  200.     }
  201.     
  202.     /**
  203.      * do that stuff in $template_options
  204.      */
  205.     function &getLink($expr, $package = false, $packages = false)
  206.     {
  207.         return Converter::getLink($expr, $package, $packages);
  208.     }
  209.     
  210.     function unmangle($s,$sourcecode)
  211.     {
  212.         return '<programlisting role="php"><![CDATA[
  213. '.$sourcecode.']]></programlisting>';
  214.     }
  215.     
  216.     function type_adjust($typename)
  217.     {
  218.         if (isset($this->template_options['typechanging'][trim($typename)]))
  219.         return $this->template_options['typechanging'][trim($typename)];
  220.         $a = $this->getLink($typename);
  221.         if (is_object($a))
  222.         {
  223.             if (get_class($a) == 'classlink')
  224.             return '<classname>'.$typename.'</classname>';
  225.             if (get_class($a) == 'functionlink' || get_class($a) == 'methodlink')
  226.             return '<function>'.$typename.'</function>';
  227.             if (get_class($a) == 'definelink')
  228.             return '<constant>'.$typename.'</constant>';
  229.             if (get_class($a) == 'varlink')
  230.             return '<varname>'.$typename.'</varname>';
  231.         }
  232.         return $typename;
  233.     }
  234.     
  235.     /**
  236.      * Writes out the template file of {@link $class_data} and unsets the template to save memory
  237.      * @see registerCurrentClass()
  238.      * @see parent::endClass()
  239.      * @todo move class summary into an array to be written out at the end
  240.      *       of parsing each package
  241.      */
  242.     function endClass()
  243.     {
  244.         $a = '../';
  245.         if (!empty($this->subpackage)) $a .= '../';
  246.         if ($this->juststarted)
  247.         {
  248.             $this->juststarted = false;
  249.             phpDocumentor_out("\n");
  250.             flush();
  251.         }
  252.         foreach($this->method_data as $func)
  253.         {
  254.             $func[0]->assign("phpdocversion",PHPDOCUMENTOR_VER);
  255.             $func[0]->assign("phpdocwebsite",PHPDOCUMENTOR_WEBSITE);
  256.             $this->setTargetDir($this->base_dir . PATH_DELIMITER . strtolower($this->category) . PATH_DELIMITER . strtolower($this->class_dir . PATH_DELIMITER . str_replace(array('_','.'),array('-','--'),$this->class)));
  257.             $this->writefile(strtolower($func[1] ). '.xml','<!-- $' . "Revision$ -->\n" . $func[0]->fetch('method.tpl'));
  258.         }
  259.         // code below is in packagename.xml handling, see Output()
  260. /*        $this->setTargetDir($this->base_dir . PATH_DELIMITER . strtolower($this->category) . PATH_DELIMITER . strtolower($this->class_dir));
  261.         $this->writefile(str_replace(array('_','.'),array('-','--'),strtolower($this->class)) . '.xml',$this->class_data->fetch('class.tpl'));*/
  262.         unset($this->class_data);
  263.     }
  264.     
  265.     function addSummaryToPackageXml($template_output)
  266.     {
  267.         $this->packagexml->append('ids',$template_output);
  268.     }
  269.     
  270.     /**
  271.      * @param parserClass|false $element is false if this is the end of all conversion
  272.      */
  273.     function flushPackageXml($element)
  274.     {
  275.         if (isset($this->packagexml))
  276.         {
  277.             if ($element->docblock->package != $this->package || !$element) // finished with package
  278.             {
  279.                 if (isset($this->_write_constants_xml[$this->category][$this->package]) &&
  280.                     $this->_write_constants_xml[$this->category][$this->package])
  281.                 {
  282.                     $this->packagexml->append('ids',
  283.                         '&package.' .
  284.                          strtolower($this->category.'.' .
  285.                          str_replace(array('_','.'),array('-','--'),$this->package).'.constants;'));
  286.                     $this->_write_constants_xml[$this->category][$this->package] = false;
  287.                 }
  288.                 if (isset($this->_write_globals_xml[$this->category][$this->package]) &&
  289.                     $this->_write_globals_xml[$this->category][$this->package])
  290.                 {
  291.                     $this->packagexml->append('ids',
  292.                             '&package.'.strtolower($this->category.'.' . 
  293.                              str_replace(array('_','.'),array('-','--'),$this->package).'.globals;'));
  294.                     $this->_write_globals_xml[$this->category][$this->package] = false;
  295.                 }
  296.                 $this->setTargetDir($this->base_dir . PATH_DELIMITER . strtolower($this->category));
  297.                 $this->writefile(str_replace('_','-',strtolower($this->package)).'.xml',
  298.                     '<!-- $' . "Revision$ -->\n" . $this->packagexml->fetch('package.tpl'));
  299.                 $this->packagexml->clear_all_assign();
  300.                 $this->packagexml->assign('package',$element->docblock->package);
  301.                 $this->packagexml->assign('ids',array());
  302.                 $this->packagexml->assign('id',$this->getId($element, true));
  303.             }
  304.         } else
  305.         {
  306.             $this->packagexml = $this->newSmarty();
  307.             $this->packagexml->assign('package',$element->docblock->package);
  308.             $this->packagexml->assign('ids',array());
  309.             $this->packagexml->assign('id',$this->getId($element, true));
  310.         }
  311.     }
  312.     
  313.     /**
  314.      * @param string
  315.      * @param string
  316.      * @return string <ulink url="'.$link.'">'.$text.'</ulink>
  317.      */
  318.     function returnLink($link,$text)
  319.     {
  320.         return '<ulink url="'.$link.'">'.$text.'</ulink>';
  321.     }
  322.     
  323.     function makeLeft()
  324.     {
  325.     }
  326.     
  327.     /**
  328.      * Does nothing
  329.      */
  330.     function formatPkgIndex()
  331.     {
  332.     }
  333.     
  334.     /**
  335.      * Does nothing
  336.      */
  337.     function formatIndex()
  338.     {
  339.     }
  340.  
  341.     /**
  342.      * Does nothing
  343.      */
  344.     function writeNewPPage($key)
  345.     {
  346.     }
  347.     
  348.     /**
  349.      * Does nothing
  350.      */
  351.     function writeSource()
  352.     {
  353.     }
  354.     
  355.     /**
  356.      * Creates package/lang/categoryname/packagename.xml for each package
  357.      */
  358.     function formatLeftIndex()
  359.     {
  360.         $this->makeLeft();
  361.     }
  362.     
  363.     function getExampleLink()
  364.     {
  365.         return '';
  366.     }
  367.     
  368.     /**
  369.      * This function takes an {@link abstractLink} descendant and returns an html link
  370.      *
  371.      * @param abstractLink a descendant of abstractlink should be passed, and never text
  372.      * @param string text to display in the link
  373.      * @param boolean this parameter is not used, and is deprecated
  374.      * @param boolean determines whether the returned text is enclosed in an <link> tag
  375.      */
  376.     function returnSee(&$element, $eltext = false, $local = true, $with_a = true)
  377.     {
  378.         if (!$element) return false;
  379.         if (!$eltext)
  380.         {
  381.             $eltext = '';
  382.             switch($element->type)
  383.             {
  384.                 case 'tutorial' :
  385.                 $eltext = $element->title;
  386.                 break;
  387.                 case 'class' :
  388.                 $eltext = '<classname>'.$element->name.'</classname>';
  389.                 break;
  390.                 case 'method' :
  391.                 $eltext .= '<function>';
  392.                 case 'var' :
  393.                 if ($element->type == 'var') $eltext .= '<varname>';
  394.                 $eltext .= $element->class.'::';
  395.                 case 'page' :
  396.                 case 'define' :
  397.                 if ($element->type == 'define')
  398.                 $eltext .= '<constant>';
  399.                 case 'function' :
  400.                 if ($element->type == 'function')
  401.                 $eltext .= '<function>';
  402.                 case 'global' :
  403.                 default :
  404.                 $eltext .= $element->name;
  405.                 if ($element->type == 'function' || $element->type == 'method') $eltext .= '</function>';
  406.                 if ($element->type == 'var') $eltext .= '</varname>';
  407.                 if ($element->type == 'define') $eltext .= '</constant>';
  408.                 break;
  409.             }
  410.         } elseif ($element->type == 'method')
  411.         {
  412.             $eltext = str_replace($element->name . '()', $element->name, $eltext);
  413.         }
  414.  
  415.         if ($element->type == 'page' || $element->type == 'function' || $element->type == 'var')
  416.         { // we ignore all procedural pages, instead, constant, function and
  417.           // global variable pages are output
  418.             return $eltext;
  419.         }
  420.         if ($element->type == 'class')
  421.         {
  422.             return '<link linkend="'.$this->getId($element).'-summary">'.$eltext.'</link>';
  423.         }
  424.         return '<link linkend="'.$this->getId($element).'">'.$eltext.'</link>';
  425.     }
  426.     
  427.     /**
  428.      * Get the id value needed to allow linking
  429.      * @param mixed descendant of parserElement or parserData/parserPage
  430.      * @param boolean true to return the id for the package page
  431.      * @see parserElement, parserData, parserPage
  432.      * @return string the id value for this element type
  433.      */
  434.     function getId(&$el, $returnpackage = false)
  435.     {
  436.         if (get_class($el) == 'parserdata')
  437.         {
  438.             $element = $this->addLink($el->parent);
  439.             $elp = $el->parent;
  440.         } elseif (!is_a($el,'abstractlink'))
  441.         {
  442.             $elp = $el;
  443.             $element = $this->addLink($el);
  444.         } else $element = $el;
  445.         $a = '';
  446.         if (!empty($element->subpackage))
  447.         {
  448.             $a = str_replace(array('_','.'),array('-','--'),$element->subpackage).'.';
  449.         }
  450.         if ($returnpackage) return 'package.'.strtolower($element->category.'.'.str_replace(array('_','.'),array('-','--'),$element->package));
  451.         switch ($element->type)
  452.         {
  453.             case 'page' :
  454.             return 'package.'.strtolower($element->category.'.'.str_replace(array('_','.'),array('-','--'),$element->package).'.'.$a.$element->fileAlias);
  455.             break;
  456.             case 'define' :
  457.             return 'package.'.strtolower($element->category.'.'.str_replace(array('_','.'),array('-','--'),$element->package).'.constants.details.'.$element->fileAlias);
  458.             break;
  459.             case 'global' :
  460.             return 'package.'.strtolower($element->category.'.'.str_replace(array('_','.'),array('-','--'),$element->package).'.globals.details.'.$element->fileAlias);
  461.             break;
  462.             case 'class' :
  463.             return 'package.'.strtolower($element->category.'.'.str_replace(array('_','.'),array('-','--'),$element->package).'.'.$a.str_replace(array('_','.'),array('-','--'),$element->name));
  464.             break;
  465.             case 'function' :
  466.             return 'package.'.strtolower($element->category.'.'.str_replace(array('_','.'),array('-','--'),$element->package).'.'.$a.$element->fileAlias.'.'.str_replace('_','-',$element->name));
  467.             break;
  468.             case 'method' :
  469.             return 'package.'.strtolower($element->category.'.'.str_replace(array('_','.'),array('-','--'),$element->package).'.'.$a.str_replace(array('_','.'),array('-','--'),$element->class).'.'.str_replace('_','-',$element->name));
  470.             break;
  471.             case 'var' :
  472.             return 'package.'.strtolower($element->category.'.'.str_replace(array('_','.'),array('-','--'),$element->package).'.'.$a.str_replace(array('_','.'),array('-','--'),$element->class).'-summary.vars.'.str_replace(array('$','_'),array('var--','-'),$element->name));
  473.             break;
  474.             case 'tutorial' :
  475.             return 'package.'.strtolower($element->category.'.'.str_replace(array('_','.'),array('-','--'),$element->package).'.'.$a.str_replace(array('_','.'),array('-','--'),$element->name)).'-tutorial';
  476.             break;
  477.         }
  478.     }
  479.  
  480.     /**
  481.      * Create errors.html template file output
  482.      *
  483.      * This method takes all parsing errors and warnings and spits them out ordered by file and line number.
  484.      * @global ErrorTracker We'll be using it's output facility
  485.      */
  486.     function ConvertErrorLog()
  487.     {
  488.         global $phpDocumentor_errors;
  489.         $allfiles = array();
  490.         $files = array();
  491.         $warnings = $phpDocumentor_errors->returnWarnings();
  492.         $errors = $phpDocumentor_errors->returnErrors();
  493.         $template = &$this->newSmarty();
  494.         foreach($warnings as $warning)
  495.         {
  496.             $file = '##none';
  497.             $linenum = 'Warning';
  498.             if ($warning->file)
  499.             {
  500.                 $file = $warning->file;
  501.                 $allfiles[$file] = 1;
  502.                 $linenum .= ' on line '.$warning->linenum;
  503.             }
  504.             $files[$file]['warnings'][] = array('name' => $linenum, 'listing' => $warning->data);
  505.         }
  506.         foreach($errors as $error)
  507.         {
  508.             $file = '##none';
  509.             $linenum = 'Error';
  510.             if ($error->file)
  511.             {
  512.                 $file = $error->file;
  513.                 $allfiles[$file] = 1;
  514.                 $linenum .= ' on line '.$error->linenum;
  515.             }
  516.             $files[$file]['errors'][] = array('name' => $linenum, 'listing' => $error->data);
  517.         }
  518.         $i=1;
  519.         $af = array();
  520.         foreach($allfiles as $file => $num)
  521.         {
  522.             $af[$i++] = $file;
  523.         }
  524.         $allfiles = $af;
  525.         usort($allfiles,'strnatcasecmp');
  526.         $allfiles[0] = "Post-parsing";
  527.         foreach($allfiles as $i => $a)
  528.         {
  529.             $allfiles[$i] = array('file' => $a);
  530.         }
  531.         $out = array();
  532.         foreach($files as $file => $data)
  533.         {
  534.             if ($file == '##none') $file = 'Post-parsing';
  535.             $out[$file] = $data;
  536.         }
  537.         $template->assign("files",$allfiles);
  538.         $template->assign("all",$out);
  539.         $template->assign("title","phpDocumentor Parser Errors and Warnings");
  540.         $this->setTargetDir($this->base_dir);
  541.         $this->writefile("errors.html",$template->fetch('errors.tpl'));
  542.         unset($template);
  543.         phpDocumentor_out("\n\nTo view errors and warnings, look at ".$this->base_dir. PATH_DELIMITER . "errors.html\n");
  544.         flush();
  545.     }
  546.     
  547.     function postProcess($text)
  548.     {
  549.         return str_replace("'", ''', htmlentities($text));
  550.     }
  551.  
  552.     function prepareDocBlock(&$element, $nopackage = true)
  553.     {
  554.         $a = new parserStringWithInlineTags;
  555.         $a->add('no exceptions thrown');
  556.         if (!$element->docblock->getKeyword('throws')) $element->docblock->addKeyword('throws',$a);
  557.         $tags = parent::prepareDocBlock($element,
  558.                 array('staticvar' => 'note','deprec' => 'deprecated',
  559.                       'abstract' => 'abstract','TODO' => 'note', 'link' => 'see',
  560.                       'uses' => 'see', 'usedby' => 'see', 'tutorial' => 'see',
  561.                       'return' => 'returns', 'access' => false), $nopackage);
  562.         $ret = array();
  563.         foreach($tags['tags'] as $tag)
  564.         {
  565.             if ($tag['keyword'] == 'return')
  566.             {
  567.                 // hack because stupid Converter isn't doing its job
  568.                 $tag['keyword'] = 'returns';
  569.             }
  570.             $ret[$tag['keyword']][] = $tag;
  571.         }
  572.         $tags['tags'] = $ret;
  573.         $tags['sdesc'] = $this->wordwrap($tags['sdesc']);
  574.         return $tags;
  575.     }
  576.     
  577.     function getTutorialId($package,$subpackage,$tutorial,$id,$category)
  578.     {
  579.         $subpackage = (empty($subpackage) ? '' : '.'.$subpackage);
  580.         $id = (empty($id) ? '' : '.'.$id);
  581.         return 'package.'.strtolower($category.'.'.$package.$subpackage.str_replace(array('_','.'),array('-','--'),$tutorial).$id);
  582.     }
  583.     
  584.     
  585.     /**
  586.      * Retrieve a Converter-specific anchor to a segment of a source code file
  587.      * parsed via a {@tutorial tags.filesource.pkg} tag.
  588.      *
  589.      * NOTE: unused
  590.      * @param string full path to source file
  591.      * @param string name of anchor
  592.      * @param string link text, if this is a link
  593.      * @param boolean returns either a link or a destination based on this
  594.      *                parameter
  595.      * @return string link to an anchor, or the anchor
  596.      */
  597.     function getSourceAnchor($sourcefile,$anchor,$text = '',$link = false)
  598.     {
  599.         return '';
  600.     }
  601.     
  602.     function Br($input)
  603.     {
  604.         return "$input\n";
  605.     }
  606.  
  607.     function getCData($value)
  608.     {
  609.         return '<!CDATA['.$value.']]>';
  610.     }
  611.     
  612.     function ProgramExample($listing, $tutorial = false, $inlinesourceparse = null/*false*/,
  613.                             $class = null/*false*/, $linenum = null/*false*/, $filesourcepath = null/*false*/)
  614.     {
  615.         if (!tokenizer_ext)
  616.         {
  617.             $listing = $this->getCData($listing);
  618.         }
  619.         return parent::ProgramExample($listing, false, $inlinesourceparse, $class, $linenum, $filesourcepath);
  620.     }
  621.     
  622.     /**
  623.      * Does nothing - use tutorials for DocBook
  624.      * @param parserPackagePage
  625.      */
  626.     function convertPackagePage(&$element)
  627.     {
  628.     }
  629.     
  630.     /**
  631.      * Convert tutorials for output
  632.      * @param parserTutorial
  633.      */
  634.     function convertTutorial(&$element)
  635.     {
  636.         $template = &parent::convertTutorial($element);
  637.         phpDocumentor_out("\n");
  638.         flush();
  639.         $x = $element->Convert($this,false);
  640.         if ($element->ini)
  641.         { // add child tutorial list to the tutorial through a slight hack :)
  642.             $subtutorials = '';
  643.             $b = '';
  644.             if (!empty($element->subpackage)) $b = '.'.$element->subpackage;
  645.             foreach($element->ini['Linked Tutorials'] as $child)
  646.             {
  647.                 $subtutorials .= '      &'.$element->category.'.'.$element->package.$b.'.'.str_replace(array('_','.'),array('-','--'),$child).'-'.$element->tutorial_type."-tutorial;\n";
  648.             }
  649.             $x = str_replace('</refsect1></refentry>','</refsect1>
  650.     <refsect1>
  651.      <title>Related Docs</title>
  652.      <para>
  653. '.$subtutorials.
  654. '     </para>
  655.     </refsect1></refentry>',$x);
  656.         }
  657.         $template->assign('contents',$x);
  658.         $contents = $template->fetch('tutorial.tpl');
  659.         $a = '';
  660.         if ($element->subpackage) $a = PATH_DELIMITER . $element->subpackage;
  661.         phpDocumentor_out("\n");
  662.         flush();
  663.         $this->setTargetDir($this->base_dir . PATH_DELIMITER . strtolower($element->category) . PATH_DELIMITER . strtolower($element->package . $a));
  664.         $this->writeFile(str_replace(array('_','.'),array('-','--'),strtolower($element->name)).'-tutorial.xml',
  665.             '<!-- $' . "Revision$ -->\n" . $contents);
  666.     }
  667.     
  668.     /**
  669.      * Does nothing in this converter
  670.      * @param parserVar
  671.      */
  672.     function convertVar(&$element)
  673.     {
  674.         return;
  675.         $docblock = $this->prepareDocBlock($element);
  676.         $b = 'mixed';
  677.         if ($element->docblock->var)
  678.         {
  679.             $b = $element->docblock->var->converted_returnType;
  680.         }
  681. //        var_dump($this->getFormattedOverrides($element));
  682.         if (isset($this->template_options['separatepage']) && $this->template_options['separatepage'])
  683.         $this->class_summary->append('vars',array('sdesc' => $docblock['sdesc'],
  684.                                                'desc' => $docblock['desc'],
  685.                                                'tags' => $docblock['tags'],
  686.                                                'var_name' => $this->type_adjust($element->getName()),
  687.                                                'var_default' => htmlspecialchars($element->getValue()),
  688.                                                'var_type' => $b,
  689.                                                'var_overrides' => $this->getFormattedOverrides($element),
  690.                                                'line_number' => $element->getLineNumber(),
  691.                                                'id' => $this->getId($element)));
  692.         else
  693.         $this->class_data->append('vars',array('sdesc' => $docblock['sdesc'],
  694.                                                'desc' => $docblock['desc'],
  695.                                                'tags' => $docblock['tags'],
  696.                                                'var_name' => $this->type_adjust($element->getName()),
  697.                                                'var_default' => htmlspecialchars($element->getValue()),
  698.                                                'var_type' => $b,
  699.                                                'var_overrides' => $this->getFormattedOverrides($element),
  700.                                                'line_number' => $element->getLineNumber(),
  701.                                                'id' => $this->getId($element)));
  702.     }
  703.     
  704.     /**
  705.      * Converts class for template output
  706.      * @param parserClass
  707.      * @uses flushPackageXml() creates packagename.xml file when all classes in
  708.      *       a package have been converted
  709.      */
  710.     function convertClass(&$element)
  711.     {
  712.         $this->flushPackageXml($element);
  713.         parent::convertClass($element);
  714.         $docblock = $this->prepareDocBlock($element);
  715.         $this->method_data = array();
  716.         $this->class_dir = str_replace(array('_','.'),array('-','--'),$element->docblock->package);
  717.         $this->package = $element->docblock->package;
  718.         $this->category = strtolower($element->docblock->category);
  719.         if (!empty($element->docblock->subpackage)) $this->class_dir .= PATH_DELIMITER . $element->docblock->subpackage;
  720.         $docblock = $this->prepareDocBlock($element,false);
  721.         
  722.         $this->class_data->assign("sdesc",$docblock['sdesc']);
  723.         $this->class_data->assign("desc",$docblock['desc']);
  724.         $this->class_data->assign("tags",$docblock['tags']);
  725.  
  726.         $this->class_data->assign("source_location",$element->getSourceLocation($this,$this->template_options['usepear']));
  727.         $this->class_data->assign("id",$this->getId($element));
  728.         $this->class_data->assign("method_ids",array());
  729.         $this->left[$this->package][] = array('link' => $this->getId($element).'-summary');
  730.         if ($t = $element->getTutorial())
  731.         {
  732.             $this->class_data->append("method_ids",$this->getId($t));
  733.         }
  734.  
  735.         if (isset($this->template_options['separatepage']) && $this->template_options['separatepage'])
  736.         {
  737.             $this->class_summary = &$this->newSmarty(true);
  738.             if ($t = $element->getTutorial())
  739.             {
  740.                 $this->class_summary->assign("tutorial",$this->returnSee($t));
  741.             }
  742.  
  743.             $this->class_summary->assign("class_name",$this->type_adjust($element->getName()));
  744.             $this->class_summary->assign("sdesc",$docblock['sdesc']);
  745.             $this->class_summary->assign("desc",$docblock['desc']);
  746.             $this->class_summary->assign("tags",$docblock['tags']);
  747.             $this->class_summary->assign("vars",array());
  748.             $this->class_summary->assign("methods",array());
  749.             $this->class_summary->assign("package",$element->docblock->package);
  750.  
  751.             $this->class_summary->assign("children", $this->generateChildClassList($element));
  752.             $this->class_summary->assign("class_tree", $this->generateFormattedClassTree($element));
  753.             $this->class_summary->assign("conflicts", $this->getFormattedConflicts($element,"classes"));
  754.         
  755.             $this->class_summary->assign("source_location",$element->getSourceLocation($this,$this->template_options['usepear']));
  756.             $this->class_summary->assign("id",$this->getId($element).'-summary');
  757.             $this->class_data->append("method_ids",$this->getId($element).'.'.strtolower(str_replace('_','-',$element->getName())).'-summary');
  758.             $inherited_methods = $this->getFormattedInheritedMethods($element);
  759.             if (!empty($inherited_methods))
  760.             {
  761.                 $this->class_summary->assign("imethods",$inherited_methods);
  762.             }
  763.             $inherited_vars = $this->getFormattedInheritedVars($element);
  764.             // variables are irrelevant in peardoc2
  765.             if (false)//!empty($inherited_vars))
  766.             {
  767.                 $this->class_summary->assign("ivars",$inherited_vars);
  768.             }
  769.             $this->addSummaryToPackageXml($this->class_summary->fetch('class_summary.tpl'));
  770.         }
  771.         $this->sourceloc = $element->getSourceLocation($this,$this->template_options['usepear']);
  772.     }
  773.     
  774.     /**
  775.      * Converts method for template output
  776.      * @see prepareDocBlock(), parserMethod::getFunctionCall(), getFormattedDescMethods(), getFormattedOverrides()
  777.      * @param parserMethod
  778.      */
  779.     function convertMethod(&$element)
  780.     {
  781.         $docblock = $this->prepareDocBlock($element);
  782.         $returntype = 'void';
  783.         if ($element->docblock->return)
  784.         {
  785.             $a = $element->docblock->return->Convert($this);
  786.             $returntype = $element->docblock->return->converted_returnType;
  787.             if ($returntype != $element->docblock->return->returnType)
  788.             {
  789.                 $returntype = "<replaceable>$returntype</replaceable>";
  790.             }
  791.         }
  792.         $params = array();
  793.         if (count($element->docblock->params))
  794.         foreach($element->docblock->params as $param => $val)
  795.         {
  796.             $a = $val->Convert($this);
  797.             $b = explode(' ',$a);
  798.             $c = '';
  799.             foreach($b as $blah) {
  800.                 if (!empty($c)) {
  801.                     $c .= ' ';
  802.                 }
  803.                 $c .= str_replace(array('true', 'false', 'null'), array('&true;', '&false;', '&null;'), $blah);
  804.             }
  805.             $params[$param] = array("var" => $param,"datatype" => str_replace(array('true', 'false', 'null'), array('&true;', '&false;', '&null;'), 
  806.                 $val->returnType), "cdatatype" => $val->converted_returnType,"data" => $this->wordwrap($c));
  807.         }
  808.  
  809.         $call = $element->getIntricateFunctionCall($this, $params);
  810.         if (isset($call['params']))
  811.         {
  812.             foreach($call['params'] as $i => $param)
  813.             {
  814.                 if (!is_string($call['params'][$i]['default']))
  815.                 {
  816.                     continue;
  817.                 }
  818.                 $call['params'][$i]['default'] = str_replace(array('true', 'false', 'null'), array('&true;', '&false;', '&null;'), $param['default']);
  819.             }
  820.         }
  821.         $this->packagexml->append('ids','&'.$this->getId($element).';');
  822.         $this->class_data->append('method_ids',$this->getId($element));
  823.         $this->class_summary->append('methods',array('id' => $this->getId($element),
  824.                                                   'sdesc' => $docblock['sdesc'],
  825.                                                   'desc' => $docblock['desc'],
  826.                                                   'tags' => $docblock['tags'],
  827.                                                   'is_constructor' => $element->isConstructor,
  828.                                                   'function_name' => $element->getName(),
  829.                                                   'function_return' => $returntype,
  830.                                                   'function_call' => $call,
  831.                                                   'descmethod' => $this->getFormattedDescMethods($element),
  832.                                                   'method_overrides' => $this->getFormattedOverrides($element),
  833.                                                   'line_number' => $element->getLineNumber(),
  834.                                                   'params' => $params));
  835.         $this->method_data[$i = count($this->method_data) - 1][0] = &$this->newSmarty(true);
  836.         $this->method_data[$i][1] = $element->getName();
  837.         $this->method_data[$i][0]->assign('class',$this->class);
  838.         $this->method_data[$i][0]->assign('source_location',$this->returnSee($this->getLink(basename($this->curpage->getFile())),$this->sourceloc));
  839.         $this->method_data[$i][0]->assign('sdesc',$docblock['sdesc']);
  840.         $this->method_data[$i][0]->assign('desc',$docblock['desc']);
  841.         $this->method_data[$i][0]->assign('tags',$docblock['tags']);
  842.         $this->method_data[$i][0]->assign('function_name',$element->getName());
  843.         $this->method_data[$i][0]->assign('function_return',$returntype);
  844.         $this->method_data[$i][0]->assign('function_call',$call);
  845.         $this->method_data[$i][0]->assign('descmethod',$this->getFormattedDescMethods($element));
  846.         $this->method_data[$i][0]->assign('method_overrides',$this->getFormattedOverrides($element));
  847.         $this->method_data[$i][0]->assign('params',$params);
  848.         $this->method_data[$i][0]->assign('id',$this->getId($element));
  849.     }
  850.     
  851.     /**
  852.      * Converts function for template output - does nothing in peardoc2!
  853.      * @param parserFunction
  854.      */
  855.     function convertFunction(&$element)
  856.     {
  857. /*        parent::convertFunction($element);
  858.         $docblock = $this->prepareDocBlock($element);
  859.         $fname = $element->getName();
  860.         $params = array();
  861.         if (count($element->docblock->params))
  862.         foreach($element->docblock->params as $param => $val)
  863.         {
  864.             $a = $val->Convert($this);
  865.             $params[$param] = array("var" => $param,"datatype" => $val->converted_returnType,"data" => $a);
  866.         }
  867.         $returntype = 'void';
  868.         if ($element->docblock->return)
  869.         {
  870.             $a = $element->docblock->return->Convert($this);
  871.             $returntype = $element->docblock->return->converted_returnType;
  872.         }
  873.  
  874.         $this->page_data->append("function_ids",$this->getId($element));
  875.         $this->page_summary->append("function_ids",$this->getId($element));
  876.         $this->page_summary->append('functions',array('id' => $this->getId($element),
  877.                                                    'sdesc' => $docblock['sdesc'],
  878.                                                    'desc' => $docblock['desc'],
  879.                                                    'tags' => $docblock['tags'],
  880.                                                    'function_name' => $element->getName(),
  881.                                                    'line_number' => $element->getLineNumber(),
  882.                                                    'function_return' => $returntype,
  883.                                                    'function_call' => $element->getIntricateFunctionCall($this,$params),
  884.                                                    'function_conflicts' => $this->getFormattedConflicts($element,'functions'),
  885.                                                    'params' => $params));
  886.         $this->function_data[$i = count($this->function_data) - 1][0] = $this->newSmarty(true);
  887.         $this->function_data[$i][1] = $element->getName();
  888.         $this->function_data[$i][0]->assign('sdesc',$docblock['sdesc']);
  889.         $this->function_data[$i][0]->assign('desc',$docblock['desc']);
  890.         $this->function_data[$i][0]->assign('tags',$docblock['tags']);
  891.         $this->function_data[$i][0]->assign('function_name',$fname);
  892.         $this->function_data[$i][0]->assign('line_number',$element->getLineNumber());
  893.         $this->function_data[$i][0]->assign('function_return',$returntype);
  894.         $this->function_data[$i][0]->assign('function_call',$element->getIntricateFunctionCall($this,$params));
  895.         $this->function_data[$i][0]->assign('function_conflicts',$this->getFormattedConflicts($element,"functions"));
  896.         $this->function_data[$i][0]->assign('params',$params);
  897.         $this->function_data[$i][0]->assign('source_location',$this->returnSee($this->getLink(basename($this->curpage->getFile())),$this->sourceloc));
  898.         $this->function_data[$i][0]->assign('id',$this->getId($element));*/
  899.     }
  900.     
  901.     /**
  902.      * Converts include elements for template output
  903.      *
  904.      * Completely ignored by this converter
  905.      * @param parserInclude
  906.      */
  907.     function convertInclude(&$element)
  908.     {
  909. /*        parent::convertInclude($element, array('include_file'    => '-'.strtr($element->getValue(),array('"' => '', "'" => '','.' => '-'))));
  910.         $docblock = $this->prepareDocBlock($element);
  911.         $per = $this->getIncludeValue($element->getValue(), $element->getPath());
  912.         $this->page_summary->append('includes',array('sdesc' => $docblock['sdesc'],
  913.                                                    'desc' => $docblock['desc'],
  914.                                                   'tags' => $docblock['tags'],
  915.                                                   'utags' => $docblock['utags'],
  916.                                                   'include_name'     => $element->getName(),
  917.                                                   'include_value'    => $per,
  918.                                                   'line_number' => $element->getLineNumber(),
  919.                                                   'include_file'    => '-'.strtr($element->getValue(),array('"' => '', "'" => '','.' => '-'))));*/
  920.     }
  921.     
  922.     /**
  923.      * Converts defines for template output
  924.      * @see prepareDocBlock(), getFormattedConflicts()
  925.      * @param parserDefine
  926.      */
  927.     function convertDefine(&$element)
  928.     {
  929.         $docblock = $this->prepareDocBlock($element);
  930.         $this->_appendDefines(array('sdesc' => $docblock['sdesc'],
  931.                                    'desc' => $docblock['desc'],
  932.                                    'tags' => $docblock['tags'],
  933.                                    'name'     => $this->postProcess($element->getName()),
  934.                                    'value'    => $this->postProcess($element->getValue()),
  935.                                    'conflicts'    => $this->getFormattedConflicts($element,"defines"),
  936.                                    'line_number' => $element->getLineNumber(),
  937.                                    'id' => $this->getId($element)));
  938.     }
  939.     
  940.     /**
  941.      * Append the constant information to the Smarty information
  942.      *
  943.      * Uses category, package, and current file to organize constants defined
  944.      * in a package for the constants.xml output file
  945.      * @param array
  946.      * @uses $_peardoc2_constants appends $define to them
  947.      * @access private
  948.      */
  949.     function _appendDefines($define)
  950.     {
  951.         if (!isset($this->_peardoc2_constants[$this->category][$this->package][$this->sourceloc]))
  952.         {
  953.             $this->_peardoc2_constants[$this->category][$this->package][$this->sourceloc]['name'] = 
  954.                 $this->sourceloc;
  955.             $this->_peardoc2_constants[$this->category][$this->package][$this->sourceloc]['page'] =
  956.                 $this->page;
  957.         }
  958.         $this->_write_constants_xml[$this->category][$this->package] = true;
  959.         $this->_peardoc2_constants[$this->category][$this->package][$this->sourceloc]['defines'][] = $define;
  960.     }
  961.     
  962.     /**
  963.      * Converts global variables for template output
  964.      * @param parserGlobal
  965.      * @see prepareDocBlock(), getFormattedConflicts()
  966.      */
  967.     function convertGlobal(&$element)
  968.     {
  969.         $docblock = $this->prepareDocBlock($element);
  970.         $value = $this->getGlobalValue($element->getValue());
  971.         if ($value == $element->getValue())
  972.         {
  973.             $value = $this->ProgramExample($value);
  974.         } else
  975.         {
  976.             $value = $this->getGlobalValue('<!CDATA[' .$element->getValue() . ']]>');
  977.         }
  978.         $this->_appendGlobals(array('sdesc' => $docblock['sdesc'],
  979.                                    'desc' => $docblock['desc'],
  980.                                    'tags' => $docblock['tags'],
  981.                                    'name'     => $this->postProcess($element->getName()),
  982.                                    'link'    => $element->getName(),
  983.                                    'value'    => $value,
  984.                                    'type' => $element->getDataType($this),
  985.                                    'line_number' => $element->getLineNumber(),
  986.                                    'conflicts'    => $this->getFormattedConflicts($element,"global variables"),
  987.                                    'id' => $this->getId($element)));
  988.     }
  989.     
  990.     /**
  991.      * Append the global variable information to the Smarty information
  992.      *
  993.      * Uses category, package, and current file to organize globals defined
  994.      * in a package for the globals.xml output file
  995.      * @param array
  996.      * @uses $_peardoc2_globals appends $global to them
  997.      * @access private
  998.      */
  999.     function _appendGlobals($global)
  1000.     {
  1001.         if (!isset($this->_peardoc2_globals[$this->category][$this->package][$this->sourceloc]))
  1002.         {
  1003.             $this->_peardoc2_globals[$this->category][$this->package][$this->sourceloc]['name'] = 
  1004.                 $this->sourceloc;
  1005.             $this->_peardoc2_globals[$this->category][$this->package][$this->sourceloc]['page'] =
  1006.                 $this->page;
  1007.         }
  1008.         $this->_write_globals_xml[$this->category][$this->package] = true;
  1009.         $this->_peardoc2_globals[$this->category][$this->package][$this->sourceloc]['globals'][] = $global;
  1010.     }
  1011.     
  1012.     /**
  1013.      * converts procedural pages for template output
  1014.      * @see prepareDocBlock(), getClassesOnPage()
  1015.      * @param parserData
  1016.      */
  1017.     function convertPage(&$element)
  1018.     {
  1019.         parent::convertPage($element);
  1020.         $this->juststarted = true;
  1021.         $this->page_dir = $element->parent->package;
  1022.         $this->page = $this->getPageName($element->parent);
  1023.         $this->category = strtolower($element->parent->category);
  1024.         $this->sourceloc = $element->parent->getSourceLocation($this,true);
  1025.         if (!empty($element->parent->subpackage)) $this->page_dir .= PATH_DELIMITER . $element->parent->subpackage;
  1026.         // registering stuff on the template
  1027.     }
  1028.     
  1029.     function getPageName(&$element)
  1030.     {
  1031.         return str_replace(array('/','_','.'),array('-','-','---'),$element->getSourceLocation($this,true));
  1032.     }
  1033.  
  1034.     /**
  1035.      * returns an array containing the class inheritance tree from the root object to the class
  1036.      *
  1037.      * @param parserClass    class variable
  1038.      * @return array Format: array(root,child,child,child,...,$class)
  1039.      * @uses parserClass::getParentClassTree()
  1040.      */
  1041.     
  1042.     function generateFormattedClassTree($class)
  1043.     {
  1044.         $tree = $class->getParentClassTree($this);
  1045.         $out = '';
  1046.         if (count($tree) - 1)
  1047.         {
  1048.             $result = array($class->getName());
  1049.             $parent = $tree[$class->getName()];
  1050.             while ($parent)
  1051.             {
  1052.                 $subpackage = $parent->docblock->subpackage;
  1053.                 $package = $parent->docblock->package;
  1054.                 $x = $parent;
  1055.                 if (is_object($parent))
  1056.                 $x = $parent->getLink($this);
  1057.                 if (!$x) $x = $parent->getName();
  1058.                 $result[] = 
  1059.                     $x;
  1060.                 if (is_object($parent))
  1061.                 $parent = $tree[$parent->getName()];
  1062.                 elseif (isset($tree[$parent]))
  1063.                 $parent = $tree[$parent];
  1064.             }
  1065.             return array_reverse($result);
  1066.         } else
  1067.         {
  1068.             return array($class->getName());
  1069.         }
  1070.     }
  1071.     
  1072.     /**
  1073.      * returns a list of child classes
  1074.      *
  1075.      * @param parserClass class variable
  1076.      * @uses parserClass::getChildClassList()
  1077.      */
  1078.     
  1079.     function generateChildClassList($class)
  1080.     {
  1081.         $kids = $class->getChildClassList($this);
  1082.         $list = array();
  1083.         if (count($kids))
  1084.         {
  1085.             for($i=0; $i<count($kids); $i++)
  1086.             {
  1087.                 $lt['link'] = '<link linkend="'.$this->getId($kids[$i]) . '-summary">'. $kids[$i]->getName().'</link>';
  1088.                 $lt['sdesc'] = $kids[$i]->docblock->getSDesc($this);
  1089.                 $list[] = $lt;
  1090.             }
  1091.         } else return false;
  1092.         return $list;
  1093.     }
  1094.  
  1095.     /** @access private */
  1096.     function sortVar($a, $b)
  1097.     {
  1098.         return strnatcasecmp($a->getName(),$b->getName());
  1099.     }
  1100.     
  1101.     /** @access private */
  1102.     function sortMethod($a, $b)
  1103.     {
  1104.         if ($a->isConstructor) return -1;
  1105.         if ($b->isConstructor) return 1;
  1106.         return strnatcasecmp($a->getName(),$b->getName());
  1107.     }
  1108.  
  1109.     /**
  1110.      * returns a template-enabled array of class trees
  1111.      * 
  1112.      * @param    string    $package    package to generate a class tree for
  1113.      * @see $roots, HTMLConverter::getRootTree()
  1114.      */
  1115.     function generateFormattedClassTrees($package)
  1116.     {
  1117.         if (!isset($this->roots[$package])) return array();
  1118.         $roots = $trees = array();
  1119.         $roots = $this->roots[$package];
  1120.         for($i=0;$i<count($roots);$i++)
  1121.         {
  1122.             $trees[] = array('class' => $roots[$i],'class_tree' => "<ul>\n".$this->getRootTree($this->getSortedClassTreeFromClass($roots[$i],$package,''),$package)."</ul>\n");
  1123.         }
  1124.         return $trees;
  1125.     }
  1126.     
  1127.     /**
  1128.      * return formatted class tree for the Class Trees page
  1129.      *
  1130.      * @param array $tree output from {@link getSortedClassTreeFromClass()}
  1131.      * @see Classes::$definitechild, generateFormattedClassTrees()
  1132.      * @return string
  1133.      */
  1134.     function getRootTree($tree,$package)
  1135.     {
  1136.         if (!$tree) return '';
  1137.         $my_tree = '';
  1138.         $cur = '#root';
  1139.         $lastcur = array(false);
  1140.         $kids = array();
  1141.         $dopar = false;
  1142.         if ($tree[$cur]['parent'])
  1143.         {
  1144.             $dopar = true;
  1145.             if (!is_object($tree[$cur]['parent']))
  1146.             {
  1147. //                debug("parent ".$tree[$cur]['parent']." not found");
  1148.                 $my_tree .= '<listitem>' . $tree[$cur]['parent'] .'<itemizedlist>';
  1149.             }
  1150.             else
  1151.             {
  1152. //                        debug("parent ".$this->returnSee($tree[$cur]['parent'], false, false)." in other package");
  1153.                 $my_tree .= '<listitem>' . $this->returnSee($tree[$cur]['parent'], false, false);
  1154.                 if ($tree[$cur]['parent']->package != $package) $my_tree .= ' <emphasis>(Different package)</emphasis><itemizedlist>';
  1155.             }
  1156.         }
  1157.         do
  1158.         {
  1159. //            fancy_debug($cur,$lastcur,$kids);
  1160.             if (count($tree[$cur]['children']))
  1161.             {
  1162. //                debug("$cur has children");
  1163.                 if (!isset($kids[$cur]))
  1164.                 {
  1165. //                    debug("set $cur kids");
  1166.                     $kids[$cur] = 1;
  1167.                     $my_tree .= '<listitem>'.$this->returnSee($tree[$cur]['link'], false, false);
  1168.                     $my_tree .= '<itemizedlist>'."\n";
  1169.                 }
  1170.                 array_push($lastcur,$cur);
  1171.                 list(,$cur) = each($tree[$cur]['children']);
  1172. //                var_dump('listed',$cur);
  1173.                 if ($cur)
  1174.                 {
  1175.                     $cur = $cur['package'] . '#' . $cur['class'];
  1176. //                    debug("set cur to child $cur");
  1177. //                    $my_tree .= '<li>'.$this->returnSee($tree[$cur]['link'], false, false);
  1178.                     continue;
  1179.                 } else
  1180.                 {
  1181. //                    debug("end of children for $cur");
  1182.                     $cur = array_pop($lastcur);
  1183.                     $cur = array_pop($lastcur);
  1184.                     $my_tree .= '</itemizedlist></listitem>'."\n";
  1185.                     if ($dopar && ($cur == '#root' || !$cur)) $my_tree .= '</itemizedlist></listitem>';
  1186.                 }
  1187.             } else 
  1188.             {
  1189. //                debug("$cur has no children");
  1190.                 $my_tree .= '<listitem>'.$this->returnSee($tree[$cur]['link'], false, false)."</listitem>";
  1191.                 if ($dopar && $cur == '#root') $my_tree .= '</itemizedlist></listitem>';
  1192.                 $cur = array_pop($lastcur);
  1193.             }
  1194.         } while ($cur);
  1195.         return $my_tree;
  1196.     }
  1197.     /**
  1198.      * does nothing
  1199.      */
  1200.     function generateElementIndex()
  1201.     {
  1202.     }
  1203.     
  1204.     function setTemplateDir($dir)
  1205.     {
  1206.         Converter::setTemplateDir($dir);
  1207.         $this->smarty_dir = $this->templateDir;
  1208.     }
  1209.     
  1210.     /**
  1211.      * Generate alphabetical index of all elements by package and subpackage
  1212.      *
  1213.      * @param string $package name of a package
  1214.      * @see $pkg_elements, walk(), generatePkgElementIndexes()
  1215.      */
  1216.     function generatePkgElementIndex($package)
  1217.     {
  1218.     }
  1219.     
  1220.     /**
  1221.      *
  1222.      * @see generatePkgElementIndex()
  1223.      */
  1224.     function generatePkgElementIndexes()
  1225.     {
  1226.     }
  1227.     
  1228.     /**
  1229.      * @param string name of class
  1230.      * @param string package name
  1231.      * @param string full path to look in (used in index generation)
  1232.      * @param boolean deprecated
  1233.      * @param boolean return just the URL, or enclose it in an html a tag
  1234.      * @return mixed false if not found, or an html a link to the class's documentation
  1235.      * @see parent::getClassLink()
  1236.      */
  1237.     function getClassLink($expr,$package, $file = false,$text = false, $local = true, $with_a = true)
  1238.     {
  1239.         $a = Converter::getClassLink($expr,$package,$file);
  1240.         if (!$a) return false;
  1241.         return $this->returnSee($a, $text, $local, $with_a);
  1242.     }
  1243.  
  1244.     /**
  1245.      * @param string name of function
  1246.      * @param string package name
  1247.      * @param string full path to look in (used in index generation)
  1248.      * @param boolean deprecated
  1249.      * @param boolean return just the URL, or enclose it in an html a tag
  1250.      * @return mixed false if not found, or an html a link to the function's documentation
  1251.      * @see parent::getFunctionLink()
  1252.      */
  1253.     function getFunctionLink($expr,$package, $file = false,$text = false, $local = true)
  1254.     {
  1255.         $a = Converter::getFunctionLink($expr,$package,$file);
  1256.         if (!$a) return false;
  1257.         return $this->returnSee($a, $text, $local);
  1258.     }
  1259.  
  1260.     /**
  1261.      * @param string name of define
  1262.      * @param string package name
  1263.      * @param string full path to look in (used in index generation)
  1264.      * @param boolean deprecated
  1265.      * @param boolean return just the URL, or enclose it in an html a tag
  1266.      * @return mixed false if not found, or an html a link to the define's documentation
  1267.      * @see parent::getDefineLink()
  1268.      */
  1269.     function getDefineLink($expr,$package, $file = false,$text = false, $local = true)
  1270.     {
  1271.         $a = Converter::getDefineLink($expr,$package,$file);
  1272.         if (!$a) return false;
  1273.         return $this->returnSee($a, $text, $local);
  1274.     }
  1275.  
  1276.     /**
  1277.      * @param string name of global variable
  1278.      * @param string package name
  1279.      * @param string full path to look in (used in index generation)
  1280.      * @param boolean deprecated
  1281.      * @param boolean return just the URL, or enclose it in an html a tag
  1282.      * @return mixed false if not found, or an html a link to the global variable's documentation
  1283.      * @see parent::getGlobalLink()
  1284.      */
  1285.     function getGlobalLink($expr,$package, $file = false,$text = false, $local = true)
  1286.     {
  1287.         $a = Converter::getGlobalLink($expr,$package,$file);
  1288.         if (!$a) return false;
  1289.         return $this->returnSee($a, $text, $local);
  1290.     }
  1291.  
  1292.     /**
  1293.      * @param string name of procedural page
  1294.      * @param string package name
  1295.      * @param string full path to look in (used in index generation)
  1296.      * @param boolean deprecated
  1297.      * @param boolean return just the URL, or enclose it in an html a tag
  1298.      * @return mixed false if not found, or an html a link to the procedural page's documentation
  1299.      * @see parent::getPageLink()
  1300.      */
  1301.     function getPageLink($expr,$package, $path = false,$text = false, $local = true)
  1302.     {
  1303.         $a = Converter::getPageLink($expr,$package,$path);
  1304.         if (!$a) return false;
  1305.         return $this->returnSee($a, $text, $local);
  1306.     }
  1307.  
  1308.     /**
  1309.      * @param string name of method
  1310.      * @param string class containing method
  1311.      * @param string package name
  1312.      * @param string full path to look in (used in index generation)
  1313.      * @param boolean deprecated
  1314.      * @param boolean return just the URL, or enclose it in an html a tag
  1315.      * @return mixed false if not found, or an html a link to the method's documentation
  1316.      * @see parent::getMethodLink()
  1317.      */
  1318.     function getMethodLink($expr,$class,$package, $file = false,$text = false, $local = true)
  1319.     {
  1320.         $a = Converter::getMethodLink($expr,$class,$package,$file);
  1321.         if (!$a) return false;
  1322.         return $this->returnSee($a, $text, $local);
  1323.     }
  1324.  
  1325.     /**
  1326.      * @param string name of var
  1327.      * @param string class containing var
  1328.      * @param string package name
  1329.      * @param string full path to look in (used in index generation)
  1330.      * @param boolean deprecated
  1331.      * @param boolean return just the URL, or enclose it in an html a tag
  1332.      * @return mixed false if not found, or an html a link to the var's documentation
  1333.      * @see parent::getVarLink()
  1334.      */
  1335.     function getVarLink($expr,$class,$package, $file = false,$text = false, $local = true)
  1336.     {
  1337.         $a = Converter::getVarLink($expr,$class,$package,$file);
  1338.         if (!$a) return false;
  1339.         return $this->returnSee($a, $text, $local);
  1340.     }
  1341.     
  1342.     /**
  1343.      * does a nat case sort on the specified second level value of the array
  1344.      *
  1345.      * @param    mixed    $a
  1346.      * @param    mixed    $b
  1347.      * @return    int
  1348.      */
  1349.     function rcNatCmp ($a, $b)
  1350.     {
  1351.         $aa = strtoupper($a[$this->rcnatcmpkey]);
  1352.         $bb = strtoupper($b[$this->rcnatcmpkey]);
  1353.         
  1354.         return strnatcasecmp($aa, $bb);
  1355.     }
  1356.     
  1357.     /**
  1358.      * does a nat case sort on the specified second level value of the array.
  1359.      * this one puts constructors first
  1360.      *
  1361.      * @param    mixed    $a
  1362.      * @param    mixed    $b
  1363.      * @return    int
  1364.      */
  1365.     function rcNatCmp1 ($a, $b)
  1366.     {
  1367.         $aa = strtoupper($a[$this->rcnatcmpkey]);
  1368.         $bb = strtoupper($b[$this->rcnatcmpkey]);
  1369.         
  1370.         if (strpos($aa,'CONSTRUCTOR') === 0)
  1371.         {
  1372.             return -1;
  1373.         }
  1374.         if (strpos($bb,'CONSTRUCTOR') === 0)
  1375.         {
  1376.             return 1;
  1377.         }
  1378.         if (strpos($aa,strtoupper($this->class)) === 0)
  1379.         {
  1380.             return -1;
  1381.         }
  1382.         if (strpos($bb,strtoupper($this->class)) === 0)
  1383.         {
  1384.             return -1;
  1385.         }
  1386.         return strnatcasecmp($aa, $bb);
  1387.     }
  1388.     
  1389.     function wordwrap($string)
  1390.     {
  1391.         return wordwrap($string);
  1392.     }
  1393.     
  1394.     /**
  1395.      * Generate the constants.xml, packagename.xml, and globals.xml files
  1396.      */
  1397.     function Output()
  1398.     {
  1399.         $this->flushPackageXml(false);
  1400.         $templ = &$this->newSmarty();
  1401.         $categories = array();
  1402.         $packages = array_flip($this->all_packages);
  1403.         foreach($this->packagecategories as $package => $category)
  1404.         {
  1405.             $categories[$category]['package.'.$category.'.'.str_replace('_','-',strtolower($package ))] = 1;
  1406.             if (isset($packages[$package])) unset($packages[$package]);
  1407.         }
  1408.         $category = $GLOBALS['phpDocumentor_DefaultCategoryName'];
  1409.         foreach($packages as $package)
  1410.         {
  1411.             $categories[$category]['package.'.$category.'.'.str_replace('_','-',strtolower($package ))] = 1;
  1412.         }
  1413.         foreach($categories as $category => $ids)
  1414.         {
  1415.             $templ->assign('id','package.'.$category);
  1416.             $templ->assign('ids',array());
  1417.             $templ->assign('category',$category);
  1418.             $this->setTargetDir($this->base_dir);
  1419.             if (file_exists($this->base_dir . PATH_DELIMITER . strtolower($category ) . '.xml'))
  1420.             {
  1421.                 $contents = @file($this->base_dir . PATH_DELIMITER . strtolower($category ) . '.xml');
  1422.                 if (is_array($contents))
  1423.                 {
  1424.                     $found = false;
  1425.                     foreach($contents as $i => $line)
  1426.                     {
  1427.                         $line = trim($line);
  1428.                         if (strlen($line) && $line{0} == '&')
  1429.                         {
  1430.                             $found = $i;
  1431.                             if (in_array(str_replace(array ('&', ';'), array ('', ''), trim($line )), array_keys($ids )))
  1432.                             {
  1433.                                 unset($ids[str_replace(array('&', ';'), array('', ''), trim($line))]);
  1434.                             }
  1435.                         }
  1436.                         if ($found !== false && (!strlen($line) || $line{0} != '&'))
  1437.                         {
  1438.                             break;
  1439.                         }
  1440.                     }
  1441.                     $newids = array();
  1442.                     foreach($ids as $id => $unll)
  1443.                     {
  1444.                         $newids[] = ' &' . $id . ";\n";
  1445.                     }
  1446.                     $newcontents = array_merge(array_slice($contents, 0, $i), $newids);
  1447.                     $newcontents = array_merge($newcontents, array_slice($contents, $i));
  1448.                 }
  1449.                 $categorycontents = implode($newcontents, '');
  1450.             } else
  1451.             {
  1452.                 foreach($ids as $id => $unll)
  1453.                 {
  1454.                     if (!in_array($id, $templ->_tpl_vars['ids']))
  1455.                     {
  1456.                         $templ->append('ids',$id);
  1457.                     }
  1458.                 }
  1459.                 $categorycontents = '<!-- $' . "Revision$ -->\n" . $templ->fetch('category.tpl');
  1460.             }
  1461.             $this->writefile(strtolower($category) . '.xml',
  1462.                 $categorycontents);
  1463.             phpDocumentor_out("\n");
  1464.             flush();
  1465.         }
  1466.         $my = &$this->newSmarty();
  1467.         if ($this->_peardoc2_constants)
  1468.         {
  1469.             foreach($this->_peardoc2_constants as $category => $r)
  1470.             {
  1471.                 foreach($r as $package => $s)
  1472.                 {
  1473.                     $my->assign('id','package.'.strtolower($category.'.'.str_replace('_','-',strtolower($package ))).'.constants');
  1474.                     $my->assign('package',$package);
  1475.                     $defines = array();
  1476.                     foreach($s as $file => $t)
  1477.                     {
  1478.                         $arr = array();
  1479.                         $arr['name'] = $file;
  1480.                         $arr['page'] = strtolower($t['page']);
  1481.                         $arr['defines'] = $t['defines'];
  1482.                         $defines[] = $arr;
  1483.                     }
  1484.                     $my->assign('defines',$defines);
  1485.                     $this->setTargetDir($this->base_dir . PATH_DELIMITER . $category
  1486.                        . PATH_DELIMITER . strtolower(str_replace('_','-',strtolower($package ))));
  1487.                     $this->writefile('constants.xml',
  1488.                         '<!-- $' . "Revision$ -->\n" . $my->fetch('constants.tpl'));
  1489.                     $my->clear_all_assign();
  1490.                 }
  1491.             }
  1492.             $this->_peardoc2_constants = false;
  1493.         }
  1494.         if ($this->_peardoc2_globals)
  1495.         {
  1496.             foreach($this->_peardoc2_globals as $category => $r)
  1497.             {
  1498.                 foreach($r as $package => $s)
  1499.                 {
  1500.                     $my->assign('id','package.'.strtolower($category.'.'.str_replace('_','-',strtolower($package ))).'.globals');
  1501.                     $my->assign('package',$package);
  1502.                     $defines = array();
  1503.                     foreach($s as $file => $t)
  1504.                     {
  1505.                         $arr = array();
  1506.                         $arr['name'] = $file;
  1507.                         $arr['page'] = strtolower($t['page']);
  1508.                         $arr['globals'] = $t['globals'];
  1509.                         $defines[] = $arr;
  1510.                     }
  1511.                     $my->assign('globals',$defines);
  1512.                     $this->setTargetDir($this->base_dir . PATH_DELIMITER . $category
  1513.                        . PATH_DELIMITER . strtolower(str_replace('_','-',strtolower($package ))));
  1514.                     $this->writefile('globals.xml',
  1515.                         '<!-- $' . "Revision$ -->\n" . $my->fetch('globals.tpl'));
  1516.                     $my->clear_all_assign();
  1517.                 }
  1518.             }
  1519.             $this->_peardoc2_globals = false;
  1520.         }
  1521.     }
  1522. }
  1523. ?>
  1524.