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