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