• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2020 The Pigweed Authors
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4# use this file except in compliance with the License. You may obtain a copy of
5# the License at
6#
7#     https://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations under
13# the License.
14"""Pigweed's Sphinx configuration."""
15
16
17from datetime import date
18import os
19from pathlib import Path
20import sys
21
22
23from pw_console.pigweed_code_style import PigweedCodeStyle
24from pw_console.pigweed_code_style import PigweedCodeLightStyle
25
26
27# Determine whether the docs are being built with Bazel or GN.
28is_bazel_build = True
29try:
30    from python.runfiles import runfiles  # type: ignore
31except ImportError:
32    is_bazel_build = False
33
34
35# The suffix of source filenames.
36source_suffix = ['.rst']
37
38# The master toctree document.  # inclusive-language: ignore
39master_doc = 'index'
40
41# General information about the project.
42project = 'Pigweed'
43copyright = f'{date.today().year} The Pigweed Authors'  # pylint: disable=redefined-builtin
44
45# The version info for the project you're documenting, acts as replacement for
46# |version| and |release|, also used in various other places throughout the
47# built documents.
48#
49# The short X.Y version.
50version = '0.1'
51# The full version, including alpha/beta/rc tags.
52release = '0.1.0'
53
54
55# Pygments plugin approach (https://pygments.org/docs/plugins/) for getting
56# Sphinx to use our custom styles doesn't work. Use this approach instead:
57# https://stackoverflow.com/q/48615629/1669860
58def pygments_monkeypatch_style(mod_name, cls):
59    import sys
60    import pygments.styles
61
62    cls_name = cls.__name__
63    mod = type(__import__('os'))(mod_name)
64    setattr(mod, cls_name, cls)
65    setattr(pygments.styles, mod_name, mod)
66    sys.modules['pygments.styles.' + mod_name] = mod
67    from pygments.styles import STYLE_MAP
68
69    STYLE_MAP[mod_name] = mod_name + '::' + cls_name
70
71
72pygments_monkeypatch_style('pigweed_code_style', PigweedCodeStyle)
73pygments_monkeypatch_style('pigweed_code_light_style', PigweedCodeLightStyle)
74
75
76# //docs/_extensions must be added to the system path so that Sphinx
77# knows where to find the Sphinx extensions that have been custom-built
78# for pigweed.dev. The path resolution changes depending on whether we're
79# building pigweed.dev with GN or Bazel.
80if is_bazel_build:
81    sys.path.append(str(Path('_extensions').resolve()))
82else:  # GN build
83    pw_root = os.environ['PW_ROOT']
84    sys.path.append(f'{pw_root}/docs/_extensions')
85
86extensions = [
87    "bug",  # Custom extension to normalize Pigweed bug links.
88    "pw_docgen.sphinx.google_analytics",  # Enables optional Google Analytics
89    "pw_docgen.sphinx.kconfig",
90    "pw_docgen.sphinx.module_metadata",
91    "pw_docgen.sphinx.modules_index",
92    "pw_docgen.sphinx.pigweed_live",
93    "pw_docgen.sphinx.pw_status_codes",
94    "pw_docgen.sphinx.seed_metadata",
95    "sitemap",  # Custom extension to handle pigweed.dev sitemap nuances.
96    "sphinx.ext.autodoc",  # Automatic documentation for Python code
97    "sphinx.ext.napoleon",  # Parses Google-style docstrings
98    "sphinxarg.ext",  # Automatic documentation of Python argparse
99    "sphinxcontrib.mermaid",
100    "sphinx_design",
101    "breathe",
102    "sphinx_copybutton",  # Copy-to-clipboard button on code blocks
103    "sphinx_reredirects",
104]
105
106# When a user clicks the copy-to-clipboard button the `$ ` prompt should not be
107# copied: https://sphinx-copybutton.readthedocs.io/en/latest/use.html
108copybutton_prompt_text = "$ "
109
110_DIAG_HTML_IMAGE_FORMAT = 'SVG'
111blockdiag_html_image_format = _DIAG_HTML_IMAGE_FORMAT
112nwdiag_html_image_format = _DIAG_HTML_IMAGE_FORMAT
113seqdiag_html_image_format = _DIAG_HTML_IMAGE_FORMAT
114actdiag_html_image_format = _DIAG_HTML_IMAGE_FORMAT
115rackdiag_html_image_format = _DIAG_HTML_IMAGE_FORMAT
116packetdiag_html_image_format = _DIAG_HTML_IMAGE_FORMAT
117
118# Tell m2r to parse links to .md files and add them to the build.
119m2r_parse_relative_links = True
120
121# The theme to use for HTML and HTML Help pages.  See the documentation for
122# a list of builtin themes.
123html_theme = 'pydata_sphinx_theme'
124
125# The name for this set of Sphinx documents.  If None, it defaults to
126# "<project> v<release> documentation".
127html_title = 'Pigweed'
128
129# If true, SmartyPants will be used to convert quotes and dashes to
130# typographically correct entities.
131html_use_smartypants = True
132
133# If false, no module index is generated.
134html_domain_indices = True
135
136html_favicon = 'https://storage.googleapis.com/pigweed-media/pw_logo.ico'
137html_logo = 'https://storage.googleapis.com/pigweed-media/pw_logo.svg'
138
139# If false, no index is generated.
140html_use_index = True
141
142# If true, the index is split into individual pages for each letter.
143html_split_index = False
144
145# If true, links to the reST sources are added to the pages.
146html_show_sourcelink = False
147
148# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
149html_show_sphinx = False
150
151# These folders are copied to the documentation's HTML output
152html_static_path = ['docs/_static']
153
154# These paths are either relative to html_static_path
155# or fully qualified paths (eg. https://...)
156html_css_files = [
157    "css/pigweed.css",
158    # We could potentially merge the Google Fonts stylesheets into a single network
159    # request but we already preconnect with the service in //docs/layout/layout.html
160    # so the performance impact of keeping these as 3 separate calls should be
161    # negligible.
162    "https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,100;0,300;0,400;0,700;0,900;1,100;1,300;1,400;1,700;1,900&display=swap",
163    "https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,100..900;1,100..900&display=swap",
164    "https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100..700;1,100..700&display=swap",
165    # FontAwesome for mermaid and sphinx-design
166    "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css",
167]
168
169html_js_files = [
170    # Do not list pigweed.js here. This will cause it to get loaded in <head>.
171    # To improve load performance we modified //docs/layout/layout.html
172    # to load pigweed.js at the end of <body> instead.
173    # "js/pigweed.js",
174]
175
176html_extra_path = [
177    # Note: In this repo the file lives at //docs/blog/rss.xml but during the
178    # Sphinx build it's copied to the root of the website, https://pigweed.dev/rss.xml
179    'docs/blog/rss.xml',
180]
181if is_bazel_build:
182    # In the Bazel build, the fully built rustdoc site is present in the Sphinx
183    # site's sources directory. Specifying the rustdoc directory here instructs
184    # Sphinx to copy over the entire directory to its output.
185    html_extra_path.append('rustdoc')
186    # Also copy over the Doxygen-generated HTML subsite.
187    html_extra_path.append('doxygen')
188
189html_theme_options = {
190    # https://pydata-sphinx-theme.readthedocs.io/en/stable/user_guide/header-links.html#navigation-bar-dropdown-links
191    'header_links_before_dropdown': 5,
192    # https://pydata-sphinx-theme.readthedocs.io/en/stable/user_guide/header-links.html#icon-links
193    'icon_links': [
194        {
195            'name': 'Source code',
196            'url': 'https://cs.opensource.google/pigweed/pigweed/',
197            'icon': 'fa-solid fa-code',
198        },
199        {
200            'name': 'Issue tracker',
201            'url': 'https://pwbug.dev',
202            'icon': 'fa-solid fa-bug',
203        },
204        {
205            'name': 'Discord',
206            'url': 'https://discord.com/channels/691686718377558037/691686718377558040',
207            'icon': 'fa-brands fa-discord',
208        },
209    ],
210    # https://pydata-sphinx-theme.readthedocs.io/en/stable/user_guide/branding.html
211    'logo': {
212        'text': 'Pigweed',
213        'image_light': 'https://storage.googleapis.com/pigweed-media/pw_logo.svg',
214        'image_dark': 'https://storage.googleapis.com/pigweed-media/pw_logo.svg',
215    },
216    # https://pydata-sphinx-theme.readthedocs.io/en/stable/user_guide/layout.html#configure-the-navbar-center-alignment
217    'navbar_align': 'right',
218    # https://pydata-sphinx-theme.readthedocs.io/en/stable/user_guide/styling.html#configure-pygments-theme
219    'pygments_light_style': 'pigweed_code_light_style',
220    'pygments_dark_style': 'pigweed_code_style',
221}
222
223if 'LUCI_IS_TRY' in os.environ and os.environ['LUCI_IS_TRY'] == '1':
224    html_theme_options['announcement'] = (
225        "You are viewing Pigweed's docs on an automatically generated staging "
226        'site. <b>The content on this staging site may be incorrect or '
227        "unapproved.</b> Pigweed's official, approved docs are only published "
228        'at <a href="https://pigweed.dev">pigweed.dev</a>.'
229    )
230
231# sphinx-sitemap needs this:
232# https://sphinx-sitemap.readthedocs.io/en/latest/getting-started.html#usage
233html_baseurl = 'https://pigweed.dev/'
234
235# Hide "Section Navigation" on homepage and changelog.
236html_sidebars = {
237    'index': [],
238    'changelog': [],
239    'toolchain': [],
240}
241
242html_context = {
243    'default_mode': 'dark',
244}
245
246if 'GOOGLE_ANALYTICS_ID' in os.environ:
247    google_analytics_id = os.environ['GOOGLE_ANALYTICS_ID']
248
249# https://sphinx-sitemap.readthedocs.io/en/latest/advanced-configuration.html
250sitemap_url_scheme = '{link}'
251
252mermaid_init_js = '''
253mermaid.initialize({
254  // Mermaid is manually started in //docs/_static/js/pigweed.js.
255  startOnLoad: false,
256  // sequenceDiagram Note text alignment
257  noteAlign: "left",
258  // Set mermaid theme to the current furo theme
259  theme: localStorage.getItem("theme") == "dark" ? "dark" : "default"
260});
261'''
262
263# Output file base name for HTML help builder.
264htmlhelp_basename = 'Pigweeddoc'
265
266# Client-side redirects. See //docs/contributing/docs/website.rst.
267# Use relative URLs and provide the full path to ensure that the
268# redirects work when developing locally. An example of using the
269# full path is `./example/docs.html`. Using just `./example/`
270# assumes that the redirect will work, which may not be true during
271# local development.
272redirects = {
273    'docs/contributing': './contributing/index.html',
274    'docs/contributing/changelog': './docs/changelog.html',
275    'docs/contributing/module_docs': './docs/modules.html',
276    'docs/getting_started': './get_started/index.html',
277    'docs/infra/github': '../get_started/github.html',
278    'docs/os_abstraction_layers': './os/index.html',
279    'docs/release_notes/index': '../../changelog.html',
280    'docs/release_notes/2022_jan': '../../changelog.html',
281    'live/index': 'https://docs.google.com/document/d/1zcXQoMX6NDSe4cdxzt8afLbDcs8GSmI_Bsy5hTF_RVM/edit',
282    'module_guides': './modules.html',
283    'pw_sys_io_pico/docs': '../pw_sys_io_rp2040/docs.html',
284    'pw_tokenizer/cli': './docs.html',
285    'pw_tokenizer/guides': './docs.html',
286    'pw_toolchain_bazel/docs': 'https://github.com/bazelbuild/rules_cc/blob/main/docs/toolchain_api.md',
287    'seed/0000-index': './0000.html',
288    'seed/0001-the-seed-process': './0001.html',
289    'seed/0002-template': './0002.html',
290    'seed/0101-pigweed.json': './0101.html',
291    'seed/0102-module-docs': './0102.html',
292    'seed/0103-pw_protobuf-past-present-future': './0103.html',
293    'seed/0104-display-support': './0104.html',
294    'seed/0105-pw_tokenizer-pw_log-nested-tokens': './0105.html',
295    'seed/0107-communications': './0107.html',
296    'seed/0108-pw_emu-emulators-frontend': './0108.html',
297    'seed/0109-comms-buffers': './0109.html',
298    'seed/0110-memory-allocation-interfaces': './0110.html',
299    'seed/0111-build-systems': './0111.html',
300    'seed/0112-async-poll': './0112.html',
301    'seed/0113-bazel-cc-toolchain-api': './0113.html',
302    'seed/0114-channels': './0114.html',
303    'seed/0117-pw_i3c': './0117.html',
304    'seed/0119-pw-sensor': './0119.html',
305    'seed/0120-pw-sensor-config': './0120.html',
306    'seed/0122-code-samples': './0122.html',
307    'seed/0124-multisink-size-info': './0124.html',
308    'seed/0128-abstracting-thread-creation': './0128.html',
309    'seed/0130-update-sphinx-theme': './0130.html',
310    'seeds/index': '../seed/0000-index.html',
311    'sense/index': '../docs/showcases/sense/',
312    'tour/index': '../docs/showcases/sense/',
313}
314
315# One entry per manual page. List of tuples
316# (source start file, name, description, authors, manual section).
317man_pages = [('index', 'pigweed', 'Pigweed', ['Google'], 1)]
318
319# Grouping the document tree into Texinfo files. List of tuples
320# (source start file, target name, title, author,
321#  dir menu entry, description, category)
322texinfo_documents = [
323    (
324        'index',
325        'Pigweed',
326        'Pigweed',
327        'Google',
328        'Pigweed',
329        'Firmware framework',
330        'Miscellaneous',
331    ),
332]
333
334templates_path = ['docs/layout']
335exclude_patterns = ['docs/templates/**']
336
337doxygen_xml_path = (
338    './_doxygen/xml/' if is_bazel_build else './../../../doxygen/xml/'
339)
340breathe_projects = {
341    # Assuming doxygen output is at out/docs/doxygen/
342    # This dir should be relative to out/docs/gen/docs/pw_docgen_tree/
343    "Pigweed": doxygen_xml_path,
344}
345breathe_default_project = "Pigweed"
346breathe_debug_trace_directives = False
347# (b/295023422) Disable the inaccurate `#include` statements that are generated
348# when `doxygennamespace` is used.
349breathe_show_include = False
350
351# Treat these as valid attributes in function signatures.
352cpp_id_attributes = [
353    "PW_EXTERN_C_START",
354    "PW_NO_LOCK_SAFETY_ANALYSIS",
355]
356# This allows directives like this to work:
357# .. cpp:function:: inline bool try_lock_for(
358#     chrono::SystemClock::duration timeout) PW_EXCLUSIVE_TRYLOCK_FUNCTION(true)
359cpp_paren_attributes = [
360    "PW_EXCLUSIVE_TRYLOCK_FUNCTION",
361    "PW_EXCLUSIVE_LOCK_FUNCTION",
362    "PW_UNLOCK_FUNCTION",
363    "PW_NO_SANITIZE",
364]
365# inclusive-language: disable
366# Info on cpp_id_attributes and cpp_paren_attributes
367# https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-cpp_id_attributes
368# inclusive-language: enable
369
370# Disable Python type hints
371# autodoc_typehints = 'none'
372
373# Break class and function signature arguments into one arg per line if the
374# total length exceeds 130 characters. 130 seems about right for keeping one or
375# two parameters on a single line.
376maximum_signature_line_length = 130
377
378
379def do_not_skip_init(app, what, name, obj, would_skip, options):
380    if name == "__init__":
381        return False  # never skip __init__ functions
382    return would_skip
383
384
385# Problem: CSS files aren't copied after modifying them. Solution:
386# https://github.com/sphinx-doc/sphinx/issues/2090#issuecomment-572902572
387def env_get_outdated(app, env, added, changed, removed):
388    return ['index']
389
390
391def setup(app):
392    app.add_css_file('css/pigweed.css')
393    app.connect('env-get-outdated', env_get_outdated)
394    app.connect("autodoc-skip-member", do_not_skip_init)
395