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