1# Zephyr documentation build configuration file.
2# Reference: https://www.sphinx-doc.org/en/master/usage/configuration.html
3
4import sys
5import os
6from pathlib import Path
7import re
8
9from sphinx.cmd.build import get_parser
10import sphinx_rtd_theme
11
12
13args = get_parser().parse_args()
14ZEPHYR_BASE = Path(__file__).resolve().parents[1]
15ZEPHYR_BUILD = Path(args.outputdir).resolve()
16
17# Add the '_extensions' directory to sys.path, to enable finding Sphinx
18# extensions within.
19sys.path.insert(0, str(ZEPHYR_BASE / "doc" / "_extensions"))
20
21# Add the '_scripts' directory to sys.path, to enable finding utility
22# modules.
23sys.path.insert(0, str(ZEPHYR_BASE / "doc" / "_scripts"))
24
25# Add the directory which contains the runners package as well,
26# for autodoc directives on runners.xyz.
27sys.path.insert(0, str(ZEPHYR_BASE / "scripts" / "west_commands"))
28
29import redirects
30
31try:
32    import west as west_found
33except ImportError:
34    west_found = False
35
36# -- Project --------------------------------------------------------------
37
38project = "Zephyr Project"
39copyright = "2015-2021 Zephyr Project members and individual contributors"
40author = "The Zephyr Project Contributors"
41
42# parse version from 'VERSION' file
43with open(ZEPHYR_BASE / "VERSION") as f:
44    m = re.match(
45        (
46            r"^VERSION_MAJOR\s*=\s*(\d+)$\n"
47            + r"^VERSION_MINOR\s*=\s*(\d+)$\n"
48            + r"^PATCHLEVEL\s*=\s*(\d+)$\n"
49            + r"^VERSION_TWEAK\s*=\s*\d+$\n"
50            + r"^EXTRAVERSION\s*=\s*(.*)$"
51        ),
52        f.read(),
53        re.MULTILINE,
54    )
55
56    if not m:
57        sys.stderr.write("Warning: Could not extract kernel version\n")
58        version = "Unknown"
59    else:
60        major, minor, patch, extra = m.groups(1)
61        version = ".".join((major, minor, patch))
62        if extra:
63            version += "-" + extra
64
65release = version
66
67# -- General configuration ------------------------------------------------
68
69extensions = [
70    "breathe",
71    "sphinx.ext.todo",
72    "sphinx.ext.extlinks",
73    "sphinx.ext.autodoc",
74    "sphinx.ext.graphviz",
75    "zephyr.application",
76    "zephyr.html_redirects",
77    "zephyr.kconfig-role",
78    "zephyr.dtcompatible-role",
79    "zephyr.link-roles",
80    "sphinx_tabs.tabs",
81    "zephyr.warnings_filter",
82    "zephyr.doxyrunner",
83    "notfound.extension",
84    "zephyr.external_content",
85]
86
87# Only use SVG converter when it is really needed, e.g. LaTeX.
88if tags.has("svgconvert"):  # pylint: disable=undefined-variable
89    extensions.append("sphinxcontrib.rsvgconverter")
90
91templates_path = ["_templates"]
92
93exclude_patterns = ["_build"]
94
95if not west_found:
96    exclude_patterns.append("**/*west-apis*")
97else:
98    exclude_patterns.append("**/*west-not-found*")
99
100# This change will allow us to use bare back-tick notation to let
101# Sphinx hunt for a reference, starting with normal "document"
102# references such as :ref:, but also including :c: and :cpp: domains
103# (potentially) helping with API (doxygen) references simply by using
104# `name`
105default_role = "any"
106
107pygments_style = "sphinx"
108
109todo_include_todos = False
110
111rst_epilog = """
112.. include:: /substitutions.txt
113"""
114
115# -- Options for HTML output ----------------------------------------------
116
117html_theme = "sphinx_rtd_theme"
118html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
119html_theme_options = {
120    "logo_only": True,
121    "prev_next_buttons_location": None
122}
123html_title = "Zephyr Project Documentation"
124html_logo = str(ZEPHYR_BASE / "doc" / "_static" / "images" / "logo.svg")
125html_favicon = str(ZEPHYR_BASE / "doc" / "_static" / "images" / "favicon.png")
126html_static_path = [str(ZEPHYR_BASE / "doc" / "_static")]
127html_last_updated_fmt = "%b %d, %Y"
128html_domain_indices = False
129html_split_index = True
130html_show_sourcelink = False
131html_show_sphinx = False
132html_search_scorer = str(ZEPHYR_BASE / "doc" / "_static" / "js" / "scorer.js")
133
134is_release = tags.has("release")  # pylint: disable=undefined-variable
135docs_title = "Docs / {}".format(version if is_release else "Latest")
136html_context = {
137    "show_license": True,
138    "docs_title": docs_title,
139    "is_release": is_release,
140    "current_version": version,
141    "versions": (
142        ("latest", "/"),
143        ("2.6.0", "/2.6.0/"),
144        ("2.5.0", "/2.5.0/"),
145        ("2.4.0", "/2.4.0/"),
146        ("2.3.0", "/2.3.0/"),
147        ("2.2.0", "/2.2.0/"),
148        ("1.14.1", "/1.14.1/"),
149    ),
150}
151
152# -- Options for LaTeX output ---------------------------------------------
153
154latex_elements = {
155    "papersize": "a4paper",
156    "maketitle": open(ZEPHYR_BASE / "doc" / "_static" / "latex" / "title.tex").read(),
157    "preamble": open(ZEPHYR_BASE / "doc" / "_static" / "latex" / "preamble.tex").read(),
158    "fontpkg": r"\usepackage{charter}",
159    "sphinxsetup": ",".join(
160        (
161            # NOTE: colors match those found in light.css stylesheet
162            "verbatimwithframe=false",
163            "VerbatimColor={HTML}{f0f2f4}",
164            "InnerLinkColor={HTML}{2980b9}",
165            "warningBgColor={HTML}{e9a499}",
166            "warningborder=0pt",
167            r"HeaderFamily=\rmfamily\bfseries",
168        )
169    ),
170}
171latex_logo = str(ZEPHYR_BASE / "doc" / "_static" / "images" / "logo-latex.pdf")
172latex_documents = [
173    ("index-tex", "zephyr.tex", "Zephyr Project Documentation", author, "manual"),
174]
175
176# -- Options for zephyr.doxyrunner plugin ---------------------------------
177
178doxyrunner_doxygen = os.environ.get("DOXYGEN_EXECUTABLE", "doxygen")
179doxyrunner_doxyfile = ZEPHYR_BASE / "doc" / "zephyr.doxyfile.in"
180doxyrunner_outdir = ZEPHYR_BUILD / "doxygen"
181doxyrunner_fmt = True
182doxyrunner_fmt_vars = {"ZEPHYR_BASE": str(ZEPHYR_BASE)}
183doxyrunner_outdir_var = "DOXY_OUT"
184
185# -- Options for Breathe plugin -------------------------------------------
186
187breathe_projects = {"Zephyr": str(doxyrunner_outdir / "xml")}
188breathe_default_project = "Zephyr"
189breathe_domain_by_extension = {
190    "h": "c",
191    "c": "c",
192}
193breathe_show_enumvalue_initializer = True
194breathe_default_members = ("members", )
195
196cpp_id_attributes = [
197    "__syscall",
198    "__deprecated",
199    "__may_alias",
200    "__used",
201    "__unused",
202    "__weak",
203    "__attribute_const__",
204    "__DEPRECATED_MACRO",
205    "FUNC_NORETURN",
206    "__subsystem",
207    "ALWAYS_INLINE",
208]
209c_id_attributes = cpp_id_attributes
210
211# -- Options for html_redirect plugin -------------------------------------
212
213html_redirect_pages = redirects.REDIRECTS
214
215# -- Options for zephyr.warnings_filter -----------------------------------
216
217warnings_filter_config = str(ZEPHYR_BASE / "doc" / "known-warnings.txt")
218warnings_filter_silent = False
219
220# -- Options for notfound.extension ---------------------------------------
221
222notfound_urls_prefix = f"/{version}/" if is_release else "/latest/"
223
224# -- Options for zephyr.external_content ----------------------------------
225
226external_content_contents = [
227    (ZEPHYR_BASE / "doc", "[!_]*"),
228    (ZEPHYR_BASE, "boards/**/*.rst"),
229    (ZEPHYR_BASE, "boards/**/doc"),
230    (ZEPHYR_BASE, "samples/**/*.rst"),
231    (ZEPHYR_BASE, "samples/**/doc"),
232]
233external_content_keep = [
234    "reference/kconfig/*",
235    "reference/devicetree/bindings.rst",
236    "reference/devicetree/bindings/**/*",
237    "reference/devicetree/compatibles/**/*",
238]
239
240# -- Options for sphinx.ext.graphviz --------------------------------------
241
242graphviz_dot = os.environ.get("DOT_EXECUTABLE", "dot")
243graphviz_output_format = "svg"
244graphviz_dot_args = [
245    "-Gbgcolor=transparent",
246    "-Nstyle=filled",
247    "-Nfillcolor=white",
248    "-Ncolor=gray60",
249    "-Nfontcolor=gray25",
250    "-Ecolor=gray60",
251]
252
253# -- Linkcheck options ----------------------------------------------------
254
255extlinks = {
256    "jira": ("https://jira.zephyrproject.org/browse/%s", "JIRA %s"),
257    "github": ("https://github.com/zephyrproject-rtos/zephyr/issues/%s", "GitHub #%s"),
258}
259
260linkcheck_timeout = 30
261linkcheck_workers = 10
262linkcheck_anchors = False
263
264
265def setup(app):
266    # theme customizations
267    app.add_css_file("css/custom.css")
268    app.add_js_file("js/dark-mode-toggle.min.mjs", type="module")
269
270    app.add_js_file("https://www.googletagmanager.com/gtag/js?id=UA-831873-47")
271    app.add_js_file("js/ga-tracker.js")
272