Docs: Python: Refactor the config file out of 'sphinx_doc_gen.py'
This was done originally because we need access to some information that is avalable from `bpy` however, we only need a few pieces of information. Instead, I have refactored the code to a traditional `conf.py` file that uses template strings that get substituted when the file is copied to the build folder. The goal here is to make it simpler to adjust the configuration. This change also moves the config generation from `rna2sphinx` to the main function. Pull Request: https://projects.blender.org/blender/blender/pulls/119904
This commit is contained in:
parent
148940ad15
commit
32db305899
|
@ -0,0 +1,116 @@
|
|||
# SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
from string import Template
|
||||
import time
|
||||
|
||||
|
||||
# These are substituted when this file is copied to the build directory.
|
||||
BLENDER_VERSION_STRING = "${BLENDER_VERSION_STRING}"
|
||||
BLENDER_VERSION_DOTS = "${BLENDER_VERSION_DOTS}"
|
||||
BLENDER_REVISION = "${BLENDER_REVISION}"
|
||||
BLENDER_REVISION_TIMESTAMP = "${BLENDER_REVISION_TIMESTAMP}"
|
||||
|
||||
if BLENDER_REVISION != "Unknown":
|
||||
# SHA1 Git hash
|
||||
BLENDER_VERSION_HASH = BLENDER_REVISION
|
||||
BLENDER_VERSION_HASH_HTML_LINK = "<a href=https://projects.blender.org/blender/blender/commit/%s>%s</a>" % (
|
||||
BLENDER_VERSION_HASH, BLENDER_VERSION_HASH)
|
||||
BLENDER_VERSION_DATE = time.strftime("%d/%m/%Y", time.localtime(BLENDER_REVISION_TIMESTAMP))
|
||||
else:
|
||||
# Fallback: Should not be used
|
||||
BLENDER_VERSION_HASH = "Hash Unknown"
|
||||
BLENDER_VERSION_HASH_HTML_LINK = BLENDER_VERSION_HASH
|
||||
BLENDER_VERSION_DATE = time.strftime("%Y-%m-%d")
|
||||
|
||||
extensions = ['sphinx.ext.intersphinx']
|
||||
intersphinx_mapping = {'blender_manual': ("https://docs.blender.org/manual/en/dev/", None)}
|
||||
project = "Blender %s Python API" % BLENDER_VERSION_STRING
|
||||
root_doc = "index"
|
||||
copyright = "Blender Authors"
|
||||
version = BLENDER_VERSION_DOTS
|
||||
release = BLENDER_VERSION_DOTS
|
||||
|
||||
# Set this as the default is a super-set of Python3.
|
||||
highlight_language = 'python3'
|
||||
# No need to detect encoding.
|
||||
highlight_options = {'default': {'encoding': 'utf-8'}}
|
||||
|
||||
# Quiet file not in table-of-contents warnings.
|
||||
exclude_patterns = [
|
||||
"include__bmesh.rst",
|
||||
]
|
||||
|
||||
html_title = "Blender Python API"
|
||||
|
||||
# The fallback to a built-in theme when furo is not found.
|
||||
html_theme = 'default'
|
||||
|
||||
try:
|
||||
import furo
|
||||
html_theme = "furo"
|
||||
del furo
|
||||
except ModuleNotFoundError:
|
||||
pass
|
||||
|
||||
if html_theme == "furo":
|
||||
html_theme_options = {
|
||||
"light_css_variables": {
|
||||
"color-brand-primary": "#265787",
|
||||
"color-brand-content": "#265787",
|
||||
},
|
||||
}
|
||||
|
||||
html_sidebars = {
|
||||
"**": [
|
||||
"sidebar/brand.html",
|
||||
"sidebar/search.html",
|
||||
"sidebar/scroll-start.html",
|
||||
"sidebar/navigation.html",
|
||||
"sidebar/scroll-end.html",
|
||||
"sidebar/variant-selector.html",
|
||||
]
|
||||
}
|
||||
|
||||
# not helpful since the source is generated, adds to upload size.
|
||||
html_copy_source = False
|
||||
html_show_sphinx = False
|
||||
html_baseurl = "https://docs.blender.org/api/current/"
|
||||
html_use_opensearch = "https://docs.blender.org/api/current"
|
||||
html_show_search_summary = True
|
||||
html_split_index = True
|
||||
html_static_path = ["static"]
|
||||
templates_path = ["templates"]
|
||||
html_context = {"commit": "%s - %s" % (BLENDER_VERSION_HASH_HTML_LINK, BLENDER_VERSION_DATE)}
|
||||
html_extra_path = ["static"]
|
||||
html_favicon = "static/favicon.ico"
|
||||
html_logo = "static/blender_logo.svg"
|
||||
# Disable default `last_updated` value, since this is the date of doc generation, not the one of the source commit.
|
||||
html_last_updated_fmt = None
|
||||
if html_theme == 'furo':
|
||||
html_css_files = ["css/theme_overrides.css", "css/version_switch.css"]
|
||||
html_js_files = ["js/version_switch.js"]
|
||||
|
||||
# needed for latex, pdf gen
|
||||
latex_elements = {
|
||||
'papersize': 'a4paper',
|
||||
}
|
||||
|
||||
latex_documents = [("contents", "contents.tex", "Blender Index", "Blender Foundation", "manual"), ]
|
||||
|
||||
# Workaround for useless links leading to compile errors
|
||||
# See https://github.com/sphinx-doc/sphinx/issues/3866
|
||||
from sphinx.domains.python import PythonDomain
|
||||
|
||||
|
||||
class PatchedPythonDomain(PythonDomain):
|
||||
def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode):
|
||||
if 'refspecific' in node:
|
||||
del node['refspecific']
|
||||
return super(PatchedPythonDomain, self).resolve_xref(
|
||||
env, fromdocname, builder, typ, target, node, contnode)
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.add_domain(PatchedPythonDomain, override=True)
|
|
@ -486,19 +486,6 @@ BLENDER_REVISION_TIMESTAMP = bpy.app.build_commit_timestamp
|
|||
BLENDER_VERSION_STRING = bpy.app.version_string
|
||||
BLENDER_VERSION_DOTS = "%d.%d" % (bpy.app.version[0], bpy.app.version[1])
|
||||
|
||||
if BLENDER_REVISION != "Unknown":
|
||||
# SHA1 Git hash
|
||||
BLENDER_VERSION_HASH = BLENDER_REVISION
|
||||
BLENDER_VERSION_HASH_HTML_LINK = "<a href=https://projects.blender.org/blender/blender/commit/%s>%s</a>" % (
|
||||
BLENDER_VERSION_HASH, BLENDER_VERSION_HASH,
|
||||
)
|
||||
BLENDER_VERSION_DATE = time.strftime("%d/%m/%Y", time.localtime(BLENDER_REVISION_TIMESTAMP))
|
||||
else:
|
||||
# Fallback: Should not be used
|
||||
BLENDER_VERSION_HASH = "Hash Unknown"
|
||||
BLENDER_VERSION_HASH_HTML_LINK = BLENDER_VERSION_HASH
|
||||
BLENDER_VERSION_DATE = time.strftime("%Y-%m-%d")
|
||||
|
||||
# Example: `2_83`.
|
||||
BLENDER_VERSION_PATH = "%d_%d" % (bpy.app.version[0], bpy.app.version[1])
|
||||
|
||||
|
@ -1895,110 +1882,6 @@ def pyrna2sphinx(basepath):
|
|||
write_ops()
|
||||
|
||||
|
||||
def write_sphinx_conf_py(basepath):
|
||||
"""
|
||||
Write sphinx's ``conf.py``.
|
||||
"""
|
||||
filepath = os.path.join(basepath, "conf.py")
|
||||
file = open(filepath, "w", encoding="utf-8")
|
||||
fw = file.write
|
||||
|
||||
fw("import sys, os\n\n")
|
||||
fw("extensions = ['sphinx.ext.intersphinx']\n\n")
|
||||
fw("intersphinx_mapping = {'blender_manual': ('https://docs.blender.org/manual/en/dev/', None)}\n\n")
|
||||
fw("project = 'Blender %s Python API'\n" % BLENDER_VERSION_STRING)
|
||||
fw("root_doc = 'index'\n")
|
||||
fw("copyright = 'Blender Authors'\n")
|
||||
fw("version = '%s'\n" % BLENDER_VERSION_DOTS)
|
||||
fw("release = '%s'\n" % BLENDER_VERSION_DOTS)
|
||||
|
||||
# Set this as the default is a super-set of Python3.
|
||||
fw("highlight_language = 'python3'\n")
|
||||
# No need to detect encoding.
|
||||
fw("highlight_options = {'default': {'encoding': 'utf-8'}}\n\n")
|
||||
|
||||
# Quiet file not in table-of-contents warnings.
|
||||
fw("exclude_patterns = [\n")
|
||||
fw(" 'include__bmesh.rst',\n")
|
||||
fw("]\n\n")
|
||||
|
||||
fw("html_title = 'Blender Python API'\n")
|
||||
|
||||
fw("html_theme = 'default'\n")
|
||||
# The theme 'sphinx_rtd_theme' is no longer distributed with sphinx by default, only use when available.
|
||||
fw(r"""
|
||||
try:
|
||||
import furo
|
||||
html_theme = "furo"
|
||||
del furo
|
||||
except ModuleNotFoundError:
|
||||
pass
|
||||
if html_theme == "furo":
|
||||
html_theme_options = {
|
||||
"light_css_variables": {
|
||||
"color-brand-primary": "#265787",
|
||||
"color-brand-content": "#265787",
|
||||
},
|
||||
}
|
||||
|
||||
html_sidebars = {
|
||||
"**": [
|
||||
"sidebar/brand.html",
|
||||
"sidebar/search.html",
|
||||
"sidebar/scroll-start.html",
|
||||
"sidebar/navigation.html",
|
||||
"sidebar/scroll-end.html",
|
||||
"sidebar/variant-selector.html",
|
||||
]
|
||||
}
|
||||
""")
|
||||
|
||||
# not helpful since the source is generated, adds to upload size.
|
||||
fw("html_copy_source = False\n")
|
||||
fw("html_show_sphinx = False\n")
|
||||
fw("html_baseurl = 'https://docs.blender.org/api/current/'\n")
|
||||
fw("html_use_opensearch = 'https://docs.blender.org/api/current'\n")
|
||||
fw("html_show_search_summary = True\n")
|
||||
fw("html_split_index = True\n")
|
||||
fw("html_static_path = ['static']\n")
|
||||
fw("templates_path = ['templates']\n")
|
||||
fw("html_context = {'commit': '%s - %s'}\n" % (BLENDER_VERSION_HASH_HTML_LINK, BLENDER_VERSION_DATE))
|
||||
fw("html_extra_path = ['static']\n")
|
||||
fw("html_favicon = 'static/favicon.ico'\n")
|
||||
fw("html_logo = 'static/blender_logo.svg'\n")
|
||||
# Disable default `last_updated` value, since this is the date of doc generation, not the one of the source commit.
|
||||
fw("html_last_updated_fmt = None\n\n")
|
||||
fw("if html_theme == 'furo':\n")
|
||||
fw(" html_css_files = ['css/theme_overrides.css', 'css/version_switch.css']\n")
|
||||
fw(" html_js_files = ['js/version_switch.js']\n")
|
||||
|
||||
# needed for latex, pdf gen
|
||||
fw("latex_elements = {\n")
|
||||
fw(" 'papersize': 'a4paper',\n")
|
||||
fw("}\n\n")
|
||||
|
||||
fw("latex_documents = [ ('contents', 'contents.tex', 'Blender Index', 'Blender Foundation', 'manual'), ]\n")
|
||||
|
||||
# Workaround for useless links leading to compile errors
|
||||
# See https://github.com/sphinx-doc/sphinx/issues/3866
|
||||
fw(r"""
|
||||
from sphinx.domains.python import PythonDomain
|
||||
|
||||
class PatchedPythonDomain(PythonDomain):
|
||||
def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode):
|
||||
if 'refspecific' in node:
|
||||
del node['refspecific']
|
||||
return super(PatchedPythonDomain, self).resolve_xref(
|
||||
env, fromdocname, builder, typ, target, node, contnode)
|
||||
|
||||
def setup(app):
|
||||
app.add_domain(PatchedPythonDomain, override=True)
|
||||
""")
|
||||
# end workaround
|
||||
|
||||
file.close()
|
||||
|
||||
|
||||
def write_rst_index(basepath):
|
||||
"""
|
||||
Write the RST file of the main page, needed for sphinx: ``index.html``.
|
||||
|
@ -2411,7 +2294,7 @@ def copy_handwritten_extra(basepath):
|
|||
shutil.copy2(f_src, f_dst)
|
||||
|
||||
|
||||
def copy_theme_assets(basepath):
|
||||
def copy_sphinx_files(basepath):
|
||||
shutil.copytree(
|
||||
os.path.join(SCRIPT_DIR, "static"),
|
||||
os.path.join(basepath, "static"),
|
||||
|
@ -2423,17 +2306,31 @@ def copy_theme_assets(basepath):
|
|||
copy_function=shutil.copy,
|
||||
)
|
||||
|
||||
shutil.copy2(os.path.join(SCRIPT_DIR, "conf.py"), basepath, )
|
||||
|
||||
|
||||
def format_config(basepath):
|
||||
"""
|
||||
Updates conf.py with context infromation from Blender.
|
||||
"""
|
||||
from string import Template
|
||||
|
||||
substitutions = {
|
||||
'BLENDER_VERSION_STRING': BLENDER_VERSION_STRING,
|
||||
'BLENDER_VERSION_DOTS': BLENDER_VERSION_DOTS,
|
||||
'BLENDER_REVISION_TIMESTAMP': BLENDER_REVISION_TIMESTAMP,
|
||||
'BLENDER_REVISION': BLENDER_REVISION,
|
||||
}
|
||||
|
||||
# Read the template string from the template file
|
||||
with open(os.path.join(basepath, "conf.py"), 'r') as file:
|
||||
template_file = file.read()
|
||||
|
||||
with open(os.path.join(basepath, "conf.py"), 'w') as file:
|
||||
file.write(Template(template_file).substitute(substitutions))
|
||||
|
||||
|
||||
def rna2sphinx(basepath):
|
||||
|
||||
try:
|
||||
os.mkdir(basepath)
|
||||
except:
|
||||
pass
|
||||
|
||||
# sphinx setup
|
||||
write_sphinx_conf_py(basepath)
|
||||
|
||||
# main page
|
||||
write_rst_index(basepath)
|
||||
|
||||
|
@ -2460,9 +2357,6 @@ def rna2sphinx(basepath):
|
|||
# copy source files referenced
|
||||
copy_handwritten_extra(basepath)
|
||||
|
||||
# copy extra files needed for theme
|
||||
copy_theme_assets(basepath)
|
||||
|
||||
|
||||
def align_sphinx_in_to_sphinx_in_tmp(dir_src, dir_dst):
|
||||
"""
|
||||
|
@ -2583,10 +2477,22 @@ def main():
|
|||
copy_function=shutil.copy,
|
||||
)
|
||||
|
||||
# Dump the API in RST files.
|
||||
# start from a clean directory everytime
|
||||
if os.path.exists(SPHINX_IN_TMP):
|
||||
shutil.rmtree(SPHINX_IN_TMP, True)
|
||||
|
||||
try:
|
||||
os.mkdir(SPHINX_IN_TMP)
|
||||
except:
|
||||
pass
|
||||
|
||||
# copy extra files needed for theme
|
||||
copy_sphinx_files(SPHINX_IN_TMP)
|
||||
|
||||
# write infromation needed for 'conf.py'
|
||||
format_config(SPHINX_IN_TMP)
|
||||
|
||||
# Dump the API in RST files.
|
||||
rna2sphinx(SPHINX_IN_TMP)
|
||||
|
||||
if ARGS.changelog:
|
||||
|
|
Loading…
Reference in New Issue