The gap sentence is one key, so a translator can move its clauses
charts.vue's hero read as six fragments concatenated around three counts and a bdi island: "of", "languages have", "— the languages of", "people." Arabic does not put those clauses in that order, so translating the fragments would have given Arabic words in English order — grammatically broken, and worse than leaving it English, because it looks translated and nobody re-checks it. Now one message with named placeholders through useSentence. The counts and the quoted phrase go in as VALUES, so the bold and the dir="ltr" survive without a translator ever reproducing markup, and keep() hands the placeholders back to t() intact — without it the lookup blanks them and the sentence renders with no values at all. Proven through a real createI18n rather than in isolation, which is the lesson from the keep() trap: en renders as it does today, and ar and ru both LEAD with the object and put the counts after — the reordering that fragment-by-fragment translation cannot express. zh reorders too. The gate moves 144 -> 142 for this one sentence. That is the honest number: six fragments collapse into one key, but the gate counts findings, not fragments, so the count falls more slowly than the work proceeds. ~26 fragments remain.
This commit is contained in:
parent
d9fb0a137b
commit
c7aa670426
12 changed files with 58 additions and 14 deletions
|
|
@ -333,7 +333,9 @@
|
|||
"c2Unit": "أشخاص في الشعوب التي هذه لغتها الأساسية — لا المتحدثين بها عمومًا",
|
||||
"c3Title": "البلدان الأكثر لغاتٍ غير مخدومة",
|
||||
"c3Sub": "البلدان الـ{n} الأكثر لغاتٍ لم يُعثر لها على شيء. طول العمود هو كل لغة موجودة في ذلك البلد.",
|
||||
"c3Unit": "لغات موجودة في البلد (اللغة العابرة للحدود تُحتسب في كل بلد)"
|
||||
"c3Unit": "لغات موجودة في البلد (اللغة العابرة للحدود تُحتسب في كل بلد)",
|
||||
"noneHero": "{noScripture} في {nNone} لغة من أصل {nLang} — وهي لغات {popNone} نسمة.",
|
||||
"noneHeroFound": "لا يوجد كتاب مقدس ولا فيلم في المجموعات التي جرى فحصها"
|
||||
},
|
||||
"filter": {
|
||||
"showingOnly": "يُعرض فقط: {what}.",
|
||||
|
|
|
|||
|
|
@ -333,7 +333,9 @@
|
|||
"c2Unit": "Menschen in den Volksgruppen, deren PRIMÄRE Sprache dies ist — nicht Sprecher der Sprache",
|
||||
"c3Title": "Länder mit den meisten unversorgten Sprachen",
|
||||
"c3Sub": "Die {n} Länder mit den meisten Sprachen, für die nichts gefunden wurde. Die Balkenlänge ist jede im Land vorhandene Sprache.",
|
||||
"c3Unit": "im Land vorhandene Sprachen (eine grenzüberschreitende Sprache zählt in jedem Land)"
|
||||
"c3Unit": "im Land vorhandene Sprachen (eine grenzüberschreitende Sprache zählt in jedem Land)",
|
||||
"noneHero": "{nNone} von {nLang} Sprachen haben {noScripture} — die Sprachen von {popNone} Menschen.",
|
||||
"noneHeroFound": "keine Bibel und keinen Film in den geprüften Beständen"
|
||||
},
|
||||
"filter": {
|
||||
"showingOnly": "Nur {what} werden angezeigt.",
|
||||
|
|
|
|||
|
|
@ -333,7 +333,9 @@
|
|||
"c2Unit": "people in the people groups whose PRIMARY language this is — not speakers of the language",
|
||||
"c3Title": "Countries with the most unserved languages",
|
||||
"c3Sub": "The {n} countries with the most languages that have nothing found. Bar length is every language present in that country.",
|
||||
"c3Unit": "languages present in the country (a cross-border language counts in each)"
|
||||
"c3Unit": "languages present in the country (a cross-border language counts in each)",
|
||||
"noneHero": "{nNone} of {nLang} languages have {noScripture} — the languages of {popNone} people.",
|
||||
"noneHeroFound": "no scripture and no film found in the pools checked"
|
||||
},
|
||||
"filter": {
|
||||
"showingOnly": "Showing only {what}.",
|
||||
|
|
|
|||
|
|
@ -333,7 +333,9 @@
|
|||
"c2Unit": "personas en las etnias cuya lengua PRINCIPAL es esta — no hablantes de la lengua",
|
||||
"c3Title": "Países con más lenguas desatendidas",
|
||||
"c3Sub": "Los {n} países con más lenguas sin nada encontrado. La longitud de la barra es cada lengua presente en ese país.",
|
||||
"c3Unit": "lenguas presentes en el país (una lengua transfronteriza cuenta en cada uno)"
|
||||
"c3Unit": "lenguas presentes en el país (una lengua transfronteriza cuenta en cada uno)",
|
||||
"noneHero": "{nNone} de {nLang} lenguas tienen {noScripture}: las lenguas de {popNone} personas.",
|
||||
"noneHeroFound": "ni Escritura ni película en los repositorios consultados"
|
||||
},
|
||||
"filter": {
|
||||
"showingOnly": "Solo se muestran {what}.",
|
||||
|
|
|
|||
|
|
@ -333,7 +333,9 @@
|
|||
"c2Unit": "personnes dans les peuples dont c'est la langue PRINCIPALE — non les locuteurs de la langue",
|
||||
"c3Title": "Pays comptant le plus de langues non desservies",
|
||||
"c3Sub": "Les {n} pays comptant le plus de langues sans rien de trouvé. La longueur de la barre correspond à chaque langue présente dans ce pays.",
|
||||
"c3Unit": "langues présentes dans le pays (une langue transfrontalière compte dans chacun)"
|
||||
"c3Unit": "langues présentes dans le pays (une langue transfrontalière compte dans chacun)",
|
||||
"noneHero": "{nNone} langues sur {nLang} ont {noScripture} — les langues de {popNone} personnes.",
|
||||
"noneHeroFound": "ni Écriture ni film dans les fonds consultés"
|
||||
},
|
||||
"filter": {
|
||||
"showingOnly": "Affichage limité aux {what}.",
|
||||
|
|
|
|||
|
|
@ -333,7 +333,9 @@
|
|||
"c2Unit": "उन जनसमूहों के लोग जिनकी मुख्य भाषा यही है — भाषा के सभी वक्ता नहीं",
|
||||
"c3Title": "सबसे अधिक असेवित भाषाओं वाले देश",
|
||||
"c3Sub": "{n} देश जिनमें सबसे अधिक भाषाओं के लिए कुछ नहीं मिला। बार की लंबाई उस देश में मौजूद हर भाषा है।",
|
||||
"c3Unit": "देश में मौजूद भाषाएँ (सीमा-पार भाषा हर देश में गिनी जाती है)"
|
||||
"c3Unit": "देश में मौजूद भाषाएँ (सीमा-पार भाषा हर देश में गिनी जाती है)",
|
||||
"noneHero": "{nLang} में से {nNone} भाषाओं में {noScripture} — ये {popNone} लोगों की भाषाएँ हैं।",
|
||||
"noneHeroFound": "जाँचे गए स्रोतों में न पवित्रशास्त्र मिला, न फ़िल्म"
|
||||
},
|
||||
"filter": {
|
||||
"showingOnly": "केवल {what} दिखाए जा रहे हैं।",
|
||||
|
|
|
|||
|
|
@ -333,7 +333,9 @@
|
|||
"c2Unit": "persone nei gruppi la cui lingua PRINCIPALE è questa — non i parlanti della lingua",
|
||||
"c3Title": "Paesi con più lingue non servite",
|
||||
"c3Sub": "I {n} paesi con più lingue per cui non è stato trovato nulla. La lunghezza della barra è ogni lingua presente in quel paese.",
|
||||
"c3Unit": "lingue presenti nel paese (una lingua transfrontaliera conta in ciascuno)"
|
||||
"c3Unit": "lingue presenti nel paese (una lingua transfrontaliera conta in ciascuno)",
|
||||
"noneHero": "{nNone} lingue su {nLang} hanno {noScripture} — le lingue di {popNone} persone.",
|
||||
"noneHeroFound": "nessuna Scrittura e nessun film nei repertori consultati"
|
||||
},
|
||||
"filter": {
|
||||
"showingOnly": "Sono mostrati solo {what}.",
|
||||
|
|
|
|||
|
|
@ -333,7 +333,9 @@
|
|||
"c2Unit": "pessoas nas etnias cuja língua PRINCIPAL é esta — não falantes da língua",
|
||||
"c3Title": "Países com mais línguas desatendidas",
|
||||
"c3Sub": "Os {n} países com mais línguas sem nada encontrado. O comprimento da barra é cada língua presente nesse país.",
|
||||
"c3Unit": "línguas presentes no país (uma língua transfronteiriça conta em cada um)"
|
||||
"c3Unit": "línguas presentes no país (uma língua transfronteiriça conta em cada um)",
|
||||
"noneHero": "{nNone} de {nLang} línguas têm {noScripture} — as línguas de {popNone} pessoas.",
|
||||
"noneHeroFound": "nenhuma Escritura e nenhum filme nos acervos consultados"
|
||||
},
|
||||
"filter": {
|
||||
"showingOnly": "Mostrando apenas {what}.",
|
||||
|
|
|
|||
|
|
@ -333,7 +333,9 @@
|
|||
"c2Unit": "persoane din grupurile a căror limbă PRINCIPALĂ este aceasta — nu vorbitorii limbii",
|
||||
"c3Title": "Țări cu cele mai multe limbi neservite",
|
||||
"c3Sub": "Cele {n} țări cu cele mai multe limbi pentru care nu s-a găsit nimic. Lungimea barei este fiecare limbă prezentă în acea țară.",
|
||||
"c3Unit": "limbi prezente în țară (o limbă transfrontalieră se numără în fiecare)"
|
||||
"c3Unit": "limbi prezente în țară (o limbă transfrontalieră se numără în fiecare)",
|
||||
"noneHero": "{nNone} din {nLang} limbi au {noScripture} — limbile a {popNone} de oameni.",
|
||||
"noneHeroFound": "nicio Scriptură și niciun film în colecțiile verificate"
|
||||
},
|
||||
"filter": {
|
||||
"showingOnly": "Se afișează doar {what}.",
|
||||
|
|
|
|||
|
|
@ -333,7 +333,9 @@
|
|||
"c2Unit": "люди в народах, для которых это ОСНОВНОЙ язык, — не все говорящие на нём",
|
||||
"c3Title": "Страны с наибольшим числом неохваченных языков",
|
||||
"c3Sub": "{n} стран с наибольшим числом языков, для которых ничего не найдено. Длина столбца — каждый язык, присутствующий в этой стране.",
|
||||
"c3Unit": "языки, присутствующие в стране (трансграничный язык считается в каждой)"
|
||||
"c3Unit": "языки, присутствующие в стране (трансграничный язык считается в каждой)",
|
||||
"noneHero": "{noScripture} — у {nNone} из {nLang} языков, языков {popNone} человек.",
|
||||
"noneHeroFound": "ни Писания, ни фильма в проверенных источниках"
|
||||
},
|
||||
"filter": {
|
||||
"showingOnly": "Показаны только {what}.",
|
||||
|
|
|
|||
|
|
@ -333,7 +333,9 @@
|
|||
"c2Unit": "以该语言为主要语言的族群人口 — 不是该语言的全部使用者",
|
||||
"c3Title": "未得服事语言最多的国家",
|
||||
"c3Sub": "一无所获语言最多的 {n} 个国家。条形长度为该国存在的全部语言。",
|
||||
"c3Unit": "该国存在的语言(跨境语言在每个国家各计一次)"
|
||||
"c3Unit": "该国存在的语言(跨境语言在每个国家各计一次)",
|
||||
"noneHero": "{nLang} 种语言中有 {nNone} 种{noScripture}——这是 {popNone} 人的语言。",
|
||||
"noneHeroFound": "在已查询的资源库中既无圣经也无影片"
|
||||
},
|
||||
"filter": {
|
||||
"showingOnly": "仅显示{what}。",
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@
|
|||
* inlining it into the IIFE would block first paint for every profile in the bundle).
|
||||
*/
|
||||
import { useOptionalT } from '@map/composables/useOptionalT.js'
|
||||
import { sentenceParts, strong, ltr, keep } from '@map/composables/useSentence.js'
|
||||
import { h } from 'vue'
|
||||
import { computed, inject, ref, watch } from 'vue'
|
||||
import BarChart from '@map/components/charts/BarChart.vue'
|
||||
import { useShadowStyles } from '@map/composables/useShadowStyles.js'
|
||||
|
|
@ -67,6 +69,22 @@ import { useShadowStyles } from '@map/composables/useShadowStyles.js'
|
|||
// with English as the last resort. tStatic resolves 'gospel.<key>' against the same catalogue.
|
||||
const tr = useOptionalT('gospel')
|
||||
|
||||
// ★ THE HERO SENTENCE, ONE KEY. Each COUNT arrives already formatted and already pluralised from its
|
||||
// own key: vue-i18n resolves one plural form per key, so a sentence carrying three counts cannot
|
||||
// pluralise them from its own message. keep() hands the placeholders back to t() intact — without it
|
||||
// the lookup BLANKS them and the sentence renders with no values at all, in every locale at once.
|
||||
const heroSentence = computed(() => {
|
||||
const msg = tr('gospel.charts.noneHero', keep('nNone', 'nLang', 'noScripture', 'popNone'))
|
||||
return h('span', sentenceParts(msg, {
|
||||
nNone: strong(fmt(nNone.value)),
|
||||
nLang: fmt(nLang.value),
|
||||
// The phrase is quoted from English sources and must not reverse inside an Arabic sentence, so it
|
||||
// keeps its own dir. Passed in as a VALUE: a translator never has to reproduce the markup.
|
||||
noScripture: ltr(tr('gospel.charts.noneHeroFound', 'no scripture and no film found in the pools checked'), true),
|
||||
popNone: strong(fmt(popNone.value)),
|
||||
}))
|
||||
})
|
||||
|
||||
|
||||
const profileConfig = inject('profileConfig', ref(null))
|
||||
const isDark = computed(() => profileConfig.value?.isDark === true)
|
||||
|
|
@ -465,9 +483,13 @@ useShadowStyles(
|
|||
group that speaks it — so the language is the unit of the gap.
|
||||
</p>
|
||||
|
||||
<div v-if="nLang" class="gc-hero">
|
||||
<b>{{ fmt(nNone) }}</b> of {{ fmt(nLang) }} languages have <b><bdi dir="ltr">no scripture and no film
|
||||
found in the pools checked</bdi></b> — the languages of <b>{{ fmt(popNone) }}</b> people.
|
||||
<!-- ONE KEY, NAMED SLOTS. This was six fragments concatenated around three counts and a bdi
|
||||
island ("of", "languages have", "the languages of", "people."). Arabic does not put those
|
||||
clauses in that order, so translating the fragments gives Arabic words in English order:
|
||||
grammatically broken, and worse than leaving it English because it looks translated. The
|
||||
sentence is now ONE message whose named placeholders a translator can reorder freely, with
|
||||
the bold counts and the ltr island passed in as values rather than written into the catalogue. -->
|
||||
<div v-if="nLang" class="gc-hero"><component :is="heroSentence" />
|
||||
<template v-if="noCodeGroups">
|
||||
<br><small><bdi dir="ltr">Counted BY LANGUAGE, so {{ fmt(noCodeGroups) }} people group{{ noCodeGroups === 1 ? '' : 's' }}
|
||||
with no ISO 639-3 code in the source — {{ fmt(noCodePeople) }} people — cannot appear here.
|
||||
|
|
|
|||
Loading…
Reference in a new issue