)'
r'(?P"|<)'
r'(?P[A-Za-z0-9_./+\-]+\.[A-Za-z0-9]+)'
r'(?P"|>)'
r'(?P)'
)
def _linkify_code_blocks(html_dir: pathlib.Path) -> None:
"""Walk every `.html` under `html_dir` and turn known identifier
tokens inside Pygments-rendered `` blocks into clickable
anchors. The substitution is scoped to spans inside `` so we
don't accidentally repaint inline `` chips in
prose; the rule above already targets only Pygments span classes
that Pygments uses inside its `` output."""
if not (_LOCAL_CLASS_URL or _LOCAL_TYPEDEF_URL or _FILE_URL):
return
if not html_dir.is_dir():
return
import os
def _resolve(name: str) -> str | None:
return _LOCAL_CLASS_URL.get(name) or _LOCAL_TYPEDEF_URL.get(name)
# `…
` blocks only — keeps the substitution from touching
# inline `` runs that may appear in other contexts.
_PRE_BLOCK_RE = re.compile(r"(.*?)
", re.DOTALL)
# Relative path from each rendered `.html` file's directory to the
# Doxygen html tree (which sits alongside `docs_sphinx/html/` at
# `doc/doxygen/html/`). Reused per file so paths render with the
# right number of `../` segments regardless of subdir depth.
_DOXY_ROOT = html_dir.parent.parent / "doc" / "doxygen" / "html"
def _doxy_rel(html_path: pathlib.Path, file_url: str) -> str:
target = _DOXY_ROOT / file_url
try:
return os.path.relpath(target, start=html_path.parent)
except ValueError:
return f"../../../doc/doxygen/html/{file_url}"
def _wrap_span(m: re.Match) -> str:
name = m.group("name")
url = _resolve(name)
if not url:
return m.group(0)
return (f''
f'{m.group("prefix")}{name}{m.group("suffix")}')
def _wrap_cpf(m: re.Match, current_html: pathlib.Path) -> str:
path = m.group("path")
# Only opencv headers — ``, `` are not in
# `_FILE_URL` and stay plain.
file_url = _FILE_URL.get(path)
if not file_url:
return m.group(0)
href = _doxy_rel(current_html, file_url)
# Keep the opening/closing quotes outside the `` (so they
# render as plain `"` / `<`/`>`), and put the link on just
# the path text — same shape the enum-detail `#include` line
# already uses elsewhere.
return (f'{m.group("prefix")}{m.group("openq")}'
f'{path}'
f'{m.group("closeq")}{m.group("suffix")}')
def _rewrite_pre(m: re.Match, current_html: pathlib.Path) -> str:
inner = m.group(1)
# Skip spans already wrapped: if `` immediately precedes
# the `…`, leave it. The Pygments
# output doesn't generate `` itself, so the only place
# `` appears in the inner text is from a prior pass — we
# detect by scanning for `` pairs and only rewrite
# text outside them.
out: list[str] = []
i, n = 0, len(inner)
while i < n:
if inner.startswith("", i)
if j < 0:
out.append(inner[i:])
break
out.append(inner[i:j + 4])
i = j + 4
else:
k = inner.find("" + "".join(out) + ""
for html in html_dir.rglob("*.html"):
try:
text = html.read_text(encoding="utf-8")
except OSError:
continue
if "" not in text:
continue
new_text = _PRE_BLOCK_RE.sub(
lambda m: _rewrite_pre(m, html), text)
if new_text != text:
try:
html.write_text(new_text, encoding="utf-8")
except OSError:
pass
_INLINE_CODE_RE = re.compile(
r'(?P[^<]*?)'
)
_A_BLOCK_RE = re.compile(r']*>.*?', re.DOTALL)
_INLINE_TOK_RE = re.compile(r'(?:cv::)?_?[A-Za-z][A-Za-z0-9_]*')
def _linkify_inline_code(html_dir: pathlib.Path) -> None:
if not (_LOCAL_CLASS_URL or _LOCAL_TYPEDEF_URL):
return
if not html_dir.is_dir():
return
def _resolve(name: str) -> str | None:
bare = name[4:] if name.startswith("cv::") else name
return _LOCAL_CLASS_URL.get(bare) or _LOCAL_TYPEDEF_URL.get(bare)
def _anchor_text(tok: str) -> str:
return tok.replace("::", "::")
def _linkify_body(body: str) -> str:
def _sub(m: re.Match) -> str:
tok = m.group(0)
url = _resolve(tok)
if not url:
return tok
return (f'{_anchor_text(tok)}')
return _INLINE_TOK_RE.sub(_sub, body)
def _rewrite_code(m: re.Match) -> str:
body = m.group("body")
new_body = _linkify_body(body)
if new_body == body:
return m.group(0)
return (f''
f'{new_body}')
for html in html_dir.rglob("*.html"):
try:
text = html.read_text(encoding="utf-8")
except OSError:
continue
if 'class="docutils literal notranslate"' not in text:
continue
masked: list[str] = []
def _mask(m: re.Match) -> str:
masked.append(m.group(0))
return f"\x00A{len(masked) - 1}\x00"
masked_text = _A_BLOCK_RE.sub(_mask, text)
new_masked = _INLINE_CODE_RE.sub(_rewrite_code, masked_text)
if new_masked == masked_text:
continue
new_text = re.sub(
r"\x00A(\d+)\x00",
lambda mm: masked[int(mm.group(1))],
new_masked,
)
try:
html.write_text(new_text, encoding="utf-8")
except OSError:
pass
def _inline_coll_graphs_on_finish(app, exception):
"""build-finished entry point."""
if exception is not None:
return
out = pathlib.Path(app.outdir)
for _api in ("main_modules", "extra_modules"):
_inline_collaboration_svgs(out / _api, out / "_images")
_strip_breathe_class_clutter(out / _api)
_linkify_code_blocks(out)
_linkify_inline_code(out)
_localize_doxygen_links(out)
_drop_moved_stub_search_entries()
_copy_js_tryit_files(out)
_fix_gapi_images(out)
_generate_search_map(out)