From 61afce4197d71ad2c36d5188c6014c0ac34f2635 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 16 Feb 2022 03:22:16 +0100 Subject: [PATCH] More translation validations --- assets/layers/artwork/artwork.json | 2 +- assets/layers/bike_shop/bike_shop.json | 2 +- assets/layers/food/food.json | 2 - .../layers/nature_reserve/nature_reserve.json | 13 +-- assets/themes/campersite/campersite.json | 2 +- assets/themes/cyclestreets/cyclestreets.json | 6 +- langs/fr.json | 7 +- langs/ja.json | 2 +- langs/layers/en.json | 5 - langs/layers/es.json | 2 +- langs/layers/it.json | 2 +- langs/layers/nl.json | 3 - langs/pl.json | 10 +- langs/pt.json | 10 +- langs/pt_BR.json | 2 +- langs/ru.json | 2 +- langs/sv.json | 2 +- langs/themes/de.json | 2 +- langs/themes/it.json | 2 +- langs/themes/ja.json | 3 +- langs/themes/nb_NO.json | 3 +- langs/themes/pt_BR.json | 2 +- langs/zh_Hant.json | 2 +- scripts/generateTranslations.ts | 109 +++++++++++++++++- 24 files changed, 138 insertions(+), 59 deletions(-) diff --git a/assets/layers/artwork/artwork.json b/assets/layers/artwork/artwork.json index 08db8f4a9..bffc6f05f 100644 --- a/assets/layers/artwork/artwork.json +++ b/assets/layers/artwork/artwork.json @@ -51,7 +51,7 @@ "id": "Karya Seni {name}", "it": "Opera {name}", "ru": "Художественная работа {name}", - "es": "Obra de arte {nombre}", + "es": "Obra de arte {name}", "ja": "アートワーク {name}", "zh_Hant": "藝術品{name}", "fi": "Taideteos {name}", diff --git a/assets/layers/bike_shop/bike_shop.json b/assets/layers/bike_shop/bike_shop.json index 81befb61b..eda028865 100644 --- a/assets/layers/bike_shop/bike_shop.json +++ b/assets/layers/bike_shop/bike_shop.json @@ -118,7 +118,7 @@ "fr": "Réparateur de vélo {name}", "gl": "Arranxo de bicicletas {name}", "de": "Fahrradwerkstatt {name}", - "it": "Riparazione biciclette {name", + "it": "Riparazione biciclette {name}", "ru": "Ремонт велосипедов {name}", "pt_BR": "Reparo de bicicletas {name}", "pt": "Reparo de bicicletas {name}" diff --git a/assets/layers/food/food.json b/assets/layers/food/food.json index 23d164d98..816aa3645 100644 --- a/assets/layers/food/food.json +++ b/assets/layers/food/food.json @@ -282,7 +282,6 @@ "if": "cuisine=turkish", "then": { "en": "Turkish dishes are served here", - "nl": "Dit is een Turks restaurant (dat meer dan enkel kebab verkoopt)" } }, @@ -290,7 +289,6 @@ "if": "cuisine=thai", "then": { "en": "Thai dishes are served here", - "nl": "Dit is een Thaïs restaurant" } } diff --git a/assets/layers/nature_reserve/nature_reserve.json b/assets/layers/nature_reserve/nature_reserve.json index 9b1db2e0f..36d39dd7c 100644 --- a/assets/layers/nature_reserve/nature_reserve.json +++ b/assets/layers/nature_reserve/nature_reserve.json @@ -27,17 +27,6 @@ "en": "Nature reserve" }, "mappings": [ - { - "if": { - "and": [ - "name:nl~*" - ] - }, - "then": { - "nl": "{name:nl}", - "en": "{name}" - } - }, { "if": { "and": [ @@ -282,7 +271,7 @@ ], "id": "Dogs?" }, - "website", + "website", { "question": { "nl": "Wie is de conservator van dit gebied?
Respecteer privacy - geef deze naam enkel als die duidelijk is gepubliceerd", diff --git a/assets/themes/campersite/campersite.json b/assets/themes/campersite/campersite.json index c65b742bf..59acbe7c6 100644 --- a/assets/themes/campersite/campersite.json +++ b/assets/themes/campersite/campersite.json @@ -736,7 +736,7 @@ "ja": "ゴミ捨て場 {name}", "it": "Luogo di sversamento {name}", "fr": "Site de vidange {name}", - "pt_BR": "Estação de despejo {nome}", + "pt_BR": "Estação de despejo {name}", "de": "Entsorgungsstation {name}", "zh_Hant": "{name} 垃圾站" }, diff --git a/assets/themes/cyclestreets/cyclestreets.json b/assets/themes/cyclestreets/cyclestreets.json index 410ac7bf7..aad78a15f 100644 --- a/assets/themes/cyclestreets/cyclestreets.json +++ b/assets/themes/cyclestreets/cyclestreets.json @@ -250,10 +250,8 @@ "question": { "nl": "Is de straat {name} een fietsstraat?", "en": "Is the street {name} a cyclestreet?", - "ja": "この通りはcyclestreetですか?", - "nb_NO": "Er denne gaten en sykkelvei?", - "de": "Ist die Straße {Name} eine Fahrradstraße?", - "it": "È una strada ciclabile?", + "de": "Ist die Straße {name} eine Fahrradstraße?", + "it": "È {name} una strada ciclabile?", "hu": "Kerékpárosutca-e {name}?" }, "mappings": [ diff --git a/langs/fr.json b/langs/fr.json index 58e137003..214212e1e 100644 --- a/langs/fr.json +++ b/langs/fr.json @@ -125,7 +125,7 @@ "getStartedNewAccount": " ou créez un compte", "noTagsSelected": "Aucune balise sélectionnée", "customThemeIntro": "

Thèmes personnalisés

Vous avez déjà visité ces thèmes personnalisés.", - "aboutMapcomplete": "

À propos de MapComplete

Avec MapComplete vous pouvez enrichir OpenStreetMap d'informations sur un thème unique. Répondez à quelques questions, et en quelques minutes vos contributions seront disponible dans le monde entier ! Le concepteur du thème définis les éléments, questions et langues pour le thème.

En savoir plus

MapComplete propose toujours l'étape suivante pour en apprendre plus sur OpenStreetMap.


Vous avez remarqué un problème ? Vous souhaitez demander une fonctionnalité ? Vous voulez aider à traduire ? Allez voir le code source ou l'<i>issue tracker.</i>

Vous voulez visualiser votre progression ? Suivez le compteur d'édition sur OsmCha.

", + "aboutMapcomplete": "

À propos de MapComplete

Avec MapComplete vous pouvez enrichir OpenStreetMap d'informations sur un thème unique. Répondez à quelques questions, et en quelques minutes vos contributions seront disponible dans le monde entier ! Le concepteur du thème définis les éléments, questions et langues pour le thème.

En savoir plus

MapComplete propose toujours l'étape suivante pour en apprendre plus sur OpenStreetMap.


Vous avez remarqué un problème ? Vous souhaitez demander une fonctionnalité ? Vous voulez aider à traduire ? Allez voir le code source ou l'<i>issue tracker.</i>

Vous voulez visualiser votre progression ? Suivez le compteur d'édition sur OsmCha.

", "backgroundMap": "Carte de fonds", "layerSelection": { "zoomInToSeeThisLayer": "Aggrandissez la carte pour voir cette couche", @@ -188,7 +188,7 @@ "wikipediaboxTitle": "Wikipédia", "loading": "Chargement de Wikipédia…", "noWikipediaPage": "Cet élément Wikidata n’a pas encore de page Wikipédia correspondante.", - "noResults": "Pas de résultats pour", + "noResults": "Pas de résultats pour {search}", "searchWikidata": "Rechercher sur Wikidata", "failed": "Le chargement de Wikipédia a échoué" }, @@ -244,8 +244,7 @@ "whyDelete": "Pourquoi ce point devrait-il être supprimé ?", "explanations": { "selectReason": "Sélectionner pourquoi cet élément devrait être supprimé", - "hardDelete": "Ce point sera supprimé d’OpenStreetmap. Il pourra être restauré par des méthodes avancées", - "softDelete": "Cet élément sera mis à jour et caché de l’application." + "hardDelete": "Ce point sera supprimé d’OpenStreetmap. Il pourra être restauré par des méthodes avancées" }, "reasons": { "test": "Élément de test qui n’a jamais été ici", diff --git a/langs/ja.json b/langs/ja.json index e4a722923..4673cfafc 100644 --- a/langs/ja.json +++ b/langs/ja.json @@ -119,7 +119,7 @@ } }, "backgroundMap": "背景マップ", - "aboutMapcomplete": "

MapCompleteについて

MapCompleteを使えば、1つのテーマに関する情報でOpenStreetMapを充実させることができます。いくつかの質問に答えると、数分以内にあなたの投稿が世界中で公開されます!テーマメンテナは、テーマの要素、質問、言語を定義します。

詳細情報を見る

MapCompleteは常にOpenStreetMapについてさらに学ぶため次のステップを提供します。


問題に気づきましたか?機能要求はありますか?翻訳の手伝いをしますか?ソースコードまたは問題追跡ツールに移動します。

進捗状況を確認しますか? OsmChaの編集数に従います。

", + "aboutMapcomplete": "

MapCompleteについて

MapCompleteを使えば、1つのテーマに関する情報でOpenStreetMapを充実させることができます。いくつかの質問に答えると、数分以内にあなたの投稿が世界中で公開されます!テーマメンテナは、テーマの要素、質問、言語を定義します。

詳細情報を見る

MapCompleteは常にOpenStreetMapについてさらに学ぶため次のステップを提供します。


問題に気づきましたか?機能要求はありますか?翻訳の手伝いをしますか?ソースコードまたは問題追跡ツールに移動します。

進捗状況を確認しますか? OsmChaの編集数に従います。

", "customThemeIntro": "

カスタムテーマ

これらは以前にアクセスされたユーザー生成テーマです。", "noTagsSelected": "タグが選択されていません", "getStartedNewAccount": " または新しいアカウントを作成する", diff --git a/langs/layers/en.json b/langs/layers/en.json index 9bcb3d904..c00b24633 100644 --- a/langs/layers/en.json +++ b/langs/layers/en.json @@ -3594,11 +3594,6 @@ } }, "title": { - "mappings": { - "0": { - "then": "{name}" - } - }, "render": "Nature reserve" } }, diff --git a/langs/layers/es.json b/langs/layers/es.json index 36050980e..c71f31cc1 100644 --- a/langs/layers/es.json +++ b/langs/layers/es.json @@ -65,7 +65,7 @@ "title": { "mappings": { "0": { - "then": "Obra de arte {nombre}" + "then": "Obra de arte {name}" } }, "render": "Obra de arte" diff --git a/langs/layers/it.json b/langs/layers/it.json index 2c1622d58..9ce9dec7e 100644 --- a/langs/layers/it.json +++ b/langs/layers/it.json @@ -771,7 +771,7 @@ "then": "Noleggio di biciclette {name}" }, "3": { - "then": "Riparazione biciclette {name" + "then": "Riparazione biciclette {name}" }, "4": { "then": "Negozio di biciclette {name}" diff --git a/langs/layers/nl.json b/langs/layers/nl.json index 4e01414da..9edc12e9e 100644 --- a/langs/layers/nl.json +++ b/langs/layers/nl.json @@ -3516,9 +3516,6 @@ "title": { "mappings": { "0": { - "then": "{name:nl}" - }, - "1": { "then": "{name}" } }, diff --git a/langs/pl.json b/langs/pl.json index e178ef321..be3e99b27 100644 --- a/langs/pl.json +++ b/langs/pl.json @@ -35,7 +35,7 @@ "zoomInFurther": "Powiększ jeszcze bardziej, aby dodać punkt.", "intro": "Kliknąłeś gdzieś, gdzie nie są jeszcze znane żadne dane.
", "title": "Czy dodać nowy punkt?", - "addNew": "Dodaj nową {kategorię} tutaj", + "addNew": "Dodaj nową {category} tutaj", "pleaseLogin": "Zaloguj się, aby dodać nowy punkt", "confirmButton": "Dodaj tutaj {category}.
Twój dodatek jest widoczny dla wszystkich
", "layerNotEnabled": "Warstwa {layer} nie jest włączona. Włącz tę warstwę, aby dodać punkt", @@ -78,7 +78,7 @@ "zoomInFurther": "Powiększ jeszcze bardziej, aby dodać punkt.", "intro": "Kliknąłeś gdzieś, gdzie nie są jeszcze znane żadne dane.
", "title": "Czy dodać nowy punkt?", - "addNew": "Dodaj nową {kategorię} tutaj", + "addNew": "Dodaj nową {category} tutaj", "pleaseLogin": "Zaloguj się, aby dodać nowy punkt", "confirmButton": "Dodaj tutaj {category}.
Twój dodatek jest widoczny dla wszystkich
", "layerNotEnabled": "Warstwa {layer} nie jest włączona. Włącz tę warstwę, aby dodać punkt", @@ -120,7 +120,7 @@ "friday": "Piątek", "thursday": "Czwartek" }, - "aboutMapcomplete": "

O MapComplete

Dzięki MapComplete możesz wzbogacić OpenStreetMap o informacje na pojedynczy temat. Odpowiedz na kilka pytań, a w ciągu kilku minut Twój wkład będzie dostępny na całym świecie! Opiekun tematu definiuje elementy, pytania i języki dla tematu.

Dowiedz się więcej

MapComplete zawsze oferuje następny krok, by dowiedzieć się więcej o OpenStreetMap.


Zauważyłeś problem? Czy masz prośbę o dodanie jakiejś funkcji? Chcesz pomóc w tłumaczeniu? Udaj się do kodu źródłowego lub issue trackera.

Chcesz zobaczyć swoje postępy? Śledź liczbę edycji na OsmCha.

", + "aboutMapcomplete": "

O MapComplete

Dzięki MapComplete możesz wzbogacić OpenStreetMap o informacje na pojedynczy temat. Odpowiedz na kilka pytań, a w ciągu kilku minut Twój wkład będzie dostępny na całym świecie! Opiekun tematu definiuje elementy, pytania i języki dla tematu.

Dowiedz się więcej

MapComplete zawsze oferuje następny krok, by dowiedzieć się więcej o OpenStreetMap.


Zauważyłeś problem? Czy masz prośbę o dodanie jakiejś funkcji? Chcesz pomóc w tłumaczeniu? Udaj się do kodu źródłowego lub issue trackera.

Chcesz zobaczyć swoje postępy? Śledź liczbę edycji na OsmCha.

", "noNameCategory": "{category} bez nazwy", "nameInlineQuestion": "Nazwa tej {category} to $$$", "osmLinkTooltip": "Zobacz ten obiekt na OpenStreetMap, aby uzyskać historię i więcej opcji edycji", @@ -189,7 +189,7 @@ "friday": "Piątek", "thursday": "Czwartek" }, - "aboutMapcomplete": "

O MapComplete

Dzięki MapComplete możesz wzbogacić OpenStreetMap o informacje na pojedynczy temat. Odpowiedz na kilka pytań, a w ciągu kilku minut Twój wkład będzie dostępny na całym świecie! Opiekun motywu definiuje elementy, pytania i języki dla tematu.

Dowiedz się więcej

MapComplete zawsze oferuje następny krok, by dowiedzieć się więcej o OpenStreetMap.


Zauważyłeś problem? Czy masz prośbę o dodanie jakiejś funkcji? Chcesz pomóc w tłumaczeniu? Udaj się do kodu źródłowego lub issue trackera.

Chcesz zobaczyć swoje postępy? Śledź liczbę edycji na OsmCha.

.", + "aboutMapcomplete": "

O MapComplete

Dzięki MapComplete możesz wzbogacić OpenStreetMap o informacje na pojedynczy temat. Odpowiedz na kilka pytań, a w ciągu kilku minut Twój wkład będzie dostępny na całym świecie! Opiekun motywu definiuje elementy, pytania i języki dla tematu.

Dowiedz się więcej

MapComplete zawsze oferuje następny krok, by dowiedzieć się więcej o OpenStreetMap.


Zauważyłeś problem? Czy masz prośbę o dodanie jakiejś funkcji? Chcesz pomóc w tłumaczeniu? Udaj się do kodu źródłowego lub issue trackera.

Chcesz zobaczyć swoje postępy? Śledź liczbę edycji na OsmCha.

.", "noNameCategory": "{category} bez nazwy", "nameInlineQuestion": "Nazwa tej {category} to $$$", "osmLinkTooltip": "Zobacz ten obiekt na OpenStreetMap, aby uzyskać historię i więcej opcji edycji", @@ -244,7 +244,7 @@ "loadingData": "Ładowanie danych…", "ready": "Zrobione!", "zoomIn": "Przybliż żeby zobaczyć lub edytować", - "retrying": "Ładowanie danych nie powiodło się. Spróbujemy ponownie za {liczba} sekund…" + "retrying": "Ładowanie danych nie powiodło się. Spróbujemy ponownie za {count} sekund…" }, "reviews": { "plz_login": "Zaloguj się, aby zostawić opinię", diff --git a/langs/pt.json b/langs/pt.json index 56fd314a5..4445f80f0 100644 --- a/langs/pt.json +++ b/langs/pt.json @@ -73,7 +73,7 @@ "zoomInFurther": "Amplie mais para adicionar um ponto.", "openLayerControl": "Abra a caixa de controlo da camada", "disableFilters": "Desativar todos os filtros", - "addNew": "Adicionar uma nova {categoria} aqui", + "addNew": "Adicionar uma nova {category} aqui", "intro": "Clicou em algum lugar onde ainda não há dados conhecidos.
", "addNewMapLabel": "Adicionar novo item", "presetInfo": "O novo POI terá {tags}", @@ -90,8 +90,8 @@ }, "questions": { "websiteOf": "Qual é o site de {category}?", - "emailOf": "Qual é o endereço de e-mail de {categoria}?", - "emailIs": "O endereço de e-mail de {categoria} é {email}", + "emailOf": "Qual é o endereço de e-mail de {category}?", + "emailIs": "O endereço de e-mail de {category} é {email}", "websiteIs": "Site: {website}", "phoneNumberIs": "O número de telefone de {category} é {phone}", "phoneNumberOf": "Qual é o número de telefone de {category}?" @@ -184,7 +184,7 @@ "editThisTheme": "Editar este tema" }, "attribution": { - "themeBy": "Tema gerido por {autor}", + "themeBy": "Tema gerido por {author}", "iconAttribution": { "title": "Ícones usados" }, @@ -211,7 +211,7 @@ "streetcomplete": "Outra aplicação semelhante é o StreetComplete.", "createYourOwnTheme": "Crie o seu próprio tema MapComplete a partir do zero", "previouslyHiddenTitle": "Temas ocultos visitados anteriormente", - "hiddenExplanation": "Estes temas só são acessíveis a quem tem a hiperligação. Você descobriu {substituído} de {total_substituído} temas ocultos.", + "hiddenExplanation": "Estes temas só são acessíveis a quem tem a hiperligação. Você descobriu {hidden_discovered} de {total_hidden} temas ocultos.", "intro": "

Mais mapas temáticos?

Gosta de colecionar dados geográficos?
Tem mais temas disponíveis." }, "about": "Edite e adicione facilmente o OpenStreetMap para um determinado tema", diff --git a/langs/pt_BR.json b/langs/pt_BR.json index c6944abce..8a3169dc1 100644 --- a/langs/pt_BR.json +++ b/langs/pt_BR.json @@ -125,7 +125,7 @@ "intro": "

Compartilhe este mapa

Compartilhe este mapa copiando o link abaixo e enviando-o para amigos e familiares:", "embedIntro": "

Incorpore em seu site

Por favor, incorpore este mapa em seu site.
Nós o encorajamos a fazer isso - você nem precisa pedir permissão.
É gratuito e sempre será. Quanto mais pessoas usarem isso, mais valioso se tornará." }, - "aboutMapcomplete": "

Sobre o MapComplete

Com o MapComplete, você pode enriquecer o OpenStreetMap com informações sobre umúnico tema.Responda a algumas perguntas e, em minutos, suas contribuições estarão disponíveis em todo o mundo! Omantenedor do temadefine elementos, questões e linguagens para o tema.

Saiba mais

MapComplete sempreoferece a próxima etapapara saber mais sobre o OpenStreetMap.


Você percebeuum problema? Você tem umasolicitação de recurso ? Querajudar a traduzir? Acesse o código-fonteou rastreador de problemas.

Quer verseu progresso? Siga a contagem de edição emOsmCha.

" + "aboutMapcomplete": "

Sobre o MapComplete

Com o MapComplete, você pode enriquecer o OpenStreetMap com informações sobre umúnico tema.Responda a algumas perguntas e, em minutos, suas contribuições estarão disponíveis em todo o mundo! Omantenedor do temadefine elementos, questões e linguagens para o tema.

Saiba mais

MapComplete sempreoferece a próxima etapapara saber mais sobre o OpenStreetMap.


Você percebeuum problema? Você tem umasolicitação de recurso ? Querajudar a traduzir? Acesse o código-fonteou rastreador de problemas.

Quer verseu progresso? Siga a contagem de edição emOsmCha.

" }, "index": { "pickTheme": "Escolha um tema abaixo para começar.", diff --git a/langs/ru.json b/langs/ru.json index a6bb476c0..991135945 100644 --- a/langs/ru.json +++ b/langs/ru.json @@ -77,7 +77,7 @@ "zoomInToSeeThisLayer": "Увеличьте масштаб, чтобы увидеть этот слой" }, "backgroundMap": "Фоновая карта", - "aboutMapcomplete": "

О MapComplete

С помощью MapComplete вы можете обогатить OpenStreetMap информацией по одной теме. Ответьте на несколько вопросов, и через несколько минут ваши материалы будут доступны по всему миру! Сопровождающий темы определяет элементы, вопросы и языки для темы.

Узнайте больше

MapComplete всегда предлагает следующий шаг, чтобы узнать больше об OpenStreetMap.


Вы заметили проблему? У вас есть запрос на функциональность? Хотите помочь с переводом? Зайдите на репозиторий с исходным кодом или трекер проблем.

Хотите увидеть свой прогресс? Следите за количеством правок на OsmCha.

", + "aboutMapcomplete": "

О MapComplete

С помощью MapComplete вы можете обогатить OpenStreetMap информацией по одной теме. Ответьте на несколько вопросов, и через несколько минут ваши материалы будут доступны по всему миру! Сопровождающий темы определяет элементы, вопросы и языки для темы.

Узнайте больше

MapComplete всегда предлагает следующий шаг, чтобы узнать больше об OpenStreetMap.


Вы заметили проблему? У вас есть запрос на функциональность? Хотите помочь с переводом? Зайдите на репозиторий с исходным кодом или трекер проблем.

Хотите увидеть свой прогресс? Следите за количеством правок на OsmCha.

", "customThemeIntro": "

Пользовательские темы

Это ранее просмотренные темы, созданные пользователями.", "noTagsSelected": "Теги не выбраны", "getStartedNewAccount": " или создать новую учетную запись", diff --git a/langs/sv.json b/langs/sv.json index 5ec958390..e6d42adeb 100644 --- a/langs/sv.json +++ b/langs/sv.json @@ -6,7 +6,7 @@ "ph_not_known": " ", "open_24_7": "Öppet dygnet runt", "closed_permanently": "Stängt tills vidare", - "closed_until": "Stängt till", + "closed_until": "Stängt till {date}", "openTill": "till", "opensAt": "från", "open_during_ph": "Om det är en röd dag är det här stället", diff --git a/langs/themes/de.json b/langs/themes/de.json index 74c7d7896..b00308813 100644 --- a/langs/themes/de.json +++ b/langs/themes/de.json @@ -692,7 +692,7 @@ "then": "Diese Straße ist keine Fahrradstraße" } }, - "question": "Ist die Straße {Name} eine Fahrradstraße?" + "question": "Ist die Straße {name} eine Fahrradstraße?" }, "1": { "question": "Wann wird diese Straße eine Fahrradstraße?", diff --git a/langs/themes/it.json b/langs/themes/it.json index 20086eed6..3534e7343 100644 --- a/langs/themes/it.json +++ b/langs/themes/it.json @@ -645,7 +645,7 @@ "then": "Questa strada non è una strada ciclabile" } }, - "question": "È una strada ciclabile?" + "question": "È {name} una strada ciclabile?" }, "1": { "question": "Questa strada diventerà una strada ciclabile quando?", diff --git a/langs/themes/ja.json b/langs/themes/ja.json index d2f6b71ba..3af65c887 100644 --- a/langs/themes/ja.json +++ b/langs/themes/ja.json @@ -518,8 +518,7 @@ "3": { "then": "この通りはcyclestreetではない" } - }, - "question": "この通りはcyclestreetですか?" + } }, "1": { "question": "この通りはいつcyclestreetになるんですか?", diff --git a/langs/themes/nb_NO.json b/langs/themes/nb_NO.json index 98b454ce6..da448944f 100644 --- a/langs/themes/nb_NO.json +++ b/langs/themes/nb_NO.json @@ -198,8 +198,7 @@ "3": { "then": "Denne gaten er ikke en sykkelvei" } - }, - "question": "Er denne gaten en sykkelvei?" + } } } }, diff --git a/langs/themes/pt_BR.json b/langs/themes/pt_BR.json index 6c7de8bfd..37227204d 100644 --- a/langs/themes/pt_BR.json +++ b/langs/themes/pt_BR.json @@ -159,7 +159,7 @@ "then": "Estação de despejo" } }, - "render": "Estação de despejo {nome}" + "render": "Estação de despejo {name}" } } }, diff --git a/langs/zh_Hant.json b/langs/zh_Hant.json index ce3b891db..0e9fcf4bb 100644 --- a/langs/zh_Hant.json +++ b/langs/zh_Hant.json @@ -89,7 +89,7 @@ "zoomInToSeeThisLayer": "放大來看這個圖層" }, "backgroundMap": "背景地圖", - "aboutMapcomplete": "

關於 MapComplete

使用 MapComplete 你可以藉由單一主題豐富開放街圖的圖資。回答幾個問題,然後幾分鐘之內你的貢獻立刻就傳遍全球!主題維護者定議主題的元素、問題與語言。

發現更多

MapComplete 總是提供學習更多開放街圖下一步的知識


你有注意到問題嗎?你想請求功能嗎?想要幫忙翻譯嗎?來到原始碼或是問題追蹤器。

想要看到你的進度嗎?到OsmCha追蹤編輯數。

", + "aboutMapcomplete": "

關於 MapComplete

使用 MapComplete 你可以藉由單一主題豐富開放街圖的圖資。回答幾個問題,然後幾分鐘之內你的貢獻立刻就傳遍全球!主題維護者定議主題的元素、問題與語言。

發現更多

MapComplete 總是提供學習更多開放街圖下一步的知識


你有注意到問題嗎?你想請求功能嗎?想要幫忙翻譯嗎?來到原始碼或是問題追蹤器。

想要看到你的進度嗎?到OsmCha追蹤編輯數。

", "customThemeIntro": "

客製化主題

觀看這些先前使用者創造的主題。", "noTagsSelected": "沒有選取標籤", "getStartedNewAccount": " 或是 註冊新帳號", diff --git a/scripts/generateTranslations.ts b/scripts/generateTranslations.ts index eccbfd3ce..997b3fd2c 100644 --- a/scripts/generateTranslations.ts +++ b/scripts/generateTranslations.ts @@ -9,6 +9,11 @@ class TranslationPart { contents: Map = new Map() + /** + * Add a leaf object + * @param language + * @param obj + */ add(language: string, obj: any) { for (const key in obj) { const v = obj[key] @@ -135,6 +140,94 @@ class TranslationPart { } return `{${parts.join(",")}}`; } + + /** + * Recursively adds a translation object, the inverse of 'toJson' + * @param language + * @param object + * @private + */ + private addTranslation(language: string, object: any){ + for (const key in object) { + const v = object[key] + let subpart = this.contents.get(key) + if(subpart === undefined){ + subpart = new TranslationPart() + this.contents.set(key, subpart) + } + if(typeof v === "string"){ + subpart.contents.set(language, v) + }else{ + subpart.addTranslation(language, v) + } + } + + } + + static fromDirectory(path): TranslationPart{ + const files = ScriptUtils.readDirRecSync(path, 1).filter(file => file.endsWith(".json")) + const rootTranslation = new TranslationPart() + for (const file of files) { + const content = JSON.parse(readFileSync(file, "UTF8")) + rootTranslation.addTranslation(file.substr(0, file.length - ".json".length), content) + } + return rootTranslation + } + + validateStrict(ctx?:string): void { + const errors = this.validate() + for (const err of errors) { + console.error("ERROR in "+(ctx ?? "")+ " " +err.path.join(".")+"\n "+err.error) + } + if(errors.length > 0){ + throw ctx+" has "+errors.length+" inconsistencies in the translation" + } + } + + /** + * Checks the leaf objects: special values must be present and identical in every leaf + */ + validate(path = []): {error: string, path: string[]} [] { + const errors : {error: string, path: string[]} []= [] + const neededSubparts = new Set() + let isLeaf : boolean = undefined + this.contents.forEach((value, key) => { + if(typeof value === "string"){ + if(isLeaf === undefined){ + isLeaf = true + }else if(!isLeaf){ + errors.push({error:"Mixed node: non-leaf node has translation strings", path: path}) + } + + let subparts: string[] = value.match(/{[^}]*}/g) + if(subparts === null){ + if(neededSubparts.size > 0){ + errors.push({error:"The translation for "+key+" does not have any subparts, but expected "+Array.from(neededSubparts).join(",")+" . The full translation is "+value, path: path}) + } + return + } + + subparts = subparts.map(p => p.split(/\(.*\)/)[0]) + + neededSubparts.forEach(part => { + if(subparts.indexOf(part) < 0){ + errors.push({error:"The translation for "+key+" does not have the required subpart "+part+". The full translation is "+value, path: path}) + } + }) + + for (const subpart of subparts) { + neededSubparts.add(subpart) + } + + }else{ + const recErrors = value.validate([...path, key]) + errors.push(...recErrors) + } + }) + + return errors + } + } /** @@ -181,6 +274,9 @@ function transformTranslation(obj: any, depth = 1) { } +/** + * Formats the specified file, helps to prevent merge conflicts + * */ function formatFile(path) { const contents = JSON.parse(readFileSync(path, "utf8")) writeFileSync(path, JSON.stringify(contents, null, " ")) @@ -210,7 +306,10 @@ function compileTranslationsFromWeblate() { .filter(path => path.indexOf(".json") > 0) const allTranslations = new TranslationPart() - + + allTranslations.validateStrict() + + for (const translationFile of translations) { try { @@ -417,4 +516,10 @@ if (!themeOverwritesWeblate) { compileTranslationsFromWeblate(); } genTranslations() -formatFile("./langs/en.json") \ No newline at end of file +formatFile("./langs/en.json") + +// SOme validation +TranslationPart.fromDirectory("./langs").validateStrict("./langs") +TranslationPart.fromDirectory("./langs/layers").validateStrict("layers") +TranslationPart.fromDirectory("./langs/themes").validateStrict("themes") +TranslationPart.fromDirectory("./langs/shared-questions").validateStrict("shared-questions")