Skip to content

docs(i18n): add Spanish, Italian, Dutch, Norwegian and Danish - #35

Merged
helmihyo merged 5 commits into
mainfrom
feat/i18n-five-languages
Aug 5, 2026
Merged

docs(i18n): add Spanish, Italian, Dutch, Norwegian and Danish#35
helmihyo merged 5 commits into
mainfrom
feat/i18n-five-languages

Conversation

@helmihyo

@helmihyo helmihyo commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Adds Spanish, Italian, Dutch, Norwegian Bokmål and Danish. The site now carries ten languages: 21 pages each, 210 translated pages in total.

Why five at once

The machinery from #26, #30 and #33 had been exercised one language at a time. Doing five in parallel tests whether it holds when nothing can be watched by hand — and it found things a single-language pass would not have. The rules that leak between languages only become visible when the languages are written side by side.

What is here

docs/es/, docs/it/, docs/nl/, docs/nb/, docs/da/, five glossaries in solutions/translation/, five locale blocks in mkdocs.yml, and two new scripts described below.

Norwegian is Bokmål (nb), the variety about 85–90% of Norwegian writing uses.

Each glossary opens with the rules where the sibling languages are actively wrong for it, because copying a pattern that worked next door is the recorded failure mode in this repository:

quotations address proper-name compounds
Spanish «…» impersonal — no usted, no no hyphen at all
Italian “…” impersonal, infinitive instructions no hyphen at all
Dutch “…” u junction hyphen
Norwegian «…» du junction hyphen
Danish »…«outward, the opposite of Norwegian du junction hyphen

Norwegian and Danish were translated in parallel by agents that could not see each other. Their quotation marks came out opposite, as they must.

Verification

Structure vs. the English source 0 deviations across 105 pages
mkdocs build --strict clean
check_anchors.py 9750 anchors across 212 pages, all resolve
check_typography.py clean in all nine translated languages
check_glossary.py clean in all five new languages
translation_status.py current=21 in all nine
Safety-critical passages read against English 1031 compared, 0 defects

That last number is the one that matters. Every warning, danger, caution and note admonition, every numbered procedure step and every prohibition on the five pages carrying fuse ratings, voltages, polarity and jumper settings was compared sentence by sentence against its English source. A zero is only worth reporting with the count beside it.

What the automation could not see, and now can

check_glossary.py finds a prescribed term nobody used. It cannot find a term that acquired a rival — the same connector under two names on adjacent pages, which no reader can reconcile. That gap was found by hand in Swedish and is now covered by a per-language sweep: 21 such concepts, 88 occurrences resolved to whichever word the glossary prescribes, 22 new glossary rows recording the decisions the glossary had not yet made.

Blind replacement would have been wrong in several places:

  • Spanish balanceo is wrong for super-capacitor balancing and right for rocking a stuck HAT loose.
  • Italian microcontrollore renders microcontroller, a different English word from controller.
  • Danish leder is the conductor inside the cable and ledning the cable — a split the English source makes too.
  • Norwegian had left 11 image alt texts in English. A screen reader would have spoken them in English on a Norwegian page. Measured centrally: every other language has exactly one untranslated alt text — the bare product name ![HALPI2] — and Norwegian had twelve.

Two new scripts

scripts/map_anchors.py rewrites English anchor fragments to the translated slugs. Translators leave fragments alone; this maps all of them once the language is complete. The mapping is positional — the nth heading of the English page and the nth heading of the translation are the same heading — because matching on heading text cannot work once the text is in another language. It rewrote 88 fragments here; the same work was 18 hand-written sed expressions in the Swedish branch.

scripts/check_typography.py measures each glossary's own rules. Every rule is scoped to the languages whose glossary asks for it, because the same pattern is correct in one language and a defect in the next: German compounds a proper name with hyphens throughout (NMEA-2000-Netzwerk) and its glossary calls a missing one the clearest sign of a translator who does not write German, while every other language treats that chain as an error. French requires a space before ; : ! ? and requires it unbreakable; everywhere else any space there is wrong.

Four times while writing these checks a rule looked violated and was not: »…« matched the gap between two correct «…» pairs; a space before a colon came from English comments inside a code fence; HaLOS-avbilder is a correct junction hyphen; HALPI2-hardware is a repository name. Each was caught by running the checker against a language that had already been reviewed and fixed — if it reports a defect there, the defect is in the checker.

