Getting started
When using the Pydoc-Markdown integration with Novella to make use of its Markdown pre-processing capabilities,
Pydoc-Markdown comes as a plugin that provides a @pydoc
and @pylink
tag to insert Markdown documentation
generated by Pydoc-Markdown in the corresponding places of your documentation.
Installation
When using Pipx, the recommended installation method is to inject Pydoc-Markdown later:
$ pipx install novella
$ pipx inject novella pydoc-markdown[novella]
If you manage the environment yourself, it's sufficient to install Pydoc-Markdown with the novella
extra.
$ pip install pydoc-markdown[novella]
Configuration
A Novella build is configured using a build.novella
script. In most cases you want to rely on a template provided
by Novella, such as the MkDocs template. Check out the Novella documentation to find what types of templates
are available here.
template "mkdocs" {
content_directory = "content"
}
action "preprocess-markdown" {
use "pydoc"
}
What is happening here?
- The
mkdocs
pipeline template is applied. Thecontent_directory
is the directory that contains your MkDocs source files. It will be copied to the temporary build location alongside themkdocs.yml
file. Note that yourbuild.novella
script should sit next two these files.
Note: You should have
mkdocs
on yourPATH
and it should have themkdocs-material
theme installed (the default theme that Novella will apply if you don't specify a different one in yourmkdocs.yml
file or inbuild.novella
).
- The
preprocess-markdown
action that is one of the actions created by the template is retrieved and configured further. We instruct it to make use of the"pydoc"
plugin, which is implemented by Pydoc-Markdown and provides the@pydoc
and{@link pydoc:}
tags.
Note
-
The
content/
directory is the default so it does not need to be set explicitly and it is sufficient to writetemplate "mkdocs"
(without an empty configuration block). -
The
mkdocs
template will apply a default configuration delivered with Novella to your MkDocs configuration. If you don't want this, you can configure the"mkdocs-update-config"
action to disable this. Note that you can also have no MkDocs configuration file and the template will create a default file for you. -
The
pydoc
tag is implemented in {@link pydoc:pydoc_markdown.novella.preprocessor.PydocTagPreprocessor}. Look it up to understand how it can be configured further. -
The
pydoc
tag processor applies a heuristic to populate the default search path for your Python source code. If the directory in which the build is executed is calleddocs
ordocumentation
, it will default to[ "../src", ".." ]
, otherwise it will default to[ "src", "." ]
.
Using Novella tags
For example, the @cat
tag is useful to inject the content of another file.
# Welcome to my Project documentation!
@cat ../../readme.md :with slice_lines = "2:"
The @pydoc
tag is the piece provided by Pydoc-Markdown itself. It uses the Class MarkdownRenderer to generate Markdown formatted API documentation of
the API object you specify.
# API Documentation
@pydoc my_module.SomeClass
Build the documentation
Change into the docs/
directory where your build.novella
script resides and invoke the Novella CLI. The MkDocs
template exposes some command-line arguments that you can pass through the CLI, one of which is the --serve
option
that runs MkDocs in the server mode instead of building the documentation and writing it to disk.
usage: novella [--version] [-h] [-i TEMPLATE] [-c PATH] [-d DIRECTORY]
[-b PATH] [-r] [--dot] [--intercept ACTION] [--serve]
[--port PORT] [--site-dir PATH] [--base-url URL]
options:
--version show program's version number and exit
-h, --help Show this help output.
-i TEMPLATE, --init TEMPLATE
Create a `build.novella` file initialized from a
template. Available templates are: "mkdocs", "hugo"
-c PATH, --config-file PATH
The configuration file to load. Can be a
pyproject.toml in which case the code is looked up
under the tool.novella.script key. (default: None)
-d DIRECTORY, --directory DIRECTORY
Switch to the specified directory before executing the
configuration file.
-b PATH, --build-directory PATH
The build directory. If not specified, a temporary
directory will be created.
-r, --use-reloader Enable reloading, which will re-execute the pipeline
if a watched file changes.
--dot Produce a DotViz representation of the build graph.
--intercept ACTION The name of an action to intercept and pause the
execution, waiting for user input to continue. Useful
for debugging intermediate steps of the build process.
Currently, the action name must be matched exactly and
actions can only be intercepted before they are run.
If this option is provided, all possible intercept
points are logged to the console.
template (mkdocs):
--serve Use mkdocs serve
--port PORT The port to serve under
--site-dir PATH Build directory for MkDocs (defaults to "_site")
--base-url URL The base URL to prefix to autogenerated link inside
the documentation.
Advantages over the YAML Configuration
The YAML Configuration allows you to define in one file all pages and the Python API objects they should contain. However, when you use Novella, each page will need to exist as a Markdown file. This has a few advantages:
- Easier to understand; The YAML
pages
configuration could be hard to reason about, while having an actual file for each page is much more human friendly and actually resembles the project structure for the static site generator in use. - 1-to-1 mapping; Each page in the final documentation is represented by a file in the source project, allowing things like the "Edit URL" generated by MkDocs to point to the actual page source rather than a 404 page.
- Mixing static and generated content; Placing generated API documentation where the
@pydoc
tag is used in the Markdown page allows you to put static documentation content around it.
Now, if you still want to generate Markdown files at build time, Pydoc-Markdown does not currently provide any functionality to do that; although some discussion around the topic is happening in #245. However, the Novella build script is just code, so if you really need it, you can generate the files there:
template "mkdocs"
def api_pages = {
"SomeClass": "my_module.SomeClass",
# ...
}
action "mkdocs-update-config" {
site_name = "My module"
profile = "readthedocs"
update_with config -> {
def items = []
for title, package in api_pages.items():
items.append({ title: 'api/{}.md'.format(package) })
config['nav'].append({ 'API Documentation': items })
}
}
action "preprocess-markdown" {
use "pydoc"
}
do
name: "generate-api-pages"
closure: {
# Make sure that this action runs before the Markdown preprocessors.
precedes "preprocess-markdown"
}
action: {
for title, package in api_pages.items():
def path = directory / 'content' / 'api' / (package + '.md')
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text('---\ntitle: {}\n---\n@pydoc {}\n'.format(title, package))
}