Browse Source

Improve abbr handling

After these changes it now seems to handle descriptions in title attributes well, both when translating a document the first time – see the abbr section in the `ru/docs/_llm-test.md` which I committed for reference, but I am not sure if everything is correct there, as I do not speak Russian – and when updating translations – tested with e.g. `ru/docs/features.md` and `ru/docs/tutorial/path-params-numeric-validations.md`, not committed.

I simplified rule 3 to just match when the separator is a colon (`:`), not when it is a comma (`,`), there are otherwise too many cases it may misunderstand, as commas are regularly used in title attributes. Updated the two instances in the English docs (`features.md` and `tutorial\sql-databases.md`) where a comma was used instead of a colon in a case, which we match with rule 3. I fixed the results in schemes they accidentally had `(de)` appended, but they are language independent.
pull/14015/head
Nils Lindemann 11 months ago
parent
commit
d1c1b26fe5
  1. 21
      docs/de/docs/_llm-test.md
  2. 21
      docs/en/docs/_llm-test.md
  3. 2
      docs/en/docs/features.md
  4. 2
      docs/en/docs/tutorial/sql-databases.md
  5. 241
      docs/ru/docs/_llm-test.md
  6. 5
      docs/ru/llm-prompt.md
  7. 97
      scripts/translate.py

21
docs/de/docs/_llm-test.md

