| 
13 | 13 | #  | 
14 | 14 | import os  | 
15 | 15 | import sys  | 
 | 16 | +from pathlib import Path  | 
 | 17 | + | 
16 | 18 | sys.path.insert(0, os.path.abspath('../'))  | 
17 | 19 | 
 
  | 
18 | 20 | 
 
  | 
 | 
41 | 43 |     'matplotlib.sphinxext.plot_directive',  | 
42 | 44 |     'sphinx.ext.autodoc',  | 
43 | 45 |     'sphinx.ext.mathjax',  | 
44 |  | -    'sphinx.ext.viewcode',  | 
 | 46 | +    'sphinx.ext.linkcode',  | 
45 | 47 |     'sphinx.ext.napoleon',  | 
46 | 48 |     'sphinx.ext.imgconverter',  | 
47 | 49 |     'IPython.sphinxext.ipython_console_highlighting',  | 
 | 
184 | 186 | ]  | 
185 | 187 | 
 
  | 
186 | 188 | 
 
  | 
187 |  | -# -- Extension configuration -------------------------------------------------  | 
 | 189 | +# -- linkcode setting -------------------------------------------------  | 
 | 190 | + | 
 | 191 | +import inspect  | 
 | 192 | +import os  | 
 | 193 | +import sys  | 
 | 194 | +import functools  | 
 | 195 | + | 
 | 196 | +GITHUB_REPO = "https://github.com/AtsushiSakai/PythonRobotics"  | 
 | 197 | +GITHUB_BRANCH = "master"  | 
 | 198 | + | 
 | 199 | + | 
 | 200 | +def linkcode_resolve(domain, info):  | 
 | 201 | +    if domain != "py":  | 
 | 202 | +        return None  | 
 | 203 | + | 
 | 204 | +    modname = info["module"]  | 
 | 205 | +    fullname = info["fullname"]  | 
 | 206 | + | 
 | 207 | +    try:  | 
 | 208 | +        module = __import__(modname, fromlist=[fullname])  | 
 | 209 | +        obj = functools.reduce(getattr, fullname.split("."), module)  | 
 | 210 | +    except (ImportError, AttributeError):  | 
 | 211 | +        return None  | 
 | 212 | + | 
 | 213 | +    try:  | 
 | 214 | +        srcfile = inspect.getsourcefile(obj)  | 
 | 215 | +        srcfile = get_relative_path_from_parent(srcfile, "PythonRobotics")  | 
 | 216 | +        lineno = inspect.getsourcelines(obj)[1]  | 
 | 217 | +    except Exception:  | 
 | 218 | +        return None  | 
 | 219 | + | 
 | 220 | +    return f"{GITHUB_REPO}/blob/{GITHUB_BRANCH}/{srcfile}#L{lineno}"  | 
 | 221 | + | 
 | 222 | + | 
 | 223 | +def get_relative_path_from_parent(file_path: str, parent_dir: str):  | 
 | 224 | +    path = Path(file_path).resolve()  | 
 | 225 | + | 
 | 226 | +    try:  | 
 | 227 | +        parent_path = next(p for p in path.parents if p.name == parent_dir)  | 
 | 228 | +        return str(path.relative_to(parent_path))  | 
 | 229 | +    except StopIteration:  | 
 | 230 | +        raise ValueError(f"Parent directory '{parent_dir}' not found in {file_path}")  | 
0 commit comments