xref: /aosp_15_r20/external/pigweed/pw_docgen/docs.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1.. _module-pw_docgen:
2
3=========
4pw_docgen
5=========
6.. pigweed-module::
7   :name: pw_docgen
8
9``pw_docgen`` provides tools to generate documentation for Pigweed-based
10projects.
11
12.. note::
13
14   Pigweed itself uses ``pw_docgen`` to generate ``pigweed.dev``.
15
16--------
17Overview
18--------
19Pigweed-based projects typically use a subset of Pigweed's modules and add their
20own product-specific modules on top of that, which may have product-specific
21documentation. ``pw_docgen`` provides a convenient way to combine all of the
22relevant documentation for a project into one place, allowing downstream
23consumers of release bundles (e.g. factory teams, QA teams, beta testers, etc.)
24to have a unified source of documentation early on.
25
26The documentation generation is integrated directly into the build system. Any
27build target can depend on documentation, which allows it to be included as part
28of a factory release build, for example. Additionally, documentation itself can
29depend on other build targets, such as :ref:`report cards <module-pw_bloat>` for
30binary size/profiling. Any time the code is changed, documentation will be
31regenerated with the updated reports.
32
33Each Pigweed module provides documentation describing its functionality, use
34cases, and programming API.
35
36Included in a module's documentation are report cards which show an overview of
37the module's size cost and performance benchmarks. These allow prospective users
38to evaluate the impact of including the module in their projects.
39
40-----------------
41Build integration
42-----------------
43Pigweed documentation files are written in `reStructuredText`_ format and
44rendered to HTML using `Sphinx`_ through Pigweed's GN build system.
45
46.. _reStructuredText: http://docutils.sourceforge.net/rst.html
47.. inclusive-language: ignore
48.. _Sphinx: http://www.sphinx-doc.org/en/master
49
50There are additonal Sphinx plugins used for rendering diagrams within
51reStructuredText files including:
52
53* `mermaid <https://mermaid-js.github.io/>`_ via the `sphinxcontrib-mermaid
54  <https://pypi.org/project/sphinxcontrib-mermaid/>`_ package.
55
56Documentation source and asset files are placed alongside code within a module
57and registered as a ``pw_doc_group`` target within a ``BUILD.gn`` file. These
58groups become available for import within a special documentation generation
59target, which accumulates all of them and renders the resulting HTML. This
60system can either be used directly within Pigweed, or integrated into a
61downstream project.
62
63GN templates
64============
65
66pw_doc_group
67------------
68The main template for defining documentation files is ``pw_doc_group``. It is
69used to logically group a collection of documentation source files and assets.
70Each Pigweed module is expected to provide at least one ``pw_doc_group`` target
71defining the module's documentation. A ``pw_doc_group`` can depend on other
72groups, causing them to be built with it.
73
74Arguments
75^^^^^^^^^
76* ``sources``: RST documentation source files.
77* ``inputs``: Additional resources required for the docs (images, data files,
78  etc.)
79* ``group_deps``: Other ``pw_doc_group`` targets required by this one.
80* ``report_deps``: Report card generating targets (e.g. ``pw_size_diff``) on
81  which the docs depend.
82* ``other_deps``: Any other GN targets that should be run before this
83  ``pw_doc_group`` runs that is not included in one of the above ``dep``
84  categories.
85
86Example
87^^^^^^^
88.. code-block::
89
90   pw_doc_group("my_doc_group") {
91     sources = [ "docs.rst" ]
92     inputs = [ "face-with-tears-of-joy-emoji.svg" ]
93     group_deps = [ ":sub_doc_group" ]
94     report_deps = [ ":my_size_report" ]
95   }
96
97pw_doc_gen
98----------
99The ``pw_doc_gen`` template creates a target which renders complete HTML
100documentation for a project. It depends on registered ``pw_doc_group`` targets
101and creates an action which collects and renders them.
102
103To generate the complete docs, the template also requires a ``conf.py`` file
104configuring Sphinx's output, and a top level ``index.rst`` for the main page of
105the documentation. These are added at the root level of the built documentation
106to tie everything together.
107
108Arguments
109^^^^^^^^^
110* ``conf``: Path to the ``conf.py`` to use for Sphinx.
111* ``index``: Path to the top-level ``index.rst`` file.
112* ``output_directory``: Directory in which to render HTML output.
113* ``deps``: List of all ``pw_doc_group`` targets required for the documentation.
114* ``python_metadata_deps``: Python-related dependencies that are only used as
115  deps for generating Python package metadata list, not the overall
116  documentation generation. This should rarely be used by non-Pigweed code.
117
118Example
119^^^^^^^
120.. code-block::
121
122   pw_doc_gen("my_docs") {
123     conf = "//my_docs/conf.py"
124     index = "//my_docs/index.rst"
125     output_directory = target_gen_dir
126     deps = [
127       "//my_module:my_doc_group",
128     ]
129   }
130
131Generating documentation
132------------------------
133All source files listed under a ``pw_doc_gen`` target and its ``pw_doc_group``
134dependencies get copied out into a directory structure mirroring the original
135layout of the modules in which the sources appear. This is demonstrated below
136using a subset of Pigweed's core documentation.
137
138Consider the following target in ``$dir_pigweed/docs/BUILD.gn``:
139
140.. code-block::
141
142   pw_doc_gen("docs") {
143     conf = "conf.py"
144     index = "index.rst"
145     output_directory = target_gen_dir
146     deps = [
147       "$dir_pw_bloat:docs",
148       "$dir_pw_docgen:docs",
149       "$dir_pw_preprocessor:docs",
150     ]
151   }
152
153A documentation tree is created under the output directory. Each of the sources
154and inputs in the target's dependency graph is copied under this tree in the
155same directory structure as they appear under the root GN build directory
156(``$dir_pigweed`` in this case). The ``conf.py`` and ``index.rst`` provided
157directly to the ``pw_doc_gen`` template are copied in at the root of the tree.
158
159.. code-block::
160
161   out/gen/docs/pw_docgen_tree/
162   ├── conf.py
163   ├── index.rst
164   ├── pw_bloat
165   │   ├── bloat.rst
166   │   └── examples
167   │       └── simple_bloat.rst
168   ├── pw_docgen
169   │   └── docgen.rst
170   └── pw_preprocessor
171       └── docs.rst
172
173This is the documentation tree which gets passed to Sphinx to build HTML output.
174Imports within documentation files must be relative to this structure. In
175practice, relative imports from within modules' documentation groups are
176identical to the project's directory structure. The only special case is the
177top-level ``index.rst`` file's imports; they must start from the project's build
178root.
179
180Viewing documentation
181---------------------
182``pw_docgen`` includes a web server that serves locally-generated documentation
183at ``pw_docgen.docserver``. It supports hot-reloading, so the rendered docs in
184your browser will refresh as you make changes to the source files.
185
186In most cases, you will not need to run the docs server directly. Instead, it
187will be run via :ref:`module-pw_watch`.
188
189-----------------------------
190pigweed.dev Sphinx extensions
191-----------------------------
192.. note:: The topics in this section only apply to ``pigweed.dev``.
193   This section isn't relevant to downstream users of ``pw_docgen``.
194
195This module houses Pigweed-specific extensions for the Sphinx documentation
196generator. Extensions are included and configured in ``docs/conf.py``.
197
198module_metadata
199===============
200See :ref:`docs-contrib-docs-modules-metadata`.
201
202Canonical URL configuration
203---------------------------
204``module_metadata`` fixes the canonical URLs for ``*/docs.html`` pages. By
205default Sphinx assumes that a page's canonical URL is its full URL. E.g. the
206default canonical URL for ``//pw_string/docs.rst`` is
207``https://pigweed.dev/pw_string/docs.html``.  The ``pigweed.dev``
208server treats ``https://pigweed.dev/pw_string/`` as the canonical URL however.
209This problem is not limited to module homepages; it occurs on any page that
210ends in ``/docs.html`` such as
211``https://pigweed.dev/third_party/emboss/docs.html``. ``module_metadata`` fixes
212this problem by ensuring that the ``<link rel="canonical" href="..."/>`` tag
213generated in the HTML is aligned with the server's configuration.
214
215After building the docs, the canonical URLs for all HTML pages can be verified
216by running the following command in a terminal from the root directory of the
217upstream Pigweed repo:
218
219.. code-block:: console
220
221   grep '<link rel="canonical' out/docs/gen/docs/html/* -R
222
223Context: :bug:`323077749`.
224
225bug
226---
227This extension simplifies adding references to issues (bugs) in the Pigweed
228issue tracker. It defines a `Docutils role
229<https://docutils.sourceforge.io/docs/ref/rst/roles.html>`__ that can be
230used as follows.
231
232.. code-block:: rst
233
234   For more details see :bug:`323077749`.
235
236This becomes a hyperlink to https://pwbug.dev/323077749.
237
238google_analytics
239----------------
240When this extension is included and a ``google_analytics_id`` is set in the
241Sphinx configuration, a Google Analytics tracking tag will be added to each
242page of the documentation when it is rendered to HTML.
243
244By default, the Sphinx configuration's ``google_analytics_id`` is set
245automatically based on the value of the GN argument
246``pw_docs_google_analytics_id``, allowing you to control whether tracking is
247enabled or not in your build configuration. Typically, you would only enable
248this for documentation builds intended for deployment on the web.
249
250Debugging Pigweed's Sphinx extensions
251-------------------------------------
252To step through your Pigweed extension code with
253`pdb <https://docs.python.org/3/library/pdb.html>`_:
254
255#. Set a breakpoint in your extension code:
256
257   .. code-block::
258
259      breakpoint()
260
261#. Build ``python.install`` to install the code change into the bootstrap venv
262   (``environment/pigweed-venv/lib/python3.8/site-packages/pw_docgen``):
263
264   .. code-block::
265
266      ninja -C out python.install
267
268#. Manually invoke Sphinx to build the docs and trigger your breakpoint:
269
270   .. code-block::
271
272      cd out
273      sphinx-build -W -b html -d docs/gen/docs/help docs/gen/docs/pw_docgen_tree docs/gen/docs/html -v -v -v
274
275   You should see build output from Sphinx. The build should pause at your
276   breakpoint and you should then see pdb's prompt (``(Pdb)``).
277