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

Documentation generated on Mon, 05 Dec 2011 20:56:26 -0600 by phpDocumentor 1.4.4