Skip to content

Commit c63e873

Browse files
authored
docs: ref redirector (#15432)
Makes the HTML builder generate a _refs.html file that redirects (global) refs (when provided as a hash i.e. `_refs.html#some-ref`) to the appropriate document. This allows tools (e.g. #15431) to link to well-known refs.
1 parent 2a89f75 commit c63e873

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

docs/source/conf.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
# Add any Sphinx extension module names here, as strings. They can be
3636
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
3737
# ones.
38-
extensions = ["sphinx.ext.intersphinx"]
38+
extensions = ["sphinx.ext.intersphinx", "docs.source.html_builder"]
3939

4040
# Add any paths that contain templates here, relative to this directory.
4141
templates_path = ["_templates"]

docs/source/html_builder.py

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from __future__ import annotations
2+
3+
import json
4+
import textwrap
5+
from pathlib import Path
6+
from typing import Any
7+
8+
from sphinx.addnodes import document
9+
from sphinx.application import Sphinx
10+
from sphinx.builders.html import StandaloneHTMLBuilder
11+
12+
13+
class MypyHTMLBuilder(StandaloneHTMLBuilder):
14+
def __init__(self, app: Sphinx) -> None:
15+
super().__init__(app)
16+
self._ref_to_doc = {}
17+
18+
def write_doc(self, docname: str, doctree: document) -> None:
19+
super().write_doc(docname, doctree)
20+
self._ref_to_doc.update({_id: docname for _id in doctree.ids})
21+
22+
def _write_ref_redirector(self) -> None:
23+
p = Path(self.outdir) / "_refs.html"
24+
data = f"""
25+
<html>
26+
<body>
27+
<script>
28+
const ref_to_doc = {json.dumps(self._ref_to_doc)};
29+
const hash = window.location.hash.substring(1);
30+
const doc = ref_to_doc[hash];
31+
if (doc) {{
32+
window.location.href = doc + '.html' + '#' + hash;
33+
}} else {{
34+
window.document.innerText = 'Unknown reference: ' + hash;
35+
}}
36+
</script>
37+
</body>
38+
</html>
39+
"""
40+
p.write_text(textwrap.dedent(data))
41+
42+
def finish(self) -> None:
43+
super().finish()
44+
self._write_ref_redirector()
45+
46+
47+
def setup(app: Sphinx) -> dict[str, Any]:
48+
app.add_builder(MypyHTMLBuilder, override=True)
49+
50+
return {"version": "0.1", "parallel_read_safe": True, "parallel_write_safe": True}

0 commit comments

Comments
 (0)