Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .claude/rules/rendering/localization.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ paths:
# Localization

For how localized strings flow from `_language.yml` through metadata merging into Pandoc templates and the crossref/authors/callouts Lua filters, see `llm-docs/localization-architecture.md`.

For editing `_language-*.yml` files, follow `src/resources/language/README.md` and `src/resources/language/AGENTS.md` (translator notes, placeholders, parity test).
1 change: 1 addition & 0 deletions news/changelog-1.12.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ All changes included in 1.12:
## Other fixes and improvements

- ([#14822](https://github.com/quarto-dev/quarto-cli/issues/14822)): Translate the `tools-share`, `tools-download`, and `skip-to-content` language keys in Greek. (author: @sogav21)
- ([#14822](https://github.com/quarto-dev/quarto-cli/issues/14822)): The Lithuanian search label and the Swedish caution callout title no longer fall back to English.
10 changes: 10 additions & 0 deletions src/resources/language/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Language files

Before editing any `_language-*.yml`:

- Read `README.md` in this directory.
- Read the translator comment above each key you translate in `_language.yml`. Some strings are screen-reader labels or use words in a specific sense.
- Keep the `{0}`-style placeholders exactly as they appear in the English value.
- Reuse the vocabulary and verb forms already in the target file.
- Region files (`de-CH`, `fr-CA`, `pt-BR`, `zh-TW`) are overlays: only add keys that differ from the base language.
- Run `unit/language-parity.test.ts` (see `.claude/rules/testing/overview.md`); an English key you cannot translate goes in `tests/unit/language-known-gaps.yml`.
79 changes: 52 additions & 27 deletions src/resources/language/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,44 @@ In some circumstances Quarto, Pandoc, and LaTeX will generate textual output tha

This directory includes a set of built-in translations, including:

| File | Language |
| --------------------- | ---------------------------- |
| `_language.yml` | English (default) |
| `_language-az.yml` | Azerbaijani |
| `_language-eu.yml` | Basque |
| `_language-ca.yml` | Catalan |
| `_language-zh.yml` | Chinese |
| `_language-cs.yml` | Czech |
| `_language-nl.yml` | Dutch |
| `_language-fi.yml` | Finnish |
| `_language-fr.yml` | French |
| `_language-de.yml` | German |
| `_language-it.yml` | Italian |
| `_language-he.yml` | Hebrew |
| `_language-ja.yml` | Japanese |
| `_language-kr.yml` | Korean |
| `_language-pl.yml` | Polish |
| `_language-pt.yml` | Portuguese |
| `_language-ru.yml` | Russian |
| `_language-es.yml` | Spanish |
| `_language-tr.yml` | Turkish |
| `_language-zh-TW.yml` | Traditional Chinese (Taiwan) |
| `_language-ua.yml` | Ukrainian |
| File | Language |
| ----------------------- | -------------------------------------- |
| `_language.yml` | English (default) |
| `_language-az.yml` | Azerbaijani |
| `_language-eu.yml` | Basque |
| `_language-pt-BR.yml` | Brazilian Portuguese (overlay) |
| `_language-bg.yml` | Bulgarian |
| `_language-fr-CA.yml` | Canadian French (overlay) |
| `_language-ca.yml` | Catalan |
| `_language-zh.yml` | Chinese |
| `_language-cs.yml` | Czech |
| `_language-da.yml` | Danish |
| `_language-nl.yml` | Dutch |
| `_language-fi.yml` | Finnish |
| `_language-fr.yml` | French |
| `_language-de.yml` | German |
| `_language-el.yml` | Greek |
| `_language-he.yml` | Hebrew |
| `_language-is.yml` | Icelandic |
| `_language-id.yml` | Indonesian |
| `_language-it.yml` | Italian |
| `_language-ja.yml` | Japanese |
| `_language-ko.yml` | Korean |
| `_language-lt.yml` | Lithuanian |
| `_language-nb.yml` | Norwegian Bokmål |
| `_language-nn.yml` | Norwegian Nynorsk |
| `_language-pl.yml` | Polish |
| `_language-pt.yml` | Portuguese |
| `_language-ru.yml` | Russian |
| `_language-sr-Latn.yml` | Serbian (Latin script) |
| `_language-sk.yml` | Slovak |
| `_language-sl.yml` | Slovenian |
| `_language-es.yml` | Spanish |
| `_language-sv.yml` | Swedish |
| `_language-de-CH.yml` | Swiss German (overlay) |
| `_language-zh-TW.yml` | Traditional Chinese (Taiwan) (overlay) |
| `_language-tr.yml` | Turkish |
| `_language-ua.yml` | Ukrainian |

The use of these translations is triggered by the [`lang`](https://pandoc.org/MANUAL.html#language-variables) Pandoc metadata variable, which identifies the main language of the document using IETF language tags (following the [BCP 47](https://tools.ietf.org/html/bcp47) standard), such as `en` or `en-GB`. The [Language subtag lookup](https://r12a.github.io/app-subtags/) tool can look up or verify these tags.

Expand All @@ -41,10 +56,20 @@ lang: fr

## Contributing Localizations

We welcome contributions of additional languages! To contribute a localization:
We welcome translations for new languages and for missing strings in existing languages! To contribute a localization:

1. Make a copy of the `_language.yml` file with the appropriate IETF language tag appended to the filename (e.g. `_language-fr.yml`).
1. For a new language, make a copy of the `_language.yml` file with the appropriate IETF language tag appended to the filename (e.g. `_language-fr.yml`).

2. Translate the English strings therein to the target language.
2. Translate the English strings into the target language. Before translating a key, read its translator comment in `_language.yml`. Some strings are screen-reader labels or use words in a specific sense, as the comments explain.

3. Submit a [pull request](https://help.github.com/articles/using-pull-requests) with your new language translation.
3. Reuse the vocabulary and verb forms already used in your language file so the interface stays consistent.

4. Keep the `{0}`-style placeholders exactly as they appear in the English value.

5. Submit a [pull request](https://help.github.com/articles/using-pull-requests) with your translation.

A few more things to know:

- **Region files are overlays.** `de-CH`, `fr-CA`, `pt-BR` and `zh-TW` are read on top of `de`, `fr`, `pt` and `zh`, so they only need the keys that differ from their base language.
- **AI help is welcome.** Check the translation against the translator comments and existing strings in the language file, and mention in the pull request that you used AI.
- **Checking your file.** `tests/unit/language-parity.test.ts` fails if a language file has a key that is not in `_language.yml`, misses a key, or changes the placeholders. If you add an English key that you cannot translate, add its language entries to `tests/unit/language-known-gaps.yml` instead.
2 changes: 1 addition & 1 deletion src/resources/language/_language-lt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ search-clear-button-title: "Išvalyti"
search-text-placeholder: ""
search-detached-cancel-button-title: "Atšaukti"
search-submit-button-title: "Pateikti"
search: "Paieška"
search-label: "Paieška"

toggle-section: "Rodyti/Slėpti skiltį"
toggle-sidebar: "Rodyti/Slėpti šoninę navigacijos skiltį"
Expand Down
2 changes: 1 addition & 1 deletion src/resources/language/_language-sv.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ callout-tip-title: "Tips"
callout-note-title: "Notera"
callout-warning-title: "Varning"
callout-important-title: "Viktigt"
callout-danger-title: "Försiktigt"
callout-caution-title: "Försiktigt"

code-summary: "Kod"

Expand Down
27 changes: 27 additions & 0 deletions src/resources/language/_language.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,14 @@ related-formats-title: "Other Formats"
related-notebooks-title: "Notebooks"
source-notebooks-prefix: "Source"
other-links-title: "Other Links"
# Heading above the list of hyperlinks to the document's code (repository, Binder, Dev Container);
# plural noun phrase, parallel to other-links-title.
code-links-title: "Code Links"
# Link text that opens the repository in a GitHub Codespace; "Launch" = start/open, not publish.
# "Dev Container" is a product name, usually left untranslated; use the same verb as launch-binder-title.
launch-dev-container-title: "Launch Dev Container"
# "Binder" is the mybinder.org service (interactive Jupyter environment); keep the name untranslated.
# Use the same verb as launch-dev-container-title.
launch-binder-title: "Launch Binder"

article-notebook-label: "Article Notebook"
Expand All @@ -32,13 +38,16 @@ title-block-author-plural: "Authors"
title-block-affiliation-single: "Affiliation"
title-block-affiliation-plural: "Affiliations"
title-block-published: "Published"
# Label shown above the document's last-modified date (date-modified) in the title block.
# Use the same form as title-block-published (e.g. "Date of modification" if that one is "Date of publication").
title-block-modified: "Modified"
title-block-keywords: "Keywords"

callout-tip-title: "Tip"
callout-note-title: "Note"
callout-warning-title: "Warning"
callout-important-title: "Important"
# Callout box title meaning "take care"; keep distinct from callout-warning-title.
callout-caution-title: "Caution"

code-summary: "Code"
Expand All @@ -49,7 +58,11 @@ code-tools-hide-all-code: "Hide All Code"
code-tools-view-source: "View Source"
code-tools-source-code: "Source Code"

# Sidebar menu in books grouping social-media links for the current page;
# "Share" = post a link to the page, not a portion. Pairs with tools-download.
tools-share: "Share"
# Book toolbar: label for the downloads menu and prefix before each format name
# (e.g. "Download PDF"). Choose wording that reads naturally before a format name.
tools-download: "Download"

code-line: "Line"
Expand All @@ -64,6 +77,9 @@ repo-action-links-issue: "Report an issue"

back-to-top: "Back to top"

# Accessibility skip link: first link on the page, shown only on keyboard focus;
# it jumps past the header and navigation to the main content. Use the usual web
# skip-link phrasing ("go to main content"), not "omit".
skip-to-content: "Skip to main content"

search-no-results-text: "No results"
Expand All @@ -76,6 +92,8 @@ search-clear-button-title: "Clear"
search-text-placeholder: ""
search-detached-cancel-button-title: "Cancel"
search-submit-button-title: "Submit"
# Accessible name and tooltip for the navbar button that opens site search.
# Use the conventional one-word label for a website search box.
search-label: "Search"

toggle-section: "Toggle section"
Expand All @@ -102,12 +120,17 @@ scrollable-code-label: "Scrollable code"
scrollable-output-label: "Scrollable output"

# Announced by screen readers after a link that opens in a new tab (never shown as visible text).
# Describes the link (third person, "opens"), not a command; keep the parentheses.
# "Tab" is a browser tab, not a window or a tab control.
link-external-newwindow-label: "(opens in a new tab)"

# Accessible name for the button that dismisses a website announcement (never shown as visible text).
# "Dismiss" = close/hide the banner (the button shows only an X icon), not reject or delete.
# Imperative, like other button labels; use the language's usual "close" verb.
announcement-dismiss-label: "Dismiss announcement"

# Accessible name for the Reveal.js slide menu button (never shown as visible text).
# "Slide" is a presentation slide (PowerPoint sense); use a noun phrase, not a command.
revealjs-menu-button-label: "Slide menu"

crossref-fig-title: "Figure"
Expand Down Expand Up @@ -147,11 +170,15 @@ listing-page-field-filename: "File Name"
listing-page-field-filemodified: "Modified"
listing-page-field-subtitle: "Subtitle"
listing-page-field-readingtime: "Reading Time"
# Label for the number of words in each listed document (a quantity, not a counter tool).
# Shown with other listing fields such as "Reading Time"; keep it short.
listing-page-field-wordcount: "Word Count"
listing-page-field-categories: "Categories"
listing-page-minutes-compact: "{0} min"
listing-page-category-all: "All"
listing-page-no-matches: "No matching items"
# Word count shown per item in a listing, e.g. "1,234 words"; {0} is the formatted number.
# A single string serves every count; pick the plural form that reads best for large numbers.
listing-page-words: "{0} words"
listing-page-filter: "Filter"

Expand Down
13 changes: 13 additions & 0 deletions tests/unit/language-known-gaps.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# <key>: [<lang>, ...] languages whose translation of <key> is still missing (languages sorted)
announcement-dismiss-label: [az, bg, ca, cs, da, de, el, es, eu, fi, fr, he, id, is, it, ja, ko, lt, nb, nl, nn, pl, pt, ru, sk, sl, sr-Latn, sv, tr, ua, zh]
code-links-title: [sr-Latn]
launch-binder-title: [sr-Latn]
launch-dev-container-title: [sr-Latn]
link-external-newwindow-label: [az, bg, ca, cs, da, de, es, eu, fi, fr, he, id, is, it, ja, ko, lt, nb, nl, nn, pl, pt, ru, sk, sl, sr-Latn, sv, tr, ua, zh]
listing-page-field-wordcount: [sr-Latn]
listing-page-words: [sr-Latn]
revealjs-menu-button-label: [az, bg, ca, cs, da, de, es, eu, fi, he, id, is, it, ja, ko, lt, nb, nl, nn, pl, pt, ru, sk, sl, sr-Latn, sv, tr, ua, zh]
skip-to-content: [bg, ca, cs, da, eu, fi, he, id, is, ko, lt, nb, nn, pl, ru, sk, sl, sr-Latn, sv, tr, ua]
title-block-modified: [ko]
tools-download: [ca, cs, da, de, fi, fr, he, id, it, ja, ko, lt, nb, nl, nn, pl, pt, ru, sk, sr-Latn, sv, tr, ua, zh]
tools-share: [ca, cs, da, de, fi, fr, he, id, it, ja, ko, lt, nb, nl, nn, pl, pt, ru, sk, sr-Latn, sv, tr, ua, zh]
Loading
Loading