/jsdocgen

API documentation generator and front end.

Primary LanguageJavaScript

jsdocgen

API documentation generator and viewer.

Features:

  • Generates the documentation quickly, a library of ~200 PHP files takes ~3 seconds on a below average laptop.
  • Designed with support of several languages in mind.
  • Markdown support, no ugly XML/HTML in the docs.
  • Each method/property/function is displayed on a separate page, not in a single page for the class.
  • Decent looking GUI, unmixed with the docs themselves.
  • No external dependencies to install.

Warning: GitHub's zip files are broken and ignore some files from the repository. You can either do full checkout (with submodules) or I will upload a proper zip file soon when I have some spare time.

Demo

The documentation of ProviderKit PHP and phptestr is generated by jsdocgen.

Contents

Status

The project currently supports only PHP but other languages (JavaScript, Java) are planned for the next release. The project version is 0.9 and is considered beta because it is not tested for long period and it may have rough edges. The PHP support is almost fully complete. All OOP features of PHP 5.4 are supported + functions, the only thing that is not implemented is the @inheritdoc tag to inherit docs from parent class, but there is autoinherit functionality for class methods without own doc comments. Documenting global variables or constants is not supported at the moment and currently there are no plans for adding such support. If necessary these elements can be described in the file level doc comment. The focus of jsdocgen is towards class libraries and there is limited ability to document scripts.

The project is tested on Windows, OSX and Linux.

Very quick start

There are no dependencies (besides PHP 5.4 itself) or anything of this sort, all you need to do is unzip jsdocgen, prepare your project and type two commands in the shell. The quickest way to build some docs is to use the bundled example.

  1. Open a shell to the folder of this readme.

  2. Parse the sources of the project

    jsdocgen -lang=php -projectdir=example -outdir=example/build/docs -intro=example/intro.md -autoinherit

    If we wanted the command to be absolutely minimal we could omit the -intro and -autoinherit.

  3. Build the viewer (front end) for your project

    jsdocgen build -lang=php -outdir=example/build -def=ProjectName:Example -def=ProjectSubtitle:Project

    If we wanted the command to be absolutely minimal we could omit the two -def arguments.

  4. Browse to example/build/index.html or check the screenshot in example/screenshot.png

  5. Everything in the build directory would be your docs. You need to redistribute everything that is in there.

The output of the first command should look similar to this, and the second command is not expected to output anything:

Looking for sources...
  ...........................\trunk\src */**.php:thirdparty ... 0.057s
Found 189 files

Generating docs...

Parsing sources...
Sources parsed in 1.608s
Found 3085 doc comments
Parsing documentation...
Doc comments parsed in 1.769s

Finished in 3.391s

Usage

This is guide how to write docs for jsdocgen and how to build these docs from the sources. Here only PHP is covered and the rest of the guide assumes PHP sources. Building the docs for other languages would be very similar but there might be some language related differences which are documented elsewhere.

jsdocgen is split in two parts - parser and viewer. The parser extracts the documentation from the project sources and converts it to more portable format (JSON). The viewer loads the formatted docs and displays them in the browser.

Writing some documentation

Writing documentation for jsdocgen is very similar to other system like PHPDocumentor or Doxygen. Actually the project started because PHPDocumentor couldn't serve my needs any more. If you already have documentation in PHPDocumentor format it will mostly work without changes. There are minor differences that can be changed with few simple "replace in files" commands. That doesn't mean jsdocgen strives for compatibility, but it is based on what I was familiar with. Unlike other popular documentation systems, the descriptions of jsdocgen are in markdown format, making them easier to read and write (in contrast to using HTML/XML) and suitable for formatting large volumes of text.

Doc comments

Doc comments are block comments with additional asterisk in the opening comment. They can be in PHPDocumentor format:

/**
 * Where
 * each line
 * starts with
 * another star
 * & each star is
 * aligned with space
 */

Or you can skip the stars and just write your docs.

