Converters
[ class tree: Converters ] [ index: Converters ] [ all elements ]

Source for file CHMdefaultConverter.inc

Documentation is available at CHMdefaultConverter.inc

  1. <?php
  2. /**
  3.  * CHM (Compiled Help Manual) output converter for Smarty Template.
  4.  *
  5.  * phpDocumentor :: automatic documentation generator
  6.  *
  7.  * PHP versions 4 and 5
  8.  *
  9.  * Copyright (c) 2003-2006 Andrew Eddie, Greg Beaver
  10.  *
  11.  * LICENSE:
  12.  *
  13.  * This library is free software; you can redistribute it
  14.  * and/or modify it under the terms of the GNU Lesser General
  15.  * Public License as published by the Free Software Foundation;
  16.  * either version 2.1 of the License, or (at your option) any
  17.  * later version.
  18.  *
  19.  * This library is distributed in the hope that it will be useful,
  20.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  22.  * Lesser General Public License for more details.
  23.  *
  24.  * You should have received a copy of the GNU Lesser General Public
  25.  * License along with this library; if not, write to the Free Software
  26.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  27.  *
  28.  * @package    Converters
  29.  * @subpackage CHMdefault
  30.  * @author     Joshua Eichorn <jeichorn@phpdoc.org>
  31.  * @author     Greg Beaver <cellog@php.net>
  32.  * @copyright  2000-2006 Joshua Eichorn, Gregory Beaver
  33.  * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL
  34.  * @version    CVS: $Id$
  35.  * @filesource
  36.  * @link       http://www.phpdoc.org
  37.  * @link       http://pear.php.net/PhpDocumentor
  38.  * @since      1.0rc1
  39.  */
  40. /**
  41.  * Generates files that MS HTML Help Worshop can use to create a MS Windows
  42.  * compiled help file (CHM)
  43.  *
  44.  * The free MS HTML Help compiler takes the project file (phpdoc.hhp) and reads
  45.  * the table of contents file specified in the project (which is always contents.hhc
  46.  * in phpDocumentor).  When the converter reaches stable state, it will also
  47.  * output an index file index.hhk.  The free download for MS HTML Help Workshop
  48.  * is available below
  49.  * @link http://www.microsoft.com/downloads/release.asp?releaseid=33071 MS HTML Help Workshop download
  50.  * @package Converters
  51.  * @subpackage CHMdefault
  52.  * @author Greg Beaver <cellog@php.net>
  53.  * @since 1.0rc1
  54.  * @version $Revision$
  55.  */
  56. {
  57.     /**
  58.      * CHMdefaultConverter wants elements sorted by type as well as alphabetically
  59.      * @see Converter::$sort_page_contents_by_type
  60.      * @var boolean 
  61.      */
  62.     var $sort_page_contents_by_type = true;
  63.     /** @var string */
  64.     var $outputformat = 'CHM';
  65.     /** @var string */
  66.     var $name = 'default';
  67.     /**
  68.      * indexes of elements by package that need to be generated
  69.      * @var array 
  70.      */
  71.     var $leftindex = array('classes' => true'pages' => true'functions' => true'defines' => false'globals' => false);
  72.  
  73.     /**
  74.      * output directory for the current procedural page being processed
  75.      * @var string 
  76.      */
  77.     var $page_dir;
  78.  
  79.     /**
  80.      * target directory passed on the command-line.
  81.      * {@link $targetDir} is malleable, always adding package/ and package/subpackage/ subdirectories onto it.
  82.      * @var string 
  83.      */
  84.     var $base_dir;
  85.  
  86.     /**
  87.      * output directory for the current class being processed
  88.      * @var string 
  89.      */
  90.     var $class_dir;
  91.  
  92.     /**
  93.      * array of converted package page names.
  94.      * Used to link to the package page in the left index
  95.      * @var array Format: array(package => 1)
  96.      */
  97.     var $package_pages = array();
  98.  
  99.     /**
  100.      * controls formatting of parser informative output
  101.      *
  102.      * Converter prints:
  103.      * "Converting /path/to/file.php... Procedural Page Elements... Classes..."
  104.      * Since CHMdefaultConverter outputs files while converting, it needs to send a \n to start a new line.  However, if there
  105.      * is more than one class, output is messy, with multiple \n's just between class file output.  This variable prevents that
  106.      * and is purely cosmetic
  107.      * @var boolean 
  108.      */
  109.     var $juststarted = false;
  110.  
  111.     /**
  112.      * contains all of the template procedural page element loop data needed for the current template
  113.      * @var array 
  114.      */
  115.     var $current;
  116.  
  117.     /**
  118.      * contains all of the template class element loop data needed for the current template
  119.      * @var array 
  120.      */
  121.     var $currentclass;
  122.     var $wrote = false;
  123.     var $ric_set = array();
  124.     /**
  125.      * Table of Contents entry for index.hhk
  126.      * @var array 
  127.      */
  128.     var $KLinks = array();
  129.  
  130.     /**
  131.      * track which files have already been parsed
  132.      */
  133.     var $_filenames = array();
  134.  
  135.     /**
  136.      * sets {@link $base_dir} to $targetDir
  137.      * @see Converter()
  138.      */
  139.     function CHMdefaultConverter(&$allp&$packp&$classes&$procpages$po$pp$qm$targetDir$templateDir$title$charset)
  140.     {
  141.         Converter::Converter($allp$packp$classes$procpages,$po$pp$qm$targetDir$templateDir$title$charset);
  142.         $this->base_dir = $targetDir;
  143.     }
  144.  
  145.     /**
  146.      * @deprecated in favor of PHP 4.3.0+ tokenizer-based source highlighting
  147.      */
  148.     function unmangle($sourcecode)
  149.     {
  150.         $sourcecode str_replace('<code>','<pre>',$sourcecode);
  151.         $sourcecode str_replace('</code>','</pre>',$sourcecode);
  152.         $sourcecode str_replace('<br />',"\n",$sourcecode);
  153.         $sourcecode str_replace('&nbsp;',' ',$sourcecode);
  154.         $sourcecode str_replace('&lt;','<',$sourcecode);
  155.         $sourcecode str_replace('&gt;','>',$sourcecode);
  156.         $sourcecode str_replace('&amp;','&',$sourcecode);
  157.         return $sourcecode;
  158.     }
  159.  
  160.     /**
  161.      * @param string full path to the source file
  162.      * @param string fully highlighted source code
  163.      */
  164.     function writeSource($path$value)
  165.     {
  166.         if (in_array($path$this->_filenames)) {
  167.             return// this file has already been parsed
  168.         }
  169.         array_push($this->_filenames,$path);
  170.         $templ &$this->newSmarty();
  171.         $pathinfo $this->proceduralpages->getPathInfo($path$this);
  172.         $templ->assign('source',$value);
  173.         $templ->assign('package',$pathinfo['package']);
  174.         $templ->assign('subpackage',$pathinfo['subpackage']);
  175.         $templ->assign('name',$pathinfo['name']);
  176.         $templ->assign('source_loc',$pathinfo['source_loc']);
  177.         $templ->assign('docs',$pathinfo['docs']);
  178.         $templ->assign("subdir",'../');
  179.         $templ->register_outputfilter('CHMdefault_outputfilter');
  180.         $this->setTargetDir($this->getFileSourcePath($this->base_dir));
  181.         $this->addSourceTOC($pathinfo['name'],$this->getFileSourceName($path),$pathinfo['package'],$pathinfo['subpackage']true);
  182.         phpDocumentor_out("\n");
  183.         $this->setSourcePaths($path);
  184.         $this->writefile($this->getFileSourceName($path).'.html',$templ->fetch('filesource.tpl'));
  185.     }
  186.  
  187.     function writeExample($title$path$source)
  188.     {
  189.         $templ &$this->newSmarty();
  190.         $templ->assign('source',$source);
  191.         if (empty($title))
  192.         {
  193.             $title 'example';
  194.             addWarning(PDERROR_EMPTY_EXAMPLE_TITLE$path$title);
  195.         }
  196.         $templ->assign('title',$title);
  197.         $templ->assign('file',$path);
  198.         $templ->assign("subdir",'../');
  199.         $templ->register_outputfilter('CHMdefault_outputfilter');
  200.         $pathinfo $this->proceduralpages->getPathInfo($path$this);
  201.         $this->setTargetDir($this->base_dir . PATH_DELIMITER . '__examplesource');
  202.         $this->addSourceTOC($title,'exsource_'.$path,$pathinfo['package'],$pathinfo['subpackage']false);
  203.         phpDocumentor_out("\n");
  204.         $this->writefile('exsource_'.$path.'.html',$templ->fetch('examplesource.tpl'));
  205.     }
  206.  
  207.     function getExampleLink($path$title)
  208.     {
  209.         return $this->returnLink('../__examplesource' PATH_DELIMITER . 'exsource_'.$path.'.html',$title);
  210.     }
  211.  
  212.     function getSourceLink($path)
  213.     {
  214.         return $this->returnLink('../__filesource/' .
  215.         $this->getFileSourceName($path).'.html','Source Code for this file');
  216.     }
  217.  
  218.     /**
  219.      * Retrieve a Converter-specific anchor to a segment of a source code file
  220.      * parsed via a {@tutorial tags.filesource.pkg} tag.
  221.      * @param string full path to source file
  222.      * @param string name of anchor
  223.      * @param string link text, if this is a link
  224.      * @param boolean returns either a link or a destination based on this
  225.      *                 parameter
  226.      * @return string link to an anchor, or the anchor
  227.      */
  228.     function getSourceAnchor($sourcefile,$anchor,$text '',$link = false)
  229.     {
  230.         if ($link{
  231.             return $this->returnLink('../__filesource/' .
  232.                 $this->getFileSourceName($sourcefile'.html#a' $anchor$text);
  233.         else {
  234.             return '<a name="a'.$anchor.'"></a>';
  235.         }
  236.     }
  237.  
  238.  
  239.     /**
  240.      * Return a line of highlighted source code with formatted line number
  241.      *
  242.      * If the $path is a full path, then an anchor to the line number will be
  243.      * added as well
  244.      * @param integer line number
  245.      * @param string highlighted source code line
  246.      * @param false|stringfull path to @filesource file this line is a part of,
  247.      *         if this is a single line from a complete file.
  248.      * @return string formatted source code line with line number
  249.      */
  250.     function sourceLine($linenumber$line$path = false)
  251.     {
  252.         $extra '';
  253.         if (strlen(str_replace("\n"''$line)) == 0{
  254.             $extra '&nbsp;';
  255.         }
  256.         if ($path)
  257.         {
  258.             return '<li><div class="src-line">' $this->getSourceAnchor($path$linenumber.
  259.                    str_replace("\n",'',$line$extra .
  260.                    "</div></li>\n";
  261.         else
  262.         {
  263.             return '<li><div class="src-line">' str_replace("\n",'',$line.
  264.                 "$extra</div></li>\n";
  265.         }
  266.     }
  267.  
  268.     /**
  269.      * Used to convert the <<code>> tag in a docblock
  270.      * @param string 
  271.      * @param boolean 
  272.      * @return string 
  273.      */
  274.     function ProgramExample($example$tutorial = false$inlinesourceparse = null/*false*/,
  275.                             $class = null/*false*/$linenum = null/*false*/$filesourcepath = null/*false*/)
  276.     {
  277.         return $this->PreserveWhiteSpace(parent::ProgramExample($example$tutorial$inlinesourceparse$class$linenum$filesourcepath));
  278.     }
  279.  
  280.     /**
  281.      * @param string 
  282.      */
  283.     function TutorialExample($example)
  284.     {
  285.         $trans $this->template_options['desctranslate'];
  286.         $this->template_options['desctranslate'= array();
  287.         $example '<ol>' . parent::TutorialExample($example)
  288.                .'</ol>';
  289.         $this->template_options['desctranslate'$trans;
  290.         if (!isset($this->template_options['desctranslate'])) return $example;
  291.         if (!isset($this->template_options['desctranslate']['code'])) return $example;
  292.         $example $this->template_options['desctranslate']['code'$example;
  293.         if (!isset($this->template_options['desctranslate']['/code'])) return $example;
  294.         return $example $this->template_options['desctranslate']['/code'];
  295.     }
  296.  
  297.     function getCurrentPageLink()
  298.     {
  299.         return $this->curname '.html';
  300.     }
  301.  
  302.     /**
  303.      * Uses htmlspecialchars() on the input
  304.      */
  305.     function postProcess($text)
  306.     {
  307.         if ($this->highlightingSource{
  308.             return str_replace(array(' ',"\t")array('&nbsp;''&nbsp;&nbsp;&nbsp;'),
  309.                 htmlspecialchars($text));
  310.         }
  311.         return htmlspecialchars($text);
  312.     }
  313.  
  314.     /**
  315.      * Use the template tutorial_toc.tpl to generate a table of contents for HTML
  316.      * @return string table of contents formatted for use in the current output format
  317.      * @param array format: array(array('tagname' => section, 'link' => returnsee link, 'id' => anchor name, 'title' => from title tag),...)
  318.      */
  319.     function formatTutorialTOC($toc)
  320.     {
  321.         $template &$this->newSmarty();
  322.         $template->assign('toc',$toc);
  323.         return $template->fetch('tutorial_toc.tpl');
  324.     }
  325.  
  326.     function &SmartyInit(&$templ)
  327.     {
  328.         if (!isset($this->package_index))
  329.         foreach($this->all_packages as $key => $val)
  330.         {
  331.             if (isset($this->pkg_elements[$key]))
  332.             {
  333.                 if (!isset($start)) $start $key;
  334.                 $this->package_index[= array('link' => "li_$key.html"'title' => $key);
  335.             }
  336.         }
  337.         $templ->assign("packageindex",$this->package_index);
  338.         $templ->assign("subdir",'');
  339.         return $templ;
  340.     }
  341.  
  342.  
  343.     /**
  344.      * Writes out the template file of {@link $class_data} and unsets the template to save memory
  345.      * @see registerCurrentClass()
  346.      * @see parent::endClass()
  347.      */
  348.     function endClass()
  349.     {
  350.         $a '../';
  351.         if (!empty($this->subpackage)) $a .= '../';
  352.         if ($this->juststarted)
  353.         {
  354.             $this->juststarted = false;
  355.             phpDocumentor_out("\n");
  356.             flush();
  357.         }
  358.         $this->setTargetDir($this->base_dir . PATH_DELIMITER . $this->class_dir);
  359.         $this->class_data->assign("subdir",$a);
  360.         $this->class_data->register_outputfilter('CHMdefault_outputfilter');
  361.         $this->addTOC($this->class,$this->class,$this->package,$this->subpackagetrue);
  362.         $this->writefile($this->class . '.html',$this->class_data->fetch('class.tpl'));
  363.         unset($this->class_data);
  364.     }
  365.  
  366.     /**
  367.      * Writes out the template file of {@link $page_data} and unsets the template to save memory
  368.      * @see registerCurrent()
  369.      * @see parent::endPage()
  370.      */
  371.     function endPage()
  372.     {
  373.         $this->package = $this->curpage->package;
  374.         $this->subpackage = $this->curpage->subpackage;
  375.         $a '../';
  376.         if (!empty($this->subpackage)) $a .= '../';
  377.         $this->setTargetDir($this->base_dir . PATH_DELIMITER . $this->page_dir);
  378.         $this->page_data->assign("package",$this->package);
  379.         $this->page_data->assign("subdir",$a);
  380.         $this->page_data->register_outputfilter('CHMdefault_outputfilter');
  381.         $this->addTOC($this->curpage->file,$this->page,$this->package,$this->subpackage);
  382.         $this->writefile($this->page . '.html',$this->page_data->fetch('page.tpl'));
  383.         unset($this->page_data);
  384.     }
  385.  
  386.     /**
  387.      * @param string 
  388.      * @param string 
  389.      * @return string &lt;a href="'.$link.'">'.$text.'</a&gt;
  390.      */
  391.     function returnLink($link,$text)
  392.     {
  393.         return '<a href="'.$link.'">'.$text.'</a>';
  394.     }
  395.  
  396.     /**
  397.      * CHMdefaultConverter chooses to format both package indexes and the complete index here
  398.      *
  399.      * This function formats output for the elementindex.html and pkgelementindex.html template files.  It then
  400.      * writes them to the target directory
  401.      * @see generateElementIndex(), generatePkgElementIndex()
  402.      */
  403.     function formatPkgIndex()
  404.     {
  405.         list($package_indexes,$packages,$mletters$this->generatePkgElementIndexes();
  406.         for($i=0;$i<count($package_indexes);$i++)
  407.         {
  408.             $template &$this->newSmarty();
  409.             $this->package = $package_indexes[$i]['package'];
  410.             $this->subpackage = '';
  411.             $template->assign("index",$package_indexes[$i]['pindex']);
  412.             $template->assign("package",$package_indexes[$i]['package']);
  413.             $template->assign("letters",$mletters[$package_indexes[$i]['package']]);
  414.             $template->assign("title","Package ".$package_indexes[$i]['package']." Element Index");
  415.             $template->assign("subdir",'../');
  416.             $template->register_outputfilter('CHMdefault_outputfilter');
  417.             $this->setTargetDir($this->base_dir . PATH_DELIMITER . $package_indexes[$i]['package']);
  418.             $this->addTOC($package_indexes[$i]['package']." Alphabetical Index",'elementindex_'.$package_indexes[$i]['package'],$package_indexes[$i]['package'],'');
  419.             $this->writefile('elementindex_'.$package_indexes[$i]['package'].'.html',$template->fetch('pkgelementindex.tpl'));
  420.         }
  421.         phpDocumentor_out("\n");
  422.         flush();
  423.         }
  424.  
  425.     /**
  426.      * CHMdefaultConverter uses this function to format template index.html and packages.html
  427.      *
  428.      * This function generates the package list from {@link $all_packages}, eliminating any
  429.      * packages that don't have any entries in their package index (no files at all, due to @ignore
  430.      * or other factors).  Then it uses the default package name as the first package index to display.
  431.      * It sets the right pane to be either a blank file with instructions on making package-level docs,
  432.      * or the package-level docs for the default package.
  433.      * @global string Used to set the starting package to display
  434.      */
  435.     function formatIndex()
  436.     {
  437.         global $phpDocumentor_DefaultPackageName;
  438.         list($elindex,$mletters$this->generateElementIndex();
  439.         $template &$this->newSmarty();
  440.         $template->assign("index",$elindex);
  441.         $template->assign("letters",$mletters);
  442.         $template->assign("title","Element Index");
  443.         $template->assign("date",date("r",time()));
  444.         $template->register_outputfilter('CHMdefault_outputfilter');
  445.         phpDocumentor_out("\n");
  446.         flush();
  447.         $this->setTargetDir($this->base_dir);
  448.         $this->addTOC("Alphabetical Index Of All Elements",'elementindex',"Index",'');
  449.         $this->writefile('elementindex.html',$template->fetch('elementindex.tpl'));
  450.         usort($this->package_index,"CHMdefault_pindexcmp");
  451.         $index &$this->newSmarty();
  452.         foreach($this->all_packages as $key => $val)
  453.         {
  454.             if (isset($this->pkg_elements[$key]))
  455.             {
  456.                 if (!isset($start)) $start $key;
  457.                 if (!isset($this->package_pages[$key])) $this->writeNewPPage($key);
  458.             }
  459.         }
  460.         $this->setTargetDir($this->base_dir);
  461.         // Created index.html
  462.         if (isset($this->pkg_elements[$phpDocumentor_DefaultPackageName])) $start $phpDocumentor_DefaultPackageName;
  463.         $this->package = $start;
  464.         $this->subpackage = '';
  465.         $setalready = false;
  466.         if (isset($this->tutorials[$start]['']['pkg']))
  467.         {
  468.             foreach($this->tutorials[$start]['']['pkg'as $tute)
  469.             {
  470.                 if ($tute->name == $start '.pkg')
  471.                 {
  472.                     $setalready = true;
  473.                        $this->addTOC("Start page",$start.'/tutorial_'.$tute->name,"Index",'');
  474.                 }
  475.             }
  476.         }
  477.         if (!$setalready)
  478.         {
  479.             if (isset($this->package_pages[$start]))
  480.             {
  481.                    $this->addTOC("Start page",'package_'.$start,"Index",'');
  482.             }
  483.             else
  484.             {
  485.                 $index->assign("blank","blank");
  486.                 $blank &$this->newSmarty();
  487.                 $blank->assign('package',$phpDocumentor_DefaultPackageName);
  488.                 $this->addTOC("Start page",'blank',"Index",'');
  489.                 $this->writefile("blank.html",$blank->fetch('blank.tpl'));
  490.                 Converter::writefile('index.html',$blank->fetch('tutorial.tpl'));
  491.             }
  492.         }
  493.         phpDocumentor_out("\n");
  494.         flush();
  495.  
  496.         unset($index);
  497.     }
  498.  
  499.     function writeNewPPage($key)
  500.     {
  501.         return;
  502.         $template &$this->newSmarty();
  503.         $this->package = $key;
  504.         $this->subpackage = '';
  505.         $template->assign("date",date("r",time()));
  506.         $template->assign("title",$this->title);
  507.         $template->assign("package",$key);
  508.         $template->register_outputfilter('CHMdefault_outputfilter');
  509.         phpDocumentor_out("\n");
  510.         flush();
  511.         $this->setTargetDir($this->base_dir);
  512.  
  513.         $this->addTOC("$key Index","li_$key",$key,'');
  514.         $this->writefile("li_$key.html",$template->fetch('index.tpl'));
  515.         unset($template);
  516.     }
  517.  
  518.     /**
  519.      * Generate indexes for li_package.html and classtree output files
  520.      *
  521.      * This function generates the li_package.html files from the template file left.html.  It does this by
  522.      * iterating through each of the $page_elements, $class_elements and  $function_elements arrays to retrieve
  523.      * the pre-sorted {@link abstractLink} descendants needed for index generation.  Conversion of these links to
  524.      * text is done by {@link returnSee()}.  The {@link $local} parameter is set to false to ensure that paths are correct.
  525.      *
  526.      * Then it uses {@link generateFormattedClassTrees()} to create class trees from the template file classtrees.html.  Output
  527.      * filename is classtrees_packagename.html.  This function also unsets {@link $elements} and {@link $pkg_elements} to free
  528.      * up the considerable memory these two class vars use
  529.      * @see $page_elements, $class_elements, $function_elements
  530.      */
  531.     function formatLeftIndex()
  532.     {
  533.         phpDocumentor_out("\n");
  534.         flush();
  535.         $this->setTargetDir($this->base_dir);
  536.         if (0)//!isset($this->left))
  537.         {
  538.             debug("Nothing parsed, check the command-line");
  539.             die();
  540.         }
  541.         foreach($this->all_packages as $package => $rest)
  542.         {
  543.             if (!isset($this->pkg_elements[$package])) continue;
  544.  
  545.             // Create class tree page
  546.             $template &$this->newSmarty();
  547.             $template->assign("classtrees",$this->generateFormattedClassTrees($package));
  548.             $template->assign("package",$package);
  549.             $template->assign("date",date("r",time()));
  550.             $template->register_outputfilter('CHMdefault_outputfilter');
  551.             $this->addTOC("$package Class Trees","classtrees_$package",$package,'');
  552.             $this->writefile("classtrees_$package.html",$template->fetch('classtrees.tpl'));
  553.             phpDocumentor_out("\n");
  554.             flush();
  555.         }
  556.         // free up considerable memory
  557.         unset($this->elements);
  558.         unset($this->pkg_elements);
  559.     }
  560.  
  561.     /**
  562.      * This function takes an {@link abstractLink} descendant and returns an html link
  563.      *
  564.      * @param abstractLink a descendant of abstractlink should be passed, and never text
  565.      * @param string text to display in the link
  566.      * @param boolean this parameter is not used, and is deprecated
  567.      * @param boolean determines whether the returned text is enclosed in an <a> tag
  568.      */
  569.     function returnSee(&$element$eltext = false$with_a = true)
  570.     {
  571.         if (!$elementreturn false;
  572.         if (!$with_areturn $this->getId($elementfalse);
  573.         if (!$eltext)
  574.         {
  575.             $eltext '';
  576.             switch($element->type)
  577.             {
  578.                 case 'tutorial' :
  579.                 $eltext strip_tags($element->title);
  580.                 break;
  581.                 case 'method' :
  582.                 case 'var' :
  583.                 case 'const' :
  584.                 $eltext .= $element->class.'::';
  585.                 case 'page' :
  586.                 case 'define' :
  587.                 case 'class' :
  588.                 case 'function' :
  589.                 case 'global' :
  590.                 default :
  591.                 $eltext .= $element->name;
  592.                 if ($element->type == 'function' || $element->type == 'method'$eltext .= '()';
  593.                 break;
  594.             }
  595.         }
  596.         return '<a href="'.$this->getId($element).'">'.$eltext.'</a>';
  597.     }
  598.  
  599.     function getId($element$fullpath = true)
  600.     {
  601.         if (phpDocumentor_get_class($element== 'parserdata')
  602.         {
  603.             $element $this->addLink($element->parent);
  604.             $elp $element->parent;
  605.         elseif (is_a($element'parserbase'))
  606.         {
  607.             $elp $element;
  608.             $element $this->addLink($element);
  609.         }
  610.         $c '';
  611.         if (!empty($element->subpackage))
  612.         {
  613.             $c '/'.$element->subpackage;
  614.         }
  615.         $b '../';
  616.         switch ($element->type)
  617.         {
  618.             case 'page' :
  619.             if ($fullpath)
  620.             return $b.$element->package.$c.'/'.$element->fileAlias.'.html';
  621.             return 'top';
  622.             break;
  623.             case 'define' :
  624.             case 'global' :
  625.             case 'function' :
  626.             if ($fullpath)
  627.             return $b.$element->package.$c.'/'.$element->fileAlias.'.html#'.$element->type.$element->name;
  628.             return $element->type.$element->name;
  629.             break;
  630.             case 'class' :
  631.             if ($fullpath)
  632.             return $b.$element->package.$c.'/'.$element->name.'.html';
  633.             return 'top';
  634.             break;
  635.             case 'method' :
  636.             case 'var' :
  637.             case 'const' :
  638.             if ($fullpath)
  639.             return $b.$element->package.$c.'/'.$element->class.'.html#'.$element->type.$element->name;
  640.             return $element->type.$element->name;
  641.             break;
  642.             case 'tutorial' :
  643.             $d '';
  644.             if ($element->section)
  645.             {
  646.                 $d '#'.$element->section;
  647.             }
  648.             return $b.$element->package.$c.'/tutorial_'.$element->name.'.html'.$d;
  649.         }
  650.     }
  651.  
  652.     function ConvertTodoList()
  653.     {
  654.         $todolist = array();
  655.         foreach($this->todoList as $package => $alltodos)
  656.         {
  657.             foreach($alltodos as $todos)
  658.             {
  659.                 $converted = array();
  660.                 $converted['link'$this->returnSee($todos[0]);
  661.                 if (!is_array($todos[1]))
  662.                 {
  663.                     $converted['todos'][$todos[1]->Convert($this);
  664.                 else
  665.                 {
  666.                     foreach($todos[1as $todo)
  667.                     {
  668.                         $converted['todos'][$todo->Convert($this);
  669.                     }
  670.                 }
  671.                 $todolist[$package][$converted;
  672.             }
  673.         }
  674.         $templ &$this->newSmarty();
  675.         $templ->assign('todos',$todolist);
  676.         $templ->register_outputfilter('CHMdefault_outputfilter');
  677.         $this->setTargetDir($this->base_dir);
  678.         $this->addTOC('Todo List','todolist','Index','',false,true);
  679.         $this->addKLink('Todo List''todolist''''Development');
  680.         $this->writefile('todolist.html',$templ->fetch('todolist.tpl'));
  681.     }
  682.  
  683.     /**
  684.      * Convert README/INSTALL/CHANGELOG file contents to output format
  685.      * @param README|INSTALL|CHANGELOG
  686.      * @param string contents of the file
  687.      */
  688.     function Convert_RIC($name$contents)
  689.     {
  690.         $template &$this->newSmarty();
  691.         $template->assign('contents',$contents);
  692.         $template->assign('name',$name);
  693.         $this->setTargetDir($this->base_dir);
  694.         $this->addTOC($name,'ric_'.$name,'Index','',false,true);
  695.         $this->addKLink($name'ric_'.$name'''Development');
  696.         $this->writefile('ric_'.$name '.html',$template->fetch('ric.tpl'));
  697.         $this->ric_set[$name= true;
  698.     }
  699.  
  700.     /**
  701.      * Create errors.html template file output
  702.      *
  703.      * This method takes all parsing errors and warnings and spits them out ordered by file and line number.
  704.      * @global ErrorTracker We'll be using it's output facility
  705.      */
  706.     function ConvertErrorLog()
  707.     {
  708.         global $phpDocumentor_errors;
  709.         $allfiles = array();
  710.         $files = array();
  711.         $warnings $phpDocumentor_errors->returnWarnings();
  712.         $errors $phpDocumentor_errors->returnErrors();
  713.         $template &$this->newSmarty();
  714.         foreach($warnings as $warning)
  715.         {
  716.             $file '##none';
  717.             $linenum 'Warning';
  718.             if ($warning->file)
  719.             {
  720.                 $file $warning->file;
  721.                 $allfiles[$file= 1;
  722.                 $linenum .= ' on line '.$warning->linenum;
  723.             }
  724.             $files[$file]['warnings'][= array('name' => $linenum'listing' => $warning->data);
  725.         }
  726.         foreach($errors as $error)
  727.         {
  728.             $file '##none';
  729.             $linenum 'Error';
  730.             if ($error->file)
  731.             {
  732.                 $file $error->file;
  733.                 $allfiles[$file= 1;
  734.                 $linenum .= ' on line '.$error->linenum;
  735.             }
  736.             $files[$file]['errors'][= array('name' => $linenum'listing' => $error->data);
  737.         }
  738.         $i=1;
  739.         $af = array();
  740.         foreach($allfiles as $file => $num)
  741.         {
  742.             $af[$i++$file;
  743.         }
  744.         $allfiles $af;
  745.         usort($allfiles,'strnatcasecmp');
  746.         $allfiles[0"Post-parsing";
  747.         foreach($allfiles as $i => $a)
  748.         {
  749.             $allfiles[$i= array('file' => $a);
  750.         }
  751.         $out = array();
  752.         foreach($files as $file => $data)
  753.         {
  754.             if ($file == '##none'$file 'Post-parsing';
  755.             $out[$file$data;
  756.         }
  757.         $template->assign("files",$allfiles);
  758.         $template->assign("all",$out);
  759.         $template->assign("title","phpDocumentor Parser Errors and Warnings");
  760.         $this->setTargetDir($this->base_dir);
  761.         $this->writefile("errors.html",$template->fetch('errors.tpl'));
  762.         unset($template);
  763.         phpDocumentor_out("\n\nTo view errors and warnings, look at ".$this->base_dirPATH_DELIMITER . "errors.html\n");
  764.         flush();
  765.     }
  766.  
  767.     function getCData($value)
  768.     {
  769.         return '<pre>'.htmlentities($value).'</pre>';
  770.     }
  771.  
  772.     function getTutorialId($package,$subpackage,$tutorial,$id)
  773.     {
  774.         return $id;
  775.     }
  776.  
  777.     /**
  778.      * Converts package page and sets its package as used in {@link $package_pages}
  779.      * @param parserPackagePage 
  780.      */
  781.     function convertPackagepage(&$element)
  782.     {
  783.         phpDocumentor_out("\n");
  784.         flush();
  785.         $this->package = $element->package;
  786.         $this->subpackage = '';
  787.         $contents $element->Convert($this);
  788.         $this->package_pages[$element->packagestr_replace('../','../',$contents);
  789.         phpDocumentor_out("\n");
  790.         flush();
  791.         $this->setTargetDir($this->base_dir . PATH_DELIMITER . $element->package);
  792.         $this->addTOC($element->package." Tutorial",'package_'.$element->package,$element->package,'');
  793.         $this->writeFile('package_'.$element->package.'.html',str_replace('../','../',$contents));
  794.         $this->setTargetDir($this->base_dir);
  795.         Converter::writefile('index.html',str_replace('../','',$contents));
  796.         $this->addKLink($element->package." Tutorial"'package_'.$element->package'''Tutorials');
  797.     }
  798.  
  799.     /**
  800.      * @param parserTutorial 
  801.      */
  802.     function convertTutorial(&$element)
  803.     {
  804.         phpDocumentor_out("\n");
  805.         flush();
  806.         $template &parent::convertTutorial($element);
  807.         $a '../';
  808.         if ($element->subpackage$a .= '../';
  809.         $template->assign('subdir',$a);
  810.         $template->register_outputfilter('CHMdefault_outputfilter');
  811.         $contents $template->fetch('tutorial.tpl');
  812.         if ($element->package == $GLOBALS['phpDocumentor_DefaultPackageName'&& empty($element->subpackage&& ($element->name == $element->package . '.pkg'))
  813.         {
  814.             $template->assign('subdir','');
  815.             $this->setTargetDir($this->base_dir);
  816.             Converter::writefile('index.html',$template->fetch('tutorial.tpl'));
  817.         }
  818.         $a '';
  819.         if ($element->subpackage$a PATH_DELIMITER . $element->subpackage;
  820.         phpDocumentor_out("\n");
  821.         flush();
  822.         $this->setTargetDir($this->base_dir . PATH_DELIMITER . $element->package . $a);
  823.         $this->addTOC($a strip_tags($element->getTitle($this))'tutorial_'.$element->name,
  824.             $element->package$element->subpackagefalsetrue);
  825.         $this->writeFile('tutorial_'.$element->name.'.html',$contents);
  826.         $this->addKLink($element->getTitle($this)$element->package . $a PATH_DELIMITER . 'tutorial_'.$element->name,
  827.             '''Tutorials');
  828.     }
  829.  
  830.     /**
  831.      * Converts class for template output
  832.      * @see prepareDocBlock(), generateChildClassList(), generateFormattedClassTree(), getFormattedConflicts()
  833.      * @see getFormattedInheritedMethods(), getFormattedInheritedVars()
  834.      * @param parserClass 
  835.      */
  836.     function convertClass(&$element)
  837.     {
  838.         parent::convertClass($element);
  839.         $this->class_dir = $element->docblock->package;
  840.         if (!empty($element->docblock->subpackage)) $this->class_dir .= PATH_DELIMITER . $element->docblock->subpackage;
  841.         $a '../';
  842.         if ($element->docblock->subpackage != ''$a = "../$a";
  843.  
  844.         $this->class_data->assign('subdir',$a);
  845.         $this->class_data->assign("title","Docs For Class " $element->getName());
  846.         $this->class_data->assign("page",$element->getName('.html');
  847.         $this->addKLink($element->name$this->class_dir . PATH_DELIMITER . $this->class'''Classes');
  848.     }
  849.  
  850.  
  851.     /**
  852.      * Converts class variables for template output
  853.      * @see prepareDocBlock(), getFormattedConflicts()
  854.      * @param parserDefine 
  855.      */
  856.     function convertVar(&$element)
  857.     {
  858.         parent::convertVar($elementarray('var_dest' => $this->getId($element,false)));
  859.         $this->setTargetDir($this->base_dir . PATH_DELIMITER . $this->class_dir);
  860.         $this->addKLink($element->name$this->class_dir . PATH_DELIMITER .$this->class$this->getId($element,false)$element->class.' Properties');
  861.     }
  862.  
  863.     /**
  864.      * Converts class constants for template output
  865.      * @see prepareDocBlock(), getFormattedConflicts()
  866.      * @param parserDefine 
  867.      */
  868.     function convertConst(&$element)
  869.     {
  870.         parent::convertConst($elementarray('const_dest' => $this->getId($element,false)));
  871.         $this->setTargetDir($this->base_dir . PATH_DELIMITER . $this->class_dir);
  872.         $this->addKLink($element->name$this->class_dir . PATH_DELIMITER .$this->class$this->getId($element,false)$element->class.' Constants');
  873.     }
  874.  
  875.     /**
  876.      * Converts class methods for template output
  877.      * @see prepareDocBlock(), getFormattedConflicts()
  878.      * @param parserDefine 
  879.      */
  880.     function convertMethod(&$element)
  881.     {
  882.         parent::convertMethod($elementarray('method_dest' => $this->getId($element,false)));
  883.         $this->setTargetDir($this->base_dir . PATH_DELIMITER . $this->class_dir);
  884.         $this->addKLink($element->name$this->class_dir . PATH_DELIMITER .$this->class$this->getId($element,false)$element->class.' Methods');
  885.     }
  886.  
  887.     /**
  888.      * Converts function for template output
  889.      * @see prepareDocBlock(), parserFunction::getFunctionCall(), getFormattedConflicts()
  890.      * @param parserFunction 
  891.      */
  892.     function convertFunction(&$element)
  893.     {
  894.         $funcloc $this->getId($this->addLink($element));
  895.         parent::convertFunction($element,array('function_dest' => $this->getId($element,false)));
  896.         $this->setTargetDir($this->base_dir . PATH_DELIMITER . $this->page_dir);
  897.         $this->addKLink($element->name$this->page_dir . PATH_DELIMITER . $this->page$this->getId($element,false)'Functions');
  898.     }
  899.  
  900.     /**
  901.      * Converts include elements for template output
  902.      * @see prepareDocBlock()
  903.      * @param parserInclude 
  904.      */
  905.     function convertInclude(&$element)
  906.     {
  907.         parent::convertInclude($elementarray('include_file'    => '_'.strtr($element->getValue(),array('"' => ''"'" => '','.' => '_'))));
  908.         $this->setTargetDir($this->base_dir . PATH_DELIMITER . $this->page_dir);
  909.         $this->addKLink(str_replace('"'''$element->getValue())$this->page_dir . PATH_DELIMITER . $this->page''ucfirst($element->name));
  910.     }
  911.  
  912.     /**
  913.      * Converts defines for template output
  914.      * @see prepareDocBlock(), getFormattedConflicts()
  915.      * @param parserDefine 
  916.      */
  917.     function convertDefine(&$element)
  918.     {
  919.         parent::convertDefine($elementarray('define_link' => $this->getId($element,false)));
  920.         $this->setTargetDir($this->base_dir . PATH_DELIMITER . $this->page_dir);
  921.         $this->addKLink($element->name$this->page_dir . PATH_DELIMITER . $this->page$this->getId($element,false)'Constants');
  922.     }
  923.  
  924.     /**
  925.      * Converts global variables for template output
  926.      * @param parserGlobal 
  927.      */
  928.     function convertGlobal(&$element)
  929.     {
  930.         parent::convertGlobal($elementarray('global_link' => $this->getId($element,false)));
  931.         $this->setTargetDir($this->base_dir . PATH_DELIMITER . $this->page_dir);
  932.         $this->addKLink($element->name$this->page_dir . PATH_DELIMITER . $this->page$this->getId($element,false)'Global Variables');
  933.     }
  934.  
  935.     /**
  936.      * converts procedural pages for template output
  937.      * @see prepareDocBlock(), getClassesOnPage()
  938.      * @param parserData 
  939.      */
  940.     function convertPage(&$element)
  941.     {
  942.         parent::convertPage($element);
  943.         $this->juststarted = true;
  944.         $this->page_dir = $element->parent->package;
  945.         if (!empty($element->parent->subpackage)) $this->page_dir .= PATH_DELIMITER . $element->parent->subpackage;
  946.         // registering stuff on the template
  947.         $this->page_data->assign("page",$this->getPageName($element'.html');
  948.         $this->page_data->assign("title","Docs for page ".$element->parent->getFile());
  949.         $this->setTargetDir($this->base_dir . PATH_DELIMITER . $this->page_dir);
  950.         $this->addKLink($element->parent->file$this->page_dir . PATH_DELIMITER . $this->page'''Files');
  951.     }
  952.  
  953.     function getPageName(&$element)
  954.     {
  955.         if (phpDocumentor_get_class($element== 'parserpage'return '_'.$element->getName();
  956.         return '_'.$element->parent->getName();
  957.     }
  958.  
  959.     /**
  960.      * returns an array containing the class inheritance tree from the root object to the class
  961.      *
  962.      * @param parserClass    class variable
  963.      * @return array Format: array(root,child,child,child,...,$class)
  964.      * @uses parserClass::getParentClassTree()
  965.      */
  966.  
  967.     function generateFormattedClassTree($class)
  968.     {
  969.         $tree $class->getParentClassTree($this);
  970.         $out '';
  971.         if (count($tree- 1)
  972.         {
  973.             $result = array($class->getName());
  974.             $parent $tree[$class->getName()];
  975.             $distance['';
  976.             while ($parent)
  977.             {
  978.                 $x $parent;
  979.                 if (is_object($parent))
  980.                 {
  981.                     $subpackage $parent->docblock->subpackage;
  982.                     $package $parent->docblock->package;
  983.                     $x $parent;
  984.                     $x $parent->getLink($this);
  985.                     if (!$x$x $parent->getName();
  986.                 }
  987.                 $result[=
  988.                     $x;
  989.                 $distance[=
  990.                     "\n%s|\n" .
  991.                     "%s--";
  992.                 if (is_object($parent))
  993.                 $parent $tree[$parent->getName()];
  994.                 elseif (isset($tree[$parent]))
  995.                 $parent $tree[$parent];
  996.             }
  997.             $nbsp '   ';
  998.             for($i=count($result- 1;$i>=0;$i--)
  999.             {
  1000.                 $my_nbsp '';
  1001.                 for($j=0;$j<count($result$i;$j++$my_nbsp .= $nbsp;
  1002.                 $distance[$isprintf($distance[$i],$my_nbsp,$my_nbsp);
  1003.             }
  1004.             return array('classes'=>array_reverse($result),'distance'=>array_reverse($distance));
  1005.         else
  1006.         {
  1007.             return array('classes'=>$class->getName(),'distance'=>array(''));
  1008.         }
  1009.     }
  1010.  
  1011.     /** @access private */
  1012.     function sortVar($a$b)
  1013.     {
  1014.         return strnatcasecmp($a->getName(),$b->getName());
  1015.     }
  1016.  
  1017.     /** @access private */
  1018.     function sortMethod($a$b)
  1019.     {
  1020.         if ($a->isConstructorreturn -1;
  1021.         if ($b->isConstructorreturn 1;
  1022.         return strnatcasecmp($a->getName(),$b->getName());
  1023.     }
  1024.  
  1025.     /**
  1026.      * returns a template-enabled array of class trees
  1027.      *
  1028.      * @param    string    $package    package to generate a class tree for
  1029.      * @see $roots, HTMLConverter::getRootTree()
  1030.      */
  1031.     function generateFormattedClassTrees($package)
  1032.     {
  1033.         if (!isset($this->roots['normal'][$package]&&
  1034.               !isset($this->roots['special'][$package])) {
  1035.             return array();
  1036.         }
  1037.         $trees = array();
  1038.         if (isset($this->roots['normal'][$package])) {
  1039.             $roots $this->roots['normal'][$package];
  1040.             for($i=0;$i<count($roots);$i++)
  1041.             {
  1042.                 $root $this->classes->getClassByPackage($roots[$i]$package);
  1043.                 if ($root && $root->isInterface()) {
  1044.                     continue;
  1045.                 }
  1046.                 $trees[= array('class' => $roots[$i],'class_tree' => "<ul>\n".$this->getRootTree($this->getSortedClassTreeFromClass($roots[$i],$package,''),$package)."</ul>\n");
  1047.             }
  1048.         }
  1049.         if (isset($this->roots['special'][$package])) {
  1050.             $roots $this->roots['special'][$package];
  1051.             foreach ($roots as $parent => $classes{
  1052.                 $thistree '';
  1053.                 foreach ($classes as $classinfo{
  1054.                     $root $this->classes->getClassByPackage($classinfo$package);
  1055.                     if ($root && $root->isInterface()) {
  1056.                         continue;
  1057.                     }
  1058.                     $thistree .=
  1059.                         $this->getRootTree(
  1060.                             $this->getSortedClassTreeFromClass(
  1061.                                 $classinfo,
  1062.                                 $package,
  1063.                                 ''),
  1064.                             $package,
  1065.                             true);
  1066.                 }
  1067.                 if (!$thistree{
  1068.                     continue;
  1069.                 }
  1070.                 $trees[= array(
  1071.                     'class' => $parent,
  1072.                     'class_tree' => "<ul>\n" $thistree "</ul>\n"
  1073.                 );
  1074.             }
  1075.         }
  1076.         return $trees;
  1077.     }
  1078.  
  1079.     /**
  1080.      * returns a template-enabled array of interface inheritance trees
  1081.      *
  1082.      * @param    string    $package    package to generate a class tree for
  1083.      * @see $roots, HTMLConverter::getRootTree()
  1084.      */
  1085.     function generateFormattedInterfaceTrees($package)
  1086.     {
  1087.         if (!isset($this->roots['normal'][$package]&&
  1088.               !isset($this->roots['special'][$package])) {
  1089.             return array();
  1090.         }
  1091.         $trees = array();
  1092.         if (isset($this->roots['normal'][$package])) {
  1093.             $roots $this->roots['normal'][$package];
  1094.             for($i=0;$i<count($roots);$i++)
  1095.             {
  1096.                 $root $this->classes->getClassByPackage($roots[$i]$package);
  1097.                 if ($root && !$root->isInterface()) {
  1098.                     continue;
  1099.                 }
  1100.                 $trees[= array('class' => $roots[$i],'class_tree' => "<ul>\n".$this->getRootTree($this->getSortedClassTreeFromClass($roots[$i],$package,''),$package)."</ul>\n");
  1101.             }
  1102.         }
  1103.         if (isset($this->roots['special'][$package])) {
  1104.             $roots $this->roots['special'][$package];
  1105.             foreach ($roots as $parent => $classes{
  1106.                 $thistree '';
  1107.                 foreach ($classes as $classinfo{
  1108.                     $root $this->classes->getClassByPackage($classinfo$package);
  1109.                     if ($root && !$root->isInterface()) {
  1110.                         continue;
  1111.                     }
  1112.                     $thistree .=
  1113.                         $this->getRootTree(
  1114.                             $this->getSortedClassTreeFromClass(
  1115.                                 $classinfo,
  1116.                                 $package,
  1117.                                 ''),
  1118.                             $package,
  1119.                             true);
  1120.                 }
  1121.                 if (!$thistree{
  1122.                     continue;
  1123.                 }
  1124.                 $trees[= array(
  1125.                     'class' => $parent,
  1126.                     'class_tree' => "<ul>\n" $thistree "</ul>\n"
  1127.                 );
  1128.             }
  1129.         }
  1130.         return $trees;
  1131.     }
  1132.  
  1133.     /**
  1134.      * return formatted class tree for the Class Trees page
  1135.      *
  1136.      * @param array $tree output from {@link getSortedClassTreeFromClass()}
  1137.      * @param string $package  package
  1138.      * @param boolean $nounknownparent if true, an object's parent will not be checked
  1139.      * @see Classes::$definitechild, generateFormattedClassTrees()
  1140.      * @return string 
  1141.      */
  1142.     function getRootTree($tree$package$noparent = false)
  1143.     {
  1144.         if (!$treereturn '';
  1145.         $my_tree '';
  1146.         $cur '#root';
  1147.         $lastcur = array(false);
  1148.         $kids = array();
  1149.         $dopar = false;
  1150.         if (!$noparent && $tree[$cur]['parent'])
  1151.         {
  1152.             $dopar = true;
  1153.             if (!is_object($tree[$cur]['parent']))
  1154.             {
  1155. //                debug("parent ".$tree[$cur]['parent']." not found");
  1156.                 $my_tree .= '<li>' $tree[$cur]['parent'.'<ul>';
  1157.             }
  1158.             else
  1159.             {
  1160. //                        debug("parent ".$this->returnSee($tree[$cur]['parent'])." in other package");
  1161.                 $my_tree .= '<li>' $this->returnSee($tree[$cur]['parent']);
  1162.                 if ($tree[$cur]['parent']->package != $package$my_tree .= ' <b>(Different package)</b><ul>';
  1163.             }
  1164.         }
  1165.         do
  1166.         {
  1167. //            fancy_debug($cur,$lastcur,$kids);
  1168.             if (count($tree[$cur]['children']))
  1169.             {
  1170. //                debug("$cur has children");
  1171.                 if (!isset($kids[$cur]))
  1172.                 {
  1173. //                    debug("set $cur kids");
  1174.                     $kids[$cur= 1;
  1175.                     $my_tree .= '<li>'.$this->returnSee($tree[$cur]['link']);
  1176.                     $my_tree .= '<ul>'."\n";
  1177.                 }
  1178.                 array_push($lastcur,$cur);
  1179.                 list(,$cureach($tree[$cur]['children']);
  1180. //                var_dump('listed',$cur);
  1181.                 if ($cur)
  1182.                 {
  1183.                     $cur $cur['package''#' $cur['class'];
  1184. //                    debug("set cur to child $cur");
  1185. //                    $my_tree .= '<li>'.$this->returnSee($tree[$cur]['link']);
  1186.                     continue;
  1187.                 else
  1188.                 {
  1189. //                    debug("end of children for $cur");
  1190.                     $cur array_pop($lastcur);
  1191.                     $cur array_pop($lastcur)// will fall into infinite loop if this second array_pop() is removed
  1192.                     $my_tree .= '</ul></li>'."\n";
  1193.                 }
  1194.             else
  1195.             {
  1196. //                debug("$cur has no children");
  1197.                 $my_tree .= '<li>'.$this->returnSee($tree[$cur]['link'])."</li>";
  1198.                 $cur array_pop($lastcur);
  1199.             }
  1200.         while ($cur);
  1201.         if ($dopar{
  1202.             $my_tree .= '</ul></li>'."\n";
  1203.         }
  1204.         return $my_tree;
  1205.     }
  1206.         /**
  1207.          * Generate indexing information for given element
  1208.          *
  1209.          * @param parserElement descendant of parserElement
  1210.          * @see generateElementIndex()
  1211.          * @return array 
  1212.          */
  1213.         function getIndexInformation($elt)
  1214.         {
  1215.             $Result['type'$elt->type;
  1216.             $Result['file_name'$elt->file;
  1217.             $Result['path'$elt->getPath();
  1218.  
  1219.             if (isset($elt->docblock))
  1220.                         {
  1221.                             $Result['description'$elt->docblock->getSDesc($this);
  1222.  
  1223.                             if ($elt->docblock->hasaccess)
  1224.                                 $Result['access'$elt->docblock->tags['access'][0]->value;
  1225.                             else
  1226.                                 $Result['access''public';
  1227.  
  1228.                             $Result['abstract'= isset ($elt->docblock->tags['abstract'][0]);
  1229.                         }
  1230.             else
  1231.                 $Result['description''';
  1232.  
  1233.             $aa $Result['description'];
  1234.             if (!empty($aa)) $aa = "<br>&nbsp;&nbsp;&nbsp;&nbsp;$aa";
  1235.  
  1236.             switch($elt->type)
  1237.             {
  1238.                     case 'class':
  1239.                             $Result['name'$elt->getName();
  1240.                             $Result['title''Class';
  1241.                             $Result['link'$this->getClassLink($elt->getName(),
  1242.                                                                   $elt->docblock->package,
  1243.                                                                   $elt->getPath(),
  1244.                                                                   $elt->getName());
  1245.                             $Result['listing''in file '.$elt->file.', class '.$Result['link']."$aa";
  1246.                     break;
  1247.                     case 'define':
  1248.                             $Result['name'$elt->getName();
  1249.                             $Result['title''Constant';
  1250.                             $Result['link'$this->getDefineLink($elt->getName(),
  1251.                                                                    $elt->docblock->package,
  1252.                                                                    $elt->getPath(),
  1253.                                                                    $elt->getName());
  1254.                             $Result['listing''in file '.$elt->file.', constant '.$Result['link']."$aa";
  1255.                     break;
  1256.                     case 'global':
  1257.                             $Result['name'$elt->getName();
  1258.                             $Result['title''Global';
  1259.                             $Result['link'$this->getGlobalLink($elt->getName(),
  1260.                                                                    $elt->docblock->package,
  1261.                                                                    $elt->getPath(),
  1262.                                                                    $elt->getName());
  1263.                             $Result['listing''in file '.$elt->file.', global variable '.$Result['link']."$aa";
  1264.                     break;
  1265.                     case 'function':
  1266.                             $Result['name'$elt->getName();
  1267.                             $Result['title''Function';
  1268.                             $Result['link'$this->getFunctionLink($elt->getName(),
  1269.                                                                      $elt->docblock->package,
  1270.                                                                      $elt->getPath(),
  1271.                                                                      $elt->getName().'()');
  1272.                             $Result['listing''in file '.$elt->file.', function '.$Result['link']."$aa";
  1273.                     break;
  1274.                     case 'method':
  1275.                             $Result['name'$elt->getName();
  1276.                             $Result['title''Method';
  1277.                             $Result['link'$this->getMethodLink($elt->getName(),
  1278.                                                                    $elt->class,
  1279.                                                                    $elt->docblock->package,
  1280.                                                                    $elt->getPath(),
  1281.                                                                    $elt->class.'::'.$elt->getName().'()'
  1282.                                                                              );
  1283.                                                         if ($elt->isConstructor$Result['constructor'= 1;
  1284.                             $Result['listing''in file '.$elt->file.', method '.$Result['link']."$aa";
  1285.                     break;
  1286.                     case 'var':
  1287.                             $Result['name'$elt->getName();
  1288.                             $Result['title''Variable';
  1289.                             $Result['link'$this->getVarLink($elt->getName(),
  1290.                                                                 $elt->class,
  1291.                                                                 $elt->docblock->package,
  1292.                                                                 $elt->getPath(),
  1293.                                                                 $elt->class.'::'.$elt->getName());
  1294.                             $Result['listing''in file '.$elt->file.', variable '.$Result['link']."$aa";
  1295.                     break;
  1296.                     case 'const':
  1297.                             $Result['name'$elt->getName();
  1298.                             $Result['title''Variable';
  1299.                             $Result['link'$this->getConstLink($elt->getName(),
  1300.                                                                 $elt->class,
  1301.                                                                 $elt->docblock->package,
  1302.                                                                 $elt->getPath(),
  1303.                                                                 $elt->class.'::'.$elt->getName());
  1304.                             $Result['listing''in file '.$elt->file.', class constant '.$Result['link']."$aa";
  1305.                     break;
  1306.                     case 'page':
  1307.                             $Result['name'$elt->getFile();
  1308.                             $Result['title''Page';
  1309.                             $Result['link'$this->getPageLink($elt->getFile(),
  1310.                                                                  $elt->package,
  1311.                                                                  $elt->getPath(),
  1312.                                                                  $elt->getFile());
  1313.                             $Result['listing''procedural page '.$Result['link'];
  1314.                     break;
  1315.                     case 'include':
  1316.                             $Result['name'$elt->getName();
  1317.                             $Result['title''Include';
  1318.                             $Result['link'$elt->getValue();
  1319.                             $Result['listing''include '.$Result['name'];
  1320.                     break;
  1321.             }
  1322.  
  1323.             return $Result;
  1324.         }
  1325.     /**
  1326.      * Generate alphabetical index of all elements
  1327.      *
  1328.      * @see $elements, walk()
  1329.      */
  1330.     function generateElementIndex()
  1331.     {
  1332.         $elementindex = array();
  1333.         $letters = array();
  1334.         $used = array();
  1335.         foreach($this->elements as $letter => $nutoh)
  1336.         {
  1337.             foreach($this->elements[$letteras $i => $yuh)
  1338.             {
  1339.                 if ($this->elements[$letter][$i]->type != 'include')
  1340.                 {
  1341.                     if (!isset($used[$letter]))
  1342.                     {
  1343.                         $letters[]['letter'$letter;
  1344.                         $elindex['letter'$letter;
  1345.                         $used[$letter= 1;
  1346.                     }
  1347.  
  1348.                     $elindex['index'][$this->getIndexInformation($this->elements[$letter][$i]);
  1349.                 }
  1350.             }
  1351.             if (isset($elindex['index']))
  1352.             {
  1353.                 $elementindex[$elindex;
  1354.             else
  1355.             {
  1356.                 unset($letters[count($letters- 1]);
  1357.             }
  1358.             $elindex = array();
  1359.         }
  1360.         return array($elementindex,$letters);
  1361.     }
  1362.  
  1363.     function setTemplateDir($dir)
  1364.     {
  1365.         Converter::setTemplateDir($dir);
  1366.         $this->smarty_dir = $this->templateDir;
  1367.     }
  1368.  
  1369.     function copyMediaRecursively($media,$targetdir,$subdir '')
  1370.     {
  1371.         $versionControlDirectories = array ('CVS''media/CVS''media\\CVS''.svn''media/.svn''media\\.svn');
  1372.         if (!is_array($media)) {
  1373.             return;
  1374.         }
  1375.         foreach($media as $dir => $files)
  1376.         {
  1377.             if ($dir === '/')
  1378.             {
  1379.                 $this->copyMediaRecursively($files,$targetdir);
  1380.             else
  1381.             {
  1382.                 if (!is_numeric($dir))
  1383.                 {
  1384.                     if (in_array($dir$versionControlDirectories))
  1385.                     {
  1386.                         // skip it entirely
  1387.                     }
  1388.                     else
  1389.                     {
  1390.                         // create the subdir
  1391.                         phpDocumentor_out("creating $targetdir" . PATH_DELIMITER . "$dir\n");
  1392.                         Converter::setTargetDir($targetdir PATH_DELIMITER . $dir);
  1393.                         if (!empty($subdir))
  1394.                         {
  1395.                             $subdir .= PATH_DELIMITER;
  1396.                         }
  1397.                         $this->copyMediaRecursively($files,"$targetdir/$dir",$subdir $dir);
  1398.                     }
  1399.                 }
  1400.                 else
  1401.                 {
  1402.                     // copy the file
  1403.                     phpDocumentor_out("copying $targetdir" . PATH_DELIMITER . $files['file']."\n");
  1404.                     $this->copyFile($files['file'],$subdir);
  1405.                 }
  1406.             }
  1407.         }
  1408.     }
  1409.  
  1410.     /**
  1411.      * calls the converter setTargetDir, and then copies any template images and the stylesheet if they haven't been copied
  1412.      * @see Converter::setTargetDir()
  1413.      */
  1414.     function setTargetDir($dir)
  1415.     {
  1416.         Converter::setTargetDir($dir);
  1417.         if ($this->wrotereturn;
  1418.         $this->wrote = true;
  1419.         $template_images = array();
  1420.         $stylesheets = array();
  1421.         $tdir $dir;
  1422.         $dir $this->templateDir;
  1423.         $this->templateDir = $this->templateDir.'templates/';
  1424.         $info = new Io;
  1425.         $this->copyMediaRecursively($info->getDirTree($this->templateDir.'media',$this->templateDir),$tdir);
  1426.     }
  1427.  
  1428.     /**
  1429.      * Generate alphabetical index of all elements by package and subpackage
  1430.      *
  1431.      * @param string $package name of a package
  1432.      * @see $pkg_elements, walk(), generatePkgElementIndexes()
  1433.      */
  1434.     function generatePkgElementIndex($package)
  1435.     {
  1436. //        var_dump($this->pkg_elements[$package]);
  1437.         $elementindex = array();
  1438.         $letters = array();
  1439.         $letterind = array();
  1440.         $used = array();
  1441.         $subp '';
  1442.         foreach($this->pkg_elements[$packageas $subpackage => $els)
  1443.         {
  1444.             if (empty($els)) continue;
  1445.             if (!empty($subpackage)) $subp = " (<b>subpackage:</b> $subpackage)"; else $subp '';
  1446.             foreach($els as $letter => $yuh)
  1447.             {
  1448.                 foreach($els[$letteras $i => $yuh)
  1449.                 {
  1450.                     if ($els[$letter][$i]->type != 'include')
  1451.                     {
  1452.                         if (!isset($used[$letter]))
  1453.                         {
  1454.                             $letters[]['letter'$letter;
  1455.                             $letterind[$lettercount($letters- 1;
  1456.                             $used[$letter= 1;
  1457.                         }
  1458.                         $elindex[$letter]['letter'$letter;
  1459.  
  1460.                         $elindex[$letter]['index'][$this->getIndexInformation($els[$letter][$i]);
  1461.                     }
  1462.                 }
  1463.             }
  1464.         }
  1465.         ksort($elindex);
  1466.         usort($letters,'CHMdefault_lettersort');
  1467.         if (isset($elindex))
  1468.         {
  1469.             while(list($letter,$tempeleach($elindex))
  1470.             {
  1471.                 if (!isset($tempel))
  1472.                 {
  1473.                     unset($letters[$letterind[$tempel['letter']]]);
  1474.                 else
  1475.                 $elementindex[$tempel;
  1476.             }
  1477.         else $letters = array();
  1478.         return array($elementindex,$letters);
  1479.     }
  1480.  
  1481.     /**
  1482.      *
  1483.      * @see generatePkgElementIndex()
  1484.      */
  1485.     function generatePkgElementIndexes()
  1486.     {
  1487.         $packages = array();
  1488.         $package_names = array();
  1489.         $pkg = array();
  1490.         $letters = array();
  1491.         foreach($this->pkg_elements as $package => $trash)
  1492.         {
  1493.             $pkgs['package'$package;
  1494.             $pkg['package'$package;
  1495.             list($pkg['pindex'],$letters[$package]$this->generatePkgElementIndex($package);
  1496.             if (count($pkg['pindex']))
  1497.             {
  1498.                 $packages[$pkg;
  1499.                 $package_names[$pkgs;
  1500.             }
  1501.             unset($pkgs);
  1502.             unset($pkg);
  1503.         }
  1504.         foreach($packages as $i => $package)
  1505.         {
  1506.             $pnames = array();
  1507.             for($j=0;$j<count($package_names);$j++)
  1508.             {
  1509.                 if ($package_names[$j]['package'!= $package['package']$pnames[$package_names[$j];
  1510.             }
  1511.             $packages[$i]['packageindexes'$pnames;
  1512.         }
  1513.         return array($packages,$package_names,$letters);
  1514.     }
  1515.  
  1516.     /**
  1517.      * @param string name of class
  1518.      * @param string package name
  1519.      * @param string full path to look in (used in index generation)
  1520.      * @param boolean deprecated
  1521.      * @param boolean return just the URL, or enclose it in an html a tag
  1522.      * @return mixed false if not found, or an html a link to the class's documentation
  1523.      * @see parent::getClassLink()
  1524.      */
  1525.     function getClassLink($expr,$package$file = false,$text = false$with_a = true)
  1526.     {
  1527.         $a Converter::getClassLink($expr,$package,$file);
  1528.         if (!$areturn false;
  1529.         return $this->returnSee($a$text$with_a);
  1530.     }
  1531.  
  1532.     /**
  1533.      * @param string name of function
  1534.      * @param string package name
  1535.      * @param string full path to look in (used in index generation)
  1536.      * @param boolean deprecated
  1537.      * @param boolean return just the URL, or enclose it in an html a tag
  1538.      * @return mixed false if not found, or an html a link to the function's documentation
  1539.      * @see parent::getFunctionLink()
  1540.      */
  1541.     function getFunctionLink($expr,$package$file = false,$text = false)
  1542.     {
  1543.         $a Converter::getFunctionLink($expr,$package,$file);
  1544.         if (!$areturn false;
  1545.         return $this->returnSee($a$text);
  1546.     }
  1547.  
  1548.     /**
  1549.      * @param string name of define
  1550.      * @param string package name
  1551.      * @param string full path to look in (used in index generation)
  1552.      * @param boolean deprecated
  1553.      * @param boolean return just the URL, or enclose it in an html a tag
  1554.      * @return mixed false if not found, or an html a link to the define's documentation
  1555.      * @see parent::getDefineLink()
  1556.      */
  1557.     function getDefineLink($expr,$package$file = false,$text = false)
  1558.     {
  1559.         $a Converter::getDefineLink($expr,$package,$file);
  1560.         if (!$areturn false;
  1561.         return $this->returnSee($a$text);
  1562.     }
  1563.  
  1564.     /**
  1565.      * @param string name of global variable
  1566.      * @param string package name
  1567.      * @param string full path to look in (used in index generation)
  1568.      * @param boolean deprecated
  1569.      * @param boolean return just the URL, or enclose it in an html a tag
  1570.      * @return mixed false if not found, or an html a link to the global variable's documentation
  1571.      * @see parent::getGlobalLink()
  1572.      */
  1573.     function getGlobalLink($expr,$package$file = false,$text = false)
  1574.     {
  1575.         $a Converter::getGlobalLink($expr,$package,$file);
  1576.         if (!$areturn false;
  1577.         return $this->returnSee($a$text);
  1578.     }
  1579.  
  1580.     /**
  1581.      * @param string name of procedural page
  1582.      * @param string package name
  1583.      * @param string full path to look in (used in index generation)
  1584.      * @param boolean deprecated
  1585.      * @param boolean return just the URL, or enclose it in an html a tag
  1586.      * @return mixed false if not found, or an html a link to the procedural page's documentation
  1587.      * @see parent::getPageLink()
  1588.      */
  1589.     function getPageLink($expr,$package$path = false,$text = false)
  1590.     {
  1591.         $a Converter::getPageLink($expr,$package,$path);
  1592.         if (!$areturn false;
  1593.         return $this->returnSee($a$text);
  1594.     }
  1595.  
  1596.     /**
  1597.      * @param string name of method
  1598.      * @param string class containing method
  1599.      * @param string package name
  1600.      * @param string full path to look in (used in index generation)
  1601.      * @param boolean deprecated
  1602.      * @param boolean return just the URL, or enclose it in an html a tag
  1603.      * @return mixed false if not found, or an html a link to the method's documentation
  1604.      * @see parent::getMethodLink()
  1605.      */
  1606.     function getMethodLink($expr,$class,$package$file = false,$text = false)
  1607.     {
  1608.         $a Converter::getMethodLink($expr,$class,$package,$file);
  1609.         if (!$areturn false;
  1610.         return $this->returnSee($a$text);
  1611.     }
  1612.  
  1613.     /**
  1614.      * @param string name of var
  1615.      * @param string class containing var
  1616.      * @param string package name
  1617.      * @param string full path to look in (used in index generation)
  1618.      * @param boolean deprecated
  1619.      * @param boolean return just the URL, or enclose it in an html a tag
  1620.      * @return mixed false if not found, or an html a link to the var's documentation
  1621.      * @see parent::getVarLink()
  1622.      */
  1623.     function getVarLink($expr,$class,$package$file = false,$text = false)
  1624.     {
  1625.         $a Converter::getVarLink($expr,$class,$package,$file);
  1626.         if (!$areturn false;
  1627.         return $this->returnSee($a$text);
  1628.     }
  1629.  
  1630.     /**
  1631.      * @param string name of class constant
  1632.      * @param string class containing class constant
  1633.      * @param string package name
  1634.      * @param string full path to look in (used in index generation)
  1635.      * @param boolean deprecated
  1636.      * @param boolean return just the URL, or enclose it in an html a tag
  1637.      * @return mixed false if not found, or an html a link to the var's documentation
  1638.      * @see parent::getVarLink()
  1639.      */
  1640.     function getConstLink($expr,$class,$package$file = false,$text = false)
  1641.     {
  1642.         $a Converter::getConstLink($expr,$class,$package,$file);
  1643.         if (!$areturn false;
  1644.         return $this->returnSee($a$text);
  1645.     }
  1646.  
  1647.     /**
  1648.      * does a nat case sort on the specified second level value of the array
  1649.      *
  1650.      * @param    mixed    $a 
  1651.      * @param    mixed    $b 
  1652.      * @return    int 
  1653.      */
  1654.     function rcNatCmp ($a$b)
  1655.     {
  1656.         $aa strtoupper($a[$this->rcnatcmpkey]);
  1657.         $bb strtoupper($b[$this->rcnatcmpkey]);
  1658.  
  1659.         return strnatcasecmp($aa$bb);
  1660.     }
  1661.  
  1662.     /**
  1663.      * does a nat case sort on the specified second level value of the array.
  1664.      * this one puts constructors first
  1665.      *
  1666.      * @param    mixed    $a 
  1667.      * @param    mixed    $b 
  1668.      * @return    int 
  1669.      */
  1670.     function rcNatCmp1 ($a$b)
  1671.     {
  1672.         $aa strtoupper($a[$this->rcnatcmpkey]);
  1673.         $bb strtoupper($b[$this->rcnatcmpkey]);
  1674.  
  1675.         if (strpos($aa,'CONSTRUCTOR'=== 0)
  1676.         {
  1677.             return -1;
  1678.         }
  1679.         if (strpos($bb,'CONSTRUCTOR'=== 0)
  1680.         {
  1681.             return 1;
  1682.         }
  1683.         if (strpos($aa,strtoupper($this->class)) === 0)
  1684.         {
  1685.             return -1;
  1686.         }
  1687.         if (strpos($bb,strtoupper($this->class)) === 0)
  1688.         {
  1689.             return -1;
  1690.         }
  1691.         return strnatcasecmp($aa$bb);
  1692.     }
  1693.  
  1694.     /**
  1695.      * Write a file to disk, and add it to the {@link $hhp_files} list of files
  1696.      * to include in the generated CHM
  1697.      *
  1698.      * {@source } 
  1699.      */
  1700.     function writefile($file,$contents)
  1701.     {
  1702.         $this->addHHP($this->targetDir . PATH_DELIMITER . $file);
  1703.         Converter::writefile($file,$contents);
  1704.     }
  1705.  
  1706.     /**
  1707.      * @uses $hhp_files creates the array by adding parameter $file
  1708.      */
  1709.     function addHHP($file)
  1710.     {
  1711.         $file str_replace($this->base_dir . PATH_DELIMITER''$file);
  1712.         $file str_replace('\\',PATH_DELIMITER,$file);
  1713.         $file str_replace('//',PATH_DELIMITER,$file);
  1714.         $file str_replace(PATH_DELIMITER,'\\',$file);
  1715.         $this->hhp_files[]['name'$file;
  1716.     }
  1717.  
  1718.     function generateTOC()
  1719.     {
  1720.         $comppack '';
  1721.         $templ &$this->newSmarty();
  1722.         foreach($this->TOC as $package => $TOC1)
  1723.         {
  1724.             $comp_subs '';
  1725.             $comp_subs1 = false;
  1726.             foreach($TOC1 as $subpackage => $types)
  1727.             {
  1728.                 $comp_types '';
  1729.                 foreach($types as $type => $files)
  1730.                 {
  1731.                     $comp '';
  1732.                     $templ1 &$this->newSmarty();
  1733.                     $templ1->assign('entry'array());
  1734.                     foreach($files as $file)
  1735.                     {
  1736.                     // use book icon for classes
  1737.                         if ($type == 'Classes'{
  1738.                             $templ1->append('entry'array('paramname' => $file[0],'outputfile' => $file[1],'isclass' => 1));
  1739.                         else {
  1740.                             $templ1->append('entry'array('paramname' => $file[0],'outputfile' => $file[1]));
  1741.                         }
  1742.                     }
  1743.                     $templ &$this->newSmarty();
  1744.                     $templ->assign('tocsubentries',$templ1->fetch('tocentry.tpl'));
  1745.                     $templ->assign('entry'array(array('paramname' => $type)));
  1746.                     $comp_types .= $templ->fetch('tocentry.tpl');
  1747.                 }
  1748.                 if (!empty($subpackage))
  1749.                 {
  1750.                     $templ &$this->newSmarty();
  1751.                     $templ->assign('tocsubentries',$comp_types);
  1752.                     $templ->assign('entry'array(array('paramname' => $subpackage)));
  1753.                     $comp_subs .= $templ->fetch('tocentry.tpl');
  1754.                 else
  1755.                 {
  1756.                     $comp_subs1 $comp_types;
  1757.                 }
  1758.             }
  1759.             if ($comp_subs1)
  1760.             $templ->assign('tocsubentries',$comp_subs1);
  1761.             if (!empty($comp_subs))
  1762.             $templ->assign('entry'array(array('paramname' => $package'tocsubentries' => $comp_subs)));
  1763.             else
  1764.             $templ->assign('entry'array(array('paramname' => $package)));
  1765.             $comppack .= $templ->fetch('tocentry.tpl');
  1766.         }
  1767.         return $comppack;
  1768.     }
  1769.  
  1770.     function addSourceTOC($name$file$package$subpackage$source = false)
  1771.     {
  1772.         $file str_replace($this->base_dir . PATH_DELIMITER''$this->targetDir)
  1773.              . PATH_DELIMITER . $file '.html';
  1774.         $file str_replace('\\',PATH_DELIMITER,$file);
  1775.         $file str_replace('//',PATH_DELIMITER,$file);
  1776.         $file str_replace(PATH_DELIMITER,'\\',$file);
  1777.         $sub $source 'Source Code' 'Examples';
  1778.         $this->TOC[$package][$subpackage][$sub][= array($name$file);
  1779.     }
  1780.  
  1781.     function addTOC($name,$file,$package,$subpackage,$class = false,$tutorial = false)
  1782.     {
  1783.         $file str_replace($this->base_dir . PATH_DELIMITER''$this->targetDir . PATH_DELIMITER)
  1784.              . $file '.html';
  1785.         $file str_replace('\\',PATH_DELIMITER,$file);
  1786.         $file str_replace('//',PATH_DELIMITER,$file);
  1787.         $file str_replace(PATH_DELIMITER,'\\',$file);
  1788.         $file str_replace($this->base_dir . '\\'''$file);
  1789.         $sub $class 'Classes' 'Files';
  1790.         if ($tutorial$sub 'Manual';
  1791.         $this->TOC[$package][$subpackage][$sub][= array($name,$file);
  1792.     }
  1793.  
  1794.     /**
  1795.      * Add an item to the index.hhk file
  1796.      * @param string $name index entry name
  1797.      * @param string $file filename containing index
  1798.      * @param string $bookmark html anchor of location in file, if any
  1799.      * @param string $group group this entry with a string
  1800.      * @uses $KLinks tracks the index
  1801.      * @author Andrew Eddie <eddieajau@users.sourceforge.net>
  1802.      */
  1803.     function addKLink($name$file$bookmark=''$group='')
  1804.     {
  1805.         $file $file '.html';
  1806.         $file str_replace('\\',PATH_DELIMITER,$file);
  1807.         $file str_replace('//',PATH_DELIMITER,$file);
  1808.         $file str_replace(PATH_DELIMITER,'\\',$file);
  1809. //        debug("added $name, $file, $bookmark, $group ");
  1810.         $link $file;
  1811.         $link .= $bookmark ? "#$bookmark" :'';
  1812.         if ($group{
  1813.             $this->KLinks[$group]['grouplink'$file;
  1814.             $this->KLinks[$group][= array($name,$link);
  1815.         }
  1816.         $this->KLinks[= array($name,$link);
  1817.     }
  1818.  
  1819.     /**
  1820.      * Get the table of contents for index.hhk
  1821.      * @return string contents of tocentry.tpl generated from $KLinks
  1822.      * @author Andrew Eddie <eddieajau@users.sourceforge.net>
  1823.      */
  1824.     function generateKLinks()
  1825.     {
  1826.         $templ &$this->newSmarty();
  1827.         $templ->assign('entry'array());
  1828.         foreach($this->KLinks as $group=>$link)
  1829.         {
  1830.             if (isset($link['grouplink'])) {
  1831.                 $templg &$this->newSmarty();
  1832.                 $templg->assign('entry'array());
  1833.                 foreach($link as $k=>$sublink)
  1834.                 {
  1835.                     if ($k != 'grouplink'{
  1836.                         $templg->append('entry'array('paramname' => $sublink[0],'outputfile' => $sublink[1]));
  1837.                     }
  1838.                 }
  1839.                 $templ->append('entry'array('paramname' => $group'outputfile' => $link['grouplink']'tocsubentries' => $templg->fetch('tocentry.tpl') ));
  1840.             else {
  1841.                 $templ->append('entry'array('paramname' => $link[0],'outputfile' => $link[1]));
  1842.             }
  1843.         }
  1844.         return $templ->fetch('tocentry.tpl');
  1845.     }
  1846.  
  1847.     /**
  1848.      * Create the phpdoc.hhp, contents.hhc files needed by MS HTML Help Compiler
  1849.      * to create a CHM file
  1850.      *
  1851.      * The output function generates the table of contents (contents.hhc)
  1852.      * and file list (phpdoc.hhp) files used to create a .CHM by the
  1853.      * free MS HTML Help compiler.
  1854.      * {@internal 
  1855.      * Using {@link $hhp_files}, a list of all separate .html files
  1856.      * is created in CHM format, and written to phpdoc.hhp.  This list was
  1857.      * generated by {@link writefile}.
  1858.      *
  1859.      * Next, a call to the table of contents:
  1860.      *
  1861.      * {@source 12 2}
  1862.      *
  1863.      * finishes things off}}}
  1864.      * @todo use to directly call html help compiler hhc.exe
  1865.      * @link http://www.microsoft.com/downloads/release.asp?releaseid=33071
  1866.      * @uses generateTOC() assigns to the toc template variable
  1867.      */
  1868.     function Output()
  1869.     {
  1870.         $templ &$this->newSmarty();
  1871.         $templ->assign('files',$this->hhp_files);
  1872.         $this->setTargetDir($this->base_dir);
  1873.         Converter::writefile('phpdoc.hhp',$templ->fetch('hhp.tpl'));
  1874.         $templ &$this->newSmarty();
  1875.         $templ->assign('toc',$this->generateTOC());
  1876.         Converter::writefile('contents.hhc',$templ->fetch('contents.hhc.tpl'));
  1877.         $templ->assign('klinks',$this->generateKLinks());
  1878.         Converter::writefile('index.hhk',$templ->fetch('index.hhk.tpl'));
  1879.         phpDocumentor_out("NOTE: to create the documentation.chm file, you must now run Microsoft Help Workshop on phpdoc.hhp\n");
  1880.         phpDocumentor_out("To get the free Microsoft Help Workshop, browse to: http://go.microsoft.com/fwlink/?LinkId=14188\n");
  1881.         flush();
  1882.     }
  1883. }
  1884.  
  1885. /**
  1886.  * @access private
  1887.  * @global string name of the package to set as the first package
  1888.  */
  1889. function CHMdefault_pindexcmp($a$b)
  1890. {
  1891.     global $phpDocumentor_DefaultPackageName;
  1892.     if ($a['title'== $phpDocumentor_DefaultPackageNamereturn -1;
  1893.     if ($b['title'== $phpDocumentor_DefaultPackageNamereturn 1;
  1894.     return strnatcasecmp($a['title'],$b['title']);
  1895. }
  1896.  
  1897. /** @access private */
  1898. function CHMdefault_lettersort($a$b)
  1899. {
  1900.     return strnatcasecmp($a['letter'],$b['letter']);
  1901. }
  1902.  
  1903. /** @access private */
  1904. function CHMdefault_outputfilter($src&$smarty)
  1905. {
  1906.     return str_replace('../',$smarty->_tpl_vars['subdir'],$src);
  1907. }
  1908. ?>

Documentation generated on Mon, 11 Mar 2019 15:50:09 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.