Skip to content

Commit f137896

Browse files
committed
Add helper functions to __init__.py
1 parent a6f2a4d commit f137896

File tree

1 file changed

+130
-13
lines changed

1 file changed

+130
-13
lines changed

sphinx_github_style/__init__.py

Lines changed: 130 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,145 @@
1+
import os
2+
import sys
13
import sphinx
2-
from sphinx.application import Sphinx
4+
import inspect
5+
import subprocess
6+
import pkg_resources
7+
from pathlib import Path
38
from typing import Dict, Any
9+
from sphinx.application import Sphinx
410

511

6-
def setup(app: Sphinx) -> Dict[str, Any]:
7-
# imports defined inside setup function, so that the __version__ can be loaded,
8-
# even if Sphinx is not yet installed.
9-
__version__ = "0.0.1b1"
10-
__author__ = 'Adam Korn <hello@dailykitten.net>'
12+
__version__ = "0.0.1b4"
13+
__author__ = 'Adam Korn <hello@dailykitten.net>'
14+
1115

12-
from .github_style import TDKStyle
13-
from .meth_lexer import TDKMethLexer
14-
from .add_linkcode_class import add_linkcode_node_class
15-
from .linkcode_resolve import linkcode_resolve
16+
from .add_linkcode_class import add_linkcode_node_class
17+
from .meth_lexer import TDKMethLexer
18+
from .github_style import TDKStyle
19+
20+
21+
def setup(app: Sphinx) -> Dict[str, Any]:
22+
# Package Info
23+
modpath = os.path.abspath('../')
24+
modname = os.path.basename(modpath)
25+
pkg = pkg_resources.require(modname)[0]
26+
pkg_name = pkg.get_metadata('top_level.txt').strip()
1627

1728
app.setup_extension('sphinx.ext.linkcode')
29+
app.connect("builder-inited", get_static_path)
1830
app.connect('doctree-resolved', add_linkcode_node_class)
1931
# app.connect('build-finished', save_generated_rst_files)
2032

21-
# app.config.linkcode_resolve = linkcode_resolve
33+
app.add_config_value('linkcode_link_text', '[source]', 'html')
34+
app.add_config_value('linkcode_default_blob', 'master', 'html')
2235
app.config.pygments_style = 'sphinx_github_style.TDKStyle'
36+
app.config.html_context['github_version'] = get_linkcode_revision(app)
2337

24-
app.add_config_value('linkcode_link_text', '[source]', 'html')
2538
app.add_css_file('github_linkcode.css')
26-
app.add_lexer('TDK', TDKMethLexer)
39+
app.add_lexer('python', TDKMethLexer)
40+
41+
linkcode_url = get_linkcode_url(app)
42+
43+
def linkcode_resolve(domain, info):
44+
"""Returns a link to the source code on GitHub, with appropriate lines highlighted
45+
46+
Adapted from https://github.com/nlgranger
47+
"""
48+
if domain != 'py' or not info['module']:
49+
return None
50+
51+
modname = info['module']
52+
fullname = info['fullname']
53+
54+
submod = sys.modules.get(modname)
55+
if submod is None:
56+
return None
57+
58+
obj = submod
59+
for part in fullname.split('.'):
60+
try:
61+
obj = getattr(obj, part)
62+
print(obj)
63+
except Exception:
64+
return None
65+
66+
try:
67+
filepath = os.path.relpath(inspect.getsourcefile(obj), modpath)
68+
if filepath is None:
69+
return
70+
except Exception:
71+
return None
2772

73+
try:
74+
source, lineno = inspect.getsourcelines(obj)
75+
except OSError:
76+
print(f'failed to get source lines for {obj}')
77+
return None
78+
else:
79+
linestart, linestop = lineno, lineno + len(source) - 1
80+
81+
# Format link using the filepath of the source file plus the line numbers
82+
# Fix links with "../../../" or "..\\..\\..\\"
83+
filepath = '/'.join(filepath[filepath.find(pkg_name):].split('\\'))
84+
85+
# Example of final link: # https://github.com/tdkorn/my-magento/blob/sphinx-docs/magento/utils.py#L355-L357
86+
final_link = linkcode_url.format(
87+
filepath=filepath,
88+
linestart=linestart,
89+
linestop=linestop
90+
)
91+
print(f"Final Link for {fullname}: {final_link}")
92+
return final_link
93+
94+
app.config.linkcode_resolve = linkcode_resolve
2895
return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
96+
97+
98+
def get_static_path(app):
99+
app.config.html_static_path.append(
100+
str(Path(__file__).parent.joinpath("_static").absolute())
101+
)
102+
103+
def get_linkcode_revision(app: Sphinx):
104+
# Get the blob to link to on GitHub
105+
linkcode_revision = "master"
106+
107+
try:
108+
# lock to commit number
109+
cmd = "git log -n1 --pretty=%H"
110+
head = subprocess.check_output(cmd.split()).strip().decode('utf-8')
111+
linkcode_revision = head
112+
113+
# if we are on master's HEAD, use master as reference
114+
cmd = "git log --first-parent master -n1 --pretty=%H"
115+
master = subprocess.check_output(cmd.split()).strip().decode('utf-8')
116+
if head == master:
117+
linkcode_revision = "master"
118+
119+
# if we have a tag, use tag as reference
120+
cmd = "git describe --exact-match --tags " + head
121+
tag = subprocess.check_output(cmd.split(" ")).strip().decode('utf-8')
122+
linkcode_revision = tag
123+
124+
125+
except subprocess.CalledProcessError:
126+
if app.config._raw_config.get('linkcode_default_blob') == 'last_tag':
127+
# Get the most recent tag to link to on GitHub
128+
try:
129+
cmd = "git describe --tags --abbrev=0"
130+
last_tag = subprocess.check_output(cmd.split(" ")).strip().decode('utf-8')
131+
linkcode_revision = last_tag
132+
133+
except subprocess.CalledProcessError:
134+
linkcode_revision = "master"
135+
136+
return linkcode_revision
137+
138+
139+
def get_linkcode_url(app):
140+
if not (url := app.config._raw_config.get("linkcode_url")):
141+
raise ValueError("conf.py missing value for ``linkcode_url``")
142+
143+
# Source link template; formatted by linkcode_resolve
144+
return f"{url.rstrip('/')}/blob/{get_linkcode_revision(app)}/" + \
145+
"{filepath}#L{linestart}-L{linestop}"

0 commit comments

Comments
 (0)