xref: /petsc/doc/conf.py (revision 9fd2a872fac71d98bdeeea4f800da4f052f7a9fb)
1# Configuration file for the Sphinx documentation builder.
2#
3# For information on options, see
4#   http://www.sphinx-doc.org/en/master/config
5#
6# This file was generated by running "sphinx-quickstart" and then modified
7
8import os
9import sys
10import subprocess
11import re
12import datetime
13
14sys.path.append(os.getcwd())
15sys.path.append(os.path.abspath('./ext'))
16
17import add_man_page_redirects
18import build_classic_docs
19import fix_man_page_edit_links
20import make_links_relative
21import update_htmlmap_links
22
23
24if not os.path.isdir("images"):
25    print("-----------------------------------------------------------------------------")
26    print("ERROR")
27    print("images directory does not seem to exist.")
28    print("To clone the required repository, try")
29    print("   make images")
30    print("-----------------------------------------------------------------------------")
31    raise Exception("Aborting because images missing")
32
33
34# -- Project information -------------------------------------------------------
35
36project = 'PETSc'
37copyright = '1991-%d, UChicago Argonne, LLC and the PETSc Development Team' % datetime.date.today().year
38author = 'The PETSc Development Team'
39
40with open(os.path.join('..', 'include', 'petscversion.h'),'r') as version_file:
41    buf = version_file.read()
42    petsc_release_flag = re.search(' PETSC_VERSION_RELEASE[ ]*([0-9]*)',buf).group(1)
43    major_version      = re.search(' PETSC_VERSION_MAJOR[ ]*([0-9]*)',buf).group(1)
44    minor_version      = re.search(' PETSC_VERSION_MINOR[ ]*([0-9]*)',buf).group(1)
45    subminor_version   = re.search(' PETSC_VERSION_SUBMINOR[ ]*([0-9]*)',buf).group(1)
46
47    git_describe_version = subprocess.check_output(['git', 'describe', '--always']).strip().decode('utf-8')
48    if petsc_release_flag == '0':
49        version = git_describe_version
50        release = git_describe_version
51    else:
52        version = '.'.join([major_version, minor_version])
53        release = '.'.join([major_version,minor_version,subminor_version])
54
55
56# -- General configuration -----------------------------------------------------
57
58# The information on the next line must also be the same in requirements.txt
59needs_sphinx='5.3'
60nitpicky = True  # checks internal links. For external links, use "make linkcheck"
61master_doc = 'index'
62templates_path = ['_templates']
63exclude_patterns = ['_build*', 'images', 'Thumbs.db', '.DS_Store','community/meetings/pre-2023']
64highlight_language = 'c'
65numfig = True
66
67# -- Extensions ----------------------------------------------------------------
68
69extensions = [
70    'sphinx_copybutton',
71    'sphinx_design',
72    'sphinxcontrib.bibtex',
73    'sphinxcontrib.katex',
74    'sphinxcontrib.rsvgconverter',
75    'myst_parser',
76    'html5_petsc',
77    'sphinx_remove_toctrees',
78]
79
80copybutton_prompt_text = '$ '
81
82bibtex_bibfiles = ['petsc.bib']
83
84myst_enable_extensions = ["dollarmath", "amsmath", "deflist"]
85
86remove_from_toctrees = ['manualpages/*/[A-Z]*','changes/2*','changes/3*']
87
88# -- Options for HTML output ---------------------------------------------------
89
90html_theme = 'pydata_sphinx_theme'
91
92html_logo_light = os.path.join('images', 'logos', 'PETSc_TAO_logos', 'PETSc-TAO', 'web', 'PETSc-TAO_RGB.svg')
93html_logo_dark = os.path.join('images', 'logos', 'PETSc_TAO_logos', 'PETSc-TAO', 'web', 'PETSc-TAO_RGB_white.svg')
94
95html_static_path = ['_static', html_logo_light, html_logo_dark]
96
97# use much smaller font for h1, h2 etc. They are absurdly large in the standard style
98# https://pydata-sphinx-theme.readthedocs.io/en/v0.12.0/user_guide/styling.html
99html_css_files = [
100    'css/custom.css',
101]
102
103html_theme_options = {
104    "icon_links": [
105        {
106            "name": "GitLab",
107            "url": "https://gitlab.com/petsc/petsc",
108            "icon": "fab fa-gitlab",
109        },
110    ],
111    "use_edit_page_button": True,
112    "footer_items": ["copyright", "sphinx-version", "last-updated"],
113#    "secondary_sidebar_items" : ["edit-this-page"],
114     "header_links_before_dropdown": 9,
115    "logo": {
116        "image_light": os.path.basename(html_logo_light),
117        "image_dark": os.path.basename(html_logo_dark)
118    }
119}
120
121try:
122  git_ref = subprocess.check_output(["git", "rev-parse", "HEAD"]).rstrip()
123  git_ref_release = subprocess.check_output(["git", "rev-parse", "origin/release"]).rstrip()
124  edit_branch = "release" if git_ref == git_ref_release else "main"
125except subprocess.CalledProcessError:
126  print("WARNING: determining branch for page edit links failed")
127  edit_branch = "main"
128
129html_context = {
130    "github_url": "https://gitlab.com",
131    "github_user": "petsc",
132    "github_repo": "petsc",
133    "github_version": edit_branch,
134    "doc_path": "doc",
135}
136
137html_logo = html_logo_light
138html_favicon = os.path.join('images', 'logos', 'PETSc_TAO_logos', 'PETSc', 'petsc_favicon.png')
139html_last_updated_fmt = r'%Y-%m-%dT%H:%M:%S%z (' + git_describe_version + ')'
140
141
142# -- Options for LaTeX output --------------------------------------------------
143latex_engine = 'xelatex'
144
145# How to arrange the documents into LaTeX files, building only the manual.
146latex_documents = [
147        ('manual/index', 'manual.tex', 'PETSc/TAO Users Manual', author, 'manual', False)
148        ]
149
150latex_additional_files = [
151    'images/manual/anl_tech_report/ArgonneLogo.pdf',
152    'images/manual/anl_tech_report/ArgonneReportTemplateLastPage.pdf',
153    'images/manual/anl_tech_report/ArgonneReportTemplatePage2.pdf',
154    'manual/anl_tech_report/first.inc',
155    'manual/anl_tech_report/last.inc',
156]
157
158latex_elements = {
159    'maketitle': r'\newcommand{\techreportversion}{%s}' % version +
160r'''
161\input{first.inc}
162''',
163    'printindex': r'''
164\printindex
165\input{last.inc}
166''',
167    'fontpkg': r'''
168\setsansfont{DejaVu Sans}
169\setmonofont{DejaVu Sans Mono}
170''',
171    'tableofcontents' : r''
172}
173
174
175# -- Setup and event callbacks -------------------------------------------------
176
177def setup(app):
178        app.connect('builder-inited', builder_init_handler)
179        app.connect('build-finished', build_finished_handler)
180
181
182def builder_init_handler(app):
183    if app.builder.name.endswith('html'):
184        _build_classic_docs(app, 'pre')
185        _copy_classic_docs(app, None, '.', 'pre')
186        _update_htmlmap_links(app)
187
188
189def build_finished_handler(app, exception):
190    if app.builder.name.endswith('html'):
191        _build_classic_docs(app, 'post')
192        _copy_classic_docs(app, exception, app.outdir, 'post')
193        _fix_links(app, exception)
194        _fix_man_page_edit_links(app, exception)
195        if app.builder.name == 'dirhtml':
196            _add_man_page_redirects(app, exception)
197        if app.builder.name == 'html':
198            print("==========================================================================")
199            print("    open %s/index.html in your browser to view the documentation " % app.outdir)
200            print("==========================================================================")
201
202def _add_man_page_redirects(app, exception):
203    if exception is None:
204        print("============================================")
205        print("    Adding man pages redirects")
206        print("============================================")
207        add_man_page_redirects.add_man_page_redirects(app.outdir)
208
209def _build_classic_docs(app, stage):
210    '''Builds the .md versions of the manual pages and the .html version of the source code'''
211    build_classic_docs.main(stage)
212
213
214def _copy_classic_docs(app, exception, destination, stage):
215    if exception is None:
216        print("============================================")
217        print("    Copying classic docs (%s)" % stage)
218        print("============================================")
219        build_classic_docs.copy_classic_docs(destination, stage)
220
221def _fix_man_page_edit_links(app, exception):
222    if exception is None:
223        print("============================================")
224        print("    Fixing man page edit links")
225        print("============================================")
226        fix_man_page_edit_links.fix_man_page_edit_links(app.outdir)
227
228#
229#   The following two scripts are needed because the Sphinx html and dirhtml builds save the output html
230#   files at different levels of the directory hierarchy. file.rst -> file.html with html but
231#   file.rst -> file/index.html with dirhtml and we want both to work correctly using relative links.
232
233def _fix_links(app, exception):
234    """We need to manage our own relative paths in the User's Manual for the source code files which
235       are auto-generated by c2html outside of Sphinx so Sphinx cannot directly handle those links for use.
236       We use the string PETSC_DOC_OUT_ROOT_PLACEHOLDER in URLs in the Sphinx .rst files as a stand in
237       for the root directory that needs to be constructed based on if the Sphinx build is html or dirhtml
238    """
239    if exception is None:
240        print("============================================")
241        print("    Fixing relative links")
242        print("============================================")
243        make_links_relative.make_links_relative(app.outdir)
244
245
246def _update_htmlmap_links(app):
247    """htmlmap maps from manualpage names to relative locations in the generated documentation directory
248       hierarchy. The format of the directory location needs to be different for the Sphinx html and dirhtml
249       builds
250    """
251    print("============================================")
252    print("    Updating htmlmap")
253    print("============================================")
254    update_htmlmap_links.update_htmlmap_links(app.builder)
255