Skip to content

Commit f0c206a

Browse files
committed
Improve theme patch: dynamic locale list, fix local file:// URLs
- Scan coreutils-l10n for available locales instead of hardcoding - Fix language switcher to use relative path replacement so it works with both deployed and local file:// URLs - Move links into the existing .additional div for better layout
1 parent 7f9102e commit f0c206a

1 file changed

Lines changed: 82 additions & 42 deletions

File tree

scripts/patch-mdbook-theme.sh

Lines changed: 82 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,116 +1,156 @@
11
#!/bin/bash
22
# Patch mdbook theme to add language selector and utility links
3-
# Usage: patch-mdbook-theme.sh <coreutils-docs-dir> [current-lang]
3+
# Usage: patch-mdbook-theme.sh <coreutils-docs-dir> <coreutils-l10n-dir>
44

55
set -euo pipefail
66

7-
DOCS_DIR="${1:?Usage: $0 <coreutils-docs-dir> [current-lang]}"
8-
CURRENT_LANG="${2:-en}"
7+
DOCS_DIR="${1:?Usage: $0 <coreutils-docs-dir> <coreutils-l10n-dir>}"
8+
L10N_DIR="${2:?Usage: $0 <coreutils-docs-dir> <coreutils-l10n-dir>}"
99

1010
HEAD_HBS="$DOCS_DIR/theme/head.hbs"
1111