@ -113,9 +113,26 @@ Etwas Text
[Interner Link](foo.md#bar){.internal-link target=_blank}
## Abbr-Elemente { #abbr-elements }
## HTML-„abbr“-Elemente { #html-abbr-elements }
Hier einige Dinge, die in `abbr`-Elemente gehüllt sind (einige sind erfunden): <abbr title="Getting Things Done – Dinge erledigt bekommen">GTD</abbr>, <abbr title="XML-Web-Token">XWT</abbr>, <abbr title="Paralleles Server-Gateway-Interface">PSGI</abbr>, <abbr title="Eine Gruppe von Maschinen, die so konfiguriert sind, dass sie verbunden sind und in irgendeiner Weise zusammenarbeiten.">Cluster</abbr>, <abbr title="Eine Methode des maschinellen Lernens, die künstliche neuronale Netze mit zahlreichen verdeckten Schichten zwischen Eingabe- und Ausgabeschichten verwendet und dabei eine umfassende interne Struktur entwickelt">Deep Learning</abbr>, <abbr title="Mozilla Developer Network – Mozilla-Entwicklernetzwerk: Dokumentation für Entwickler, geschrieben von den Firefox-Leuten">MDN</abbr>.
Hier einige Dinge, die in HTML-„abbr“-Elemente gewrappt sind (einige sind erfunden):
### Ganze Phrase { #full-phrase }
* <abbr title="Getting Things Done – Dinge erledigt bekommen">GTD</abbr>
* <abbr title="less than – kleiner als"><code>lt</code></abbr>
* <abbr title="XML-Web-Token">XWT</abbr>
* <abbr title="Paralleles Server-Gateway-Interface">PSGI</abbr>
### Erklärung { #explanation }
* <abbr title="Eine Gruppe von Maschinen, die so konfiguriert sind, dass sie verbunden sind und in irgendeiner Weise zusammenarbeiten.">Cluster</abbr>
* <abbr title="Eine Methode des maschinellen Lernens, die künstliche neuronale Netze mit zahlreichen verdeckten Schichten zwischen Eingabe- und Ausgabeschichten verwendet und dabei eine umfassende interne Struktur entwickelt">Deep Learning</abbr>
### Ganze Phrase: Erklärung { #full-phrase-explanation }
* <abbr title="Mozilla Developer Network – Mozilla-Entwicklernetzwerk: Dokumentation für Entwickler, geschrieben von den Firefox-Leuten">MDN</abbr>
* <abbr title="Input/Output – Eingabe/Ausgabe: Lesen oder Schreiben auf der Festplatte, Netzwerkkommunikation.">I/O</abbr>.
## Überschriften { #headings }

21
docs/en/docs/_llm-test.md

@ -113,9 +113,26 @@ Some text
[Internal link](foo.md#bar){.internal-link target=_blank}
## Abbr elements { #abbr-elements }
## HTML "abbr" elements { #html-abbr-elements }
Here some things wrapped in `abbr` elements (Some are invented): <abbr title="Getting Things Done">GTD</abbr>, <abbr title="XML Web Token">XWT</abbr>, <abbr title="Parallel Server Gateway Interface">PSGI</abbr>, <abbr title="A group of machines that are configured to be connected and work together in some way.">cluster</abbr>, <abbr title="A method of machine learning that uses artificial neural networks with numerous hidden layers between input and output layers, thereby developing a comprehensive internal structure">Deep Learning</abbr>, <abbr title="Mozilla Developer Network: Documentation for developers, written by the Firefox people">MDN</abbr>.
Here some things wrapped in HTML "abbr" elements (Some are invented):
### Full phrase { #full-phrase }
* <abbr title="Getting Things Done">GTD</abbr>
* <abbr title="less than"><code>lt</code></abbr>
* <abbr title="XML Web Token">XWT</abbr>
* <abbr title="Parallel Server Gateway Interface">PSGI</abbr>
### Explanation { #explanation }
* <abbr title="A group of machines that are configured to be connected and work together in some way.">cluster</abbr>
* <abbr title="A method of machine learning that uses artificial neural networks with numerous hidden layers between input and output layers, thereby developing a comprehensive internal structure">Deep Learning</abbr>
### Full phrase: Explanation { #full-phrase-explanation }
* <abbr title="Mozilla Developer Network: Documentation for developers, written by the Firefox people">MDN</abbr>
* <abbr title="Input/Output: disk reading or writing, network communications.">I/O</abbr>.
## Headings { #headings }

2
docs/en/docs/features.md

@ -190,7 +190,7 @@ With **FastAPI** you get all of **Pydantic**'s features (as FastAPI is based on
* **No brainfuck**:
* No new schema definition micro-language to learn.
* If you know Python types you know how to use Pydantic.
* Plays nicely with your **<abbr title="Integrated Development Environment, similar to a code editor">IDE</abbr>/<abbr title="A program that checks for code errors">linter</abbr>/brain**:
* Plays nicely with your **<abbr title="Integrated Development Environment: similar to a code editor">IDE</abbr>/<abbr title="A program that checks for code errors">linter</abbr>/brain**:
* Because pydantic data structures are just instances of classes you define; auto-completion, linting, mypy and your intuition should all work properly with your validated data.
* Validate **complex structures**:
* Use of hierarchical Pydantic models, Python `typing`’s `List` and `Dict`, etc.

2
docs/en/docs/tutorial/sql-databases.md

@ -8,7 +8,7 @@ Here we'll see an example using <a href="https://sqlmodel.tiangolo.com/" class="
/// tip
You could use any other SQL or NoSQL database library you want (in some cases called <abbr title="Object Relational Mapper, a fancy term for a library where some classes represent SQL tables and instances represent rows in those tables">"ORMs"</abbr>), FastAPI doesn't force you to use anything. 😎
You could use any other SQL or NoSQL database library you want (in some cases called <abbr title="Object Relational Mapper: a fancy term for a library where some classes represent SQL tables and instances represent rows in those tables">"ORMs"</abbr>), FastAPI doesn't force you to use anything. 😎
///

241
docs/ru/docs/_llm-test.md

@ -0,0 +1,241 @@
# Тест LLM { #llm-test }
Этот документ проверяет, понимает ли <abbr title="Large Language Model – Большая языковая модель">LLM</abbr> инструкции, заданные в общем промпте в `scripts/translate.py`, и инструкции в языковом промпте `docs/{language code}/llm-prompt.md` (которые добавляются к инструкциям в общем промпте).
Использование:
* Сделайте свежий перевод этого документа на нужный целевой язык.
* Проверьте, что в целом всё в порядке.
* Если что‑то не так, но это можно исправить улучшением английского документа или общего/языкового промпта, сделайте это.
* Затем вручную исправьте оставшиеся проблемы в переводе, чтобы получился хороший перевод.
* Повторно переведите, используя существующий, хороший перевод. Идеальный результат — LLM ничего не меняет. Это означало бы, что общий промпт и языковой промпт настолько хороши, насколько это возможно (Неожиданный поворот: обычно он всё же внесёт несколько на вид случайных правок, вероятно потому, что <a href="https://doublespeak.chat/#/handbook#deterministic-output" class="external-link" target="_blank">LLM — не детерминированные алгоритмы</a>).
Идея в том, что при работе над переводом для конкретного языка (если есть возможность запускать `scripts/translate.py`) добавлять сюда примеры найденных частных случаев (не подробный список, лишь примеры таких случаев) и тестировать на этом документе, а не на каждом отдельном документе, переводя его многократно, что стоит по нескольку центов за перевод. Кроме того, добавляя такие частные случаи сюда, другие проекты перевода тоже узнают о них.
## Фрагменты кода { #code-snippets}
Это фрагмент кода: `foo`. А это ещё один фрагмент кода: `bar`. И ещё один: `baz quux`.
## Кавычки { #quotes }
Вчера мой друг написал: "Если вы правильно напишете слово 'incorrectly', вы напишете его неправильно". На что я ответил: "Верно, но 'incorrectly' — это неправильно, а не '"incorrectly"'".
## Кавычки во фрагментах кода { #quotes-in-code-snippets}
`pip install "foo[bar]"`
Примеры строковых литералов во фрагментах кода: `"this"`, `'that'`.
Сложный пример строковых литералов во фрагментах кода: `f"I like {'oranges' if orange else "apples"}"`
Хардкор: `Yesterday my friend wrote: "If you spell incorrectly correctly you have spelled it incorrectly". To which I answered: "Correct, but 'incorrectly' is incorrectly not '"incorrectly"'!"`
## Блоки кода { #code-blocks }
Пример кода Bash...
```bash
# Напечатать приветствие вселенной
echo "Hello universe"
```
...и пример кода консоли...
```console
$ <font color="#4E9A06">fastapi</font> run <u style="text-decoration-style:solid">main.py</u>
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting server
Searching for package file structure
```
...и ещё один пример кода консоли...
```console
// Создайте каталог "Code"
$ mkdir code
// Перейдите в этот каталог
$ cd code
```
...и пример кода на Python...
```Python
wont_work() # Это не сработает 😱
works(foo="bar") # Это сработает 🎉
```
...и на этом всё.
## Вкладки и цветные блоки { #tabs-and-colored-boxes }
//// tab | Это вкладка
/// info | Информация
Немного текста
///
/// note | Примечание
Немного текста
///
/// note | Технические детали
Немного текста
///
/// check | Проверка
Немного текста
///
/// tip | Совет
Немного текста
///
/// warning | Предупреждение
Немного текста
///
/// danger | Опасность
Немного текста
///
////
## Веб‑ и внутренние ссылки { #web-and-internal-links }
[Ссылка на заголовок выше](#code-snippets)
<a href="https://sqlmodel.tiangolo.com/" class="external-link" target="_blank">Внешняя ссылка</a>
<a href="https://fastapi.tiangolo.com/ru/the/link/#target" class="external-link" target="_blank">Ссылка FastAPI</a>
<a href="https://fastapi.tiangolo.com/css/styles.css" class="external-link" target="_blank">Ссылка на стиль</a>
<a href="https://fastapi.tiangolo.com/js/logic.js" class="external-link" target="_blank">Ссылка на скрипт</a>
<a href="https://fastapi.tiangolo.com/img/foo.jpg" class="external-link" target="_blank">Ссылка на изображение</a>
[Внутренняя ссылка](foo.md#bar){.internal-link target=_blank}
## Элементы HTML "abbr" { #html-abbr-elements }
Здесь некоторые вещи, обёрнутые в элементы HTML "abbr" (некоторые вымышленные):
### Полная фраза { #full-phrase }
* <abbr title="Getting Things Done – Доведение дел до конца">GTD</abbr>
* <abbr title="less than – меньше чем"><code>lt</code></abbr>
* <abbr title="XML Web Token – XML веб-токен">XWT</abbr>
* <abbr title="Parallel Server Gateway Interface – Параллельный интерфейс шлюза сервера">PSGI</abbr>
### Объяснение { #explanation }
* <abbr title="Группа машин, настроенных на подключение и совместную работу определённым образом.">кластер</abbr>
* <abbr title="Метод машинного обучения, использующий искусственные нейронные сети с многочисленными скрытыми слоями между входным и выходным слоями, тем самым формируя сложную внутреннюю структуру">Глубокое обучение</abbr>
### Полная фраза: Объяснение { #full-phrase-explanation }
* <abbr title="Mozilla Developer Network – Сеть разработчиков Mozilla: Документация для разработчиков, написанная людьми из команды Firefox">MDN</abbr>
* <abbr title="Input/Output – Ввод/Вывод: чтение или запись на диск, сетевые коммуникации.">I/O</abbr>.
## Заголовки { #headings }
### Разработка веб‑приложения — учебник { #develop-a-webapp-a-tutorial }
Здравствуйте.
### Подсказки типов и аннотации { #type-hints-and-annotations }
Ещё раз здравствуйте.
### Супер‑ и подклассы { #super-and-subclasses }
Ещё раз здравствуйте.
## Предложения с предпочтительными переводами, (возможно) заданными в языковом промпте { #sentences-with-preferred-translations-maybe-defined-in-the-language-prompt }
Добро пожаловать.
Я восхищаюсь вашим пуловером.
Ей нравятся фрукты, например, яблоки.
Ему нравятся апельсины, бананы и т. д.
Читайте документацию.
Прочтите учебник — Руководство пользователя.
Затем прочтите Руководство для продвинутых пользователей.
Если эта переменная окружения существует, сделайте что‑нибудь.
Прочитайте переменную окружения `PATH`.
Это то же самое, что `PATH`.
Установите из `requirements.txt`.
Используйте APIRouter.
Запустите приложение.
Создайте приложение.
Это заголовок Authorization.
Это заголовок `Authorization`.
Ожидание фоновой задачи.
Нажмите кнопку.
Попробуйте этого облачного провайдера.
Используйте CLI.
То есть интерфейс командной строки.
Значение по умолчанию — "foo".
Объявление по умолчанию — "bar".
Словари, или dict, — полезные структуры данных.
Перечисления, или Enum, тоже имеют своё применение.
Движок сделает это.
Верните ответ с ошибкой.
Дождитесь события.
Бросьте исключение.
Обработчик исключений обработает это.
Определение модели формы.
Отправка тела формы.
Доступ к заголовку.
Изменение заголовков.
Написание в заголовках.
Пересылаемые заголовки часто используются в связке с прокси‑серверами.
Прослушивание события жизненного цикла.
Блокировка означает, что мы «захватываем» ресурс, чтобы безопасно его изменить.
Разработка мобильного приложения.
Определение объекта модели.
Что‑то ждёт монтирования.
Теперь это смонтировано.
Другой источник.
У нас есть переопределение для этого.
У функции один параметр.
Параметр функции — int.
У функции много параметров.
Параметр по умолчанию — bool.
Параметр body содержит тело запроса.
Также называется параметром тела запроса.
Параметр path содержит переменную в пути запроса.
Параметр query содержит параметры строки запроса в пути запроса.
Параметр cookie содержит куки запроса.
Параметр header содержит заголовки запроса.
Параметр form содержит поля формы запроса.
Полезная нагрузка — это запрос/ответ без метаданных.
Этот запрос запрашивает элементы старше недели.
Итог: всё гладко.
Запрос получен.
Получение тела запроса.
Получение тел запросов.
Возврат ответа.
То, что возвращает функция, имеет возвращаемое значение.
И тип возвращаемого значения.
Мы слушаем события запуска и остановки.
Мы ждём запуска сервера.
Подробности описаны в документации SQLModel.
Используйте SDK.
Тег `Horst` означает, что Хорст должен это сделать.
У этого параметра есть аннотация типа.
То есть подсказка типа.
Подстановочный символ — `*`.
Класс worker делает то и это.
Рабочий процесс тоже что‑то делает.
Я закоммичу это завтра.
Вчера я изменил код.
Давайте запустим наше приложение.
Давайте отдадим эту страницу.
Прежде чем делать это, обновите FastAPI.
Это обёрнуто в HTML‑тег.
`foo` как `int`.
`bar` как `str`.
`baz` как `list`.
Документация FastAPI.
Производительность Starlette.
`foo` чувствителен к регистру.
"Bar" не чувствителен к регистру.
Стандартные классы Python.
Это устарело.

5
docs/ru/llm-prompt.md

@ -0,0 +1,5 @@
### Target language
Translate to Russian (русский язык).
Language code: ru.

97
scripts/translate.py

@ -508,9 +508,19 @@ Example:
### HTML abbr elements
Translate HTML abbr elements as follows:
Translate HTML abbr elements («<abbr title="description">text</abbr>») as follows:
1) If the title attribute gives the full phrase for an abbreviation, then keep the phrase, append a dash («»), followed by the translation of the phrase.
1) If the text surrounded by the abbr element is an abbreviation (the text may be surrounded by further HTML or Markdown markup or quotes, for example «<code>text</code>» or «`text`» or «"text"», ignore that further markup when deciding if the text is an abbreviation), and if the description (the text inside the title attribute) contains the full phrase for this abbreviation, then append a dash («») to the full phrase, followed by the translation of the full phrase.
Conversion scheme:
Source (English):
<abbr title="{full phrase}">{abbreviation}</abbr>
Result:
<abbr title="{full phrase} – {translation of full phrase}">{abbreviation}</abbr>
Examples:
@ -530,17 +540,17 @@ Examples:
<abbr title="too long; didn't read – zu lang; hab's nicht gelesen"><strong>TL;DR:</strong></abbr>
»»»
Conversion scheme title attribute:
1.1) If the language to which you translate mostly uses the letters of the ASCII char set (for example Spanish, French, German, but not Russian, Chinese) and if the translation of the full phrase is identical to, or starts with the same letters as the original full phrase, then only give the translation of the full phrase.
Conversion scheme:
Source (English):
{full phrase}
<abbr title="{full phrase}">{abbreviation}</abbr>
Result (German):
{full phrase} {translation of full phrase}
Result:
1.1) If the translation of the phrase starts with the same letters, then just use the translation.
<abbr title="{translation of full phrase}">{abbreviation}</abbr>
Examples:
@ -548,7 +558,7 @@ Examples:
«««
<abbr title="JSON Web Tokens">JWT</abbr>
<abbr title="Enumeration">`Enum`</abbr>
<abbr title="Enumeration">Enum</abbr>
<abbr title="Asynchronous Server Gateway Interface">ASGI</abbr>
»»»
@ -556,21 +566,21 @@ Examples:
«««
<abbr title="JSON Web Tokens">JWT</abbr>
<abbr title="Enumeration">`Enum`</abbr>
<abbr title="Enumeration">Enum</abbr>
<abbr title="Asynchrones Server-Gateway-Interface">ASGI</abbr>
»»»
Conversion scheme title attribute:
2) If the description is not a full phrase for an abbreviation which the abbr element surrounds, but some other information, then just translate the description.
Source (English):
Conversion scheme:
{full phrase}
Source (English):
Result (German):
<abbr title="{description}">{text}</abbr>
{translation of full phrase}
Result:
2) If the title attribute explains something in its own words, then translate it, if possible.
<abbr title="{translation of description}">{translation of text}</abbr>
Examples:
@ -578,8 +588,8 @@ Examples:
«««
<abbr title="also known as: endpoints, routes">path</abbr>
<abbr title="A program that checks for code errors">linter</abbr>
<abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>
<abbr title="a program that checks for code errors">linter</abbr>
<abbr title="converting the string that comes from an HTTP request into Python data">parsing</abbr>
<abbr title="before 2023-03">0.95.0</abbr>
<abbr title="2023-08-26">at the time of writing this</abbr>
»»»
@ -589,22 +599,23 @@ Examples:
«««
<abbr title="auch bekannt als: Endpunkte, Routen">Pfad</abbr>
<abbr title="Programm das auf Fehler im Code prüft">Linter</abbr>
<abbr title="Konvertieren des Strings eines HTTP-Requests in Python-Daten">Parsen</abbr>
<abbr title="Konvertieren des Strings eines HTTP-Requests in Python-Daten">Parsen</abbr>
<abbr title="vor 2023-03">0.95.0</abbr>
<abbr title="2023-08-26">zum Zeitpunkt als das hier geschrieben wurde</abbr>
»»»
Conversion scheme title attribute:
Source (English):
3) If the text surrounded by the abbr element is an abbreviation and the description contains both the full phrase for that abbreviation, and other information, separated by a colon («:»), then append a dash («») and the translation of the full phrase to the original full phrase and translate the other information.
{explanation}
Conversion scheme:
Result (German):
Source (English):
<abbr title="{full phrase}: {other information}">{abbreviation}</abbr>
{translation of explanation}
Result:
3) If the title attribute gives the full phrase for an abbreviation, followed by a colon («:») or a comma («,»), followed by an explanation, then keep the phrase, append a dash («»), followed by the translation of the phrase, followed by a colon («:»), followed by the translation of the explanation.
<abbr title="{full phrase} – {translation of full phrase}: {translation of other information}">{abbreviation}</abbr>
Examples:
@ -612,9 +623,8 @@ Examples:
«««
<abbr title="Input/Output: disk reading or writing, network communication.">I/O</abbr>
<abbr title="Content Delivery Network: Service, that provides static files.">CDN</abbr>
<abbr title="Integrated Development Environment, similar to a code editor">IDE</abbr>
<abbr title="Object Relational Mapper, a fancy term for a library where some classes represent SQL tables and instances represent rows in those tables">"ORMs"</abbr>
<abbr title="Content Delivery Network: service, that provides static files.">CDN</abbr>
<abbr title="Integrated Development Environment: similar to a code editor">IDE</abbr>
»»»
Result (German):
@ -623,34 +633,37 @@ Examples:
<abbr title="Input/Output – Eingabe/Ausgabe: Lesen oder Schreiben auf der Festplatte, Netzwerkkommunikation.">I/O</abbr>
<abbr title="Content Delivery Network – Inhalte auslieferndes Netzwerk: Dienst, der statische Dateien bereitstellt.">CDN</abbr>
<abbr title="Integrated Development Environment – Integrierte Entwicklungsumgebung: Ähnlich einem Code-Editor">IDE</abbr>
<abbr title="Object Relational Mapper – Objektrelationaler Mapper: Ein Fachbegriff für eine Bibliothek, in der einige Klassen SQL-Tabellen und Instanzen Zeilen in diesen Tabellen darstellen">ORMs</abbr>
»»»
Conversion scheme title attribute:
Source (English):
{full phrase}: {explanation}
3.1) Like in rule 2.1, you can leave the original full phrase away, if the translated full phrase is identical or starts with the same letters as the original full phrase.
OR
Conversion scheme:
Source (English):
{full phrase}, {explanation}
<abbr title="{full phrase}: {information}">{abbreviation}</abbr>
Result (German):
Result:
{full phrase} {translation of full phrase}: {translation of explanation}
<abbr title="{translation of full phrase}: {translation of information}">{abbreviation}</abbr>
3.1) For the full phrase (the part before the dash in the translation) rule 1.1 also applies, speak, you can leave the original full phrase away and just use the translated full phrase, if it starts with the same letters. The result becomes:
Example:
Source (English):
Conversion scheme title attribute:
«««
<abbr title="Object Relational Mapper: a fancy term for a library where some classes represent SQL tables and instances represent rows in those tables">ORM</abbr>
»»»
Result (German):
{translation of full phrase}: {translation of explanation}
«««
<abbr title="Objektrelationaler Mapper: Ein Fachbegriff für eine Bibliothek, in der einige Klassen SQL-Tabellen und Instanzen Zeilen in diesen Tabellen darstellen">ORM</abbr>
»»»
4) Apply above rules also when there is an existing translation! Make sure that all title attributes in abbr elements get properly translated or updated, using the schemes given above.
4) If there is an HTML abbr element in a sentence in an existing translation, but that element does not exist in the related sentence in the English text, then keep that HTML abbr element in the translation, do not change or remove it. Except when you remove the whole sentence from the translation, because the whole sentence was removed from the English text. The reasoning for this rule is, that such abbr elements are manually added by the human editor of the translation, in order to translate or explain an English word to the human readers of the translation. They would not make sense in the English text, but they do make sense in the translation. So keep them in the translation, even though they are not part of the English text. This rule only applies to HTML abbr elements.
5) If there is an existing translation, and it has ADDITIONAL abbr elements in a sentence, and these additional abbr elements do not exist in the related sentence in the English text, then KEEP those additional abbr elements in the translation. Do not remove them. Except when you remove the whole sentence from the translation, because the whole sentence was removed from the English text, then also remove the abbr element. The reasoning for this rule is, that such additional abbr elements are manually added by the human editor of the translation, in order to translate or explain an English word to the human readers of the translation. These additional abbr elements would not make sense in the English text, but they do make sense in the translation. So keep them in the translation, even though they are not part of the English text. This rule only applies to abbr elements.
"""

Loading…
Cancel
Save