blob: c6f792a81d53e28ba5ae98fb8d2d8ef94e5154d9 [file] [view]
# 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:
```rst
==================
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:
```rst
=====
Title
=====
-------
Section
-------
Subsection
==========
```
No (too long):
```rst
========
Title
========
--------
Section
--------
Subsection
===============
```
No (too short):
```rst
====
Title
====
---
Section
---
Subsection
======
```
### Section title whitespace
Do not put a blank line between a section title and the content that follows
it.
Yes:
```rst
=====
Title
=====
Lorem ipsum
```
No:
```rst
=====
Title
=====
Lorem ipsum
```
Put one blank line between the end of content and a following section title.
Yes:
```rst
Lorem ipsum
-------
Section
-------
```
No (too many blank lines):
```rst
Lorem ipsum
-------
Section
-------
```
No (no blank line):
```rst
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:
```rst
.. foo::
:attr:
Content
```
No (attribute and content are indented 2 spaces):
```rst
.. foo::
:attr:
Content
```
No (missing blank line between attribute and content):
```rst
.. foo::
:attr:
Content
```
## Tables
Do not use [grid tables] or [simple tables]. Use [list-table] (preferred) or
[csv-table].
Yes:
```rst
.. list-table::
:header-rows: 1
* - cat
- dog
* - green
- blue
```
No (grid table):
```rst
+-------+------+
| cat | dog |
+=======+======+
| green | blue |
+-------+------+
```
No (simple table):
```rst
===== ====
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](https://pygments.org/languages/):
```rst
.. 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:
```rst
:cs:`pw_allocator/allocator.cc`
```
Link to a file or directory at a specific commit:
```rst
:cs:`pw_allocator/allocator.cc
<a18dd872b2c6fd544f96b38b31aafca6b4a0fa7b:pw_allocator/allocator.cc>`
```
Link to a commit:
```rst
:cs:`my commit <a18dd872b2c6fd544f96b38b31aafca6b4a0fa7b>`
```
Link to a specific line within a file at a certain commit:
```rst
: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:
```rst
:cc:`TinyBlock <pw::allocator::TinyBlock>`
```
`TinyBlock` is the link text and `pw::allocator::TinyBlock` is the underlying
link.
No (the underlying link is relative):
```rst
:cc:`TinyBlock <allocator::TinyBlock>`
```
#### Unqualified symbols
Never allowed.
Yes:
```rst
:cc:`pw::foo::Bar`
```
No:
```rst
: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:
```rst
:cc:`pw::IntrusiveList`
```
No:
```rst
: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):
```rst
:cc:`PendRead <pw::channel::AnyChannel::PendRead>`
```
No (when linking from a `pw_channel` doc to a `pw_channel` symbol):
```rst
: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):
```rst
:cc:`channel::AnyChannel::PendRead <pw::channel::AnyChannel::PendRead>`
```
No (when linking from a `pw_async2` doc to a `pw_channel` symbol):
```rst
: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.
[grid tables]: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#grid-tables
[simple tables]: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#simple-tables
[list-table]: https://docutils.sourceforge.io/docs/ref/rst/directives.html#list-table
[csv-table]: https://docutils.sourceforge.io/docs/ref/rst/directives.html#csv-table