Skip to content

Commit 6e09183

Browse files
committed
doc: Fix cool URIs
1 parent aa2928f commit 6e09183

File tree

2 files changed

+99
-24
lines changed

2 files changed

+99
-24
lines changed

doc/cool-uris.yaml

+10-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
# WARNING: This file is autogenerated by: scripts/ensure-stable-doc-urls.py
22
# Do not edit manually.
3+
__optional__:
4+
- doxygen_crawl.html
5+
- meson_options.html
36
annotated.html: []
47
classes.html: []
8+
debugging.html: []
59
deprecated.html: []
610
dir_63ce773eee1f9b680e6e312b48cc99ca.html: []
711
dir_891596f32582d3133e8915e72908625f.html: []
812
dir_d44c64559bbebec7f509842c48db8b23.html: []
913
dir_e68e8157741866f444e17edd764ebbae.html: []
14+
doxygen_crawl.html: []
1015
error-index.html: []
1116
files.html: []
1217
functions.html: []
@@ -33,8 +38,9 @@ group__x11.html: []
3338
index.html: []
3439
keymap-text-format-v1.html:
3540
- md_doc_keymap_format_text_v1.html
36-
md_doc_quick_guide.html: []
37-
modules.html: []
41+
md_doc_2quick-guide.html:
42+
- md_doc_quick_guide.html
43+
meson_options.html: []
3844
pages.html: []
3945
rule-file-format.html:
4046
- md_doc_rules_format.html
@@ -54,6 +60,8 @@ structxkb__keymap.html: []
5460
structxkb__rule__names.html: []
5561
structxkb__state.html: []
5662
todo.html: []
63+
topics.html:
64+
- modules.html
5765
user-configuration.html:
5866
- md_doc_user_configuration.html
5967
xkb-intro.html: []

scripts/ensure-stable-doc-urls.py

+89-22
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,15 @@ class ExitCode(IntFlag):
2828
NORMAL = 0
2929
INVALID_UPDATES = 1 << 4
3030
MISSING_UPDATES = 1 << 5
31+
NON_UNIQUE_DIRECTIONS = 1 << 6
3132

3233

3334
THIS_SCRIPT_PATH = Path(__file__)
3435
RELATIVE_SCRIPT_PATH = THIS_SCRIPT_PATH.relative_to(THIS_SCRIPT_PATH.parent.parent)
3536

3637
REDIRECTION_DELAY = 6 # in seconds. Note: at least 6s for accessibility
38+
REDIRECTION_TITLE = "xkbcommon: Page Redirection"
39+
OPTIONAL_ENTRY = "__optional__"
3740

3841
# NOTE: The redirection works with the HTML tag: <meta http-equiv="refresh">.
3942
# See: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta#http-equiv
@@ -50,7 +53,7 @@ class ExitCode(IntFlag):
5053
<meta http-equiv="refresh" content="${delay}; url=${canonical}">
5154
<link href="doxygen.css" rel="stylesheet" type="text/css">
5255
<link href="doxygen-extra.css" rel="stylesheet" type="text/css">
53-
<title>xkbcommon: Page Redirection</title>
56+
<title>${title}</title>
5457
</head>
5558
<body>
5659
<div id="top">
@@ -87,6 +90,14 @@ def parse_page_update(update: str) -> Update:
8790
return updateʹ
8891

8992

