git-upstream/doc/source/transform_github_links.py

92 lines
3.4 KiB
Python

# based on the idea from
# https://github.com/andsens/bootstrap-vz/blob/5250f8233215f6f2e3a571be2f5cf3e09accd4b6/docs/transform_github_links.py
#
# Copyright 2013-2014 Anders Ingemann <anders@ingemann.de>
# Copyright 2016 Darragh Bailey <dbailey@hpe.com>
from docutils import nodes
import os.path
def transform_github_links(app, doctree, fromdocname):
"""Convert file references for github to correct target
Scans the doctree for links directly referencing ReSTructured
text documents within this repository. It converts these links
to a suitable target for sphinx generated docs.
Such references as <file>.rst are used by source code hosting
sites such as GitHub when rendering documents directly from
individual source files without parsing the entire doctree.
However referencing the original <file>.rst is not useful for
sphinx generated documentation as <file>.rst will not exist in
the resulting documentation as it will also have been converted
to the chosen format e.g. <file>.html
Supporting automatic conversion ensures that GitHub/BitBucket
and any other git hosting site performing rendering on a file
by file basis allowing users to navigate through the documentation,
while still ensuring the output from fully generated sphinx docs
will point to the correct target.
"""
try:
target_format = app.builder.link_suffix
except AttributeError:
# if the builder has no link_suffix, then no need to modify
# the current links.
return
source_suffix = app.config.source_suffix
# Links are either absolute against the repository or relative to
# the current document's directory. Note that this is not
# necessarily app.srcdir, which is the documentation root
# directory. Instead rely on 'source' attribute of doctree to
# identify the path of the file providing the current doctree
try:
doc_path = doctree.attributes['source']
doc_dir = os.path.dirname(doc_path)
except KeyError:
# some doctrees added by other libraries through dynamic
# generation do not have a source file. Assume paths are
# relative to the repo.
doc_dir = ""
for node in doctree.traverse(nodes.reference):
if 'refuri' not in node:
continue
if node['refuri'].startswith('http'):
continue
try:
link, anchor = node['refuri'].split('#', 1)
anchor = '#' + anchor
except ValueError:
link = node['refuri']
anchor = ''
if link is None:
continue
# Replace the suffix with the correct target format file ending,
# but only if the link ends with both the correct source suffix
# and refers to a local file.
for src_suffix in source_suffix:
if link.endswith(src_suffix):
# absolute paths are considered relative to repo
if link.startswith("/"):
basepath = ""
# relative paths are against the current doctree source path
else:
basepath = doc_dir
if os.path.exists(os.path.join(basepath, link)):
node['refuri'] = (link[:-len(source_suffix)] + target_format +
anchor)
def setup(app):
app.connect('doctree-resolved', transform_github_links)
return {'version': '0.1'}