adoc project
This program generates HTML documentation for Python projects by parsing the source code using Python's AST module. As such the source code is not loaded, it never reaches the interpreter and side-effects are effortlessly avoided.
This projet targets Python 3.5 and above.
Features
- AST-based Python parsing
- Fully
setup.py
-based configuration - MD/RST docstrings support
- Additional files inclusion as separate doc sections
- Built-in HTTP live-server
- Single HTML, PDF or Markdown artifact
Long-term Goals
- Symbol resolution, allowing linking through symbols within the document
- JPEG/PNG media inclusion (only one final artifact)
- In-document Graphviz processing
Installation
This is fairly straighforward:
pip install adoc
If you wish to output PDF documentation you'll need to install a different
flavour of adoc
:
pip install adoc[pdf]
Usage
For iteractive generation:
adoc --http .
For an HTML export:
adoc --html docs/index.html .
Hacking on the project
Prepare a virtual environment:
python -m venv env source env/bin/activate pip install -r requirements.txt pip install -r requirements-pdf.txt pip install -r requirements-test.txt
Run the test suite:
pytest .
To start the web server:
python -m adoc --http .
FAQ
Why aren't my Python packages discovered properly?
adoc relies on either setup.py
or find_packages()
for package
discovery. If you have any issue, you may want to check these places first.
The result of find_packages()
is easy to reproduce:
>>> from setuptools import find_packages >>> find_packages('.') ['adoc', 'adoc.formats']
If a package appears missing even though it's a valid package, you'll probably
want to make sure it contains __init__.py
since find_packages()
relies on
these files to determine what is a package and what is not (even though they
are not required in recent Python versions).
Why is one of my packages not showing up at all?
adoc is probably detecting that your package is empty. Here's the definition of an empty package:
- Your package does not hold any function
- Your package does not hold any class
- Your package does not hold any package
That definition is recursive so that a package holding empty packages is considered empty
My setup.py
is weird, I don't want to rely on it.
adoc allows you to override most relevant directives:
--package-dir
: where packages are located.--packages
: manually list packages.--no-setup
: ignoresetup.py
altogether.--find-packages
: force-discover packages.
I don't have a setup.py
.
adoc will attempt to rely on setup.py
as much as possible, but it will
resort to find_packages()
if it has to (and there are still command line
overrides as well).
On a typical project, there wouldn't be any noticeable difference:
adoc --http .
However, you may need to adjust a couple of things if the documentaion comes out as expected:
adoc --package-dir=src --http .
See examples/django-project
and the corresponding HTML
documentation to get an
idea.
My project is just a bunch of scripts.
adoc supports scripts declared in setup.py
and these can be specified
manually on the command-line as well:
adoc --scripts=main.py --http .
See examples/appengine-project
and the corresponding HTML
documentation to get an
idea.
Examples
- examples/django-project:
Django project, no
setup.py
- examples/appengine-project:
AppEngine project, no
setup.py
, no module
API Reference
Module adoc
Module adoc.cli
Command-line interface.
This module exports the program's entry point: main
.
Functions
def cli_setup(
)
CLI arguments parser setup.
def cli_compat(
ap)
CLI backward compatibility.
def logging_setup(
verbose)
def main(
args=None)
Program entry point.
This is where command line arguments are configured and read. Then the configuration is fine-tuned for execution.
Classes
class SplitAppend
Argument parsing action for repeatable csv strings.
Ancestors
Methods
def __call__(
self, parser, namespace, values, option_string=None)
Module adoc.codegen
Python source code generation.
Functions
def lookup(
mapping, atom)
def make_signature(
node)
def make_python(
node)
Generate Python code from an AST node (a subtree).
Module adoc.errors
Classes
class FatalError
Module adoc.formats
Module adoc.formats.md
Markdown formatter.
Functions
def format_md(
text)
Format Markdown text to HTML.
Module adoc.formats.rst
reStructuredText formatter.
This module aims to bring a decent level of compatibility with Sphinx without
relying on anything except docutils
.
This is obviously still a work in progress.
Docutils resources:
- https://docutils.readthedocs.io/en/sphinx-docs/howto/rst-directives.html
- https://docutils.readthedocs.io/en/sphinx-docs/howto/rst-roles.html
Sphinx resources:
- http://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html
- http://www.sphinx-doc.org/en/master/usage/restructuredtext/roles.html
- http://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html
- http://www.sphinx-doc.org/en/master/usage/restructuredtext/field-lists.html
- http://www.sphinx-doc.org/en/master/usage/restructuredtext/domains.html
Functions
def dummy_role(
role, rawtext, text, lineno, inliner, options={}, content=[])
def symbol_lookup(
role, rawtext, text, lineno, inliner, options={}, content=[])
def emphasis(
role, rawtext, text, lineno, inliner, options={}, content=[])
def format_rst(
text)
Format reStructuredText text to HTML.
Classes
class DummyDirective
Generic directive that does nothing.
class VersionAdmonition
Version-based admonitions.
Supports the following construction:
.. deprecated:: 0.1 This method is ...
Module adoc.httpd
Documentaion HTTP server.
This module provides an HTTP server exclusively for the purpose of serving HTML documentation over HTTP.
Classes
class RequestHandler
Documentation HTTP request handler.
It will serve HTML documentation for the project at project_path
. A
documentation server will only accept HEAD
and GET
requests and reply
with 404s for any request that's not made on /
.
Ancestors
Methods
def send_headers(
self)
def do_HEAD(
self)
Respond to HEAD
requests.
def do_GET(
self)
Respond to GET
requests.
Only /
will be served, other paths will result in 404s.
def log_message(
self, format, *args)
class Server
Documentation HTTP server.
It will reponde to HTTP requests using RequestHandler
.
Ancestors
Methods
def __init__(
self, host, port, parser, docstrings_format, strip_docstrings)
Module adoc.models
Project modelisation objects.
These data structures allow the modelisation of a project's documentation and source code.
They are handled mostly while parsing a project's source code and later transmited to the HTML writer.
Functions
def walk(
root, attr, max_depth=-1)
Classes
class Atom
Lowest-level unit representing a source code unit.
Methods
def __init__(
self, name, doc=None)
def __str__(
self)
def type(
self)
def fully_qualified_name(
self)
Recursively generate an Atom
's fully qualified name.
def from_ast(
cls, node)
Build Atom
instances from an AST node.
class ParametersMixin
Mixin for classes that hold parameters.
Methods
def add_parameters(
self, parameters)
Add parameters representation (ie. str
).
class DecoratorsMixin
Mixin for classes that hold decorators.
Methods
def add_decorators(
self, decorators)
Add decorators, (ie. str
).
class FunctionsMixin
Mixin for classes that hold Function
instances.
Methods
def is_empty(
self)
def add_function(
self, function)
Add a Function
instance, setting self
as its parent.
class Function
Representation of a function.
Ancestors
Methods
def from_ast(
cls, node)
Build a Function
instance from an AST node.
class ClassesMixin
Mixin for classes that hold Class
instances.
Methods
def is_empty(
self)
def add_class(
self, klass)
Add a Class
instance, setting self
as its parent.
class Class
Representation of a class.
Ancestors
Methods
def add_base(
self, base)
def from_ast(
cls, node)
Build a Class
instance from an AST node.
class ModulesMixin
Mixin for classes that hold Module
instances.
Methods
def is_empty(
self)
def add_module(
self, module)
Add a Module
instance, setting self
as its parent.
class Module
Representation of a module.
No distinction is made between modules and packages.
Ancestors
Methods
def is_empty(
self)
def merge(
self, module)
def from_ast(
cls, node, name)
Build a Module
instance from an AST node.
class Project
Representation of a project.
Ancestors
Methods
def __init__(
self, name, doc, metadata=None)
def add_document(
self, document)
def has_meta(
self, *keys)
def get_meta(
self, key, default=None)
def iter_modules(
self, max_depth=-1)
def iter_functions(
self, max_depth=-1)
def iter_classes(
self, max_depth=-1)
class Document
Representation of a document.
Supported document formats are html
, md
and rst
.
Methods
def __init__(
self, filename)
def html(
self)
Format a document to HTML.
The value of this property is cached for better performances.
def title(
self)
Extract a document's title.
For this to be possible, it has first to formatted to HTML.
The value of this property is cached for better performances.
Module adoc.parser
High-level parsing functions.
Classes
class ProjectParser
Methods
def __init__(
self, path, overrides, no_setup=False, exclude=None, find_packages=False, documents=None)
def parse(
self)
Parse a project, setting the current working directiory.
def parse_project(
self)
Parse a Python project in the current working directory.
def find_readme(
self)
Parse a README file in the current working directory.
def setup_exists(
self)
def load_setup(
self)
Parse a setup.py
file in the current working directory.
def parse_module(
self, path, name)
Parse a Python module.
def parse_file(
self, path, name, strip_ext=True)
Parse a Python file.
Module adoc.utils
Functions
def memoized(
f)
def compose(
*functions)
Classes
class WorkingDirectory
Methods
def __init__(
self, directory)
def __enter__(
self)
def __exit__(
self, *args)
Module adoc.writers
Module adoc.writers.html
HTML writer.
Functions
def write_html(
filename, project, docstrings_format='md', strip_docstrings=False)
def make_html(
project, docstrings_format, strip_docstrings)
Module adoc.writers.md
Markdown writer.
Functions
def write_md(
filename, project, docstrings_format, strip_docstrings)
def make_md(
project, docstrings_format, strip_docstrings)
Module adoc.writers.pdf
Functions
def write_pdf(
filename, project, docstrings_format, strip_docstring)
def make_pdf(
project, docstrings_format, strip_docstring)
Classes
class WeasyPrintLogFilter