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# prevents incorrect WARNING: duplicate citation for key "xxxx" warnings 90suppress_warnings = ['bibtex.duplicate_citation'] 91 92# -- Options for HTML output --------------------------------------------------- 93 94html_theme = 'pydata_sphinx_theme' 95 96html_logo_light = os.path.join('images', 'logos', 'PETSc_TAO_logos', 'PETSc-TAO', 'web', 'PETSc-TAO_RGB.svg') 97html_logo_dark = os.path.join('images', 'logos', 'PETSc_TAO_logos', 'PETSc-TAO', 'web', 'PETSc-TAO_RGB_white.svg') 98 99html_static_path = ['_static', html_logo_light, html_logo_dark] 100 101# use much smaller font for h1, h2 etc. They are absurdly large in the standard style 102# https://pydata-sphinx-theme.readthedocs.io/en/v0.12.0/user_guide/styling.html 103html_css_files = [ 104 'css/custom.css', 105] 106 107html_theme_options = { 108 "icon_links": [ 109 { 110 "name": "GitLab", 111 "url": "https://gitlab.com/petsc/petsc", 112 "icon": "fab fa-gitlab", 113 }, 114 ], 115 "use_edit_page_button": True, 116 "footer_items": ["copyright", "sphinx-version", "last-updated"], 117# "secondary_sidebar_items" : ["edit-this-page"], 118 "header_links_before_dropdown": 10, 119 "logo": { 120 "image_light": os.path.basename(html_logo_light), 121 "image_dark": os.path.basename(html_logo_dark) 122 }, 123 "navigation_with_keys":True 124} 125 126try: 127 git_ref = subprocess.check_output(["git", "rev-parse", "HEAD"]).rstrip() 128 git_ref_release = subprocess.check_output(["git", "rev-parse", "origin/release"]).rstrip() 129 edit_branch = "release" if git_ref == git_ref_release else "main" 130except subprocess.CalledProcessError: 131 print("WARNING: determining branch for page edit links failed") 132 edit_branch = "main" 133 134html_context = { 135 "github_url": "https://gitlab.com", 136 "github_user": "petsc", 137 "github_repo": "petsc", 138 "github_version": edit_branch, 139 "doc_path": "doc", 140} 141 142html_logo = html_logo_light 143html_favicon = os.path.join('images', 'logos', 'PETSc_TAO_logos', 'PETSc', 'petsc_favicon.png') 144html_last_updated_fmt = r'%Y-%m-%dT%H:%M:%S%z (' + git_describe_version + ')' 145 146 147# -- Options for LaTeX output -------------------------------------------------- 148latex_engine = 'xelatex' 149 150# How to arrange the documents into LaTeX files, building only the manual. 151latex_documents = [ 152 ('manual/index', 'manual.tex', 'PETSc/TAO Users Manual', author, 'manual', False) 153 ] 154 155latex_additional_files = [ 156 'images/manual/anl_tech_report/ArgonneLogo.pdf', 157 'images/manual/anl_tech_report/ArgonneReportTemplateLastPage.pdf', 158 'images/manual/anl_tech_report/ArgonneReportTemplatePage2.pdf', 159 'manual/anl_tech_report/first.inc', 160 'manual/anl_tech_report/last.inc', 161] 162 163latex_elements = { 164 'maketitle': r'\newcommand{\techreportversion}{%s}' % version + 165r''' 166\input{first.inc} 167''', 168 'printindex': r''' 169\printindex 170\input{last.inc} 171''', 172 'fontpkg': r''' 173\setsansfont{DejaVu Sans} 174\setmonofont{DejaVu Sans Mono} 175''', 176 'tableofcontents' : r'' 177} 178 179 180# -- Setup and event callbacks ------------------------------------------------- 181 182def setup(app): 183 app.connect('builder-inited', builder_init_handler) 184 app.connect('build-finished', build_finished_handler) 185 186 187def builder_init_handler(app): 188 if app.builder.name.endswith('html'): 189 _build_classic_docs(app, 'pre') 190 _update_htmlmap_links(app) 191 192 193def build_finished_handler(app, exception): 194 if app.builder.name.endswith('html'): 195 _build_classic_docs(app, 'post') 196 build_petsc4py_docs(app) 197 _fix_links(app, exception) 198 _fix_man_page_edit_links(app, exception) 199 fix_pydata_margins.fix_pydata_margins(app.outdir) 200 if app.builder.name == 'dirhtml': 201 _add_man_page_redirects(app, exception) 202 # remove sources for manual pages since they are automatically generated and should not be looked at on the website 203 if os.path.isdir(os.path.join(app.outdir,'_sources','manualpages')): 204 shutil.rmtree(os.path.join(app.outdir,'_sources','manualpages')) 205 if app.builder.name == 'html': 206 print("==========================================================================") 207 print(" open %s/index.html in your browser to view the documentation " % app.outdir) 208 print("==========================================================================") 209 210def _add_man_page_redirects(app, exception): 211 if exception is None: 212 import time 213 print("============================================") 214 print(" Adding man pages redirects") 215 x = time.clock_gettime(time.CLOCK_REALTIME) 216 add_man_page_redirects.add_man_page_redirects(app.outdir) 217 print("Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - x)) 218 print("============================================") 219 220def _build_classic_docs(app, stage): 221 '''Builds the .md versions of the manual pages and the .html version of the source code''' 222 build_classic_docs.main(stage,app.outdir) 223 224def _fix_man_page_edit_links(app, exception): 225 if exception is None: 226 import time 227 print("============================================") 228 print(" Fixing manual page edit links") 229 x = time.clock_gettime(time.CLOCK_REALTIME) 230 fix_man_page_edit_links.fix_man_page_edit_links(app.outdir) 231 print("Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - x)) 232 print("============================================") 233 234# 235# The following two scripts are needed because the Sphinx html and dirhtml builds save the output html 236# files at different levels of the directory hierarchy. file.rst -> file.html with html but 237# file.rst -> file/index.html with dirhtml and we want both to work correctly using relative links. 238 239def _fix_links(app, exception): 240 """We need to manage our own relative paths in the User's Manual for the source code files which 241 are auto-generated by c2html outside of Sphinx so Sphinx cannot directly handle those links for use. 242 We use the string PETSC_DOC_OUT_ROOT_PLACEHOLDER in URLs in the Sphinx .rst files as a stand in 243 for the root directory that needs to be constructed based on if the Sphinx build is html or dirhtml 244 """ 245 if exception is None: 246 import time 247 print("============================================") 248 print(" Fixing relative links") 249 x = time.clock_gettime(time.CLOCK_REALTIME) 250 make_links_relative.make_links_relative(app.outdir) 251 print("Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - x)) 252 print("============================================") 253 254 255def _update_htmlmap_links(app): 256 """htmlmap maps from manualpage names to relative locations in the generated documentation directory 257 hierarchy. The format of the directory location needs to be different for the Sphinx html and dirhtml 258 builds 259 """ 260 import time 261 print("============================================") 262 print(" Updating htmlmap") 263 x = time.clock_gettime(time.CLOCK_REALTIME) 264 update_htmlmap_links.update_htmlmap_links(app.builder,os.path.join('manualpages','htmlmap')) 265 print("Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - x)) 266 print("============================================") 267 268def build_petsc4py_docs(app): 269 petsc_dir = os.path.dirname(os.path.abspath(os.path.join(__file__,'..'))) 270 petsc_arch = 'arch-classic-docs' 271 272 # petsc4py needs to be built to build petsc4py docs via introspection 273 command = ['make', 'all', 274 'PETSC_DIR=%s' % petsc_dir, 275 'PETSC_ARCH=%s' % petsc_arch] 276 import time 277 print('==============================================') 278 print('Building library to make petsc4py docs') 279 print(command) 280 x = time.clock_gettime(time.CLOCK_REALTIME) 281 subprocess.run(command, cwd=petsc_dir, check=True) 282 print("Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - x)) 283 print('==============================================') 284 285 command = ['make', 'website', 286 'PETSC_DIR=%s' % petsc_dir, 287 'PETSC_ARCH=%s' % petsc_arch, 288 'LOC=%s' % app.outdir] 289 print('============================================') 290 print('Building petsc4py docs') 291 print(command) 292 x = time.clock_gettime(time.CLOCK_REALTIME) 293 subprocess.run(command, cwd=os.path.join(petsc_dir,'src','binding','petsc4py'), check=True) 294 print("Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - x)) 295 print('============================================') 296