93+
def is_page_redirection(path: Path):
94+
with path.open("rt", encoding="utf-8") as fd:
95+
for line in fd:
96+
if REDIRECTION_TITLE in line:
97+
return True
98+
return False
99+
100+
90101
def update_registry(registry_path: Path, doc_dir: Path, updates: Sequence[str]):
91102
"""
92103
Update the URL registry by:
@@ -95,21 +106,35 @@ def update_registry(registry_path: Path, doc_dir: Path, updates: Sequence[str]):
95106
"""
96107
# Parse updates
97108
updates_ = dict(map(parse_page_update, updates))
109+
# Update
110+
invalid_updates = set(updates_)
98111
# Load previous registry
99112
with registry_path.open("rt", encoding="utf-8") as fd:
100-
registry = yaml.safe_load(fd) or {}
113+
registry: dict[str, list[str]] = yaml.safe_load(fd) or {}
114+
registryʹ = dict(
115+
(canonical, aliases)
116+
for canonical, aliases in registry.items()
117+
if canonical != OPTIONAL_ENTRY
118+
)
101119
# Expected updates
102-
missing_updates = set(file for file in registry if not (doc_dir / file).is_file())
103-
# Update
104-
invalid_updates = set(updates_)
105-
redirections = frozenset(chain(*registry.values()))
120+
missing_updates = set(
121+
canonical for canonical in registryʹ if not (doc_dir / canonical).is_file()
122+
)
123+
# Ensure each page is unique
124+
for d, rs in registryʹ.items():
125+
if clashes := frozenset(rs).intersection(registry):
126+
print(
127+
f"[ERROR] The following redirections of “{d}”",
128+
f"clash with canonical directions: {clashes}",
129+
)
130+
exit(ExitCode.NON_UNIQUE_DIRECTIONS)
131+
redirections = frozenset(chain.from_iterable(registryʹ.values()))
106132
for file in glob.iglob("**/*.html", root_dir=doc_dir, recursive=True):
107133
# Skip redirection pages
108134
if file in redirections:
109135
continue
110136
# Get previous entry and potential update
111-
old = updates_.get(file)
112-
if old:
137+
if old := updates_.get(file):
113138
# Update old entry
114139
invalid_updates.remove(file)
115140
entry = registry.get(old)
@@ -137,19 +162,36 @@ def update_registry(registry_path: Path, doc_dir: Path, updates: Sequence[str]):
137162
exit_code |= ExitCode.INVALID_UPDATES
138163
if missing_updates:
139164
for old in missing_updates:
140-
print(f"[ERROR] “{old}” not found and has no update.")
141-
exit_code |= ExitCode.MISSING_UPDATES
165+
# Handle older Doxygen versions
166+
if old in registry.get(OPTIONAL_ENTRY, []):
167+
print(
168+
"[WARNING] Handling old Doxygen version:",
169+
f"skip optional “{old}”",
170+
)
171+
missing_updates.remove(old)
172+
continue
173+
old_redirections = registry[old]
174+
for r in old_redirections:
175+
path = doc_dir / r
176+
if path.is_file() and not is_page_redirection(path):
177+
print(
178+
"[WARNING] Handling old Doxygen version:",
179+
f"use “{r}” instead of “{old}” for the canonical direction",
180+
)
181+
missing_updates.remove(old)
182+
break
183+
else:
184+
print(f"[ERROR] “{old}” not found and has no update.")
185+
if missing_updates:
186+
exit_code |= ExitCode.MISSING_UPDATES
142187
if exit_code:
143188
print("[ERROR] Processing interrupted: please fix the errors above.")
144189
exit(exit_code.value)
145190
# Write changes
146191
with registry_path.open("wt", encoding="utf-8") as fd:
147192
fd.write(f"# WARNING: This file is autogenerated by: {RELATIVE_SCRIPT_PATH}\n")
148193
fd.write("# Do not edit manually.\n")
149-
yaml.dump(
150-
registry,
151-
fd,
152-
)
194+
yaml.dump(registry, fd)
153195

154196

155197
def generate_redirections(registry_path: Path, doc_dir: Path):
@@ -159,22 +201,47 @@ def generate_redirections(registry_path: Path, doc_dir: Path):
159201
cool = True
160202
# Load registry
161203
with registry_path.open("rt", encoding="utf-8") as fd:
162-
registry = yaml.safe_load(fd) or {}
163-
for canonical, aliases in registry.items():
204+
registry: dict[str, list[str]] = yaml.safe_load(fd) or {}
205+
registryʹ = dict(
206+
(canonical, aliases)
207+
for canonical, aliases in registry.items()
208+
if canonical != OPTIONAL_ENTRY
209+
)
210+
for canonical, aliases in registryʹ.items():
164211
# Check canonical path is up-to-date
165212
if not (doc_dir / canonical).is_file():
166-
cool = False
167-
print(
168-
f"ERROR: missing canonical documentation page “{canonical}”. "
169-
f"Please update “{registry_path}” using {RELATIVE_SCRIPT_PATH}”."
170-
)
213+
# Handle older Doxygen versions
214+
if canonical in registry.get(OPTIONAL_ENTRY, []):
215+
print(
216+
"[WARNING] Handling old Doxygen version:",
217+
f"skip optional “{canonical}”",
218+
)
219+
continue
220+
for r in aliases:
221+
path = doc_dir / r
222+
if path.is_file() and not is_page_redirection(path):
223+
print(
224+
"[WARNING] Handling old Doxygen version:",
225+
f"use “{r}” instead of “{canonical}” for the canonical direction",
226+
)
227+
canonical = r
228+
aliases.remove(r)
229+
break
230+
else:
231+
cool = False
232+
print(
233+
f"ERROR: missing canonical documentation page “{canonical}”. "
234+
f"Please update “{registry_path}” using {RELATIVE_SCRIPT_PATH}”."
235+
)
171236
# Add a redirection page
172237
for alias in aliases:
173238
path = doc_dir / alias
174239
with path.open("wt", encoding="utf-8") as fd:
175240
fd.write(
176241
REDIRECTION_PAGE_TEMPLATE.substitute(
177-
canonical=canonical, delay=REDIRECTION_DELAY
242+
canonical=canonical,
243+
delay=REDIRECTION_DELAY,
244+
title=REDIRECTION_TITLE,
178245
)
179246
)
180247
if not cool:

0 commit comments

Comments
 (0)