/**
Stars are looking good but
I find them one of the reasons
why I write less docs. They are
not keyboard friendly.
*/

A doc comment consists of:

  • Optional one line summary.
  • Optional, possibly multiline, description.
  • List of tags. Each tag has a name and optional value. The value spans from after the name (+ one space) to the start of the next tag.
  • No tags before the summary or the description.
  • /** and */ reside on their own lines, not with the actual comments.
  • All lines after /** must have same indentation, including */. This indentation may differ from the indent before the /**.
  • Newlines will be converted to Unix format.
/**
 * This is a docblock summary (summary).
 * (description:) The asterisks at the beginning of lines,
 * together with the white space
 * will be trimmed.
 * @tags start after the description. The tag here is "tags".
 * @another tag - the tag here is
 * "another", this one spans multiple lines.
 */

The first doc comment in the file, just after the opening PHP tag, is a file-level block.

The text of the summary, the description and the description of each tag that has free form text is in markdown format.

Markdown

The markdown is mostly compatible with "GitHub Flavoured Markdown".

Additionally:

  • ~~~ can be used for code blocks (GitHub also supports this)
  • [Internal link][^anchor-name] will link to an anchor placed elsewhere in the same document.
  • [^anchor-name]: will place and anchor (it will be invisible)
  • This is ___underline___.
  • This is --strike through--.
  • Line breaks inside headers.
  • GFM line breaks (enter) are not respected. Always two trailing spaces and a newline to insert a line break.
  • \b will delete the previous character. This is useful if, for example, you want to type */ without closing the comment. You can write it as * \b/ and it will show as */.
  • Additional escape characters: ~ < > / | and space and tab.

Basic tags:

These are common tags that apply to all source elements.

@package <package[.subpackage.subsub...]>
Only supported in the file level block, marks all elements in this file as belonging to a package. If this tag is missing, the file will be assigned to the default package (which can be user defined).

@private
The element of the doc comment is marked private. It will not show in the viewer.

@deprecated [description]
Marks the API as deprecated and shows a warning.

@author <author>
Puts an author field in the meta section.

@license <license>
Puts a license field in the meta section.

@copyright <copyright>
Puts a copyright field in the meta section.

@todo <todo text>
Not implemented at the moment.

@see <target> [description]
Creates a 'see also' section and puts an entry with link there. The see target can be one of the following formats:

  • function()
  • Class or \Full\Class\Name
  • Class::$property
  • Class::constant
  • Class::method()
  • php:PHP_builtin_symbol where 'PHP_builtin_symbol' can be any of the above.
  • file/relative/tothe/projectdir.php
  • http://url.com

If classes and functions are not expressed with their full form (with namespace prefix) they are resolved by looking for them in the current namespace or class and then in the global namespace. In the context of a class 'function()' can refer to a method of the same class named 'function', the class prefix can be omitted. Also the 'php:' prefix for built symbols can be omitted and jsdocgen will attempt to autodetect that the symbol comes with PHP.

Inline tags

These can be inlined in another tags' description.

{@see <target> [description]}
The same as @see but will not create a 'see also' section and instead show the link where the tags is.

Context specific tags

@param <type> [description]
Can appear in the context of functions and methods. One @param tag can be placed for each function argument, in the same order. The 'type' describes the type of the variable that this argument accepts. If the argument contains a type hint, only the type hint is taken into account and everything in the @param tag is considered a description. Type can refer to any class with its full or short name, also to builtin PHP types or can be array of type, e.g. array of strings string[]. Other types that will not show as links include mixed, int, float, string, null, function, callback. Multiple types can be separated with a pipe, e.g. string|float[].

@return <type> [description]
Can appear in the context of functions and methods. Describes the return value of the function. The type is in the same format as in @param and additionally type $this can indicate the method can be used for chain calls.

@throws <type> [description]
Can appear in the context of a function or method. Indicates that the function may throw exception. 'type' is the same as in @param.