What this needs from a reader

Nobody who reads Spanish, Italian, Dutch, Norwegian or Danish has read any of this. That was decided explicitly, with the scale on the table: 105 pages at once, carrying fuse ratings, voltage ranges, polarity instructions and jumper settings. Every mechanical check above passes, and none of them can tell whether a fluent sentence says the right thing. The 1031-passage audit is the strongest evidence here and it is still an unverified reading, not a native one.

Corrections belong in solutions/translation/<language>-glossary.md as well as in the pages, so the next translator inherits them rather than repeating the choice.

🤖 Generated with Claude Code

helmihyo and others added 5 commits August 4, 2026 17:37
Five glossaries and five mkdocs locale blocks, no pages yet. Each glossary
opens with the rules where the sibling languages are actively wrong for it,
because copying a pattern that worked next door is the recorded failure
mode here: Norwegian quotes «…» and Danish »…« point opposite ways, and
Spanish, Italian and Dutch each reject the French space before ;:!?.

All five split pilot hole from pre-drilled hole into two rows. Conflating
them is what turned a Swedish mounting step into an instruction to drill
holes that were already drilled.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Spanish and Italian complete; Dutch 16/21, Danish 12/21, Norwegian 4/21.
The remaining 31 pages stopped on a session usage limit, not on anything
in the content: every page that was written matches its English source
exactly on headings, lists, tables, images, admonitions and code fences.

Terms the translators met and the glossaries lacked are consolidated into
the glossaries here rather than written by each translator, because five
agents share one file per language.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
All 105 pages exist and match their English source exactly on headings,
lists, tables, images, admonitions and code fences. 88 cross-page anchors
were mapped positionally: the nth heading of the English page and the nth
heading of the translation are the same heading, which is the only mapping
that survives the text being in another language.

Two glossary cells were typed without their diacritics — aplicaciones
nauticas, stopegrad — so the checker looked for words that do not exist
while the pages had them right. Fixed, and the checker now compares
letters underneath the accents, because Romance plurals move them:
tapón becomes tapones, imagen becomes imágenes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A term that acquires a rival is invisible to check_glossary.py, which only
finds a prescribed term nobody used. A per-language sweep found 21 such
concepts — one connector under two names, one page apart — and 88
occurrences were resolved to whichever word the glossary prescribes, with
22 new rows recording the decisions the glossary had not yet made.

Blind replacement would have been wrong in several places and was avoided:
Spanish balanceo is wrong for super-capacitor balancing and right for
rocking a HAT loose; Italian microcontrollore renders microcontroller, not
controller; Danish leder is the conductor and ledning the cable, a split
the English makes too. Norwegian had left 11 image alt texts in English,
which a screen reader would have read out in English on a Norwegian page.

The safety-critical passages were then read against the English one by
one: every warning, danger, caution and note admonition, every numbered
procedure step and every prohibition on the five pages that carry fuse
ratings, voltages, polarity and jumper settings. 1031 passages compared
across the five languages, no defect found. That is a counted zero, not
an unexamined one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Both did work by hand in the earlier language branches. The anchor mapper
rewrote 88 cross-page fragments here that were rewritten one sed at a time
for Swedish; the typography checker measures each glossary's own rules.

Each rule is scoped to the languages whose glossary asks for it, because
the same pattern is right in one language and wrong in the next. German
compounds a proper name with hyphens throughout — NMEA-2000-Netzwerk —
and its glossary calls a missing one the clearest sign of a translator who
does not write German, while every other language treats that chain as an
error. French requires a space before ; : ! ? and requires it unbreakable;
everywhere else any space there is a defect.

Four times while writing these checks a rule looked violated and was not:
the pair »…« matched the gap between two correct «…» pairs, a space before
a colon came from English comments inside a code fence, HaLOS-avbilder is
a correct junction hyphen, and HALPI2-hardware is a repository name. Each
was caught by running the checker against a language already reviewed and
fixed — if it reports a defect there, the defect is in the checker.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@helmihyo
helmihyo merged commit b7f5a67 into main Aug 5, 2026
1 check passed
@helmihyo
helmihyo deleted the feat/i18n-five-languages branch August 5, 2026 07:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant