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 13import time 14 15sys.path.append(os.getcwd()) 16sys.path.append(os.path.abspath('./ext')) 17 18import add_man_page_redirects 19import build_manpages_c2html 20import fix_man_page_edit_links 21import make_links_relative 22import update_htmlmap_links 23import fix_pydata_margins 24 25 26if not os.path.isdir("images"): 27 print("-----------------------------------------------------------------------------") 28 print("ERROR") 29 print("images directory does not seem to exist.") 30 print("To clone the required repository, try") 31 print(" make images") 32 print("-----------------------------------------------------------------------------") 33 raise Exception("Aborting because images missing") 34 35 36# -- Project information ------------------------------------------------------- 37 38project = 'PETSc' 39copyright = '1991-%d, UChicago Argonne, LLC and the PETSc Development Team' % datetime.date.today().year 40author = 'The PETSc Development Team' 41 42includedir = os.path.join('..', 'include', 'petscversion.h') 43if not os.path.isfile(includedir): includedir = os.path.join('..', '..', 'include', 'petscversion.h') 44with open(includedir,'r') as version_file: 45 buf = version_file.read() 46 petsc_release_flag = re.search(' PETSC_VERSION_RELEASE[ ]*([0-9]*)',buf).group(1) 47 major_version = re.search(' PETSC_VERSION_MAJOR[ ]*([0-9]*)',buf).group(1) 48 minor_version = re.search(' PETSC_VERSION_MINOR[ ]*([0-9]*)',buf).group(1) 49 subminor_version = re.search(' PETSC_VERSION_SUBMINOR[ ]*([0-9]*)',buf).group(1) 50 51 git_describe_version = subprocess.check_output(['git', 'describe', '--always']).strip().decode('utf-8') 52 if petsc_release_flag == '0': 53 version = git_describe_version 54 release = git_describe_version 55 else: 56 version = '.'.join([major_version, minor_version]) 57 release = '.'.join([major_version,minor_version,subminor_version]) 58 59 60# -- General configuration ----------------------------------------------------- 61 62# The information on the next line must also be the same in requirements.txt 63needs_sphinx='5.3' 64nitpicky = True # checks internal links. For external links, use "make linkcheck" 65master_doc = 'index' 66templates_path = ['_templates'] 67exclude_patterns = ['_build*', 'images', 'Thumbs.db', '.DS_Store','community/meetings/pre-2023'] 68highlight_language = 'c' 69numfig = True 70 71# -- Extensions ---------------------------------------------------------------- 72 73extensions = [ 74 'sphinx_copybutton', 75 'sphinx_design', 76 'sphinxcontrib.bibtex', 77 'sphinxcontrib.katex', 78 'sphinxcontrib.rsvgconverter', 79 'myst_parser', 80 'html5_petsc', 81 'sphinx_remove_toctrees', 82 'sphinx_design', 83] 84 85copybutton_prompt_text = '$ ' 86 87bibtex_bibfiles = ['petsc.bib'] 88 89myst_enable_extensions = ["fieldlist", "dollarmath", "amsmath", "deflist", "colon_fence"] 90 91remove_from_toctrees = ['manualpages/*/[A-Z]*','changes/2*','changes/3*'] 92 93# prevents incorrect WARNING: duplicate citation for key "xxxx" warnings 94suppress_warnings = ['bibtex.duplicate_citation'] 95 96# -- Options for HTML output --------------------------------------------------- 97 98html_theme = 'pydata_sphinx_theme' 99 100html_logo_light = os.path.join('images', 'logos', 'PETSc_TAO_logos', 'PETSc-TAO', 'web', 'PETSc-TAO_RGB.svg') 101html_logo_dark = os.path.join('images', 'logos', 'PETSc_TAO_logos', 'PETSc-TAO', 'web', 'PETSc-TAO_RGB_white.svg') 102 103html_static_path = ['_static', html_logo_light, html_logo_dark] 104 105# use much smaller font for h1, h2 etc. They are absurdly large in the standard style 106# https://pydata-sphinx-theme.readthedocs.io/en/v0.12.0/user_guide/styling.html 107html_css_files = [ 108 'css/custom.css', 109] 110 111html_theme_options = { 112 "icon_links": [ 113 { 114 "name": "GitLab", 115 "url": "https://gitlab.com/petsc/petsc", 116 "icon": "fab fa-gitlab", 117 }, 118 ], 119 "use_edit_page_button": True, 120 "footer_end": ["theme-version", "last-updated"], 121# "secondary_sidebar_items" : ["edit-this-page"], 122 "header_links_before_dropdown": 10, 123 "logo": { 124 "image_light": os.path.basename(html_logo_light), 125 "image_dark": os.path.basename(html_logo_dark) 126 }, 127 "navigation_with_keys":True 128} 129 130try: 131 git_ref = subprocess.check_output(["git", "rev-parse", "HEAD"]).rstrip() 132 git_ref_release = subprocess.check_output(["git", "rev-parse", "origin/release"]).rstrip() 133 edit_branch = "release" if git_ref == git_ref_release else "main" 134except subprocess.CalledProcessError: 135 print("WARNING: determining branch for page edit links failed") 136 edit_branch = "main" 137 138html_context = { 139 "display_gitlab": True, 140 "gitlab_user": "petsc", 141 "gitlab_repo": "petsc", 142 "gitlab_version": edit_branch, 143 "doc_path": "doc", 144} 145 146html_logo = html_logo_light 147html_favicon = os.path.join('images', 'logos', 'PETSc_TAO_logos', 'PETSc', 'petsc_favicon.png') 148html_last_updated_fmt = r'%Y-%m-%dT%H:%M:%S%z (' + git_describe_version + ')' 149 150 151# -- Options for LaTeX output -------------------------------------------------- 152latex_engine = 'xelatex' 153 154# How to arrange the documents into LaTeX files, building only the manual. 155latex_documents = [ 156 ('manual/index', 'manual.tex', 'PETSc/TAO Users Manual', author, 'manual', False) 157 ] 158 159latex_additional_files = [ 160 'images/manual/anl_tech_report/ArgonneLogo.pdf', 161 'images/manual/anl_tech_report/ArgonneReportTemplateLastPage.pdf', 162 'images/manual/anl_tech_report/ArgonneReportTemplatePage2.pdf', 163 'manual/anl_tech_report/first.inc', 164 'manual/anl_tech_report/last.inc', 165] 166 167latex_elements = { 168 'maketitle': r'\newcommand{\techreportversion}{%s}' % version + 169r''' 170\input{first.inc} 171''', 172 'printindex': r''' 173\printindex 174\input{last.inc} 175''', 176 'fontpkg': r''' 177\setsansfont{DejaVu Sans} 178\setmonofont{DejaVu Sans Mono} 179''', 180 'tableofcontents' : r'' 181} 182 183# -- Setup and event callbacks ------------------------------------------------- 184 185def setup(app): 186 app.connect('builder-inited', builder_init_handler) 187 app.connect('build-finished', build_finished_handler) 188 if 'PETSC_DIR' in os.environ: 189 app.petsc_dir = os.path.abspath(os.environ['PETSC_DIR']) 190 else: 191 app.petsc_dir = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")) 192 app.build_dir = os.path.abspath(os.getcwd()) 193 194def builder_init_handler(app): 195 global xtime 196 if app.builder.name.endswith('html'): 197 build_manpages_c2html.main('pre',app.petsc_dir,app.build_dir,app.outdir) 198 _update_htmlmap_links(app) 199 ptype = 'html' 200 else: ptype = 'pdf' 201 print("============================================") 202 print(" Running Sphinx on PETSc " + ptype) 203 xtime = time.clock_gettime(time.CLOCK_REALTIME) 204 205 206def build_finished_handler(app, exception): 207 global xtime 208 print("Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - xtime)) 209 print("============================================") 210 if app.builder.name.endswith('html'): 211 build_manpages_c2html.main('post',app.petsc_dir,app.build_dir,app.outdir) 212 build_petsc4py_docs(app) 213 _fix_links(app, exception) 214 _fix_man_page_edit_links(app, exception) 215 fix_pydata_margins.fix_pydata_margins(app.outdir) 216 if app.builder.name == 'dirhtml': 217 _add_man_page_redirects(app, exception) 218 # remove sources for manual pages since they are automatically generated and should not be looked at on the website 219 if os.path.isdir(os.path.join(app.outdir,'_sources','manualpages')): 220 shutil.rmtree(os.path.join(app.outdir,'_sources','manualpages')) 221 if app.builder.name == 'html': 222 print("==========================================================================") 223 print(" open %s/index.html in your browser to view the documentation " % app.outdir) 224 print("==========================================================================") 225 226def _add_man_page_redirects(app, exception): 227 if exception is None: 228 import time 229 print("============================================") 230 print(" Adding man pages redirects") 231 x = time.clock_gettime(time.CLOCK_REALTIME) 232 add_man_page_redirects.add_man_page_redirects(app.outdir) 233 print("Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - x)) 234 print("============================================") 235 236def _fix_man_page_edit_links(app, exception): 237 if exception is None: 238 import time 239 print("============================================") 240 print(" Fixing manual page edit links") 241 x = time.clock_gettime(time.CLOCK_REALTIME) 242 fix_man_page_edit_links.fix_man_page_edit_links(app.outdir) 243 print("Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - x)) 244 print("============================================") 245 246# 247# The following two scripts are needed because the Sphinx html and dirhtml builds save the output html 248# files at different levels of the directory hierarchy. file.rst/md -> file.html with html but 249# file.rst/md -> file/index.html with dirhtml and we want both to work correctly using relative links. 250 251def _fix_links(app, exception): 252 """We need to manage our own relative paths in the User's Manual for the source code files which 253 are auto-generated by c2html outside of Sphinx so Sphinx cannot directly handle those links for use. 254 We use the string PETSC_DOC_OUT_ROOT_PLACEHOLDER in URLs in the Sphinx .rst files as a stand in 255 for the root directory that needs to be constructed based on if the Sphinx build is html or dirhtml 256 """ 257 if exception is None: 258 import time 259 print("============================================") 260 print(" Fixing relative links") 261 x = time.clock_gettime(time.CLOCK_REALTIME) 262 make_links_relative.make_links_relative(app.outdir) 263 print("Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - x)) 264 print("============================================") 265 266 267def _update_htmlmap_links(app): 268 """htmlmap maps from manualpage names to relative locations in the generated documentation directory 269 hierarchy. The format of the directory location needs to be different for the Sphinx html and dirhtml 270 builds 271 """ 272 import time 273 print("============================================") 274 print(" Updating htmlmap") 275 x = time.clock_gettime(time.CLOCK_REALTIME) 276 update_htmlmap_links.update_htmlmap_links(app.builder,os.path.join('manualpages','htmlmap')) 277 print("Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - x)) 278 print("============================================") 279 280def build_petsc4py_docs(app): 281 '''Builds the petsc4py docs and puts the results into the same directory tree as the PETSc docs''' 282 # petsc4py needs to be built to build petsc4py docs via introspection 283 command = ['make', '-f', 'makefile', 'libs', 284 'PETSC_DIR=%s' % app.petsc_dir, 285 'PETSC_ARCH=arch-docs'] 286 import time 287 print('==============================================') 288 print('Building library to make petsc4py docs') 289 print(command) 290 x = time.clock_gettime(time.CLOCK_REALTIME) 291 subprocess.run(command, cwd=app.petsc_dir, check=True) 292 print("End building library for petsc4py docs Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - x)) 293 print('==============================================') 294 295 command = ['make', 'website', 296 'PETSC_DIR=%s' % app.petsc_dir, 297 'PETSC_ARCH=arch-docs', 298 'LOC=%s' % app.outdir] 299 print('============================================') 300 print('Building petsc4py docs') 301 print(command) 302 x = time.clock_gettime(time.CLOCK_REALTIME) 303 subprocess.run(command, cwd=os.path.join(app.petsc_dir,'src','binding','petsc4py'), check=True) 304 print("End petsc4py docs Time: "+str(time.clock_gettime(time.CLOCK_REALTIME) - x)) 305 print('============================================') 306