reStructuredText (reST) style guide and conventions

Formatting

Line length

In general, 80 columns is the limit.

The following components can exceed 80 columns when it improves readability or is necessary for some other reason:

  • Tables

  • Code blocks

Indentation character

Always use spaces, never tabs.

Sections

Section title adornment conventions

reST identifies sections through their titles, which are marked up with underline and (optional) overline adornment. All Pigweed documentation must follow these section title adornment conventions:

==================
H1: Document title
==================

-----------
H2: Section
-----------

H3: Subsection
==============

H4: Subsubsection
-----------------

H5: Subsubsubsection
^^^^^^^^^^^^^^^^^^^^

H6: Subsubsubsubsection
.......................

H7 or higher section titles are not allowed.

Adornment length

The underline and overline (when present) must match the length of the section title text that they adorn.

Yes:

=====
Title
=====

-------
Section
-------

Subsection
==========

No (too long):

========
Title
========

--------
Section
--------

Subsection
===============

No (too short):

====
Title
====

---
Section
---

Subsection
======

Section title whitespace

Do not put a blank line between a section title and the content that follows it.

Yes:

=====
Title
=====
Lorem ipsum

No:

=====
Title
=====

Lorem ipsum

Put one blank line between the end of content and a following section title.

Yes:

Lorem ipsum

-------
Section
-------

No (too many blank lines):

Lorem ipsum


-------
Section
-------

No (no blank line):

Lorem ipsum
-------
Section
-------

Directives

Whitespace

Indent the attributes and content of directives 3 spaces so that they align with the directive name. Don't put a blank line between the directive name and its attributes. Put 1 blank line between the directive name (or last attribute) and the content.

Yes:

.. foo::
   :attr:

   Content

No (attribute and content are indented 2 spaces):

.. foo::
  :attr:

  Content

No (missing blank line between attribute and content):

.. foo::
   :attr:
   Content

Tables

Do not use grid tables or simple tables. Use list-table (preferred) or csv-table.

Yes:

.. list-table::
   :header-rows: 1

   * - cat
     - dog
   * - green
     - blue

No (grid table):

+-------+------+
| cat   | dog  |
+=======+======+
| green | blue |
+-------+------+

No (simple table):

===== ====
cat   dog
===== ====
green blue
===== ====

Code blocks

Use the code-block directive. Do not use the code or sourcecode aliases.

If Google has a style guide for the programming language in the code block, then the code should match that style guide.

Short names

code-block requires a lexer short name:

.. code-block:: <name>

   

Many languages support 2 or more short names. Always use the following:

  • Bazel: bazel for *.bazel files and starlark for *.bzl files

  • CMake: cmake

  • C++: c++

  • General log output, text diagrams, and unformatted text: output

  • GN: py

  • Python: py for *.py scripts and pycon for console sessions

  • Rust: rs

  • Shell scripts: bash for Bash and fish for Fish

  • CLI interactions: console for Unix and doscon for Windows

When in doubt, use the short name that seems most canonical and inform the user of your uncertainty.

Links

Code Search links

Use the custom :cs: role when linking to cs.opensource.google/pigweed/pigweed.

Examples

Link to a tip-of-tree file or directory:

:cs:`pw_allocator/allocator.cc`

Link to a file or directory at a specific commit:

:cs:`pw_allocator/allocator.cc
<a18dd872b2c6fd544f96b38b31aafca6b4a0fa7b:pw_allocator/allocator.cc>`

Link to a commit:

:cs:`my commit <a18dd872b2c6fd544f96b38b31aafca6b4a0fa7b>`

Link to a specific line within a file at a certain commit:

:cs:`my line
<a18dd872b2c6fd544f96b38b31aafca6b4a0fa7b:pw_allocator/allocator.cc;l=22>`

Sphinx-to-Doxygen links (Doxylink)

Pigweed's C/C++ API reference is hosted on a Doxygen subsite. To link from a Sphinx page to a Doxygen page, use the :cc: role.

[!NOTE] The :cc: role is powered by a fork of Doxylink that Pigweed maintains.

Always fully namespace underlying links

When using customized link text, the underlying link must always be fully namespaced.

Yes:

:cc:`TinyBlock <pw::allocator::TinyBlock>`

TinyBlock is the link text and pw::allocator::TinyBlock is the underlying link.

No (the underlying link is relative):

:cc:`TinyBlock <allocator::TinyBlock>`

Unqualified symbols

Never allowed.

Yes:

:cc:`pw::foo::Bar`

No:

:cc:`Bar`

If multiple Bar symbols exist in different namespaces, Doxylink guesses at what particular Bar it should link to. The docs can become incorrect in subtle, difficult-to-detect ways.

Symbols in the pw namespace

For symbols in the pw namespace (e.g. pw::Status) always use the fully qualified name.

Yes:

:cc:`pw::IntrusiveList`

No:

:cc:`IntrusiveList <pw::IntrusiveList>`

Symbols with 2 or more levels of namespace

When referring to a symbol within the same namespace, display the unqualified name.

Yes (when linking from a pw_channel doc to a pw_channel symbol):

:cc:`PendRead <pw::channel::AnyChannel::PendRead>`

No (when linking from a pw_channel doc to a pw_channel symbol):

:cc:`pw::channel::AnyChannel::PendRead`

When referring to a symbol from another namespace, use the minimal amount of namespacing that's required to disambiguate the namespace.

Yes (when linking from a pw_async2 doc to a pw_channel symbol):

:cc:`channel::AnyChannel::PendRead <pw::channel::AnyChannel::PendRead>`

No (when linking from a pw_async2 doc to a pw_channel symbol):

:cc:`pw::channel::AnyChannel::PendRead`

Cross-referencing docs in toctrees

Adding a doc to a toctree causes that doc to appear in the “section navigation” section of the UI. However, adding a doc to 2 or more toctree nodes causes undefined behavior. Sometimes the doc will appear in one section navigation, othertimes it appears in another section navigation.

To fix this, ensure that the doc has only 1 canonical toctree location in one particular doc across the entire site:

.. toctree::

   foo

To cross-reference this doc so that it appears in other section navigations, use our custom pw:// protocol:

.. toctree::

   foo <pw://pw_foo/docs.html>

At build time, our custom Sphinx extension (//docs/sphinx/_extensions/toctree.py) intercepts it and rewrites it to the correct local relative path (e.g., ../../pw_allocator_zephyr/docs.html).

Iteration loop

To check your work, build the documentation and resolve any errors:

  1. Run bazelisk build //docs.

  2. Address any warnings or errors reported by the build.

  3. Repeat until the build is clean.