xref: /petsc/doc/conf.py (revision 21e3ffae2f3b73c0bd738cf6d0a809700fc04bb0)
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/*/*','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 = [html_logo_light, html_logo_dark]
96
97html_theme_options = {
98    "icon_links": [
99        {
100            "name": "GitLab",
101            "url": "https://gitlab.com/petsc/petsc",
102            "icon": "fab fa-gitlab",
103        },
104    ],
105    "use_edit_page_button": True,
106    "footer_items": ["copyright", "sphinx-version", "last-updated"],
107#    "secondary_sidebar_items" : ["edit-this-page"],
108    "logo": {
109        "image_light": os.path.basename(html_logo_light),
110        "image_dark": os.path.basename(html_logo_dark)
111    }
112}
113
114try:
115  git_ref = subprocess.check_output(["git", "rev-parse", "HEAD"]).rstrip()
116  git_ref_release = subprocess.check_output(["git", "rev-parse", "origin/release"]).rstrip()
117  edit_branch = "release" if git_ref == git_ref_release else "main"
118except subprocess.CalledProcessError:
119  print("WARNING: determining branch for page edit links failed")
120  edit_branch = "main"
121
122html_context = {
123    "github_url": "https://gitlab.com",
124    "github_user": "petsc",
125    "github_repo": "petsc",
126    "github_version": edit_branch,
127    "doc_path": "doc",
128}
129
130html_logo = html_logo_light
131html_favicon = os.path.join('images', 'logos', 'PETSc_TAO_logos', 'PETSc', 'petsc_favicon.png')
132html_last_updated_fmt = r'%Y-%m-%dT%H:%M:%S%z (' + git_describe_version + ')'
133
134
135# -- Options for LaTeX output --------------------------------------------------
136latex_engine = 'xelatex'
137
138# How to arrange the documents into LaTeX files, building only the manual.
139latex_documents = [
140        ('manual/index', 'manual.tex', 'PETSc/TAO Users Manual', author, 'manual', False)
141        ]
142
143latex_additional_files = [
144    'images/manual/anl_tech_report/ArgonneLogo.pdf',
145    'images/manual/anl_tech_report/ArgonneReportTemplateLastPage.pdf',
146    'images/manual/anl_tech_report/ArgonneReportTemplatePage2.pdf',
147    'manual/anl_tech_report/first.inc',
148    'manual/anl_tech_report/last.inc',
149]
150
151latex_elements = {
152    'maketitle': r'\newcommand{\techreportversion}{%s}' % version +
153r'''
154\input{first.inc}
155''',
156    'printindex': r'''
157\printindex
158\input{last.inc}
159''',
160    'fontpkg': r'''
161\setsansfont{DejaVu Sans}
162\setmonofont{DejaVu Sans Mono}
163''',
164    'tableofcontents' : r''
165}
166
167
168# -- Setup and event callbacks -------------------------------------------------
169
170def setup(app):
171        app.connect('builder-inited', builder_init_handler)
172        app.connect('build-finished', build_finished_handler)
173
174
175def builder_init_handler(app):
176    if app.builder.name.endswith('html'):
177        _build_classic_docs(app, 'pre')
178        _copy_classic_docs(app, None, '.', 'pre')
179        _update_htmlmap_links(app)
180
181
182def build_finished_handler(app, exception):
183    if app.builder.name.endswith('html'):
184        _build_classic_docs(app, 'post')
185        _copy_classic_docs(app, exception, app.outdir, 'post')
186        _fix_links(app, exception)
187        _fix_man_page_edit_links(app, exception)
188        if app.builder.name == 'dirhtml':
189            _add_man_page_redirects(app, exception)
190        if app.builder.name == 'html':
191            print("==========================================================================")
192            print("    open %s/index.html in your browser to view the documentation " % app.outdir)
193            print("==========================================================================")
194
195def _add_man_page_redirects(app, exception):
196    if exception is None:
197        print("============================================")
198        print("    Adding man pages redirects")
199        print("============================================")
200        add_man_page_redirects.add_man_page_redirects(app.outdir)
201
202def _build_classic_docs(app, stage):
203    '''Builds the .md versions of the manual pages and the .html version of the source code'''
204    build_classic_docs.main(stage)
205
206
207def _copy_classic_docs(app, exception, destination, stage):
208    if exception is None:
209        print("============================================")
210        print("    Copying classic docs (%s)" % stage)
211        print("============================================")
212        build_classic_docs.copy_classic_docs(destination, stage)
213
214def _fix_man_page_edit_links(app, exception):
215    if exception is None:
216        print("============================================")
217        print("    Fixing man page edit links")
218        print("============================================")
219        fix_man_page_edit_links.fix_man_page_edit_links(app.outdir)
220
221#
222#   The following two scripts are needed because the Sphinx html and dirhtml builds save the output html
223#   files at different levels of the directory hierarchy. file.rst -> file.html with html but
224#   file.rst -> file/index.html with dirhtml and we want both to work correctly using relative links.
225
226def _fix_links(app, exception):
227    """We need to manage our own relative paths in the User's Manual for the source code files which
228       are auto-generated by c2html outside of Sphinx so Sphinx cannot directly handle those links for use.
229       We use the string PETSC_DOC_OUT_ROOT_PLACEHOLDER in URLs in the Sphinx .rst files as a stand in
230       for the root directory that needs to be constructed based on if the Sphinx build is html or dirhtml
231    """
232    if exception is None:
233        print("============================================")
234        print("    Fixing relative links")
235        print("============================================")
236        make_links_relative.make_links_relative(app.outdir)
237
238
239def _update_htmlmap_links(app):
240    """htmlmap maps from manualpage names to relative locations in the generated documentation directory
241       hierarchy. The format of the directory location needs to be different for the Sphinx html and dirhtml
242       builds
243    """
244    print("============================================")
245    print("    Updating htmlmap")
246    print("============================================")
247    update_htmlmap_links.update_htmlmap_links(app.builder)
248