xref: /petsc/doc/conf.py (revision b8253ccf9c68ffd41d47bf46b17501b60136f0e8)
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
42404447afSPatrick Sananwith open(os.path.join('..', 'include', 'petscversion.h'),'r') as version_file:
43ee12ae39SPatrick Sanan    buf = version_file.read()
44ee12ae39SPatrick Sanan    petsc_release_flag = re.search(' PETSC_VERSION_RELEASE[ ]*([0-9]*)',buf).group(1)
45ee12ae39SPatrick Sanan    major_version      = re.search(' PETSC_VERSION_MAJOR[ ]*([0-9]*)',buf).group(1)
46ee12ae39SPatrick Sanan    minor_version      = re.search(' PETSC_VERSION_MINOR[ ]*([0-9]*)',buf).group(1)
47ee12ae39SPatrick Sanan    subminor_version   = re.search(' PETSC_VERSION_SUBMINOR[ ]*([0-9]*)',buf).group(1)
48ee12ae39SPatrick Sanan
49ffebb2dfSPatrick Sanan    git_describe_version = subprocess.check_output(['git', 'describe', '--always']).strip().decode('utf-8')
50ee12ae39SPatrick Sanan    if petsc_release_flag == '0':
51ffebb2dfSPatrick Sanan        version = git_describe_version
52ffebb2dfSPatrick Sanan        release = git_describe_version
53ee12ae39SPatrick Sanan    else:
54ee12ae39SPatrick Sanan        version = '.'.join([major_version, minor_version])
55ee12ae39SPatrick Sanan        release = '.'.join([major_version,minor_version,subminor_version])
56ee12ae39SPatrick Sanan
57ee12ae39SPatrick Sanan
5896b7068eSPatrick Sanan# -- General configuration -----------------------------------------------------
5996b7068eSPatrick Sanan
6066c9fbddSBarry Smith# The information on the next line must also be the same in requirements.txt
61d1f92df0SBarry Smithneeds_sphinx='5.3'
6296b7068eSPatrick Sanannitpicky = True  # checks internal links. For external links, use "make linkcheck"
63ee12ae39SPatrick Sananmaster_doc = 'index'
64ee12ae39SPatrick Sanantemplates_path = ['_templates']
6566c9fbddSBarry Smithexclude_patterns = ['_build*', 'images', 'Thumbs.db', '.DS_Store','community/meetings/pre-2023']
6696b7068eSPatrick Sananhighlight_language = 'c'
6796b7068eSPatrick Sanannumfig = True
68ee12ae39SPatrick Sanan
6996b7068eSPatrick Sanan# -- Extensions ----------------------------------------------------------------
70ee12ae39SPatrick Sanan
714b6f941bSPatrick Sananextensions = [
724b6f941bSPatrick Sanan    'sphinx_copybutton',
734a3b3e5fSJed Brown    'sphinx_design',
744b6f941bSPatrick Sanan    'sphinxcontrib.bibtex',
754b6f941bSPatrick Sanan    'sphinxcontrib.katex',
764b6f941bSPatrick Sanan    'sphinxcontrib.rsvgconverter',
778f2bcf5fSPatrick Sanan    'myst_parser',
784b6f941bSPatrick Sanan    'html5_petsc',
794707091fSPatrick Sanan    'sphinx_remove_toctrees',
80ce78bad3SBarry Smith    'sphinx_design',
814b6f941bSPatrick Sanan]
824b6f941bSPatrick Sanan
83f3c6b5cdSPatrick Sanancopybutton_prompt_text = '$ '
844b6f941bSPatrick Sanan
8554129d2fSPatrick Sananbibtex_bibfiles = ['petsc.bib']
864b6f941bSPatrick Sanan
8709cc9507SBarry Smithmyst_enable_extensions = ["fieldlist", "dollarmath", "amsmath", "deflist", "colon_fence"]
888f2bcf5fSPatrick Sanan
898a0d1e8bSBarry Smithremove_from_toctrees = ['manualpages/*/[A-Z]*','changes/2*','changes/3*']
904707091fSPatrick Sanan
911d27aa22SBarry Smith# prevents incorrect WARNING: duplicate citation for key "xxxx" warnings
921d27aa22SBarry Smithsuppress_warnings = ['bibtex.duplicate_citation']
931d27aa22SBarry Smith
9496b7068eSPatrick Sanan# -- Options for HTML output ---------------------------------------------------
95ee12ae39SPatrick Sanan
96ee12ae39SPatrick Sananhtml_theme = 'pydata_sphinx_theme'
97ee12ae39SPatrick Sanan
9880dc5c2eSToby Isaachtml_logo_light = os.path.join('images', 'logos', 'PETSc_TAO_logos', 'PETSc-TAO', 'web', 'PETSc-TAO_RGB.svg')
9980dc5c2eSToby Isaachtml_logo_dark = os.path.join('images', 'logos', 'PETSc_TAO_logos', 'PETSc-TAO', 'web', 'PETSc-TAO_RGB_white.svg')
10080dc5c2eSToby Isaac
1017c561f09SBarry Smithhtml_static_path = ['_static', html_logo_light, html_logo_dark]
1027c561f09SBarry Smith
1037c561f09SBarry Smith# use much smaller font for h1, h2 etc. They are absurdly large in the standard style
1047c561f09SBarry Smith# https://pydata-sphinx-theme.readthedocs.io/en/v0.12.0/user_guide/styling.html
1057c561f09SBarry Smithhtml_css_files = [
1067c561f09SBarry Smith    'css/custom.css',
1077c561f09SBarry Smith]
10880dc5c2eSToby Isaac
109ee12ae39SPatrick Sananhtml_theme_options = {
110ee12ae39SPatrick Sanan    "icon_links": [
111ee12ae39SPatrick Sanan        {
112ee12ae39SPatrick Sanan            "name": "GitLab",
113ee12ae39SPatrick Sanan            "url": "https://gitlab.com/petsc/petsc",
114ee12ae39SPatrick Sanan            "icon": "fab fa-gitlab",
115ee12ae39SPatrick Sanan        },
116ee12ae39SPatrick Sanan    ],
117ee12ae39SPatrick Sanan    "use_edit_page_button": True,
1182c804a55SBarry Smith    "footer_end": ["theme-version", "last-updated"],
119d1f92df0SBarry Smith#    "secondary_sidebar_items" : ["edit-this-page"],
1203d8af492SBarry Smith     "header_links_before_dropdown": 10,
12180dc5c2eSToby Isaac    "logo": {
12280dc5c2eSToby Isaac        "image_light": os.path.basename(html_logo_light),
12380dc5c2eSToby Isaac        "image_dark": os.path.basename(html_logo_dark)
124bc1908f0SBarry Smith    },
125bc1908f0SBarry Smith    "navigation_with_keys":True
126ee12ae39SPatrick Sanan}
127ee12ae39SPatrick Sanan
128d3edb92dSPatrick Sanantry:
129d3edb92dSPatrick Sanan  git_ref = subprocess.check_output(["git", "rev-parse", "HEAD"]).rstrip()
130d3edb92dSPatrick Sanan  git_ref_release = subprocess.check_output(["git", "rev-parse", "origin/release"]).rstrip()
131d3edb92dSPatrick Sanan  edit_branch = "release" if git_ref == git_ref_release else "main"
132d3edb92dSPatrick Sananexcept subprocess.CalledProcessError:
133d3edb92dSPatrick Sanan  print("WARNING: determining branch for page edit links failed")
134d3edb92dSPatrick Sanan  edit_branch = "main"
135d3edb92dSPatrick Sanan
136ee12ae39SPatrick Sananhtml_context = {
137585d687eSPierre Jolivet    "display_gitlab": True,
138585d687eSPierre Jolivet    "gitlab_user": "petsc",
139585d687eSPierre Jolivet    "gitlab_repo": "petsc",
140585d687eSPierre Jolivet    "gitlab_version": edit_branch,
141ee12ae39SPatrick Sanan    "doc_path": "doc",
142ee12ae39SPatrick Sanan}
143ee12ae39SPatrick Sanan
14480dc5c2eSToby Isaachtml_logo = html_logo_light
145fc1137abSPatrick Sananhtml_favicon = os.path.join('images', 'logos', 'PETSc_TAO_logos', 'PETSc', 'petsc_favicon.png')
14696b7068eSPatrick Sananhtml_last_updated_fmt = r'%Y-%m-%dT%H:%M:%S%z (' + git_describe_version + ')'
147ee12ae39SPatrick Sanan
148ee12ae39SPatrick Sanan
14996b7068eSPatrick Sanan# -- Options for LaTeX output --------------------------------------------------
150ee12ae39SPatrick Sananlatex_engine = 'xelatex'
151ee12ae39SPatrick Sanan
15296b7068eSPatrick Sanan# How to arrange the documents into LaTeX files, building only the manual.
153ee12ae39SPatrick Sananlatex_documents = [
15473fdd05bSBarry Smith        ('manual/index', 'manual.tex', 'PETSc/TAO Users Manual', author, 'manual', False)
155ee12ae39SPatrick Sanan        ]
156ee12ae39SPatrick Sanan
157ee12ae39SPatrick Sananlatex_additional_files = [
15873fdd05bSBarry Smith    'images/manual/anl_tech_report/ArgonneLogo.pdf',
15973fdd05bSBarry Smith    'images/manual/anl_tech_report/ArgonneReportTemplateLastPage.pdf',
16073fdd05bSBarry Smith    'images/manual/anl_tech_report/ArgonneReportTemplatePage2.pdf',
16173fdd05bSBarry Smith    'manual/anl_tech_report/first.inc',
16273fdd05bSBarry Smith    'manual/anl_tech_report/last.inc',
163ee12ae39SPatrick Sanan]
164ee12ae39SPatrick Sanan
165ee12ae39SPatrick Sananlatex_elements = {
166ee12ae39SPatrick Sanan    'maketitle': r'\newcommand{\techreportversion}{%s}' % version +
167ee12ae39SPatrick Sananr'''
168ee12ae39SPatrick Sanan\input{first.inc}
169ee12ae39SPatrick Sanan''',
170ee12ae39SPatrick Sanan    'printindex': r'''
171ee12ae39SPatrick Sanan\printindex
172ee12ae39SPatrick Sanan\input{last.inc}
173ee12ae39SPatrick Sanan''',
174ee12ae39SPatrick Sanan    'fontpkg': r'''
175ee12ae39SPatrick Sanan\setsansfont{DejaVu Sans}
176ee12ae39SPatrick Sanan\setmonofont{DejaVu Sans Mono}
1771b671caaSPatrick Sanan''',
1781b671caaSPatrick Sanan    'tableofcontents' : r''
179ee12ae39SPatrick Sanan}
180ee12ae39SPatrick Sanan
18196b7068eSPatrick Sanan# -- Setup and event callbacks -------------------------------------------------
182ee12ae39SPatrick Sanan
18375662446SPatrick Sanandef setup(app):
18475662446SPatrick Sanan        app.connect('builder-inited', builder_init_handler)
18575662446SPatrick Sanan        app.connect('build-finished', build_finished_handler)
18602f5a9aaSPatrick Sanan
18702f5a9aaSPatrick Sanan
18802f5a9aaSPatrick Sanandef builder_init_handler(app):
189ec83d434SBarry Smith    global xtime
19075662446SPatrick Sanan    if app.builder.name.endswith('html'):
191c6267af9SBarry Smith        _build_manpages_c2html(app, 'pre')
1925becb6a3SPatrick Sanan        _update_htmlmap_links(app)
193ec83d434SBarry Smith        ptype = 'html'
194ec83d434SBarry Smith    else: ptype = 'pdf'
195ec83d434SBarry Smith    print("============================================")
196ec83d434SBarry Smith    print("    Running Sphinx on PETSc " + ptype)
197ec83d434SBarry Smith    xtime = time.clock_gettime(time.CLOCK_REALTIME)
19802f5a9aaSPatrick Sanan
19902f5a9aaSPatrick Sanan
20002f5a9aaSPatrick Sanandef build_finished_handler(app, exception):
201ec83d434SBarry Smith    global xtime
202ec83d434SBarry Smith    print("Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - xtime))
203ec83d434SBarry Smith    print("============================================")
20475662446SPatrick Sanan    if app.builder.name.endswith('html'):
205c6267af9SBarry Smith        _build_manpages_c2html(app, 'post')
206c6c2e312SBarry Smith        build_petsc4py_docs(app)
2071540e0edSPatrick Sanan        _fix_links(app, exception)
208c9f6b0acSPatrick Sanan        _fix_man_page_edit_links(app, exception)
2099f89e73bSBarry Smith        fix_pydata_margins.fix_pydata_margins(app.outdir)
21095216c61SPatrick Sanan        if app.builder.name == 'dirhtml':
21195216c61SPatrick Sanan            _add_man_page_redirects(app, exception)
2129cd31cfbSBarry Smith        # remove sources for manual pages since they are automatically generated and should not be looked at on the website
2139cd31cfbSBarry Smith        if os.path.isdir(os.path.join(app.outdir,'_sources','manualpages')):
2149cd31cfbSBarry Smith            shutil.rmtree(os.path.join(app.outdir,'_sources','manualpages'))
21530f5c8b0SPatrick Sanan        if app.builder.name == 'html':
21628cbf9b2SBarry Smith            print("==========================================================================")
21728cbf9b2SBarry Smith            print("    open %s/index.html in your browser to view the documentation " % app.outdir)
21828cbf9b2SBarry Smith            print("==========================================================================")
21902f5a9aaSPatrick Sanan
22095216c61SPatrick Sanandef _add_man_page_redirects(app, exception):
22195216c61SPatrick Sanan    if exception is None:
2226058a5bfSBarry Smith        import time
22395216c61SPatrick Sanan        print("============================================")
22495216c61SPatrick Sanan        print("    Adding man pages redirects")
2256058a5bfSBarry Smith        x = time.clock_gettime(time.CLOCK_REALTIME)
22695216c61SPatrick Sanan        add_man_page_redirects.add_man_page_redirects(app.outdir)
2276058a5bfSBarry Smith        print("Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - x))
2286058a5bfSBarry Smith        print("============================================")
2297553d27dSPatrick Sanan
230c6267af9SBarry Smithdef _build_manpages_c2html(app, stage):
231862e4a30SBarry Smith    '''Builds the .md versions of the manual pages and the .html version of the source code'''
232c6267af9SBarry Smith    build_manpages_c2html.main(stage,app.outdir)
23375662446SPatrick Sanan
234c9f6b0acSPatrick Sanandef _fix_man_page_edit_links(app, exception):
235c9f6b0acSPatrick Sanan    if exception is None:
2366058a5bfSBarry Smith        import time
237c9f6b0acSPatrick Sanan        print("============================================")
2383ecf4727SBarry Smith        print("    Fixing manual page edit links")
2396058a5bfSBarry Smith        x = time.clock_gettime(time.CLOCK_REALTIME)
240c9f6b0acSPatrick Sanan        fix_man_page_edit_links.fix_man_page_edit_links(app.outdir)
2416058a5bfSBarry Smith        print("Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - x))
2426058a5bfSBarry Smith        print("============================================")
243c9f6b0acSPatrick Sanan
244862e4a30SBarry Smith#
245862e4a30SBarry Smith#   The following two scripts are needed because the Sphinx html and dirhtml builds save the output html
246*b8253ccfSBarry Smith#   files at different levels of the directory hierarchy. file.rst/md -> file.html with html but
247*b8253ccfSBarry Smith#   file.rst/md -> file/index.html with dirhtml and we want both to work correctly using relative links.
248862e4a30SBarry Smith
249862e4a30SBarry Smithdef _fix_links(app, exception):
250862e4a30SBarry Smith    """We need to manage our own relative paths in the User's Manual for the source code files which
251862e4a30SBarry Smith       are auto-generated by c2html outside of Sphinx so Sphinx cannot directly handle those links for use.
252862e4a30SBarry Smith       We use the string PETSC_DOC_OUT_ROOT_PLACEHOLDER in URLs in the Sphinx .rst files as a stand in
253862e4a30SBarry Smith       for the root directory that needs to be constructed based on if the Sphinx build is html or dirhtml
254862e4a30SBarry Smith    """
255862e4a30SBarry Smith    if exception is None:
2566058a5bfSBarry Smith        import time
257862e4a30SBarry Smith        print("============================================")
258862e4a30SBarry Smith        print("    Fixing relative links")
2596058a5bfSBarry Smith        x = time.clock_gettime(time.CLOCK_REALTIME)
260862e4a30SBarry Smith        make_links_relative.make_links_relative(app.outdir)
2616058a5bfSBarry Smith        print("Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - x))
2626058a5bfSBarry Smith        print("============================================")
263862e4a30SBarry Smith
264c9f6b0acSPatrick Sanan
26575662446SPatrick Sanandef _update_htmlmap_links(app):
266862e4a30SBarry Smith    """htmlmap maps from manualpage names to relative locations in the generated documentation directory
267862e4a30SBarry Smith       hierarchy. The format of the directory location needs to be different for the Sphinx html and dirhtml
268862e4a30SBarry Smith       builds
269862e4a30SBarry Smith    """
2706058a5bfSBarry Smith    import time
27175662446SPatrick Sanan    print("============================================")
27275662446SPatrick Sanan    print("    Updating htmlmap")
2736058a5bfSBarry Smith    x = time.clock_gettime(time.CLOCK_REALTIME)
2749cd31cfbSBarry Smith    update_htmlmap_links.update_htmlmap_links(app.builder,os.path.join('manualpages','htmlmap'))
2756058a5bfSBarry Smith    print("Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - x))
2766058a5bfSBarry Smith    print("============================================")
277c6c2e312SBarry Smith
278c6c2e312SBarry Smithdef build_petsc4py_docs(app):
279c6c2e312SBarry Smith    petsc_dir = os.path.dirname(os.path.abspath(os.path.join(__file__,'..')))
280c6267af9SBarry Smith    petsc_arch = 'arch-docs'
281c6c2e312SBarry Smith
2826058a5bfSBarry Smith    # petsc4py needs to be built to build petsc4py docs via introspection
2832c804a55SBarry Smith    command = ['make', '-f', 'makefile', 'libs',
284c6c2e312SBarry Smith               'PETSC_DIR=%s' % petsc_dir,
285c6c2e312SBarry Smith               'PETSC_ARCH=%s' % petsc_arch]
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)
291c6c2e312SBarry Smith    subprocess.run(command, cwd=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',
296c6c2e312SBarry Smith               'PETSC_DIR=%s' % petsc_dir,
297c6c2e312SBarry Smith               'PETSC_ARCH=%s' % petsc_arch,
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)
303c6c2e312SBarry Smith    subprocess.run(command, cwd=os.path.join(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