2017-01-19 03:16:06 -05:00
|
|
|
# based on http://protips.readthedocs.io/link-roles.html
|
|
|
|
|
2018-09-07 07:46:50 -04:00
|
|
|
from __future__ import print_function
|
|
|
|
from __future__ import unicode_literals
|
2018-01-17 14:01:36 -05:00
|
|
|
import re
|
2018-03-15 14:28:58 -04:00
|
|
|
import os
|
2017-01-19 03:16:06 -05:00
|
|
|
from docutils import nodes
|
docs: speed up incremental builds
On each documentation build (‘make html’), doxygen regenerates XML
files. In addition to that, gen-dxd.py regenerates API reference
files under _build/inc/. This results in Sphinx flagging about half
of the input files as modified, and incremental builds taking long
time.
With this change, XML files generated by Doxygen are copied into
docs/xml_in directory only when they are changed. Breathe is pointed
to docs/xml_in directory instead of docs/xml. In addition to that,
gen-dxd.py is modified to only write to the output file when contents
change.
Overall, incremental build time (with no source files changed) is
reduced from ~7 minutes to ~8 seconds (on a particular OS X
computer).
Due to the way Breathe includes Doxygen XML files, there is still
going to be a massive rebuild every time functions, enums, macros,
structures are added or removed from the header files scanned
by Doxygen, but at least individual .rst files can be edited
at a much faster pace.
2018-03-05 07:12:52 -05:00
|
|
|
from local_util import run_cmd_get_output
|
2021-03-10 05:55:43 -05:00
|
|
|
from sphinx.transforms.post_transforms import SphinxPostTransform
|
2017-01-19 03:16:06 -05:00
|
|
|
|
2018-12-01 03:25:08 -05:00
|
|
|
|
2017-01-19 03:16:06 -05:00
|
|
|
def get_github_rev():
|
|
|
|
path = run_cmd_get_output('git rev-parse --short HEAD')
|
|
|
|
tag = run_cmd_get_output('git describe --exact-match')
|
2018-09-07 07:46:50 -04:00
|
|
|
print('Git commit ID: ', path)
|
2017-01-19 03:16:06 -05:00
|
|
|
if len(tag):
|
2018-09-07 07:46:50 -04:00
|
|
|
print('Git tag: ', tag)
|
2017-01-19 03:16:06 -05:00
|
|
|
path = tag
|
|
|
|
return path
|
|
|
|
|
2018-12-01 03:25:08 -05:00
|
|
|
|
2017-01-19 03:16:06 -05:00
|
|
|
def setup(app):
|
|
|
|
rev = get_github_rev()
|
2018-03-15 14:28:58 -04:00
|
|
|
|
|
|
|
# links to files or folders on the GitHub
|
|
|
|
baseurl = 'https://github.com/espressif/esp-idf'
|
2017-01-19 03:16:06 -05:00
|
|
|
app.add_role('idf', autolink('{}/tree/{}/%s'.format(baseurl, rev)))
|
|
|
|
app.add_role('idf_file', autolink('{}/blob/{}/%s'.format(baseurl, rev)))
|
|
|
|
app.add_role('idf_raw', autolink('{}/raw/{}/%s'.format(baseurl, rev)))
|
|
|
|
app.add_role('component', autolink('{}/tree/{}/components/%s'.format(baseurl, rev)))
|
|
|
|
app.add_role('component_file', autolink('{}/blob/{}/components/%s'.format(baseurl, rev)))
|
|
|
|
app.add_role('component_raw', autolink('{}/raw/{}/components/%s'.format(baseurl, rev)))
|
|
|
|
app.add_role('example', autolink('{}/tree/{}/examples/%s'.format(baseurl, rev)))
|
|
|
|
app.add_role('example_file', autolink('{}/blob/{}/examples/%s'.format(baseurl, rev)))
|
|
|
|
app.add_role('example_raw', autolink('{}/raw/{}/examples/%s'.format(baseurl, rev)))
|
|
|
|
|
2018-03-15 14:28:58 -04:00
|
|
|
# link to the current documentation file in specific language version
|
2021-03-10 05:55:43 -05:00
|
|
|
app.add_role('link_to_translation', link_to_translation)
|
|
|
|
app.add_node(translation_link)
|
|
|
|
app.add_post_transform(TranslationLinkNodeTransform)
|
|
|
|
|
|
|
|
|
|
|
|
class translation_link(nodes.Element):
|
|
|
|
"""Node for "link_to_translation" role."""
|
|
|
|
|
|
|
|
|
|
|
|
# Linking to translation is done at the "writing" stage to avoid issues with the info being cached between builders
|
|
|
|
def link_to_translation(name, rawtext, text, lineno, inliner, options={}, content=[]):
|
|
|
|
node = translation_link()
|
|
|
|
node['expr'] = (rawtext, text, options)
|
|
|
|
return [node], []
|
|
|
|
|
|
|
|
|
|
|
|
class TranslationLinkNodeTransform(SphinxPostTransform):
|
|
|
|
# Transform needs to happen early to ensure the new reference node is also transformed
|
|
|
|
default_priority = 0
|
|
|
|
|
|
|
|
def run(self, **kwargs):
|
|
|
|
|
|
|
|
# Only output relative links if building HTML
|
|
|
|
for node in self.document.traverse(translation_link):
|
|
|
|
if 'html' in self.app.builder.name:
|
|
|
|
rawtext, text, options = node['expr']
|
|
|
|
(language, link_text) = text.split(':')
|
|
|
|
env = self.document.settings.env
|
|
|
|
docname = env.docname
|
|
|
|
doc_path = env.doc2path(docname, None, None)
|
|
|
|
return_path = '../' * doc_path.count('/') # path back to the root from 'docname'
|
|
|
|
# then take off 2 more paths for language/release/ and build the new URL
|
|
|
|
url = '{}.html'.format(os.path.join(return_path, '../..', language, env.config.release, docname))
|
|
|
|
node.replace_self(nodes.reference(rawtext, link_text, refuri=url, **options))
|
|
|
|
else:
|
|
|
|
node.replace_self([])
|
2018-03-15 14:28:58 -04:00
|
|
|
|
2018-12-01 03:25:08 -05:00
|
|
|
|
2017-01-19 03:16:06 -05:00
|
|
|
def autolink(pattern):
|
|
|
|
def role(name, rawtext, text, lineno, inliner, options={}, content=[]):
|
2018-12-01 03:25:08 -05:00
|
|
|
m = re.search('(.*)\s*<(.*)>', text) # noqa: W605 - regular expression
|
2018-01-17 14:01:36 -05:00
|
|
|
if m:
|
|
|
|
link_text = m.group(1)
|
|
|
|
link = m.group(2)
|
|
|
|
else:
|
|
|
|
link_text = text
|
|
|
|
link = text
|
|
|
|
url = pattern % (link,)
|
|
|
|
node = nodes.reference(rawtext, link_text, refuri=url, **options)
|
2017-01-19 03:16:06 -05:00
|
|
|
return [node], []
|
|
|
|
return role
|
2018-03-15 14:28:58 -04:00
|
|
|
|
2018-12-01 03:25:08 -05:00
|
|
|
|
2018-03-15 14:28:58 -04:00
|
|
|
def crosslink(pattern):
|
|
|
|
def role(name, rawtext, text, lineno, inliner, options={}, content=[]):
|
|
|
|
(language, link_text) = text.split(':')
|
|
|
|
docname = inliner.document.settings.env.docname
|
|
|
|
doc_path = inliner.document.settings.env.doc2path(docname, None, None)
|
2018-12-01 03:25:08 -05:00
|
|
|
return_path = '../' * doc_path.count('/')
|
2018-03-15 14:28:58 -04:00
|
|
|
url = pattern % (return_path, language, docname)
|
|
|
|
node = nodes.reference(rawtext, link_text, refuri=url, **options)
|
|
|
|
return [node], []
|
|
|
|
return role
|