fix: keep glossary tooltips out of proper names

The glossary's capitalised terms matched mostly inside product names and paths: Free Unix Spectrum Emulator, Windows Terminal, Documents/Dolphin Emulator, on 35 pages. A capitalised term after a capitalised word or a slash is now left alone. Acronyms keep their tooltip.
This commit is contained in:
Abdessamad Derraz committed 2026-11-05 19:35:32 +01:00
1 parent d63ef4b1cf
commit 124e96cd09
2 files changed
+33 -1

No files matched your search

+12 -1
View File
@@ -244,10 +244,21 @@ def _tooltip_line(line: str, pattern: re.Pattern, pending: dict[str, str]) -> st
return "".join(out)
_NAME_BEFORE = re.compile(r"(?:/|\b[A-Z][\w'-]*[ \t]+)$")
def _in_proper_name(term: str, before: str) -> bool:
"""A capitalised term after a capitalised word or a slash is part of a
name: Free Unix Spectrum Emulator, Windows Terminal, Documents/Dolphin
Emulator. An acronym (BIOS, ZIP) is the term wherever it stands."""
first = term.split()[0]
return first[:1].isupper() and not first.isupper() and bool(_NAME_BEFORE.search(before))
def _tooltip_text(text: str, pattern: re.Pattern, pending: dict[str, str]) -> str:
def swap(match: re.Match) -> str:
term = match.group(1)
if term not in pending:
if term not in pending or _in_proper_name(term, text[:match.start()]):
return term
definition = pending.pop(term)
return f'<abbr class="rb-term" title="{html.escape(definition)}">{term}</abbr>'
+21
View File
@@ -484,3 +484,24 @@ class AMemberIsReadInItsArchive(unittest.TestCase):
lambda _f: True, owner="fbneo"))
self.assertIn("Collection copy: member `sm1.sm1` of", rows)
self.assertIn(shipped, rows)
class NoTooltipInsideAName(unittest.TestCase):
"""The glossary's capitalised terms matched almost only product names:
Free Unix Spectrum Emulator, Windows Terminal, Documents/Dolphin Emulator."""
def test_names_are_left_and_terms_are_marked(self):
import sitestarlight
terms = {"Emulator": "An app that acts like a console.",
"Terminal": "A window where you type commands.",
"BIOS": "The console's built-in software."}
for line in ("Fuse (Free Unix Spectrum Emulator) reads it.",
"Open Windows Terminal (WSL).",
"Copy it to Documents/Dolphin Emulator/Sys."):
with self.subTest(line=line):
self.assertNotIn("rb-term", sitestarlight.add_tooltips(line, terms))
marked = sitestarlight.add_tooltips(
"Emulator settings come first. The PlayStation BIOS goes there.", terms)
self.assertIn('title="An app that acts like a console.">Emulator</abbr>', marked)
self.assertIn('>BIOS</abbr>', marked)