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: CHMdefaultConverter.inc,v 1.12 2007/04/19 20:20:57 ashnazg Exp $
  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: 1.12 $
  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