xref: /petsc/doc/conf.py (revision 1d27aa22b2f6148b2c4e3f06a75e0638d6493e09)
1ee12ae39SPatrick Sanan# Configuration file for the Sphinx documentation builder.
2ee12ae39SPatrick Sanan#
396b7068eSPatrick Sanan# For information on options, see
4ee12ae39SPatrick Sanan#   http://www.sphinx-doc.org/en/master/config
5ee12ae39SPatrick Sanan#
696b7068eSPatrick Sanan
7ee12ae39SPatrick Sananimport os
8ee12ae39SPatrick Sananimport sys
9ee12ae39SPatrick Sananimport subprocess
10ee12ae39SPatrick Sananimport re
11ee12ae39SPatrick Sananimport datetime
129cd31cfbSBarry Smithimport shutil
13ee12ae39SPatrick Sanan
14ee12ae39SPatrick Sanansys.path.append(os.getcwd())
15ee12ae39SPatrick Sanansys.path.append(os.path.abspath('./ext'))
16ee12ae39SPatrick Sanan
1795216c61SPatrick Sananimport add_man_page_redirects
1802f5a9aaSPatrick Sananimport build_classic_docs
19c9f6b0acSPatrick Sananimport fix_man_page_edit_links
2002f5a9aaSPatrick Sananimport make_links_relative
215becb6a3SPatrick Sananimport update_htmlmap_links
229f89e73bSBarry Smithimport fix_pydata_margins
2302f5a9aaSPatrick Sanan
2402f5a9aaSPatrick Sanan
25e6bab0d2SPatrick Sananif not os.path.isdir("images"):
26e6bab0d2SPatrick Sanan    print("-----------------------------------------------------------------------------")
27e6bab0d2SPatrick Sanan    print("ERROR")
28e6bab0d2SPatrick Sanan    print("images directory does not seem to exist.")
29e6bab0d2SPatrick Sanan    print("To clone the required repository, try")
30e6bab0d2SPatrick Sanan    print("   make images")
31e6bab0d2SPatrick Sanan    print("-----------------------------------------------------------------------------")
32e6bab0d2SPatrick Sanan    raise Exception("Aborting because images missing")
33e6bab0d2SPatrick Sanan
34e6bab0d2SPatrick Sanan
3596b7068eSPatrick Sanan# -- Project information -------------------------------------------------------
36ee12ae39SPatrick Sanan
37ee12ae39SPatrick Sananproject = 'PETSc'
38ee12ae39SPatrick Sanancopyright = '1991-%d, UChicago Argonne, LLC and the PETSc Development Team' % datetime.date.today().year
39ee12ae39SPatrick Sananauthor = 'The PETSc Development Team'
40ee12ae39SPatrick Sanan
41404447afSPatrick Sananwith open(os.path.join('..', 'include', 'petscversion.h'),'r') as version_file:
42ee12ae39SPatrick Sanan    buf = version_file.read()
43ee12ae39SPatrick Sanan    petsc_release_flag = re.search(' PETSC_VERSION_RELEASE[ ]*([0-9]*)',buf).group(1)
44ee12ae39SPatrick Sanan    major_version      = re.search(' PETSC_VERSION_MAJOR[ ]*([0-9]*)',buf).group(1)
45ee12ae39SPatrick Sanan    minor_version      = re.search(' PETSC_VERSION_MINOR[ ]*([0-9]*)',buf).group(1)
46ee12ae39SPatrick Sanan    subminor_version   = re.search(' PETSC_VERSION_SUBMINOR[ ]*([0-9]*)',buf).group(1)
47ee12ae39SPatrick Sanan
48ffebb2dfSPatrick Sanan    git_describe_version = subprocess.check_output(['git', 'describe', '--always']).strip().decode('utf-8')
49ee12ae39SPatrick Sanan    if petsc_release_flag == '0':
50ffebb2dfSPatrick Sanan        version = git_describe_version
51ffebb2dfSPatrick Sanan        release = git_describe_version
52ee12ae39SPatrick Sanan    else:
53ee12ae39SPatrick Sanan        version = '.'.join([major_version, minor_version])
54ee12ae39SPatrick Sanan        release = '.'.join([major_version,minor_version,subminor_version])
55ee12ae39SPatrick Sanan
56ee12ae39SPatrick Sanan
5796b7068eSPatrick Sanan# -- General configuration -----------------------------------------------------
5896b7068eSPatrick Sanan
5966c9fbddSBarry Smith# The information on the next line must also be the same in requirements.txt
60d1f92df0SBarry Smithneeds_sphinx='5.3'
6196b7068eSPatrick Sanannitpicky = True  # checks internal links. For external links, use "make linkcheck"
62ee12ae39SPatrick Sananmaster_doc = 'index'
63ee12ae39SPatrick Sanantemplates_path = ['_templates']
6466c9fbddSBarry Smithexclude_patterns = ['_build*', 'images', 'Thumbs.db', '.DS_Store','community/meetings/pre-2023']
6596b7068eSPatrick Sananhighlight_language = 'c'
6696b7068eSPatrick Sanannumfig = True
67ee12ae39SPatrick Sanan
6896b7068eSPatrick Sanan# -- Extensions ----------------------------------------------------------------
69ee12ae39SPatrick Sanan
704b6f941bSPatrick Sananextensions = [
714b6f941bSPatrick Sanan    'sphinx_copybutton',
724a3b3e5fSJed Brown    'sphinx_design',
734b6f941bSPatrick Sanan    'sphinxcontrib.bibtex',
744b6f941bSPatrick Sanan    'sphinxcontrib.katex',
754b6f941bSPatrick Sanan    'sphinxcontrib.rsvgconverter',
768f2bcf5fSPatrick Sanan    'myst_parser',
774b6f941bSPatrick Sanan    'html5_petsc',
784707091fSPatrick Sanan    'sphinx_remove_toctrees',
794b6f941bSPatrick Sanan]
804b6f941bSPatrick Sanan
81f3c6b5cdSPatrick Sanancopybutton_prompt_text = '$ '
824b6f941bSPatrick Sanan
8354129d2fSPatrick Sananbibtex_bibfiles = ['petsc.bib']
844b6f941bSPatrick Sanan
853d8af492SBarry Smithmyst_enable_extensions = ["fieldlist", "dollarmath", "amsmath", "deflist"]
868f2bcf5fSPatrick Sanan
878a0d1e8bSBarry Smithremove_from_toctrees = ['manualpages/*/[A-Z]*','changes/2*','changes/3*']
884707091fSPatrick Sanan
89*1d27aa22SBarry Smith# prevents incorrect WARNING: duplicate citation for key "xxxx" warnings
90*1d27aa22SBarry Smithsuppress_warnings = ['bibtex.duplicate_citation']
91*1d27aa22SBarry Smith
9296b7068eSPatrick Sanan# -- Options for HTML output ---------------------------------------------------
93ee12ae39SPatrick Sanan
94ee12ae39SPatrick Sananhtml_theme = 'pydata_sphinx_theme'
95ee12ae39SPatrick Sanan
9680dc5c2eSToby Isaachtml_logo_light = os.path.join('images', 'logos', 'PETSc_TAO_logos', 'PETSc-TAO', 'web', 'PETSc-TAO_RGB.svg')
9780dc5c2eSToby Isaachtml_logo_dark = os.path.join('images', 'logos', 'PETSc_TAO_logos', 'PETSc-TAO', 'web', 'PETSc-TAO_RGB_white.svg')
9880dc5c2eSToby Isaac
997c561f09SBarry Smithhtml_static_path = ['_static', html_logo_light, html_logo_dark]
1007c561f09SBarry Smith
1017c561f09SBarry Smith# use much smaller font for h1, h2 etc. They are absurdly large in the standard style
1027c561f09SBarry Smith# https://pydata-sphinx-theme.readthedocs.io/en/v0.12.0/user_guide/styling.html
1037c561f09SBarry Smithhtml_css_files = [
1047c561f09SBarry Smith    'css/custom.css',
1057c561f09SBarry Smith]
10680dc5c2eSToby Isaac
107ee12ae39SPatrick Sananhtml_theme_options = {
108ee12ae39SPatrick Sanan    "icon_links": [
109ee12ae39SPatrick Sanan        {
110ee12ae39SPatrick Sanan            "name": "GitLab",
111ee12ae39SPatrick Sanan            "url": "https://gitlab.com/petsc/petsc",
112ee12ae39SPatrick Sanan            "icon": "fab fa-gitlab",
113ee12ae39SPatrick Sanan        },
114ee12ae39SPatrick Sanan    ],
115ee12ae39SPatrick Sanan    "use_edit_page_button": True,
116ffebb2dfSPatrick Sanan    "footer_items": ["copyright", "sphinx-version", "last-updated"],
117d1f92df0SBarry Smith#    "secondary_sidebar_items" : ["edit-this-page"],
1183d8af492SBarry Smith     "header_links_before_dropdown": 10,
11980dc5c2eSToby Isaac    "logo": {
12080dc5c2eSToby Isaac        "image_light": os.path.basename(html_logo_light),
12180dc5c2eSToby Isaac        "image_dark": os.path.basename(html_logo_dark)
122bc1908f0SBarry Smith    },
123bc1908f0SBarry Smith    "navigation_with_keys":True
124ee12ae39SPatrick Sanan}
125ee12ae39SPatrick Sanan
126d3edb92dSPatrick Sanantry:
127d3edb92dSPatrick Sanan  git_ref = subprocess.check_output(["git", "rev-parse", "HEAD"]).rstrip()
128d3edb92dSPatrick Sanan  git_ref_release = subprocess.check_output(["git", "rev-parse", "origin/release"]).rstrip()
129d3edb92dSPatrick Sanan  edit_branch = "release" if git_ref == git_ref_release else "main"
130d3edb92dSPatrick Sananexcept subprocess.CalledProcessError:
131d3edb92dSPatrick Sanan  print("WARNING: determining branch for page edit links failed")
132d3edb92dSPatrick Sanan  edit_branch = "main"
133d3edb92dSPatrick Sanan
134ee12ae39SPatrick Sananhtml_context = {
135ee12ae39SPatrick Sanan    "github_url": "https://gitlab.com",
136ee12ae39SPatrick Sanan    "github_user": "petsc",
137ee12ae39SPatrick Sanan    "github_repo": "petsc",
138d3edb92dSPatrick Sanan    "github_version": edit_branch,
139ee12ae39SPatrick Sanan    "doc_path": "doc",
140ee12ae39SPatrick Sanan}
141ee12ae39SPatrick Sanan
14280dc5c2eSToby Isaachtml_logo = html_logo_light
143fc1137abSPatrick Sananhtml_favicon = os.path.join('images', 'logos', 'PETSc_TAO_logos', 'PETSc', 'petsc_favicon.png')
14496b7068eSPatrick Sananhtml_last_updated_fmt = r'%Y-%m-%dT%H:%M:%S%z (' + git_describe_version + ')'
145ee12ae39SPatrick Sanan
146ee12ae39SPatrick Sanan
14796b7068eSPatrick Sanan# -- Options for LaTeX output --------------------------------------------------
148ee12ae39SPatrick Sananlatex_engine = 'xelatex'
149ee12ae39SPatrick Sanan
15096b7068eSPatrick Sanan# How to arrange the documents into LaTeX files, building only the manual.
151ee12ae39SPatrick Sananlatex_documents = [
15273fdd05bSBarry Smith        ('manual/index', 'manual.tex', 'PETSc/TAO Users Manual', author, 'manual', False)
153ee12ae39SPatrick Sanan        ]
154ee12ae39SPatrick Sanan
155ee12ae39SPatrick Sananlatex_additional_files = [
15673fdd05bSBarry Smith    'images/manual/anl_tech_report/ArgonneLogo.pdf',
15773fdd05bSBarry Smith    'images/manual/anl_tech_report/ArgonneReportTemplateLastPage.pdf',
15873fdd05bSBarry Smith    'images/manual/anl_tech_report/ArgonneReportTemplatePage2.pdf',
15973fdd05bSBarry Smith    'manual/anl_tech_report/first.inc',
16073fdd05bSBarry Smith    'manual/anl_tech_report/last.inc',
161ee12ae39SPatrick Sanan]
162ee12ae39SPatrick Sanan
163ee12ae39SPatrick Sananlatex_elements = {
164ee12ae39SPatrick Sanan    'maketitle': r'\newcommand{\techreportversion}{%s}' % version +
165ee12ae39SPatrick Sananr'''
166ee12ae39SPatrick Sanan\input{first.inc}
167ee12ae39SPatrick Sanan''',
168ee12ae39SPatrick Sanan    'printindex': r'''
169ee12ae39SPatrick Sanan\printindex
170ee12ae39SPatrick Sanan\input{last.inc}
171ee12ae39SPatrick Sanan''',
172ee12ae39SPatrick Sanan    'fontpkg': r'''
173ee12ae39SPatrick Sanan\setsansfont{DejaVu Sans}
174ee12ae39SPatrick Sanan\setmonofont{DejaVu Sans Mono}
1751b671caaSPatrick Sanan''',
1761b671caaSPatrick Sanan    'tableofcontents' : r''
177ee12ae39SPatrick Sanan}
178ee12ae39SPatrick Sanan
179ee12ae39SPatrick Sanan
18096b7068eSPatrick Sanan# -- Setup and event callbacks -------------------------------------------------
181ee12ae39SPatrick Sanan
18275662446SPatrick Sanandef setup(app):
18375662446SPatrick Sanan        app.connect('builder-inited', builder_init_handler)
18475662446SPatrick Sanan        app.connect('build-finished', build_finished_handler)
18502f5a9aaSPatrick Sanan
18602f5a9aaSPatrick Sanan
18702f5a9aaSPatrick Sanandef builder_init_handler(app):
18875662446SPatrick Sanan    if app.builder.name.endswith('html'):
189b8a29d3aSPatrick Sanan        _build_classic_docs(app, 'pre')
1905becb6a3SPatrick Sanan        _update_htmlmap_links(app)
19102f5a9aaSPatrick Sanan
19202f5a9aaSPatrick Sanan
19302f5a9aaSPatrick Sanandef build_finished_handler(app, exception):
19475662446SPatrick Sanan    if app.builder.name.endswith('html'):
195b8a29d3aSPatrick Sanan        _build_classic_docs(app, 'post')
196c6c2e312SBarry Smith        build_petsc4py_docs(app)
1971540e0edSPatrick Sanan        _fix_links(app, exception)
198c9f6b0acSPatrick Sanan        _fix_man_page_edit_links(app, exception)
1999f89e73bSBarry Smith        fix_pydata_margins.fix_pydata_margins(app.outdir)
20095216c61SPatrick Sanan        if app.builder.name == 'dirhtml':
20195216c61SPatrick Sanan            _add_man_page_redirects(app, exception)
2029cd31cfbSBarry Smith        # remove sources for manual pages since they are automatically generated and should not be looked at on the website
2039cd31cfbSBarry Smith        if os.path.isdir(os.path.join(app.outdir,'_sources','manualpages')):
2049cd31cfbSBarry Smith            shutil.rmtree(os.path.join(app.outdir,'_sources','manualpages'))
20530f5c8b0SPatrick Sanan        if app.builder.name == 'html':
20628cbf9b2SBarry Smith            print("==========================================================================")
20728cbf9b2SBarry Smith            print("    open %s/index.html in your browser to view the documentation " % app.outdir)
20828cbf9b2SBarry Smith            print("==========================================================================")
20902f5a9aaSPatrick Sanan
21095216c61SPatrick Sanandef _add_man_page_redirects(app, exception):
21195216c61SPatrick Sanan    if exception is None:
2126058a5bfSBarry Smith        import time
21395216c61SPatrick Sanan        print("============================================")
21495216c61SPatrick Sanan        print("    Adding man pages redirects")
2156058a5bfSBarry Smith        x = time.clock_gettime(time.CLOCK_REALTIME)
21695216c61SPatrick Sanan        add_man_page_redirects.add_man_page_redirects(app.outdir)
2176058a5bfSBarry Smith        print("Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - x))
2186058a5bfSBarry Smith        print("============================================")
2197553d27dSPatrick Sanan
22075662446SPatrick Sanandef _build_classic_docs(app, stage):
221862e4a30SBarry Smith    '''Builds the .md versions of the manual pages and the .html version of the source code'''
2229cd31cfbSBarry Smith    build_classic_docs.main(stage,app.outdir)
22375662446SPatrick Sanan
224c9f6b0acSPatrick Sanandef _fix_man_page_edit_links(app, exception):
225c9f6b0acSPatrick Sanan    if exception is None:
2266058a5bfSBarry Smith        import time
227c9f6b0acSPatrick Sanan        print("============================================")
2283ecf4727SBarry Smith        print("    Fixing manual page edit links")
2296058a5bfSBarry Smith        x = time.clock_gettime(time.CLOCK_REALTIME)
230c9f6b0acSPatrick Sanan        fix_man_page_edit_links.fix_man_page_edit_links(app.outdir)
2316058a5bfSBarry Smith        print("Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - x))
2326058a5bfSBarry Smith        print("============================================")
233c9f6b0acSPatrick Sanan
234862e4a30SBarry Smith#
235862e4a30SBarry Smith#   The following two scripts are needed because the Sphinx html and dirhtml builds save the output html
236862e4a30SBarry Smith#   files at different levels of the directory hierarchy. file.rst -> file.html with html but
237862e4a30SBarry Smith#   file.rst -> file/index.html with dirhtml and we want both to work correctly using relative links.
238862e4a30SBarry Smith
239862e4a30SBarry Smithdef _fix_links(app, exception):
240862e4a30SBarry Smith    """We need to manage our own relative paths in the User's Manual for the source code files which
241862e4a30SBarry Smith       are auto-generated by c2html outside of Sphinx so Sphinx cannot directly handle those links for use.
242862e4a30SBarry Smith       We use the string PETSC_DOC_OUT_ROOT_PLACEHOLDER in URLs in the Sphinx .rst files as a stand in
243862e4a30SBarry Smith       for the root directory that needs to be constructed based on if the Sphinx build is html or dirhtml
244862e4a30SBarry Smith    """
245862e4a30SBarry Smith    if exception is None:
2466058a5bfSBarry Smith        import time
247862e4a30SBarry Smith        print("============================================")
248862e4a30SBarry Smith        print("    Fixing relative links")
2496058a5bfSBarry Smith        x = time.clock_gettime(time.CLOCK_REALTIME)
250862e4a30SBarry Smith        make_links_relative.make_links_relative(app.outdir)
2516058a5bfSBarry Smith        print("Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - x))
2526058a5bfSBarry Smith        print("============================================")
253862e4a30SBarry Smith
254c9f6b0acSPatrick Sanan
25575662446SPatrick Sanandef _update_htmlmap_links(app):
256862e4a30SBarry Smith    """htmlmap maps from manualpage names to relative locations in the generated documentation directory
257862e4a30SBarry Smith       hierarchy. The format of the directory location needs to be different for the Sphinx html and dirhtml
258862e4a30SBarry Smith       builds
259862e4a30SBarry Smith    """
2606058a5bfSBarry Smith    import time
26175662446SPatrick Sanan    print("============================================")
26275662446SPatrick Sanan    print("    Updating htmlmap")
2636058a5bfSBarry Smith    x = time.clock_gettime(time.CLOCK_REALTIME)
2649cd31cfbSBarry Smith    update_htmlmap_links.update_htmlmap_links(app.builder,os.path.join('manualpages','htmlmap'))
2656058a5bfSBarry Smith    print("Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - x))
2666058a5bfSBarry Smith    print("============================================")
267c6c2e312SBarry Smith
268c6c2e312SBarry Smithdef build_petsc4py_docs(app):
269c6c2e312SBarry Smith    petsc_dir = os.path.dirname(os.path.abspath(os.path.join(__file__,'..')))
270c6c2e312SBarry Smith    petsc_arch = 'arch-classic-docs'
271c6c2e312SBarry Smith
2726058a5bfSBarry Smith    # petsc4py needs to be built to build petsc4py docs via introspection
273c6c2e312SBarry Smith    command = ['make', 'all',
274c6c2e312SBarry Smith               'PETSC_DIR=%s' % petsc_dir,
275c6c2e312SBarry Smith               'PETSC_ARCH=%s' % petsc_arch]
2766058a5bfSBarry Smith    import time
277c6c2e312SBarry Smith    print('==============================================')
278c6c2e312SBarry Smith    print('Building library to make petsc4py docs')
279c6c2e312SBarry Smith    print(command)
2806058a5bfSBarry Smith    x = time.clock_gettime(time.CLOCK_REALTIME)
281c6c2e312SBarry Smith    subprocess.run(command, cwd=petsc_dir, check=True)
2826058a5bfSBarry Smith    print("Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - x))
2836058a5bfSBarry Smith    print('==============================================')
284c6c2e312SBarry Smith
285c6c2e312SBarry Smith    command = ['make', 'website',
286c6c2e312SBarry Smith               'PETSC_DIR=%s' % petsc_dir,
287c6c2e312SBarry Smith               'PETSC_ARCH=%s' % petsc_arch,
288c6c2e312SBarry Smith               'LOC=%s' % app.outdir]
289c6c2e312SBarry Smith    print('============================================')
290c6c2e312SBarry Smith    print('Building petsc4py docs')
291c6c2e312SBarry Smith    print(command)
2926058a5bfSBarry Smith    x = time.clock_gettime(time.CLOCK_REALTIME)
293c6c2e312SBarry Smith    subprocess.run(command, cwd=os.path.join(petsc_dir,'src','binding','petsc4py'), check=True)
2946058a5bfSBarry Smith    print("Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - x))
2956058a5bfSBarry Smith    print('============================================')
296