Converter Manual
Learn how to use and extend a Converter
Detailed Documentation of the tag specification is available at phpDocumentor tags. Detailed information on phpDocumentor and a tutorial on basic usage is at: phpDocumentor Tutorial
If you are wondering how to extend the capabilities of phpDocumentor's output, this is the documentation you need. This documentation does not discuss how to document your code or project, and only deals with the specific requirements of extending phpDocumentor.
Internals: how phpDocumentor takes source code and generates documentation
phpDocumentor is divided into three logical components: Parser, IntermediateParser and Converter. These three divisions communicate through special method interfaces.
Parser internals
The Parser component does the work of reading the actual files, both source code and tutorial/manual files. For a detailed discussion of how to write a tutorial, see phpDocumentor Tutorials, or read the source files for phpDocumentor's manual in the tutorials/ subdirectory. The Parser encapsulates input into abstract classes, all of which are defined in seven files:
The abstract classes are then passed to the Intermediate Parser.
The IntermediateParser class organizes and processes abstract data passed in with the assistance of the ProceduralPages and Classes classes. All data is sorted alphabetically and then passed to the converters specified on the command-line one by one. Traditionally, the next step would be to generate output by passing the abstract data to a template engine. phpDocumentor has one more layer of separation to accomodate different output formats called "Converters."
What is a Converter? To understand this, one must first understand the problem that Converters solve. Documentation is not always best viewed as a web page. Sometimes a user may want to print it out, or view it in XML with an interface program that can search or perform other advanced functions. Printing html does not work very well, and may look very different on different user's screens. To solve this problem, we need an interface between the parser and the template engine, hence the Converter.
On an even more basic level, the linking performed by phpDocumentor requires that the program pass over the data at least twice to set up relationships and create the @see, @tutorial, {@tutorial} and {@link} hyperlinks that make it such an effective tool. In earlier versions of phpDocumentor, the parser passed over the data twice, with significant redundancy and slow parsing times. In addition, the linking pass had to be first, and the order of parsing was important. In other words, if file A contains class B extends foo, and file B contains class foo, if file A is parsed before file B, no inheritance occurs between the classes (you can try this with phpDocumentor 0.4.2a and earlier, it breaks the parser). The Converter works with temporary data structures (all defined in ParserData.inc, ParserElements.inc, and ParserDocBlock.inc if you want a peek), and allows the linking pass to occur in-memory after parsing, with a significant speedup (almost twice as fast as earlier versions).
Adding a template
In most cases, it is possible to leverage the existing code to create spectacular output simply by writing a new set of templates for one of the existing Converters. To learn how to write templates for each specific converter, choose from the list below:
Extending an existing Converter by writing your own Converter Class
If the existing converters work except for a small detail that could be fixed by adding a small patch to the source code of an output converter, then you need to extend a Converter. There are several straightforward rules that allow you to easily extend a Converter.
Rules for extending a Converter
First, the extended converter must be defined by a single word that would work as a valid filename. For an example, if the Converter extends the HTMLframesConverter, and provides search functionality in the generated documentation through the insertion of special php code into the generated files, it might be named "Search."
Once a name has been chosen, a subdirectory of the parent converter (HTMLframesConverter is in phpDocumentor/Converters/HTML/frames/) must be created with the same name as the child converter. So, for our "Search" Converter, the directory phpDocumentor/Converters/HTML/frames/Search/ must be created. Put your new Converter in a file called "HTMLframesSearchConverter.inc". Note the insertion of our new Converter's name before the word "Converter" in the filename.
Next, create a class declaration in the new HTMLframesSearchConverter.inc file as below:
/**
* HTML output converter.
*
* This Converter takes output from the {@link Parser} and converts it to HTML-ready output for use with {@link Smarty}.
* Add any extra documentation about the search capabilities here
* @package Converters
* @subpackage HTMLframes
*/
class HTMLframesSearchConverter extends Converter
{
/**
* frames/Search Converter wants elements sorted by type as well as alphabetically
* @see Converter::$sort_page_contents_by_type
* @var boolean
*/
var $sort_page_contents_by_type = true;
/** @var string */
var $outputformat = 'HTML';
/** @var string */
var $name = 'frames/Search';
Note the var $name is set to the relative subdirectory. This is very important. Do not set the name to be "framesSearch", as the Converter::setTemplateDir() method uses this variable to set the template directory.
If the existing templates work fine, and there is some other change needed, set the name to be the same as the parent, and phpDocumentor will use the parent templates.
After extending the methods the new Search Converter will need, place the templates in a subdirectory named templates/ (as in phpDocumentor/Converters/HTML/frames/Search/templates/), just as they are used in the converters that come with phpDocumentor.
Using an extended Converter with phpDocumentor
After all this complexity of setting up the Converter, using it is straightforward. simply pass -o HTML:frames/Search:templatename to phpDocumentor's web interface or commandline!
Writing a Converter for a new output format
This topic is very large, and a separate manual entry is devoted entirely to this subject, Writing a New Converter