xref: /petsc/doc/conf.py (revision fbf9dbe564678ed6eff1806adbc4c4f01b9743f4)
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
7import os
8import sys
9import subprocess
10import re
11import datetime
12import shutil
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 = ["fieldlist", "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": 10,
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        _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        _fix_links(app, exception)
193        _fix_man_page_edit_links(app, exception)
194        fix_pydata_margins.fix_pydata_margins(app.outdir)
195        if app.builder.name == 'dirhtml':
196            _add_man_page_redirects(app, exception)
197        # remove sources for manual pages since they are automatically generated and should not be looked at on the website
198        if os.path.isdir(os.path.join(app.outdir,'_sources','manualpages')):
199            shutil.rmtree(os.path.join(app.outdir,'_sources','manualpages'))
200        if app.builder.name == 'html':
201            print("==========================================================================")
202            print("    open %s/index.html in your browser to view the documentation " % app.outdir)
203            print("==========================================================================")
204
205def _add_man_page_redirects(app, exception):
206    if exception is None:
207        print("============================================")
208        print("    Adding man pages redirects")
209        print("============================================")
210        add_man_page_redirects.add_man_page_redirects(app.outdir)
211
212def _build_classic_docs(app, stage):
213    '''Builds the .md versions of the manual pages and the .html version of the source code'''
214    build_classic_docs.main(stage,app.outdir)
215
216def _fix_man_page_edit_links(app, exception):
217    if exception is None:
218        print("============================================")
219        print("    Fixing man page edit links")
220        print("============================================")
221        fix_man_page_edit_links.fix_man_page_edit_links(app.outdir)
222
223#
224#   The following two scripts are needed because the Sphinx html and dirhtml builds save the output html
225#   files at different levels of the directory hierarchy. file.rst -> file.html with html but
226#   file.rst -> file/index.html with dirhtml and we want both to work correctly using relative links.
227
228def _fix_links(app, exception):
229    """We need to manage our own relative paths in the User's Manual for the source code files which
230       are auto-generated by c2html outside of Sphinx so Sphinx cannot directly handle those links for use.
231       We use the string PETSC_DOC_OUT_ROOT_PLACEHOLDER in URLs in the Sphinx .rst files as a stand in
232       for the root directory that needs to be constructed based on if the Sphinx build is html or dirhtml
233    """
234    if exception is None:
235        print("============================================")
236        print("    Fixing relative links")
237        print("============================================")
238        make_links_relative.make_links_relative(app.outdir)
239
240
241def _update_htmlmap_links(app):
242    """htmlmap maps from manualpage names to relative locations in the generated documentation directory
243       hierarchy. The format of the directory location needs to be different for the Sphinx html and dirhtml
244       builds
245    """
246    print("============================================")
247    print("    Updating htmlmap")
248    print("============================================")
249    update_htmlmap_links.update_htmlmap_links(app.builder,os.path.join('manualpages','htmlmap'))
250