xref: /petsc/doc/conf.py (revision a16d7c54a90597f5c8be70e4d1d8614d0ec77e42)
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
13ec83d434SBarry Smithimport time
14ee12ae39SPatrick Sanan
15ee12ae39SPatrick Sanansys.path.append(os.getcwd())
16ee12ae39SPatrick Sanansys.path.append(os.path.abspath('./ext'))
17ee12ae39SPatrick Sanan
1895216c61SPatrick Sananimport add_man_page_redirects
19c6267af9SBarry Smithimport build_manpages_c2html
20c9f6b0acSPatrick Sananimport fix_man_page_edit_links
2102f5a9aaSPatrick Sananimport make_links_relative
225becb6a3SPatrick Sananimport update_htmlmap_links
239f89e73bSBarry Smithimport fix_pydata_margins
2402f5a9aaSPatrick Sanan
2502f5a9aaSPatrick Sanan
26e6bab0d2SPatrick Sananif not os.path.isdir("images"):
27e6bab0d2SPatrick Sanan    print("-----------------------------------------------------------------------------")
28e6bab0d2SPatrick Sanan    print("ERROR")
29e6bab0d2SPatrick Sanan    print("images directory does not seem to exist.")
30e6bab0d2SPatrick Sanan    print("To clone the required repository, try")
31e6bab0d2SPatrick Sanan    print("   make images")
32e6bab0d2SPatrick Sanan    print("-----------------------------------------------------------------------------")
33e6bab0d2SPatrick Sanan    raise Exception("Aborting because images missing")
34e6bab0d2SPatrick Sanan
35e6bab0d2SPatrick Sanan
3696b7068eSPatrick Sanan# -- Project information -------------------------------------------------------
37ee12ae39SPatrick Sanan
38ee12ae39SPatrick Sananproject = 'PETSc'
39ee12ae39SPatrick Sanancopyright = '1991-%d, UChicago Argonne, LLC and the PETSc Development Team' % datetime.date.today().year
40ee12ae39SPatrick Sananauthor = 'The PETSc Development Team'
41ee12ae39SPatrick Sanan
42*7f019730SBarry Smithincludedir = os.path.join('..', 'include', 'petscversion.h')
43*7f019730SBarry Smithif not os.path.isfile(includedir): includedir = os.path.join('..', '..', 'include', 'petscversion.h')
44*7f019730SBarry Smithwith open(includedir,'r') as version_file:
45ee12ae39SPatrick Sanan    buf = version_file.read()
46ee12ae39SPatrick Sanan    petsc_release_flag = re.search(' PETSC_VERSION_RELEASE[ ]*([0-9]*)',buf).group(1)
47ee12ae39SPatrick Sanan    major_version      = re.search(' PETSC_VERSION_MAJOR[ ]*([0-9]*)',buf).group(1)
48ee12ae39SPatrick Sanan    minor_version      = re.search(' PETSC_VERSION_MINOR[ ]*([0-9]*)',buf).group(1)
49ee12ae39SPatrick Sanan    subminor_version   = re.search(' PETSC_VERSION_SUBMINOR[ ]*([0-9]*)',buf).group(1)
50ee12ae39SPatrick Sanan
51ffebb2dfSPatrick Sanan    git_describe_version = subprocess.check_output(['git', 'describe', '--always']).strip().decode('utf-8')
52ee12ae39SPatrick Sanan    if petsc_release_flag == '0':
53ffebb2dfSPatrick Sanan        version = git_describe_version
54ffebb2dfSPatrick Sanan        release = git_describe_version
55ee12ae39SPatrick Sanan    else:
56ee12ae39SPatrick Sanan        version = '.'.join([major_version, minor_version])
57ee12ae39SPatrick Sanan        release = '.'.join([major_version,minor_version,subminor_version])
58ee12ae39SPatrick Sanan
59ee12ae39SPatrick Sanan
6096b7068eSPatrick Sanan# -- General configuration -----------------------------------------------------
6196b7068eSPatrick Sanan
6266c9fbddSBarry Smith# The information on the next line must also be the same in requirements.txt
63d1f92df0SBarry Smithneeds_sphinx='5.3'
6496b7068eSPatrick Sanannitpicky = True  # checks internal links. For external links, use "make linkcheck"
65ee12ae39SPatrick Sananmaster_doc = 'index'
66ee12ae39SPatrick Sanantemplates_path = ['_templates']
6766c9fbddSBarry Smithexclude_patterns = ['_build*', 'images', 'Thumbs.db', '.DS_Store','community/meetings/pre-2023']
6896b7068eSPatrick Sananhighlight_language = 'c'
6996b7068eSPatrick Sanannumfig = True
70ee12ae39SPatrick Sanan
7196b7068eSPatrick Sanan# -- Extensions ----------------------------------------------------------------
72ee12ae39SPatrick Sanan
734b6f941bSPatrick Sananextensions = [
744b6f941bSPatrick Sanan    'sphinx_copybutton',
754a3b3e5fSJed Brown    'sphinx_design',
764b6f941bSPatrick Sanan    'sphinxcontrib.bibtex',
774b6f941bSPatrick Sanan    'sphinxcontrib.katex',
784b6f941bSPatrick Sanan    'sphinxcontrib.rsvgconverter',
798f2bcf5fSPatrick Sanan    'myst_parser',
804b6f941bSPatrick Sanan    'html5_petsc',
814707091fSPatrick Sanan    'sphinx_remove_toctrees',
82ce78bad3SBarry Smith    'sphinx_design',
834b6f941bSPatrick Sanan]
844b6f941bSPatrick Sanan
85f3c6b5cdSPatrick Sanancopybutton_prompt_text = '$ '
864b6f941bSPatrick Sanan
8754129d2fSPatrick Sananbibtex_bibfiles = ['petsc.bib']
884b6f941bSPatrick Sanan
8909cc9507SBarry Smithmyst_enable_extensions = ["fieldlist", "dollarmath", "amsmath", "deflist", "colon_fence"]
908f2bcf5fSPatrick Sanan
918a0d1e8bSBarry Smithremove_from_toctrees = ['manualpages/*/[A-Z]*','changes/2*','changes/3*']
924707091fSPatrick Sanan
931d27aa22SBarry Smith# prevents incorrect WARNING: duplicate citation for key "xxxx" warnings
941d27aa22SBarry Smithsuppress_warnings = ['bibtex.duplicate_citation']
951d27aa22SBarry Smith
9696b7068eSPatrick Sanan# -- Options for HTML output ---------------------------------------------------
97ee12ae39SPatrick Sanan
98ee12ae39SPatrick Sananhtml_theme = 'pydata_sphinx_theme'
99ee12ae39SPatrick Sanan
10080dc5c2eSToby Isaachtml_logo_light = os.path.join('images', 'logos', 'PETSc_TAO_logos', 'PETSc-TAO', 'web', 'PETSc-TAO_RGB.svg')
10180dc5c2eSToby Isaachtml_logo_dark = os.path.join('images', 'logos', 'PETSc_TAO_logos', 'PETSc-TAO', 'web', 'PETSc-TAO_RGB_white.svg')
10280dc5c2eSToby Isaac
1037c561f09SBarry Smithhtml_static_path = ['_static', html_logo_light, html_logo_dark]
1047c561f09SBarry Smith
1057c561f09SBarry Smith# use much smaller font for h1, h2 etc. They are absurdly large in the standard style
1067c561f09SBarry Smith# https://pydata-sphinx-theme.readthedocs.io/en/v0.12.0/user_guide/styling.html
1077c561f09SBarry Smithhtml_css_files = [
1087c561f09SBarry Smith    'css/custom.css',
1097c561f09SBarry Smith]
11080dc5c2eSToby Isaac
111ee12ae39SPatrick Sananhtml_theme_options = {
112ee12ae39SPatrick Sanan    "icon_links": [
113ee12ae39SPatrick Sanan        {
114ee12ae39SPatrick Sanan            "name": "GitLab",
115ee12ae39SPatrick Sanan            "url": "https://gitlab.com/petsc/petsc",
116ee12ae39SPatrick Sanan            "icon": "fab fa-gitlab",
117ee12ae39SPatrick Sanan        },
118ee12ae39SPatrick Sanan    ],
119ee12ae39SPatrick Sanan    "use_edit_page_button": True,
1202c804a55SBarry Smith    "footer_end": ["theme-version", "last-updated"],
121d1f92df0SBarry Smith#    "secondary_sidebar_items" : ["edit-this-page"],
1223d8af492SBarry Smith     "header_links_before_dropdown": 10,
12380dc5c2eSToby Isaac    "logo": {
12480dc5c2eSToby Isaac        "image_light": os.path.basename(html_logo_light),
12580dc5c2eSToby Isaac        "image_dark": os.path.basename(html_logo_dark)
126bc1908f0SBarry Smith    },
127bc1908f0SBarry Smith    "navigation_with_keys":True
128ee12ae39SPatrick Sanan}
129ee12ae39SPatrick Sanan
130d3edb92dSPatrick Sanantry:
131d3edb92dSPatrick Sanan  git_ref = subprocess.check_output(["git", "rev-parse", "HEAD"]).rstrip()
132d3edb92dSPatrick Sanan  git_ref_release = subprocess.check_output(["git", "rev-parse", "origin/release"]).rstrip()
133d3edb92dSPatrick Sanan  edit_branch = "release" if git_ref == git_ref_release else "main"
134d3edb92dSPatrick Sananexcept subprocess.CalledProcessError:
135d3edb92dSPatrick Sanan  print("WARNING: determining branch for page edit links failed")
136d3edb92dSPatrick Sanan  edit_branch = "main"
137d3edb92dSPatrick Sanan
138ee12ae39SPatrick Sananhtml_context = {
139585d687eSPierre Jolivet    "display_gitlab": True,
140585d687eSPierre Jolivet    "gitlab_user": "petsc",
141585d687eSPierre Jolivet    "gitlab_repo": "petsc",
142585d687eSPierre Jolivet    "gitlab_version": edit_branch,
143ee12ae39SPatrick Sanan    "doc_path": "doc",
144ee12ae39SPatrick Sanan}
145ee12ae39SPatrick Sanan
14680dc5c2eSToby Isaachtml_logo = html_logo_light
147fc1137abSPatrick Sananhtml_favicon = os.path.join('images', 'logos', 'PETSc_TAO_logos', 'PETSc', 'petsc_favicon.png')
14896b7068eSPatrick Sananhtml_last_updated_fmt = r'%Y-%m-%dT%H:%M:%S%z (' + git_describe_version + ')'
149ee12ae39SPatrick Sanan
150ee12ae39SPatrick Sanan
15196b7068eSPatrick Sanan# -- Options for LaTeX output --------------------------------------------------
152ee12ae39SPatrick Sananlatex_engine = 'xelatex'
153ee12ae39SPatrick Sanan
15496b7068eSPatrick Sanan# How to arrange the documents into LaTeX files, building only the manual.
155ee12ae39SPatrick Sananlatex_documents = [
15673fdd05bSBarry Smith        ('manual/index', 'manual.tex', 'PETSc/TAO Users Manual', author, 'manual', False)
157ee12ae39SPatrick Sanan        ]
158ee12ae39SPatrick Sanan
159ee12ae39SPatrick Sananlatex_additional_files = [
16073fdd05bSBarry Smith    'images/manual/anl_tech_report/ArgonneLogo.pdf',
16173fdd05bSBarry Smith    'images/manual/anl_tech_report/ArgonneReportTemplateLastPage.pdf',
16273fdd05bSBarry Smith    'images/manual/anl_tech_report/ArgonneReportTemplatePage2.pdf',
16373fdd05bSBarry Smith    'manual/anl_tech_report/first.inc',
16473fdd05bSBarry Smith    'manual/anl_tech_report/last.inc',
165ee12ae39SPatrick Sanan]
166ee12ae39SPatrick Sanan
167ee12ae39SPatrick Sananlatex_elements = {
168ee12ae39SPatrick Sanan    'maketitle': r'\newcommand{\techreportversion}{%s}' % version +
169ee12ae39SPatrick Sananr'''
170ee12ae39SPatrick Sanan\input{first.inc}
171ee12ae39SPatrick Sanan''',
172ee12ae39SPatrick Sanan    'printindex': r'''
173ee12ae39SPatrick Sanan\printindex
174ee12ae39SPatrick Sanan\input{last.inc}
175ee12ae39SPatrick Sanan''',
176ee12ae39SPatrick Sanan    'fontpkg': r'''
177ee12ae39SPatrick Sanan\setsansfont{DejaVu Sans}
178ee12ae39SPatrick Sanan\setmonofont{DejaVu Sans Mono}
1791b671caaSPatrick Sanan''',
1801b671caaSPatrick Sanan    'tableofcontents' : r''
181ee12ae39SPatrick Sanan}
182ee12ae39SPatrick Sanan
18396b7068eSPatrick Sanan# -- Setup and event callbacks -------------------------------------------------
184ee12ae39SPatrick Sanan
18575662446SPatrick Sanandef setup(app):
18675662446SPatrick Sanan    app.connect('builder-inited', builder_init_handler)
18775662446SPatrick Sanan    app.connect('build-finished', build_finished_handler)
188*7f019730SBarry Smith    if 'PETSC_DIR' in os.environ:
189*7f019730SBarry Smith      app.petsc_dir = os.path.abspath(os.environ['PETSC_DIR'])
190*7f019730SBarry Smith    else:
191*7f019730SBarry Smith      app.petsc_dir = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), ".."))
192*7f019730SBarry Smith    app.build_dir = os.path.abspath(os.getcwd())
19302f5a9aaSPatrick Sanan
19402f5a9aaSPatrick Sanandef builder_init_handler(app):
195ec83d434SBarry Smith    global xtime
19675662446SPatrick Sanan    if app.builder.name.endswith('html'):
197*7f019730SBarry Smith        build_manpages_c2html.main('pre',app.petsc_dir,app.build_dir,app.outdir)
1985becb6a3SPatrick Sanan        _update_htmlmap_links(app)
199ec83d434SBarry Smith        ptype = 'html'
200ec83d434SBarry Smith    else: ptype = 'pdf'
201ec83d434SBarry Smith    print("============================================")
202ec83d434SBarry Smith    print("    Running Sphinx on PETSc " + ptype)
203ec83d434SBarry Smith    xtime = time.clock_gettime(time.CLOCK_REALTIME)
20402f5a9aaSPatrick Sanan
20502f5a9aaSPatrick Sanan
20602f5a9aaSPatrick Sanandef build_finished_handler(app, exception):
207ec83d434SBarry Smith    global xtime
208ec83d434SBarry Smith    print("Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - xtime))
209ec83d434SBarry Smith    print("============================================")
21075662446SPatrick Sanan    if app.builder.name.endswith('html'):
211*7f019730SBarry Smith        build_manpages_c2html.main('post',app.petsc_dir,app.build_dir,app.outdir)
212c6c2e312SBarry Smith        build_petsc4py_docs(app)
2131540e0edSPatrick Sanan        _fix_links(app, exception)
214c9f6b0acSPatrick Sanan        _fix_man_page_edit_links(app, exception)
2159f89e73bSBarry Smith        fix_pydata_margins.fix_pydata_margins(app.outdir)
21695216c61SPatrick Sanan        if app.builder.name == 'dirhtml':
21795216c61SPatrick Sanan            _add_man_page_redirects(app, exception)
2189cd31cfbSBarry Smith        # remove sources for manual pages since they are automatically generated and should not be looked at on the website
2199cd31cfbSBarry Smith        if os.path.isdir(os.path.join(app.outdir,'_sources','manualpages')):
2209cd31cfbSBarry Smith            shutil.rmtree(os.path.join(app.outdir,'_sources','manualpages'))
22130f5c8b0SPatrick Sanan        if app.builder.name == 'html':
22228cbf9b2SBarry Smith            print("==========================================================================")
22328cbf9b2SBarry Smith            print("    open %s/index.html in your browser to view the documentation " % app.outdir)
22428cbf9b2SBarry Smith            print("==========================================================================")
22502f5a9aaSPatrick Sanan
22695216c61SPatrick Sanandef _add_man_page_redirects(app, exception):
22795216c61SPatrick Sanan    if exception is None:
2286058a5bfSBarry Smith        import time
22995216c61SPatrick Sanan        print("============================================")
23095216c61SPatrick Sanan        print("    Adding man pages redirects")
2316058a5bfSBarry Smith        x = time.clock_gettime(time.CLOCK_REALTIME)
23295216c61SPatrick Sanan        add_man_page_redirects.add_man_page_redirects(app.outdir)
2336058a5bfSBarry Smith        print("Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - x))
2346058a5bfSBarry Smith        print("============================================")
2357553d27dSPatrick Sanan
236c9f6b0acSPatrick Sanandef _fix_man_page_edit_links(app, exception):
237c9f6b0acSPatrick Sanan    if exception is None:
2386058a5bfSBarry Smith        import time
239c9f6b0acSPatrick Sanan        print("============================================")
2403ecf4727SBarry Smith        print("    Fixing manual page edit links")
2416058a5bfSBarry Smith        x = time.clock_gettime(time.CLOCK_REALTIME)
242c9f6b0acSPatrick Sanan        fix_man_page_edit_links.fix_man_page_edit_links(app.outdir)
2436058a5bfSBarry Smith        print("Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - x))
2446058a5bfSBarry Smith        print("============================================")
245c9f6b0acSPatrick Sanan
246862e4a30SBarry Smith#
247862e4a30SBarry Smith#   The following two scripts are needed because the Sphinx html and dirhtml builds save the output html
248b8253ccfSBarry Smith#   files at different levels of the directory hierarchy. file.rst/md -> file.html with html but
249b8253ccfSBarry Smith#   file.rst/md -> file/index.html with dirhtml and we want both to work correctly using relative links.
250862e4a30SBarry Smith
251862e4a30SBarry Smithdef _fix_links(app, exception):
252862e4a30SBarry Smith    """We need to manage our own relative paths in the User's Manual for the source code files which
253862e4a30SBarry Smith       are auto-generated by c2html outside of Sphinx so Sphinx cannot directly handle those links for use.
254862e4a30SBarry Smith       We use the string PETSC_DOC_OUT_ROOT_PLACEHOLDER in URLs in the Sphinx .rst files as a stand in
255862e4a30SBarry Smith       for the root directory that needs to be constructed based on if the Sphinx build is html or dirhtml
256862e4a30SBarry Smith    """
257862e4a30SBarry Smith    if exception is None:
2586058a5bfSBarry Smith        import time
259862e4a30SBarry Smith        print("============================================")
260862e4a30SBarry Smith        print("    Fixing relative links")
2616058a5bfSBarry Smith        x = time.clock_gettime(time.CLOCK_REALTIME)
262862e4a30SBarry Smith        make_links_relative.make_links_relative(app.outdir)
2636058a5bfSBarry Smith        print("Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - x))
2646058a5bfSBarry Smith        print("============================================")
265862e4a30SBarry Smith
266c9f6b0acSPatrick Sanan
26775662446SPatrick Sanandef _update_htmlmap_links(app):
268862e4a30SBarry Smith    """htmlmap maps from manualpage names to relative locations in the generated documentation directory
269862e4a30SBarry Smith       hierarchy. The format of the directory location needs to be different for the Sphinx html and dirhtml
270862e4a30SBarry Smith       builds
271862e4a30SBarry Smith    """
2726058a5bfSBarry Smith    import time
27375662446SPatrick Sanan    print("============================================")
27475662446SPatrick Sanan    print("    Updating htmlmap")
2756058a5bfSBarry Smith    x = time.clock_gettime(time.CLOCK_REALTIME)
2769cd31cfbSBarry Smith    update_htmlmap_links.update_htmlmap_links(app.builder,os.path.join('manualpages','htmlmap'))
2776058a5bfSBarry Smith    print("Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - x))
2786058a5bfSBarry Smith    print("============================================")
279c6c2e312SBarry Smith
280c6c2e312SBarry Smithdef build_petsc4py_docs(app):
281*7f019730SBarry Smith    '''Builds the petsc4py docs and puts the results into the same directory tree as the PETSc docs'''
2826058a5bfSBarry Smith    # petsc4py needs to be built to build petsc4py docs via introspection
2832c804a55SBarry Smith    command = ['make', '-f', 'makefile', 'libs',
284*7f019730SBarry Smith               'PETSC_DIR=%s' % app.petsc_dir,
285*7f019730SBarry Smith               'PETSC_ARCH=arch-docs']
2866058a5bfSBarry Smith    import time
287c6c2e312SBarry Smith    print('==============================================')
288c6c2e312SBarry Smith    print('Building library to make petsc4py docs')
289c6c2e312SBarry Smith    print(command)
2906058a5bfSBarry Smith    x = time.clock_gettime(time.CLOCK_REALTIME)
291*7f019730SBarry Smith    subprocess.run(command, cwd=app.petsc_dir, check=True)
292ec83d434SBarry Smith    print("End building library for petsc4py docs Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - x))
2936058a5bfSBarry Smith    print('==============================================')
294c6c2e312SBarry Smith
295c6c2e312SBarry Smith    command = ['make', 'website',
296*7f019730SBarry Smith               'PETSC_DIR=%s' % app.petsc_dir,
297*7f019730SBarry Smith               'PETSC_ARCH=arch-docs',
298c6c2e312SBarry Smith               'LOC=%s' % app.outdir]
299c6c2e312SBarry Smith    print('============================================')
300c6c2e312SBarry Smith    print('Building petsc4py docs')
301c6c2e312SBarry Smith    print(command)
3026058a5bfSBarry Smith    x = time.clock_gettime(time.CLOCK_REALTIME)
303*7f019730SBarry Smith    subprocess.run(command, cwd=os.path.join(app.petsc_dir,'src','binding','petsc4py'), check=True)
304ec83d434SBarry Smith    print("End petsc4py docs Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - x))
3056058a5bfSBarry Smith    print('============================================')
306