aboutsummaryrefslogtreecommitdiff
path: root/docs/style/sphinx.rst
diff options
context:
space:
mode:
Diffstat (limited to 'docs/style/sphinx.rst')
-rw-r--r--docs/style/sphinx.rst632
1 files changed, 632 insertions, 0 deletions
diff --git a/docs/style/sphinx.rst b/docs/style/sphinx.rst
new file mode 100644
index 000000000..06a6a82ed
--- /dev/null
+++ b/docs/style/sphinx.rst
@@ -0,0 +1,632 @@
+.. _docs-pw-style-sphinx:
+
+==========================
+Sphinx documentation style
+==========================
+.. note::
+
+ Pigweed's documentation style guide came after much of the documentation was
+ written, so Pigweed's docs don't yet 100% conform to this style guide. When
+ updating docs, please update them to match the style guide.
+
+Pigweed documentation is written using the `reStructuredText
+<https://docutils.sourceforge.io/rst.html>`_ markup language and processed by
+`Sphinx`_. We use the `Furo theme <https://github.com/pradyunsg/furo>`_ along
+with the `sphinx-design <https://sphinx-design.readthedocs.io/en/furo-theme/>`_
+extension.
+
+.. _Sphinx: https://www.sphinx-doc.org/
+
+Syntax Reference Links
+======================
+.. admonition:: See also
+ :class: seealso
+
+ - `reStructuredText Primer`_
+
+ - `reStructuredText Directives <https://docutils.sourceforge.io/docs/ref/rst/directives.html>`_
+
+ - `Furo Reference <https://pradyunsg.me/furo/reference/>`_
+
+ - `Sphinx-design Reference <https://sphinx-design.readthedocs.io/en/furo-theme/>`_
+
+ReST is flexible, supporting formatting the same logical document in a few ways
+(for example headings, blank lines). Pigweed has the following restrictions to
+make our documentation consistent.
+
+.. inclusive-language: disable
+
+.. _reStructuredText Primer: https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html
+
+.. inclusive-language: enable
+
+Headings
+========
+Use headings according to the following hierarchy, with the shown characters
+for the ReST heading syntax.
+
+.. code-block:: rst
+
+ ==================================
+ Document Title: Two Bars of Equals
+ ==================================
+ Document titles use equals ("====="), above and below. Capitalize the words
+ in the title, except for 'a', 'of', and 'the'.
+
+ ---------------------------
+ Major Sections Within a Doc
+ ---------------------------
+ Major sections use hyphens ("----"), above and below. Capitalize the words in
+ the title, except for 'a', 'of', and 'the'.
+
+ Heading 1 - For Sections Within a Doc
+ =====================================
+ These should be title cased. Use a single equals bar ("====").
+
+ Heading 2 - for subsections
+ ---------------------------
+ Subsections use hyphens ("----"). In many cases, these headings may be
+ sentence-like. In those cases, only the first letter should be capitalized.
+ For example, FAQ subsections would have a title with "Why does the X do the
+ Y?"; note the sentence capitalization (but not title capitalization).
+
+ Heading 3 - for subsubsections
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ Use the caret symbol ("^^^^") for subsubsections.
+
+ Note: Generally don't go beyond heading 3.
+
+ Heading 4 - for subsubsubsections
+ .................................
+ Don't use this heading level, but if you must, use period characters
+ ("....") for the heading.
+
+Do not put blank lines after headings.
+--------------------------------------
+.. admonition:: **Yes**: No blank after heading
+ :class: checkmark
+
+ .. code-block:: rst
+
+ Here is a heading
+ -----------------
+ Note that there is no blank line after the heading separator!
+
+.. admonition:: **No**: Unnecessary blank line
+ :class: error
+
+ .. code-block:: rst
+
+ Here is a heading
+ -----------------
+
+ There is a totally unnecessary blank line above this one. Don't do this.
+
+Do not put multiple blank lines before a heading.
+-------------------------------------------------
+.. admonition:: **Yes**: Just one blank after section content before the next heading
+ :class: checkmark
+
+ .. code-block:: rst
+
+ There is some text here in the section before the next. It's just here to
+ illustrate the spacing standard. Note that there is just one blank line
+ after this paragraph.
+
+ Just one blank!
+ ---------------
+ There is just one blank line before the heading.
+
+.. admonition:: **No**: Extra blank lines
+ :class: error
+
+ .. code-block:: rst
+
+ There is some text here in the section before the next. It's just here to
+ illustrate the spacing standard. Note that there are too many blank lines
+ after this paragraph; there should be just one.
+
+
+
+ Too many blanks
+ ---------------
+ There are too many blanks before the heading for this section.
+
+Directives
+==========
+Indent directives 3 spaces; and put a blank line between the directive and the
+content. This aligns the directive content with the directive name.
+
+.. admonition:: **Yes**: Three space indent for directives; and nested
+ :class: checkmark
+
+ .. code-block:: none
+
+ Here is a paragraph that has some content. After this content is a
+ directive.
+
+ .. my_directive::
+
+ Note that this line's start aligns with the "m" above. The 3-space
+ alignment accounts for the ".. " prefix for directives, to vertically
+ align the directive name with the content.
+
+ This indentation must continue for nested directives.
+
+ .. nested_directive::
+
+ Here is some nested directive content.
+
+.. admonition:: **No**: One space, two spaces, four spaces, or other indents
+ for directives
+ :class: error
+
+ .. code-block:: none
+
+ Here is a paragraph with some content.
+
+ .. my_directive::
+
+ The indentation here is incorrect! It's one space short; doesn't align
+ with the directive name above.
+
+ .. nested_directive::
+
+ This isn't indented correctly either; it's too much (4 spaces).
+
+.. admonition:: **No**: Missing blank between directive and content.
+ :class: error
+
+ .. code-block:: none
+
+ Here is a paragraph with some content.
+
+ .. my_directive::
+ Note the lack of blank line above here.
+
+Tables
+======
+Consider using ``.. list-table::`` syntax, which is more maintainable and
+easier to edit for complex tables (`details
+<https://docutils.sourceforge.io/docs/ref/rst/directives.html#list-table>`_).
+
+Code Snippets
+=============
+Use code blocks from actual source code files wherever possible. This helps keep
+documentation fresh and removes duplicate code examples. There are a few ways to
+do this with Sphinx.
+
+The `literalinclude`_ directive creates a code blocks from source files. Entire
+files can be included or a just a subsection. The best way to do this is with
+the ``:start-after:`` and ``:end-before:`` options.
+
+Example:
+
+.. card::
+
+ Documentation Source (``.rst`` file)
+ ^^^
+
+ .. code-block:: rst
+
+ .. literalinclude:: run_doxygen.py
+ :start-after: [doxygen-environment-variables]
+ :end-before: [doxygen-environment-variables]
+
+.. card::
+
+ Source File
+ ^^^
+
+ .. code-block::
+
+ # DOCSTAG: [doxygen-environment-variables]
+ env = os.environ.copy()
+ env['PW_DOXYGEN_OUTPUT_DIRECTORY'] = str(output_dir.resolve())
+ env['PW_DOXYGEN_INPUT'] = ' '.join(pw_module_list)
+ env['PW_DOXYGEN_PROJECT_NAME'] = 'Pigweed'
+ # DOCSTAG: [doxygen-environment-variables]
+
+.. card::
+
+ Rendered Output
+ ^^^
+
+ .. code-block::
+
+ env = os.environ.copy()
+ env['PW_DOXYGEN_OUTPUT_DIRECTORY'] = str(output_dir.resolve())
+ env['PW_DOXYGEN_INPUT'] = ' '.join(pw_module_list)
+ env['PW_DOXYGEN_PROJECT_NAME'] = 'Pigweed'
+
+.. inclusive-language: disable
+
+.. _literalinclude: https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-literalinclude
+
+.. inclusive-language: enable
+
+Generating API documentation from source
+========================================
+Whenever possible, document APIs in the source code and use Sphinx to generate
+documentation for them. This keeps the documentation in sync with the code and
+reduces duplication.
+
+Python
+------
+Include Python API documentation from docstrings with `autodoc directives`_.
+Example:
+
+.. inclusive-language: disable
+
+.. _autodoc directives: https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#directives
+
+.. inclusive-language: enable
+
+.. code-block:: rst
+
+ .. automodule:: pw_cli.log
+ :members:
+
+ .. automodule:: pw_console.embed
+ :members: PwConsoleEmbed
+ :undoc-members:
+ :show-inheritance:
+
+ .. autoclass:: pw_console.log_store.LogStore
+ :members: __init__
+ :undoc-members:
+ :show-inheritance:
+
+Include argparse command line help with the `argparse
+<https://sphinx-argparse.readthedocs.io/en/latest/usage.html>`_
+directive. Example:
+
+.. code-block:: rst
+
+ .. argparse::
+ :module: pw_watch.watch
+ :func: get_parser
+ :prog: pw watch
+ :nodefaultconst:
+ :nodescription:
+ :noepilog:
+
+Customize the depth of a page's table of contents
+=================================================
+Put ``:tocdepth: X`` on the first line of the page, where ``X`` equals how many
+levels of section heading you want to show in the page's table of contents. See
+``//docs/changelog.rst`` for an example.
+
+Changelog
+=========
+This section explains how we update the changelog.
+
+#. On the Friday before Pigweed Live, use
+ `changelog <https://kaycebasques.github.io/changelog/>`_ to generate a first
+ draft of the changelog.
+
+#. Copy-paste the reStructuredText output from the changelog tool to the top
+ of ``//docs/changelog.rst``.
+
+#. Delete these lines from the previous update in ``changelog.rst``
+ (which is no longer the latest update):
+
+ * ``.. _docs-changelog-latest:``
+ * ``.. changelog_highlights_start``
+ * ``.. changelog_highlights_end``
+
+#. Polish up the auto-generated first draft into something more readable:
+
+ * Don't change the section headings. The text in each section heading
+ should map to one of the categories that we allow in our commit
+ messages, such as ``bazel``, ``docs``, ``pw_base64``, and so on.
+ * Add a 1-paragraph summary to each section.
+ * Focus on features, important bug fixes, and breaking changes. Delete
+ internal commits that Pigweed customers won't care about.
+
+#. Push your change up to Gerrit and kick off a dry run. After a few minutes
+ the docs will get staged.
+
+#. Copy the rendered content from the staging site into the Pigweed Live
+ Google Doc.
+
+#. Make sure to land the changelog updates the same week as Pigweed Live.
+
+There is no need to update ``//docs/index.rst``. The ``What's new in Pigweed``
+content on the homepage is pulled from the changelog (that's what the
+``docs-changelog-latest``, ``changelog_highlights_start``, and
+``changelog_highlights_end`` labels are for).
+
+Why "changelog" and not "release notes"?
+----------------------------------------
+Because Pigweed doesn't have releases.
+
+Why organize by module / category?
+----------------------------------
+Why is the changelog organized by category / module? Why not the usual
+3 top-level sections: features, fixes, breaking changes?
+
+* Because some Pigweed customers only use a few modules. Organizing by module
+ helps them filter out all the changes that aren't relevant to them faster.
+* If we keep the changelog section heading text fairly structured, we may
+ be able to present the changelog in other interesting ways. For example,
+ it should be possible to collect every ``pw_base64`` section in the changelog
+ and then provide a changelog for only ``pw_base64`` over in the ``pw_base64``
+ docs.
+* The changelog tool is easily able to organize by module / category due to
+ how we annotate our commits. We will not be able to publish changelog updates
+ every 2 weeks if there is too much manual work involved.
+
+.. _docs-site-scroll:
+
+Site nav scrolling
+==================
+We have had recurring issues with scrolling on pigweed.dev. This section
+provides context on the issue and fix(es).
+
+
+The behavior we want:
+
+* The page that you're currently on should be visible in the site nav.
+* URLs with deep links (e.g. ``pigweed.dev/pw_allocator/#size-report``) should
+ instantly jump to the target section (e.g. ``#size-report``).
+* There should be no scrolling animations anywhere on the site. Scrolls should
+ happen instantly.
+
+.. _furo.js: https://github.com/pradyunsg/furo/blob/main/src/furo/assets/scripts/furo.js
+
+A few potential issues at play:
+
+* Our theme (Furo) has non-configurable scrolling logic. See `furo.js`_.
+* There seems to be a race condition between Furo's scrolling behavior and our
+ text-to-diagram tool, Mermaid, which uses JavaScript to render the diagrams
+ on page load. However, we also saw issues on pages that didn't have any
+ diagrams, so that can't be the site-wide root cause.
+
+.. _scrollTop: https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollTop
+.. _scrollIntoView: https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
+.. _scroll-behavior: https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior
+
+Our current fix:
+
+* In ``//docs/_static/js/pigweed.js`` we manually scroll the site nav and main
+ content via `scrollTop`_. Note that we previously tried `scrollIntoView`_
+ but it was not an acceptable fix because the main content would always scroll
+ down about 50 pixels, even when a deep link was not present in the URL.
+ We also manually control when Mermaid renders its diagrams.
+* In ``//docs/_static/css/pigweed.css`` we use an aggressive CSS rule
+ to ensure that `scroll-behavior`_ is set to ``auto`` (i.e. instant scrolling)
+ for all elements on the site.
+
+Background:
+
+* `Tracking issue <https://issues.pigweed.dev/issues/303261476>`_
+* `First fix <https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/162410>`_
+* `Second fix <https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/162990>`_
+* `Third fix <https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/168555>`_
+* `Fourth fix <https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/178591>`_
+
+.. _docs-pw-style-cta:
+
+Call-to-action buttons on sales pitch pages (docs.rst)
+======================================================
+Use the following directive to put call-to-action buttons on a ``docs.rst``
+page:
+
+.. code-block::
+
+ .. grid:: 2
+
+ .. grid-item-card:: :octicon:`zap` Get started & guides
+ :link: <REF>
+ :link-type: ref
+ :class-item: sales-pitch-cta-primary
+
+ Learn how to integrate <MODULE> into your project and implement
+ common use cases.
+
+ .. grid-item-card:: :octicon:`info` API reference
+ :link: <REF>
+ :link-type: ref
+ :class-item: sales-pitch-cta-secondary
+
+ Get detailed reference information about the <MODULE> API.
+
+ .. grid:: 2
+
+ .. grid-item-card:: :octicon:`info` CLI reference
+ :link: <REF>
+ :link-type: ref
+ :class-item: sales-pitch-cta-secondary
+
+ Get usage information about <MODULE> command line utilities.
+
+ .. grid-item-card:: :octicon:`table` Design
+ :link: <REF>
+ :link-type: ref
+ :class-item: sales-pitch-cta-secondary
+
+ Read up on how <MODULE> is designed.
+
+* Remove cards for content that does not exist. For example, if the module
+ doesn't have a CLI reference, remove the card for that doc.
+* Replace ``<REF>`` and ``<MODULE>``. Don't change anything else. We want
+ a consistent call-to-action experience across all the modules.
+
+Copy-to-clipboard feature on code blocks
+========================================
+
+.. _sphinx-copybutton: https://sphinx-copybutton.readthedocs.io/en/latest/
+.. _Remove copybuttons using a CSS selector: https://sphinx-copybutton.readthedocs.io/en/latest/use.html#remove-copybuttons-using-a-css-selector
+
+The copy-to-clipboard feature on code blocks is powered by `sphinx-copybutton`_.
+
+``sphinx-copybutton`` recognizes ``$`` as an input prompt and automatically
+removes it.
+
+There is a workflow for manually removing the copy-to-clipboard button for a
+particular code block but it has not been implemented yet. See
+`Remove copybuttons using a CSS selector`_.
+
+Grouping related content with tabs
+==================================
+Use the ``tab-set`` directive to group related content together. This feature is
+powered by `sphinx-design Tabs
+<https://sphinx-design.readthedocs.io/en/furo-theme/tabs.html>`_
+
+Tabs for code-only content
+--------------------------
+Use the ``tabs`` and ``code-tab`` directives together. Example:
+
+.. code-block:: rst
+
+ .. tab-set-code::
+
+ .. code-block:: c++
+
+ // C++ code...
+
+ .. code-block:: python
+
+ # Python code...
+
+Rendered output:
+
+.. tab-set-code::
+
+ .. code-block:: c++
+
+ // C++ code...
+
+ .. code-block:: python
+
+ # Python code...
+
+Tabs for all other content
+--------------------------
+Use the ``tabs`` and ``tab-item`` directives together. Example:
+
+.. code-block:: rst
+
+ .. tab-set::
+
+ .. tab-item:: Linux
+
+ Linux instructions...
+
+ .. tab-item:: Windows
+
+ Windows instructions...
+
+Rendered output:
+
+.. tab-set::
+
+ .. tab-item:: Linux
+
+ Linux instructions...
+
+ .. tab-item:: Windows
+
+ Windows instructions...
+
+Tab synchronization
+-------------------
+Tabs are synchronized in two ways:
+
+1. ``tab-set-code::`` ``code-block`` languages names.
+2. ``tab-item::`` ``:sync:`` values.
+
+For Example:
+
+.. code-block:: rst
+
+ .. tabs-set-code::
+
+ .. code-block:: c++
+
+ // C++ code...
+
+ .. code-block:: py
+
+ # Python code...
+
+ .. tabs-set-code::
+
+ .. code-block:: c++
+
+ // More C++ code...
+
+ .. code-block:: py
+
+ # More Python code...
+
+ .. tab-set::
+
+ .. tab-item:: Linux
+ :sync: key1
+
+ Linux instructions...
+
+ .. tab-item:: Windows
+ :sync: key2
+
+ Windows instructions...
+
+ .. tab-set::
+
+ .. tab-item:: Linux
+ :sync: key1
+
+ More Linux instructions...
+
+ .. tab-item:: Windows
+ :sync: key2
+
+ More Windows instructions...
+
+Rendered output:
+
+.. tab-set-code::
+
+ .. code-block:: c++
+
+ // C++ code...
+
+ .. code-block:: py
+
+ # Python code...
+
+.. tab-set-code::
+
+ .. code-block:: c++
+
+ // More C++ code...
+
+ .. code-block:: py
+
+ # More Python code...
+
+.. tab-set::
+
+ .. tab-item:: Linux
+ :sync: key1
+
+ Linux instructions...
+
+ .. tab-item:: Windows
+ :sync: key2
+
+ Windows instructions...
+
+.. tab-set::
+
+ .. tab-item:: Linux
+ :sync: key1
+
+ More Linux instructions...
+
+ .. tab-item:: Windows
+ :sync: key2
+
+ More Windows instructions...