BreakingExpress

Building customized documentation workflows with Sphinx

Sphinx is a well-liked utility for creating documentation, just like JavaDoc or Jekyll. However, Sphinx’s reStructured Text enter permits for the next diploma of customization than these different instruments.

This tutorial will clarify easy methods to customise Sphinx to fit your workflow. You can comply with alongside utilizing pattern code on GitHub.

Some definitions

Sphinx goes far past simply enabling you to type textual content with predefined tags. It means that you can form and automate your documentation by defining new roles and directives. A position is a single phrase aspect that often is rendered inline in your documentation, whereas a directive can include extra advanced content material. These will be contained in a area.

A Sphinx area is a set of directives and roles in addition to a couple of different issues, comparable to an index definition. Your subsequent Sphinx area might be a particular programming language (Sphinx was developed to create Python’s documentation). Or you might need a command line instrument that implements the identical command sample (e.g., instrument <command> –args) time and again. You can doc it with a customized area, including directives and indexes alongside the best way.

Here’s an instance from our recipe area:

The recipe accommodates `tomato` and `cilantro`.

.. rcp:recipe:: TomatoSoup
  :accommodates: tomato cilantro salt pepper  

  This recipe is a tasty tomato soup, mix all substances
  and prepare dinner.

Now that we have outlined the recipe TomatoSoup, we will reference it anyplace in our documentation utilizing the customized position refef. For instance:

You can use the :rcp:reref:`TomatoSoup` recipe to feed your loved ones.

This permits our recipes to point out up in two indices: the primary lists all recipes, and the second lists all recipes by ingredient.

What’s in a site?

A Sphinx area is a specialised container that ties collectively roles, directives, and indices, amongst different issues. The area has a reputation (rcp) to handle its parts within the documentation supply. It proclaims its existence to Sphinx within the setup() technique of the package deal. From there, Sphinx can discover roles and directives, since these are a part of the area.

This area additionally serves because the central catalog of objects on this pattern. Using preliminary knowledge, it defines two variables, objects and obj2ingredient. These include an inventory of all objects outlined (all recipes) and a hash that maps a canonical ingredient title to the record of objects.

initial_data =

The approach we title objects is frequent throughout our extension. For every object created, the canonical title is rcp.<typename>.<objectname>, the place <typename> is the Python sort of the item, and <objectname> is the title the documentation author offers the item. This permits the extension to make use of totally different object varieties that share the identical title.

Having a canonical title and central place for our objects is a big benefit. Both our indices and our cross-referencing code use this function.

Custom roles and directives

In our instance, .. rcp:recipe:: signifies a customized directive. You would possibly assume it is overly particular to create customized syntax for these things, nevertheless it illustrates the diploma of customization you will get in Sphinx. This offers wealthy markup that constructions paperwork and results in higher docs. Specialization permits us to extract info from our docs.

Our definition for this directive will present minimal formatting, however it is going to be purposeful.

class RecipeNode(ObjectDescription):
  """A customized node that describes a recipe."""

  required_arguments = 1

  option_spec =

For this directive, required_arguments tells Sphinx to count on one parameter, the recipe title. option_spec lists the non-compulsory arguments, together with their names. Finally, has_content specifies that there will probably be extra reStructured Text as a baby to this node.

We additionally implement a number of strategies:

  • handle_signature() implements parsing the signature of the directive and passes on the item’s title and kind to its superclass
  • add_taget_and_index() provides a goal (to hyperlink to) and an entry to the index for this node

Creating indices

Both IngredientIndex and RecipeIndex are derived from Sphinx’s Index class. They implement customized logic to generate a tuple of values that outline the index. Note that RecipeIndex is a degenerate index that has just one entry. Extending it to cowl extra object varieties—and shifting from a RecipeDomain to a CookbookDomain—shouldn’t be but a part of the code.

Both indices use the tactic generate() to do their work. This technique combines the knowledge from our area, kinds it, and returns it in an inventory construction that will probably be accepted by Sphinx. See the Sphinx Domain API web page for extra info.

The first time you go to the Domain API web page, you could be a little bit overwhelmed by the construction. But our ingredient index is only a record of tuples, like (‘tomato’, ‘TomatoSoup’, ‘take a look at’, ‘rec-TomatoSoup’,…).

Referencing recipes

Adding cross-references shouldn’t be troublesome (nevertheless it’s additionally not a given). Add an XRefRole to the area and implement the tactic resolve_xref(). Having a customized position to reference a kind permits us to unambiguously reference any object, even when two objects have the identical title. If you have a look at the parameters of resolve_xref() in Domain, you will see typ and goal. These outline the cross-reference sort and its goal title. We’ll use goal to resolve our vacation spot from our area’s objects as a result of we at present have just one sort of node.

We can add the cross-reference position to RecipeDomain within the following approach:

roles =
    'reref': XRefRole()

There’s nothing for us to implement. Defining a working resolve_xref() and attaching an XRefRole to the area is all that you must do.

For additional studying

If you’d prefer to be taught extra, try these assets:

Exit mobile version