From e0d2706b7070b13803ab8a62d89966a58f5aeb6b Mon Sep 17 00:00:00 2001 From: Alan Knowles Date: Fri, 14 Oct 2016 10:36:46 +0800 Subject: [PATCH] CodeDoc.php --- CodeDoc.php | 420 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 420 insertions(+) create mode 100644 CodeDoc.php diff --git a/CodeDoc.php b/CodeDoc.php new file mode 100644 index 0000000..80b6b76 --- /dev/null +++ b/CodeDoc.php @@ -0,0 +1,420 @@ + | +// +----------------------------------------------------------------------+ +// +/** +* 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; + } + + foreach(self::$parser->classes as $k=>$cls) { + var_dump($cls->name); + $ar = $cls->toJs(); + if (!$ar) { + continue; + } + $cats = $ar[$cls->name]; + unset($ar[$cls->name]); + print_R($cats); + 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)); + } + + + } + + } + +} \ No newline at end of file -- 2.39.2