Design Reference ================ Python ------ When choosing what to document, AutoAPI aims to document anything that is publicly accessible through the actual package when loaded in Python. For example if a function is imported from a submodule into a package, that function is documented in both the submodule and the package. There are some exceptions to this rule: * Anything that is imported into a module is not documented. Usually a module is where implementations exist. Therefore an import of something is usually for the usage of the implementation, and not as something to be accessed publicly. * When the module or package defines an ``__all__``, only the members named in ``__all__`` are documented. * When a configuration option indicates that private or special members should also be documented. Furthermore, AutoAPI follows the same docstring inheritance rules as :func:`inspect.getdoc`, with some exceptions: * The docstrings of the following methods are not inherited because they are usually redundant: * :meth:`object.__init__` * :meth:`object.__new__` * :meth:`type.__init__` * :meth:`type.__new__` Introduction ------------ We are working with Sphinx, which has an existing way of doing this. Generally, you define a `Domain` which describes the various language structure, a *Class* or *Method*, for example. Then the user will write RST that uses these definitions, and Sphinx will create output from that markup. .. code-block:: rst .. py:function:: spam(eggs) Spam the foo. The author of the documentation will have now told Sphinx that the *spam* function exists in the Python project that is being documented. Autogenerated Output ~~~~~~~~~~~~~~~~~~~~ Sphinx then built a series of tools to make the generation of this markup easier and more automatic: * `Autodoc `_ * `Autosummary `_ Autodoc is a Python-only solution that imports the author's code into memory, and then allows the author to more automatically document full objects. For example, you can document a whole class on a page. .. code-block:: py .. autoclass:: Noodle This will generate output that looks like: .. class:: Noodle :noindex: Noodle's docstring. There are also options for it to include a full listing of the classes attributes, methods, and other things, automatically. .. warning:: Remember, this depends on ``Noodle`` being importable by the Python interpreter running Sphinx. Proposed Architecture --------------------- The proposed architecture for this project is as follows: * A parser will read the source files into an internal representation of the objects that can be documented. * Take the internal representation and generate in-memory rst that corresponds to the Sphinx domain objects. * Sphinx will output HTML based on the doctree generated from the in-memory rst. In diagram form:: Code -> Internal Objects -> RST -> Sphinx -> HTML File Structure vs. Hierarchy ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Specific ID's should have one specific detail representation. This means that every internal object should only have one place that it is rendered with a ``.. :::`` canonical identifier. All other places it is referenced should be in either: * A reference * A toctree (listing) Sphinx Implementation ~~~~~~~~~~~~~~~~~~~~~ The user will run a normal `make html` as part of the experience. The generation and loading will be done as an extension that can be configured. There will be Sphinx configuration for how things get built: .. code-block:: rst autoapi_root = 'api' # Where HTML is generated autoapi_dirs = ['yaml'] # Directory of YAML sources We will then loop over all source files in the ``autoapi_dir`` and parse them. They will then be output into ``autoapi_root`` inside the documentation. Examples -------- A nice example of Sphinx Python output similar to what we want: * http://dta.googlecode.com/git/doc/_build/html/index.html * Src: https://raw.githubusercontent.com/sfcta/dta/master/doc/index.rst An example domain for Spec: * https://subversion.xray.aps.anl.gov/bcdaext/specdomain/trunk/src/specdomain/sphinxcontrib/specdomain.py