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
8import textwrap
9
10from sphinx.cmd.build import get_parser
11import sphinx_rtd_theme
12
13
14args = get_parser().parse_args()
15ZEPHYR_BASE = Path(__file__).resolve().parents[1]
16ZEPHYR_BUILD = Path(args.outputdir).resolve()
17
18# Add the '_extensions' directory to sys.path, to enable finding Sphinx
19# extensions within.
20sys.path.insert(0, str(ZEPHYR_BASE / "doc" / "_extensions"))
21
22# Add the '_scripts' directory to sys.path, to enable finding utility
23# modules.
24sys.path.insert(0, str(ZEPHYR_BASE / "doc" / "_scripts"))
25
26# Add the directory which contains the runners package as well,
27# for autodoc directives on runners.xyz.
28sys.path.insert(0, str(ZEPHYR_BASE / "scripts" / "west_commands"))
29
30import redirects
31
32try:
33    import west as west_found
34except ImportError:
35    west_found = False
36
37# -- Project --------------------------------------------------------------
38
39project = "Zephyr Project"
40copyright = "2015-2023 Zephyr Project members and individual contributors"
41author = "The Zephyr Project Contributors"
42
43# parse version from 'VERSION' file
44with open(ZEPHYR_BASE / "VERSION") as f:
45    m = re.match(
46        (
47            r"^VERSION_MAJOR\s*=\s*(\d+)$\n"
48            + r"^VERSION_MINOR\s*=\s*(\d+)$\n"
49            + r"^PATCHLEVEL\s*=\s*(\d+)$\n"
50            + r"^VERSION_TWEAK\s*=\s*\d+$\n"
51            + r"^EXTRAVERSION\s*=\s*(.*)$"
52        ),
53        f.read(),
54        re.MULTILINE,
55    )
56
57    if not m:
58        sys.stderr.write("Warning: Could not extract kernel version\n")
59        version = "Unknown"
60    else:
61        major, minor, patch, extra = m.groups(1)
62        version = ".".join((major, minor, patch))
63        if extra:
64            version += "-" + extra
65
66release = version
67
68# -- General configuration ------------------------------------------------
69
70extensions = [
71    "breathe",
72    "sphinx.ext.todo",
73    "sphinx.ext.extlinks",
74    "sphinx.ext.autodoc",
75    "sphinx.ext.graphviz",
76    "sphinxcontrib.jquery",
77    "zephyr.application",
78    "zephyr.html_redirects",
79    "zephyr.kconfig",
80    "zephyr.dtcompatible-role",
81    "zephyr.link-roles",
82    "sphinx_tabs.tabs",
83    "zephyr.warnings_filter",
84    "zephyr.doxyrunner",
85    "zephyr.vcs_link",
86    "zephyr.manifest_projects_table",
87    "notfound.extension",
88    "sphinx_copybutton",
89    "sphinx_togglebutton",
90    "zephyr.external_content",
91    "zephyr.domain",
92]
93
94# Only use SVG converter when it is really needed, e.g. LaTeX.
95if tags.has("svgconvert"):  # pylint: disable=undefined-variable
96    extensions.append("sphinxcontrib.rsvgconverter")
97
98templates_path = ["_templates"]
99
100exclude_patterns = ["_build"]
101
102if not west_found:
103    exclude_patterns.append("**/*west-apis*")
104else:
105    exclude_patterns.append("**/*west-not-found*")
106
107pygments_style = "sphinx"
108
109todo_include_todos = False
110
111nitpick_ignore = [
112    # ignore C standard identifiers (they are not defined in Zephyr docs)
113    ("c:identifier", "FILE"),
114    ("c:identifier", "int8_t"),
115    ("c:identifier", "int16_t"),
116    ("c:identifier", "int32_t"),
117    ("c:identifier", "int64_t"),
118    ("c:identifier", "intptr_t"),
119    ("c:identifier", "off_t"),
120    ("c:identifier", "size_t"),
121    ("c:identifier", "ssize_t"),
122    ("c:identifier", "time_t"),
123    ("c:identifier", "uint8_t"),
124    ("c:identifier", "uint16_t"),
125    ("c:identifier", "uint32_t"),
126    ("c:identifier", "uint64_t"),
127    ("c:identifier", "uintptr_t"),
128    ("c:identifier", "va_list"),
129]
130
131rst_epilog = """
132.. include:: /substitutions.txt
133"""
134
135# -- Options for HTML output ----------------------------------------------
136
137html_theme = "sphinx_rtd_theme"
138html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
139html_theme_options = {
140    "logo_only": True,
141    "prev_next_buttons_location": None
142}
143html_baseurl = "https://docs.zephyrproject.org/latest/"
144html_title = "Zephyr Project Documentation"
145html_logo = str(ZEPHYR_BASE / "doc" / "_static" / "images" / "logo.svg")
146html_favicon = str(ZEPHYR_BASE / "doc" / "_static" / "images" / "favicon.png")
147html_static_path = [str(ZEPHYR_BASE / "doc" / "_static")]
148html_last_updated_fmt = "%b %d, %Y"
149html_domain_indices = False
150html_split_index = True
151html_show_sourcelink = False
152html_show_sphinx = False
153html_search_scorer = str(ZEPHYR_BASE / "doc" / "_static" / "js" / "scorer.js")
154
155is_release = tags.has("release")  # pylint: disable=undefined-variable
156reference_prefix = ""
157if tags.has("publish"):  # pylint: disable=undefined-variable
158    reference_prefix = f"/{version}" if is_release else "/latest"
159docs_title = "Docs / {}".format(version if is_release else "Latest")
160html_context = {
161    "show_license": True,
162    "docs_title": docs_title,
163    "is_release": is_release,
164    "current_version": version,
165    "versions": (
166        ("latest", "/"),
167        ("3.5.0", "/3.5.0/"),
168        ("3.4.0", "/3.4.0/"),
169        ("3.3.0", "/3.3.0/"),
170        ("2.7.5 (LTS)", "/2.7.5/"),
171    ),
172    "display_vcs_link": True,
173    "reference_links": {
174        "API": f"{reference_prefix}/doxygen/html/index.html",
175        "Kconfig Options": f"{reference_prefix}/kconfig.html",
176        "Devicetree Bindings": f"{reference_prefix}/build/dts/api/bindings.html",
177        "West Projects": f"{reference_prefix}/develop/manifest/index.html",
178    }
179}
180
181# -- Options for LaTeX output ---------------------------------------------
182
183latex_elements = {
184    "papersize": "a4paper",
185    "maketitle": open(ZEPHYR_BASE / "doc" / "_static" / "latex" / "title.tex").read(),
186    "preamble": open(ZEPHYR_BASE / "doc" / "_static" / "latex" / "preamble.tex").read(),
187    "fontpkg": textwrap.dedent(r"""
188                                    \usepackage{noto}
189                                    \usepackage{inconsolata-nerd-font}
190                                    \usepackage[T1]{fontenc}
191                                """),
192    "sphinxsetup": ",".join(
193        (
194            # NOTE: colors match those found in light.css stylesheet
195            "verbatimwithframe=false",
196            "VerbatimColor={HTML}{f0f2f4}",
197            "InnerLinkColor={HTML}{2980b9}",
198            "warningBgColor={HTML}{e9a499}",
199            "warningborder=0pt",
200            r"HeaderFamily=\rmfamily\bfseries",
201        )
202    ),
203}
204latex_logo = str(ZEPHYR_BASE / "doc" / "_static" / "images" / "logo-latex.pdf")
205latex_documents = [
206    ("index-tex", "zephyr.tex", "Zephyr Project Documentation", author, "manual"),
207]
208latex_engine = "xelatex"
209
210# -- Options for zephyr.doxyrunner plugin ---------------------------------
211
212doxyrunner_doxygen = os.environ.get("DOXYGEN_EXECUTABLE", "doxygen")
213doxyrunner_doxyfile = ZEPHYR_BASE / "doc" / "zephyr.doxyfile.in"
214doxyrunner_outdir = ZEPHYR_BUILD / "doxygen"
215doxyrunner_fmt = True
216doxyrunner_fmt_vars = {"ZEPHYR_BASE": str(ZEPHYR_BASE), "ZEPHYR_VERSION": version}
217doxyrunner_outdir_var = "DOXY_OUT"
218
219# -- Options for Breathe plugin -------------------------------------------
220
221breathe_projects = {"Zephyr": str(doxyrunner_outdir / "xml")}
222breathe_default_project = "Zephyr"
223breathe_domain_by_extension = {
224    "h": "c",
225    "c": "c",
226}
227breathe_show_enumvalue_initializer = True
228breathe_default_members = ("members", )
229
230cpp_id_attributes = [
231    "__syscall",
232    "__syscall_always_inline",
233    "__deprecated",
234    "__may_alias",
235    "__used",
236    "__unused",
237    "__weak",
238    "__attribute_const__",
239    "__DEPRECATED_MACRO",
240    "FUNC_NORETURN",
241    "__subsystem",
242    "ALWAYS_INLINE",
243]
244c_id_attributes = cpp_id_attributes
245
246# -- Options for html_redirect plugin -------------------------------------
247
248html_redirect_pages = redirects.REDIRECTS
249
250# -- Options for zephyr.warnings_filter -----------------------------------
251
252warnings_filter_config = str(ZEPHYR_BASE / "doc" / "known-warnings.txt")
253
254# -- Options for zephyr.link-roles ----------------------------------------
255
256link_roles_manifest_project = "zephyr"
257link_roles_manifest_baseurl = "https://github.com/zephyrproject-rtos/zephyr"
258
259# -- Options for notfound.extension ---------------------------------------
260
261notfound_urls_prefix = f"/{version}/" if is_release else "/latest/"
262
263# -- Options for zephyr.vcs_link ------------------------------------------
264
265vcs_link_version = f"v{version}" if is_release else "main"
266vcs_link_base_url = f"https://github.com/zephyrproject-rtos/zephyr/blob/{vcs_link_version}"
267vcs_link_prefixes = {
268    "samples/.*": "",
269    "boards/.*": "",
270    "snippets/.*": "",
271    ".*": "doc",
272}
273vcs_link_exclude = [
274    "reference/kconfig.*",
275    "build/dts/api/bindings.*",
276    "build/dts/api/compatibles.*",
277]
278
279# -- Options for zephyr.kconfig -------------------------------------------
280
281kconfig_generate_db = True
282kconfig_ext_paths = [ZEPHYR_BASE]
283
284# -- Options for zephyr.external_content ----------------------------------
285
286external_content_contents = [
287    (ZEPHYR_BASE / "doc", "[!_]*"),
288    (ZEPHYR_BASE, "boards/**/*.rst"),
289    (ZEPHYR_BASE, "boards/**/doc"),
290    (ZEPHYR_BASE, "samples/**/*.html"),
291    (ZEPHYR_BASE, "samples/**/*.rst"),
292    (ZEPHYR_BASE, "samples/**/doc"),
293    (ZEPHYR_BASE, "snippets/**/*.rst"),
294    (ZEPHYR_BASE, "snippets/**/doc"),
295]
296external_content_keep = [
297    "reference/kconfig/*",
298    "develop/manifest/index.rst",
299    "build/dts/api/bindings.rst",
300    "build/dts/api/bindings/**/*",
301    "build/dts/api/compatibles/**/*",
302]
303
304# -- Options for sphinx.ext.graphviz --------------------------------------
305
306graphviz_dot = os.environ.get("DOT_EXECUTABLE", "dot")
307graphviz_output_format = "svg"
308graphviz_dot_args = [
309    "-Gbgcolor=transparent",
310    "-Nstyle=filled",
311    "-Nfillcolor=white",
312    "-Ncolor=gray60",
313    "-Nfontcolor=gray25",
314    "-Ecolor=gray60",
315]
316
317# -- Options for sphinx_copybutton ----------------------------------------
318
319copybutton_prompt_text = r"\$ |uart:~\$ "
320copybutton_prompt_is_regexp = True
321
322# -- Linkcheck options ----------------------------------------------------
323
324linkcheck_ignore = [
325    r"https://github.com/zephyrproject-rtos/zephyr/issues/.*"
326]
327
328extlinks = {
329    "github": ("https://github.com/zephyrproject-rtos/zephyr/issues/%s", "GitHub #%s"),
330}
331
332linkcheck_timeout = 30
333linkcheck_workers = 10
334linkcheck_anchors = False
335
336
337def setup(app):
338    # theme customizations
339    app.add_css_file("css/custom.css")
340    app.add_js_file("js/dark-mode-toggle.min.mjs", type="module")
341