12-
# Append language selector and utility links to head.hbs
12+
# Language display names (ftl filename -> display name)
13+
declare -A LANG_NAMES=(
14+
[en-US]="English"
15+
[ar]="العربية" [ast]="Asturianu" [ca]="Català" [cs]="Čeština"
16+
[da]="Dansk" [de]="Deutsch" [eo]="Esperanto" [es-ES]="Español"
17+
[fi]="Suomi" [fr-FR]="Français" [he]="עברית" [id]="Bahasa Indonesia"
18+
[it]="Italiano" [ja]="日本語" [kab]="Taqbaylit" [ko]="한국어"
19+
[nb-NO]="Norsk Bokmål" [ne]="नेपाली" [pl]="Polski" [pt]="Português"
20+
[pt-BR]="Português (Brasil)" [ru]="Русский" [sv]="Svenska"
21+
[tr]="Türkçe" [uk]="Українська" [vi]="Tiếng Việt"
22+
[zh-Hans]="中文 (简体)" [zh-Hant]="中文 (繁體)"
23+
)
24+
25+
# ftl filename -> URL lang code (used in /coreutils/docs-{code}/)
26+
declare -A FTL_TO_URL=(
27+
[en-US]="en" [fr-FR]="fr" [es-ES]="es" [zh-Hans]="zh" [zh-Hant]="zh-Hant"
28+
[pt-BR]="pt-BR" [nb-NO]="nb-NO"
29+
)
30+
# For others, the ftl name IS the URL code (ar, de, it, ja, etc.)
31+
32+
# Scan l10n repo to find which locales have translations
33+
# Use a representative utility (ls) to find available locales
34+
LANGS_JSON="['en', 'English']"
35+
for ftl in "$L10N_DIR"/src/uu/ls/locales/*.ftl; do
36+
[ -f "$ftl" ] || continue
37+
ftl_name=$(basename "$ftl" .ftl)
38+
[ "$ftl_name" = "en-US" ] && continue
39+
40+
display="${LANG_NAMES[$ftl_name]:-$ftl_name}"
41+
url_code="${FTL_TO_URL[$ftl_name]:-$ftl_name}"
42+
LANGS_JSON="$LANGS_JSON, ['$url_code', '$display']"
43+
done
44+
45+
# Append styles and JS to head.hbs
1346
cat >> "$HEAD_HBS" << 'ENDSTYLE'
1447
<style>
15-
.util-bar {
48+
.util-links {
1649
display: flex;
17-
justify-content: flex-end;
18-
gap: 15px;
50+
gap: 12px;
1951
align-items: center;
20-
font-size: 0.85em;
21-
margin-bottom: 10px;
52+
font-size: 0.75em;
2253
}
23-
.util-bar a {
54+
.util-links a {
2455
color: var(--links);
2556
text-decoration: none;
2657
}
27-
.util-bar a:hover {
58+
.util-links a:hover {
2859
text-decoration: underline;
2960
}
3061
.lang-selector {
3162
position: relative;
63+
display: inline-block;
3264
}
3365
.lang-selector select {
3466
appearance: none;
3567
background: var(--bg);
3668
color: var(--fg);
3769
border: 1px solid var(--table-border-color);
3870
border-radius: 4px;
39-
padding: 4px 24px 4px 8px;
40-
font-size: 0.85em;
71+
padding: 2px 20px 2px 6px;
72+
font-size: 1em;
4173
cursor: pointer;
4274
}
4375
.lang-selector::after {
4476
content: "▾";
4577
position: absolute;
46-
right: 8px;
78+
right: 6px;
4779
top: 50%;
4880
transform: translateY(-50%);
4981
pointer-events: none;
5082
color: var(--fg);
83+
font-size: 0.8em;
5184
}
5285
</style>
5386
ENDSTYLE
54-
55-
# Add JavaScript for language switching and utility bar injection
56-
cat >> "$HEAD_HBS" << ENDSCRIPT
87+
cat >> "$HEAD_HBS" << 'ENDSCRIPT'
5788
<script>
5889
document.addEventListener('DOMContentLoaded', function() {
59-
// Only add util-bar on utility pages
6090
var path = window.location.pathname;
61-
var match = path.match(/\/coreutils\/docs(?:-([a-z]{2}(?:-[A-Z]{2})?))?\/utils\/(\w+)\.html/);
91+
// Match both deployed (/coreutils/docs[-lang]/utils/X.html) and local (book[-lang]/utils/X.html)
92+
var match = path.match(/\/(?:coreutils\/)?docs(?:-([a-z]{2}(?:-[A-Z]{2})?))?\/utils\/(\w+)\.html/)
93+
|| path.match(/\/book(?:-([a-z]{2}(?:-[A-Z]{2})?))?\/utils\/(\w+)\.html/);
6294
if (!match) return;
6395
6496
var currentLang = match[1] || 'en';
6597
var utilName = match[2];
6698
67-
var bar = document.createElement('div');
68-
bar.className = 'util-bar';
99+
// Find the existing .additional div and append our links there
100+
var additional = document.querySelector('.additional');
101+
if (!additional) return;
102+
103+
var links = document.createElement('div');
104+
links.className = 'util-links';
69105
70106
// Source code link
71107
var srcLink = document.createElement('a');
72108
srcLink.href = 'https://github.com/uutils/coreutils/tree/main/src/uu/' + utilName;
73-
srcLink.textContent = 'Source code';
109+
srcLink.textContent = 'Source';
74110
srcLink.target = '_blank';
75-
bar.appendChild(srcLink);
111+
links.appendChild(srcLink);
76112
77113
// Report issue link
78114
var issueLink = document.createElement('a');
79115
issueLink.href = 'https://github.com/uutils/coreutils/issues/new?title=' + utilName + ':%20&labels=bug';
80-
issueLink.textContent = 'Report an issue';
116+
issueLink.textContent = 'Report a bug';
81117
issueLink.target = '_blank';
82-
bar.appendChild(issueLink);
118+
links.appendChild(issueLink);
83119
84120
// Language selector
85121
var langDiv = document.createElement('div');
86122
langDiv.className = 'lang-selector';
87123
var select = document.createElement('select');
88-
var langs = {
89-
'en': 'English', 'fr': 'Français', 'de': 'Deutsch', 'es': 'Español',
90-
'it': 'Italiano', 'pt': 'Português', 'pt-BR': 'Português (BR)',
91-
'ja': '日本語', 'ko': '한국어', 'ru': 'Русский', 'zh': '中文',
92-
'uk': 'Українська', 'sv': 'Svenska', 'pl': 'Polski', 'tr': 'Türkçe'
93-
};
94-
for (var code in langs) {
124+
var langs = LANGS_PLACEHOLDER;
125+
langs.forEach(function(l) {
95126
var opt = document.createElement('option');
96-
opt.value = code;
97-
opt.textContent = langs[code];
98-
if (code === currentLang) opt.selected = true;
127+
opt.value = l[0];
128+
opt.textContent = l[1];
129+
if (l[0] === currentLang) opt.selected = true;
99130
select.appendChild(opt);
100-
}
131+
});
101132
select.addEventListener('change', function() {
102133
var newLang = this.value;
103-
var suffix = newLang === 'en' ? '' : '-' + newLang;
104-
window.location.href = '/coreutils/docs' + suffix + '/utils/' + utilName + '.html';
134+
var curPath = window.location.pathname;
135+
// Replace the directory segment right before /utils/:
136+
// .../book[-lang]/utils/X.html or .../docs[-lang]/utils/X.html
137+
var newPath = curPath.replace(
138+
/\/(book|docs)(?:-[a-zA-Z]{2}(?:-[a-zA-Z]+)?)?\/utils\//,
139+
function(m, base) {
140+
return '/' + base + (newLang === 'en' ? '' : '-' + newLang) + '/utils/';
141+
}
142+
);
143+
window.location.href = newPath;
105144
});
106145
langDiv.appendChild(select);
107-
bar.appendChild(langDiv);
146+
links.appendChild(langDiv);
108147
109-
// Insert bar at the top of the content
110-
var main = document.querySelector('main');
111-
if (main) main.insertBefore(bar, main.firstChild);
148+
additional.appendChild(links);
112149
});
113150
</script>
114151
ENDSCRIPT
115152

153+
# Inject the dynamically-built language list
154+
sed -i "s|LANGS_PLACEHOLDER|[${LANGS_JSON}]|" "$HEAD_HBS"
155+
116156
echo "Patched $HEAD_HBS with language selector and utility links"

0 commit comments

Comments
 (0)