@vaarg [description]
Can appear in the context of functions and methods. Indicates the function accepts variable number of arguments.

@var <type> [description]
Can appear in the context of a property to describe the type of this property. 'type' is the same as in @param. If this tag appears and it has description, but there is no doc comment summary, the description of the tag will be put in the place of the doc comment summary.

Generating the docs

Once you populate your sources with doc comments you can use jsdocgen to parse the sources and generate docs in a format it can display. The process is twofold. First you invoke the parser, then you build the front end to make it specific for your project - to have your project's title and know about the location of your docs. The frontend needs to be built only once (unless you want to update), while the docs will be re-generated many times while you work and change them.

Parsing the sources

Before starting the parser it is important to understand how it works. It uses PHP's built in reflection capabilities, so to parse the sources it actually includes them in a PHP script. The downside of this approach is it can only parse libraries. On the upside it is fast. If you attempt to parse scripts that perform actions, not just declare classes, these scripts will actually be executed and may do something unwanted.

Before executing any scripts, the parser will define a constant named JSDOCGEN_PHP_PARSER, so if you need to tweak your sources for the parsing step, you can identify that the script is started by jsdocgen by checking if this constant is defined.

Additionally most libraries require some kind of autoloading mechanism or other setup. If your project needs such step you can create a small script that the parser will perform before including any sources.

Example

Lets look at the quick start example in details:

jsdocgen -lang=php -projectdir=example -outdir=example/build/docs -intro=example/intro.md -autoinherit

-lang=php is mandatory since extended language supported is planned for the next release.

-projectdir is mandatory and tells jsdocgen where to look for source files.

-outdir tell jsdocgen where to put the generated docs. If the directory does not exist it will be created. Strictly speaking this argument is optional but who wants to look for their sources in the temp folder. This directory will be filled with a lot of files that are not immediately useful, so you probably want them in a subfolder of where your docs will be. In this case the root of the docs is 'example/build' and this is where the viewer is placed, and 'docs' is the subfolder.

-intro tells jsdocgen to parse this file as markdown and show it on the front, before any API is selected.

-autoinherit will make jsdocgen attemt to automatically inherit documentation for class members without a doc comment. For example if you have interface which defines a method and class which implements this interface. But the method is not implemented by the class but by a trait that the class uses. If the method is documented in the interface, jsdocgen will be able to inherit its documentation for all classes that implement it (if the doc comment of the method implementation is omitted).

The important option that you will most likely need to include a setup script is -phpinit=<location> to point to the location of your setup script. This setup can boot your autoloader or just include some files so there won't be any undefined classes when your sources are included.

The "TravelSDK Core" from the demo section is not using special init script for the docs at all, it is directly including its own init script from the command line. But if it was to use init script for the documentation it would look like this - just a single line to include the autoloader of the library:

<?

require_once __DIR__ . '/../../lib/travelsdk-core-php/src/init.php';

?>

Additional useful options are -warnings or -strict which will display warning messages about the documentation if, for example, there is a @see tag that points to invalid symbol. This helps keeping your docs in good shape.

For all available options see "Using the parser" bellow.

Building the front end

Onece the documentation is built from sources we need to build the front end that displays them. This front end needs a building step so it knows about the name of your project. It only needs to be built once and not every time the documentation is rebuilt.

Example

Again the example from the quick start:

jsdocgen build -lang=php -outdir=example/build -def=ProjectName:Example -def=ProjectSubtitle:Project

build means we will be building the viewer, not generating docs.

-lang must match the language of the generated docs.

-outdir is where the viewer's main file (index.html) will be placed.

The two -def arguments define some variables that will be hardcoded in the viewer while building it.

By default the viewer will look for the docs in subfolder of where it is placed named 'docs'. If you choose a different location you also need to provide -docslocation=<location> argument. Location points to a folder relative to the viewer's root.

Using the parser

The parser is started with a command from the shell.

