| // +----------------------------------------------------------------------+ // /** * Docbook data container (for pages and sections) * * @package PHP_CodeDoc * @access public * @author Alan Knowles * */ ini_set("memory_limit","128M"); set_time_limit(0); error_reporting(E_ALL); require_once("PEAR.php"); require_once("HTML/Template/Flexy.php"); require_once("PHP/CodeDoc/Parser.php"); require_once("PHP/CodeDoc/Error.php"); /* * @Docbook * @Docbook_package_section packages.php.codedoc * @Docbook_title PHP Code Documenter * @Docbook_page INDEX * * This chapter expains how to use the phpcodedoc tool which can generate lxr type html and docbook * output from comments embedded in class files * * @Docbook_page Introduction * @Docbook_page_summary what is PHP_CodeDoc all about? * * @Docbook_section Introduction * * PHP_CodeDoc was written for a number of reasons * @Docbook_list * - To make use of the php tokenizer module to generate documentation * - To produce documentation that showed the source code as well as the notes * - Because I saw the ruby class documentation, and thought it looked very clear.. * * * PHP_CodeDoc was not written (unlike most other similar applications) to emulate javadoc, * my main logic here was that javadoc is focused on documenting closed source applicaitons * where as most of the stuff I need to document is open source - so including the source * in the output was essential to understanding what the class really did. * * @Docbook_page Configuring PHP_CodeDoc * @Docbook_page_summary Setting up PHP_CodeDoc * * @Docbook_section Main configuration options * * */ /** * The Main PHP_CodeDoc class - only really public class... * * @version $Id: CodeDoc.php,v 1.15 2002/12/22 13:51:23 alan Exp $ */ class PHP_CodeDoc { static $parser; static $options; /** * Start the Parsing and Generation Process * * based on information contained in the PEAR::getStaticProperty('PHP_CodeDoc','options') * parse all the directories and generate all the requested documentation * * * @return none */ function __construct() { self::$options = PEAR::getStaticProperty('PHP_CodeDoc','options'); self::$parser = new PHP_CodeDoc_Parser(); self::$parser->start(); $this->_prepareOutput(); $this->outputJs(); die("done"); PHP_CodeDoc::_outputFromTemplate("navigation.template.html", '/nav.html'); PHP_CodeDoc::_outputFromTemplate("index.template.html",'/index.html'); PHP_CodeDoc::_outputFunctions(); PHP_CodeDoc::_outputDefines(); PHP_CodeDoc::_outputClasses(); PHP_CodeDoc::_outputDocbook(); } // -------------------------------Outputting Methods --------------- /** * Output parser's data using a template * * Takes the parser object and overlays that on the template, * outputing to a file * * * @param string Template filename * @param string Output filename * * * @return none * @access private */ function _outputFromTemplate($template="test.html",$output_file_name) { $toptions = PEAR::getStaticProperty('HTML_Template_Flexy','options'); $poptions = PEAR::getStaticProperty('PHP_CodeDoc','options'); if (!@$toptions['templateDir']) { $toptions['templateDir'] = dirname(__FILE__)."/CodeDoc/templates"; } echo "Building $template: $output_file_name\n"; $template_engine = new HTML_Template_Flexy($toptions); $template_engine->compile($template); $data = $template_engine->bufferedOutputObject(self::$parser); $dir = dirname($poptions['destDir'].$output_file_name); if (!@file_exists($dir)) { `mkdir -p $dir`; // not very portable } $fh = fopen($poptions['destDir'].$output_file_name,"w"); fputs($fh,$data); fclose($fh); } /** * Output individual classes a single files using template and directory * * @return none * @access private */ function _outputClasses() { foreach(array_keys(self::$parser->classes) as $i) { self::$parser->active_class = &self::$parser->classes[$i]; if (@!self::$parser->active_class->name) continue; echo "Outputing {self::$parser->active_class->name}\n"; PHP_CodeDoc::_outputFromTemplate( "class.template.html", "/{self::$parser->active_class->name}.html" ); } } /* Output Defines from class directories * * @return none * @access private */ function _outputDefines() { foreach(array_keys(self::$parser->packages) as $packagename) { if (!self::$parser->packages[$packagename]->directories) continue; self::$parser->active_package = &self::$parser->packages[$packagename]; foreach(array_keys(self::$parser->packages[$packagename]->directories) as $dir) { if (!self::$parser->packages[$packagename]->directories[$dir]->defines) continue; self::$parser->defines = & self::$parser->packages[$packagename]->directories[$dir]->defines; echo "Outputing Defines for {$packagename}:{$dir}\n"; self::$parser->output_active_directory = self::$parser->packages[$packagename]->directories[$dir]; PHP_CodeDoc::_outputFromTemplate("defines.template.html", "/".urlencode($dir). "-defines.html"); } } } /* * Output Functions in a package * * @return none * @access private */ function _outputFunctions() { foreach(array_keys(self::$parser->packages) as $packagename) { if (!self::$parser->packages[$packagename]->directories) continue; self::$parser->active_package = &self::$parser->packages[$packagename]; foreach(array_keys(self::$parser->packages[$packagename]->directories) as $dir) { if (!self::$parser->packages[$packagename]->directories[$dir]->functions) continue; self::$parser->functions = & self::$parser->packages[$packagename]->directories[$dir]->functions; echo "Outputing Defines for {$packagename}:{$dir}\n"; self::$parser->output_active_directory = self::$parser->packages[$packagename]->directories[$dir]; PHP_CodeDoc::_outputFromTemplate("functions.template.html","/".urlencode($dir). "-functions.html"); } } } /* * Output Docbook * * @return none * @access private */ function _outputDocbook() { if (!@self::$options['makeDocbook']) { return; } foreach(array_keys(self::$parser->packages) as $i) { self::$parser->active_package = &self::$parser->packages[$i]; //print_r(self::$parser->active_package->docbook); if (@!self::$parser->active_package->docbook) { unset(self::$parser->packages[$i]); continue; } if (!method_exists(self::$parser->active_package->docbook, 'mergeMethods')) { unset(self::$parser->packages[$i]); continue; } if (self::$parser->active_package->name == "No Package") { unset(self::$parser->packages[$i]); continue; } self::$parser->active_package->docbook->mergeMethods(); if (!@self::$parser->active_package->docbookBase) { self::$parser->active_package->docbookBase = "packages." . str_replace('_','.',self::$parser->active_package->name); } echo "Outputing {self::$parser->active_package->name}\n"; $filename = str_replace('_', '/', self::$parser->active_package->name); PHP_CodeDoc::_outputFromTemplate( "docbook.template.xml", "/docbook/en/packages/$filename.xml"); } PHP_CodeDoc::_outputFromTemplate( "manual.template.xml.in", "/docbook/manual.xml.in"); } /* * Prepare Output for display * - eg. sort some of the classes and functions by name * apply extends * * @return none * @access private */ function _prepareOutput() { PHP_CodeDoc::_buildExtends(); echo "\n starting sorting \n"; uksort(self::$parser->classes_by_name, "strnatcasecmp"); $highlight = 1; foreach(array_keys(self::$parser->classes) as $k) { self::$parser->classes[$k]->highlight = $highlight; //if (@$this->classes[$k]->Operations) // uksort($this->classes[$k]->Operations, "strnatcasecmp"); if (@self::$parser->classes[$k]->Attributes) uksort(self::$parser->classes[$k]->Attributes, "strnatcasecmp"); $highlight = !$highlight; } // set highlihgts by name $highlight = 1; foreach(array_keys(self::$parser->classes_by_name) as $k) { $id = self::$parser->classes_by_name[$k]->id; self::$parser->classes[$id]->highlight_by_name = $highlight; $highlight = !$highlight; } uksort(self::$parser->packages, "strnatcasecmp"); // sorts package names foreach(array_keys(self::$parser->packages) as $packagename) { $package = & self::$parser->packages[$packagename]; if (!$package->directories) { continue; } uksort($package->directories, "strnatcasecmp"); // sorts dirs foreach(array_keys($package->directories) as $directoryname) { $directory = &$package->directories[$directoryname]; if (@$directory->classes) uksort($directory->classes, "strnatcasecmp"); // sorts classes } } //print_r($this->classes); //ob_start() } /* * build the extends arrays for classes * * @return none * @access private */ function _buildExtends() { echo "BUIDLING EXTENDS"; foreach(array_keys(self::$parser->classes) as $k) { echo self::$parser->classes[$k]->name ."\n"; /*if (self::$parser->classes[$k]->name == 'PDO_DataObject') { print_r(self::$parser->classes[$k]); exit; } */ PHP_CodeDoc::_mergeExtends($k,self::$parser->classes[$k]->Parent); if (self::$parser->classes[$k]->extends) self::$parser->classes[$k]->extends = array_reverse(self::$parser->classes[$k]->extends); } echo "\n"; } /* * Merge the Operations/Attributes for classes * * @return none * @access private */ function _mergeExtends($original_id,$Parent) { if (!$Parent) return; $id = @self::$parser->classes_by_name[$Parent]->id; if (!$id) return; self::$parser->classes[$original_id]->extends[] = $Parent; foreach(self::$parser->classes[$id]->Operations as $k=>$v) { if (@self::$parser->classes[$original_id]->Operations[$k]) { self::$parser->classes[$original_id]->Operations[$k]->override =1; continue; // ignore overrides } if (@self::$parser->classes[$original_id]->iOperations[$k]) continue; self::$parser->classes[$original_id]->iOperations[$k] = &self::$parser->classes[$id]->Operations[$k]; } foreach(self::$parser->classes[$id]->Attributes as $k=>$v) { if (@self::$parser->classes[$original_id]->Attributes[$k]) { self::$parser->classes[$original_id]->Attributes[$k]->override =1; continue; } if (@self::$parser->classes[$original_id]->iAttributes[$k]) continue; self::$parser->classes[$original_id]->iAttributes[$k] = &self::$parser->classes[$id]->Attributes[$k]; } PHP_CodeDoc::_mergeExtends($original_id,self::$parser->classes[$id]->Parent); } function outputJs() { if (!isset(self::$options['targetJS'])) { return; } $cats = array(); foreach(self::$parser->classes as $k=>$cls) { var_dump($cls->name); $ar = $cls->toJs(); if (!$ar) { continue; } foreach($ar[$cls->name] as $cat=>$catdata) { $cats[$cat] = isset($cats[$cat]) ? array_merge($cats[$cat], $catdata) : $catdata; } unset($ar[$cls->name]); print_R($cats); //print_R($cls); exit; foreach($ar as $fn => $data) { if (!$data){ continue; } $file = self::$options['targetJS'].'/'.$fn.'.bjs'; if (!file_exists(dirname($file))) { mkdir(dirname($file),0755,true); } echo "$file\n"; file_put_contents($file, json_encode($data,JSON_PRETTY_PRINT)); } } $file = self::$options['targetJS'].'/categories.json'; file_put_contents($file, json_encode($cats ,JSON_PRETTY_PRINT)); } }