jsdocgen OPTIONS

OPTIONS

-lang=language

Required. Language of the project to parse. Supported languages are: "php".

-projectdir=path

Required. Path where project sources are located.

-outdir=path

Optional. Path where the output files will be stored. Defaults to the system temp directory.

-pattern=pattern

Optional. Pattern(s) in the -projectdir used to recognize source files. There is default based on the selected -lang. For example for PHP the default pattern is to look inside all subdirectories for .php files.

Patterns are simple regular expressions. * matches everything but forward slash /, and ** matches everything. Non greedy and only forward slashes are supported (they work fine on Windows). For example *.php will match all files with extension 'php' in the same directory. **.php will match all files with extension 'php' in the same directory and all sub directories. Multiple patterns can be delimited with a pipe |. For example *.php4|*.php5 will match all files with extension 'php4' or 'php5'. Additionally a list of exclude patterns can be appended after a colon :. Files and directories matching one of the exclude patterns will be filtered out.

More examples:

  • *.cpp will match "file.cpp" but not "dir/file.cpp".
  • **.cpp will match "dir/file.cpp" and "file.cpp".
  • **/*.cpp will match "dir/file.cpp" and "dir/subdir/file.cpp" but not "file.cpp".
  • **/**/*.cpp will match "dir/subdir/file.cpp" but not "dir/file.cpp" and "file.cpp".
-intro=path

Optional. File to use as intro page, before any API is selected. The format is the same as the descriptions in the doc comments of the selected language.

-defaultpackage=packagename

Optional. Put symbols without package in this one. The effect of this also depends on the actual language.

-withprivatemembers

Optional. Will include doc comments which are marked with @private or private class members, which are otherwise excluded from the generated documentation.

-warnings

Optional. Will print warnings about errors that will not prevent the docs from working, but may hinder quality.

-strict

Optional. Will treat all warnings as errors (does not depend on the -warnings option).

-autonotices

Optional. Displays console message when doing something automatically like detecting see symbols (see -phpautosee), or automatically inheriting missing documentation for class methods and such (see -autoinherit).

-autoinherit

Optional. Will attempt to inherit documentation for inherited class members which don't have a doc comment. The effect of this depends on the actual language.

-debug

Optional. Shows debug info and keeps intermediate files.

-cache

Optional. Use caching if possible. Used while debugging to avoid parsing sources if they were not changed.

PHP specific options

If no pattern is specified, the pattern for this parser defaults to **.php:.*|**/.* which is to include all files with php extension recursively and to exclude all files and folders starting with a dot.

Warning:
This parser uses PHP's built in reflection capabilities, so to parse the sources it actually includes them in a PHP script. This means it can only parse libraries. If you attempt to parse scripts that perform actions, these scripts will actually be executed and may do something unwanted.

Before executing any scripts, the parser will define a constant named JSDOCGEN_PHP_PARSER, so if you need to tweak your sources for the parsing step, you can identify that the script is started by jsdocgen by checking if this constant is defined.

-phpinit=setup_script

Optional. Setup script for the project. Some libraries need some initialization like including their autoloader. This script will be performed before any other source file.

-phpbin=path

Optional. Path to the PHP binary to use. Defaults to "php" and it should be in the system path for the default to work.

-phpautosee

Optional. Attempts to detect and link symbol references like methods() and classes::etc() in the descriptions, as if they were enclosed in a {@see} tag. Use with caution as this feature is not fully implemented and could interfere with markdown and/or HTML tags.

-phpextrafiles="file1[|file2|file3...]"

Optional. Pipe delimited list of additional files to parse for their file-level doc comment. The files in this list are parsed only for their file-level doc comment. Other elements will not be included. These files may be scripts as they will not be included by the PHP parser as the rest of the sources, only read as plain text and their first comment extracted.

Authors

Borislav Peev (borislav.asdf at gmail dot com) Tino Jahnke (tino.jahnke at web dot de)