Skip to content

Commit 7868276

Browse files
docs-botCopilot
andauthored
fix(translations): add new Liquid corruption correction patterns (#61297)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent ab95125 commit 7868276

2 files changed

Lines changed: 117 additions & 0 deletions

File tree

src/languages/lib/correct-translation-content.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,18 @@ export function correctTranslatedContentStrings(
205205
'{%$1 %}',
206206
)
207207

208+
// `{% de escritorio %}` — Spanish "de escritorio" = desktop (platform tab)
209+
content = content.replaceAll('{% de escritorio %}', '{% desktop %}')
210+
content = content.replaceAll('{%- de escritorio %}', '{%- desktop %}')
211+
212+
// `{% variablesdatos.producto.` — translator fused "variables" + "datos" (data)
213+
// without the `data` keyword and used "producto" (product) instead of "variables.product".
214+
// e.g. `{% variablesdatos.producto.prodname_dotcom %}` → `{% data variables.product.prodname_dotcom %}`
215+
content = content.replace(
216+
/\{%(-?)\s*variablesdatos\.producto\.([A-Za-z0-9._-]+)(\s*-?%\})/g,
217+
'{%$1 data variables.product.$2$3',
218+
)
219+
208220
// [SCRAPE-6548] Per-file fix for the Spanish reusable
209221
// `data/reusables/dependency-graph/deduplication.md`. The translation
210222
// dropped the `{% endif %}` after the Dependabot graph jobs item (the
@@ -771,6 +783,12 @@ export function correctTranslatedContentStrings(
771783
// already opened on the previous line. Drop the inner duplicate so the
772784
// outer endif balances correctly.
773785
content = content.replaceAll('> * {% ifversion ghes %} 本文包含', '> * 本文包含')
786+
787+
// `{% 捕获IDENTIFIER %}` — Chinese "捕获" = "to capture" = capture.
788+
// Translator translated the tag name but kept the variable name in English.
789+
// Pattern: `{% 捕获IDENTIFIER %}` (no space) or `{% 捕获 IDENTIFIER %}` (with space)
790+
// → `{% capture IDENTIFIER %}`
791+
content = content.replace(/\{%(-?)\s*\s*(\w+)\s*(-?)%\}/g, '{%$1 capture $2 $3%}')
774792
}
775793

776794
if (context.code === 'ru') {
@@ -900,6 +918,23 @@ export function correctTranslatedContentStrings(
900918
content = content.replaceAll('{%- эндкёрл %}', '{%- endcurl %}')
901919
content = content.replaceAll('{% запроса %}', '{% endraw %}')
902920
content = content.replaceAll('{%- запроса %}', '{%- endraw %}')
921+
// `{% API %}` — uppercase API used as platform/tool tab tag (correct: lowercase `{% api %}`)
922+
content = content.replaceAll('{% API %}', '{% api %}')
923+
content = content.replaceAll('{%- API %}', '{%- api %}')
924+
925+
// `{% захватить VARNAME %}` — "захватить" = "to capture" = capture
926+
// The translator translated the tag name but kept the variable name in English.
927+
// Pattern: `{% захватить IDENTIFIER %}` → `{% capture IDENTIFIER %}`
928+
content = content.replace(/\{%(-?)\s*захватить\s+(\w+)\s*(-?)%\}/g, '{%$1 capture $2 $3%}')
929+
930+
// Comma-separated plan names in ifversion/elsif/if tags:
931+
// `{% ifversion fpt, ghec %}` — translator used comma instead of `or` between plans.
932+
// Only safe to fix when the comma appears between recognised plan-name tokens.
933+
content = content.replace(
934+
/\{%(-?\s+(?:ifversion|elsif|if)\s+[^%]*?),\s*((?:fpt|ghec|ghes|ghae|ghecom)[^%]*?-?%\})/g,
935+
'{%$1 or $2',
936+
)
937+
903938
// `{% джетмозги %}` — Russian literal translation of "JetBrains" (джет=jet, мозги=brains)
904939
content = content.replaceAll('{% джетмозги %}', '{% jetbrains %}')
905940
content = content.replaceAll('{%- джетмозги %}', '{%- jetbrains %}')
@@ -1059,6 +1094,15 @@ export function correctTranslatedContentStrings(
10591094
'Вы можете увидеть, кто внес{% endif %} коммиты в репозиторий{% ifversion fpt or ghec %} и его зависимости.',
10601095
'Вы можете увидеть, кто внес коммиты в репозиторий{% ifversion fpt or ghec %} и его зависимости{% endif %}.',
10611096
)
1097+
1098+
// data/reusables/enterprise-licensing/unique-user-licensing-model.md:
1099+
// The translator garbled `{% ifversion enterprise-licensing-language %}licenses{% else %}licensed seats{% endif %}`
1100+
// into `{% ifversion enterprise-licensing-language %}license-language%else %}licenses{% license seats{% endif %}`.
1101+
// Restore the correct conditional.
1102+
content = content.replaceAll(
1103+
'{% ifversion enterprise-licensing-language %}license-language%else %}licenses{% license seats{% endif %}',
1104+
'{% ifversion enterprise-licensing-language %}licenses{% else %}licensed seats{% endif %}',
1105+
)
10621106
}
10631107

10641108
if (context.code === 'fr') {
@@ -1343,6 +1387,11 @@ export function correctTranslatedContentStrings(
13431387
content = content.replaceAll('{% Variable.', '{% data variables.')
13441388
content = content.replaceAll('{%- Variable.', '{%- data variables.')
13451389

1390+
// `{% 캡처 IDENTIFIER %}` — Korean "캡처" = "capture".
1391+
// Translator translated the tag name but kept the variable name in English.
1392+
// Pattern: `{% 캡처 IDENTIFIER %}` → `{% capture IDENTIFIER %}`
1393+
content = content.replace(/\{%(-?)\s*\s+(\w+)\s*(-?)%\}/g, '{%$1 capture $2 $3%}')
1394+
13461395
// [SCRAPE-6548] Per-file fix:
13471396
// account-and-profile/concepts/username-changes.md (intro): orphan
13481397
// `{% endif %}` and `{% ifversion ghes %}` swapped — the conditional

src/languages/tests/correct-translation-content.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,23 @@ describe('correctTranslatedContentStrings', () => {
161161
expect(fix('{% siVersion productos-ghas %}', 'es')).toBe('{% ifversion productos-ghas %}')
162162
expect(fix('{%- siVersion productos-ghas %}', 'es')).toBe('{%- ifversion productos-ghas %}')
163163
})
164+
165+
test('fixes {% de escritorio %} → {% desktop %} (platform tab)', () => {
166+
expect(fix('{% de escritorio %}', 'es')).toBe('{% desktop %}')
167+
expect(fix('{%- de escritorio %}', 'es')).toBe('{%- desktop %}')
168+
})
169+
170+
test('fixes fused {% variablesdatos.producto.X %} → {% data variables.product.X %}', () => {
171+
expect(fix('{% variablesdatos.producto.prodname_dotcom %}', 'es')).toBe(
172+
'{% data variables.product.prodname_dotcom %}',
173+
)
174+
expect(fix('{%- variablesdatos.producto.github %}', 'es')).toBe(
175+
'{%- data variables.product.github %}',
176+
)
177+
expect(fix('{%variablesdatos.producto.github%}', 'es')).toBe(
178+
'{% data variables.product.github%}',
179+
)
180+
})
164181
})
165182

166183
// ─── JAPANESE (ja) ──────────────────────────────────────────────────
@@ -535,6 +552,16 @@ describe('correctTranslatedContentStrings', () => {
535552
'{%- data variables.product.github %}',
536553
)
537554
})
555+
556+
test('fixes {% 捕获 X %} → {% capture X %} (translated capture tag)', () => {
557+
// With space between 捕获 and identifier
558+
expect(fix('{% 捕获 myvar %}', 'zh')).toBe('{% capture myvar %}')
559+
// Without space
560+
expect(fix('{% 捕获myvar %}', 'zh')).toBe('{% capture myvar %}')
561+
// Whitespace-stripping forms
562+
expect(fix('{%- 捕获 myvar -%}', 'zh')).toBe('{%- capture myvar -%}')
563+
expect(fix('{%- 捕获myvar %}', 'zh')).toBe('{%- capture myvar %}')
564+
})
538565
})
539566

540567
// ─── RUSSIAN (ru) ──────────────────────────────────────────────────
@@ -758,6 +785,42 @@ describe('correctTranslatedContentStrings', () => {
758785
expect(fix('{% джетмозги %}', 'ru')).toBe('{% jetbrains %}')
759786
expect(fix('{%- джетмозги %}', 'ru')).toBe('{%- jetbrains %}')
760787
})
788+
789+
test('fixes uppercase {% API %} → {% api %} (platform tab)', () => {
790+
expect(fix('{% API %}', 'ru')).toBe('{% api %}')
791+
expect(fix('{%- API %}', 'ru')).toBe('{%- api %}')
792+
})
793+
794+
test('fixes {% захватить X %} → {% capture X %} (translated capture tag)', () => {
795+
expect(fix('{% захватить myvar %}', 'ru')).toBe('{% capture myvar %}')
796+
expect(fix('{%- захватить myvar -%}', 'ru')).toBe('{%- capture myvar -%}')
797+
})
798+
799+
test('fixes comma between plan names in ifversion/elsif/if to `or`', () => {
800+
expect(fix('{% ifversion fpt, ghec %}', 'ru')).toBe('{% ifversion fpt or ghec %}')
801+
expect(fix('{% elsif fpt, ghec %}', 'ru')).toBe('{% elsif fpt or ghec %}')
802+
expect(fix('{%- ifversion ghes, ghec %}', 'ru')).toBe('{%- ifversion ghes or ghec %}')
803+
})
804+
805+
test('fixAt: enterprise-licensing-language reusable garbled conditional', () => {
806+
function fixAt(content: string, code: string, relativePath: string) {
807+
return correctTranslatedContentStrings(content, '', {
808+
code,
809+
relativePath,
810+
skipOrphanStripping: true,
811+
})
812+
}
813+
const broken =
814+
'{% ifversion enterprise-licensing-language %}license-language%else %}licenses{% license seats{% endif %}'
815+
const out = fixAt(
816+
broken,
817+
'ru',
818+
'data/reusables/enterprise-licensing/unique-user-licensing-model.md',
819+
)
820+
expect(out).toBe(
821+
'{% ifversion enterprise-licensing-language %}licenses{% else %}licensed seats{% endif %}',
822+
)
823+
})
761824
})
762825

763826
// ─── FRENCH (fr) ───────────────────────────────────────────────────
@@ -1016,6 +1079,11 @@ describe('correctTranslatedContentStrings', () => {
10161079
'{%- data variables.product.github %}',
10171080
)
10181081
})
1082+
1083+
test('fixes {% 캡처 X %} → {% capture X %} (translated capture tag)', () => {
1084+
expect(fix('{% 캡처 myvar %}', 'ko')).toBe('{% capture myvar %}')
1085+
expect(fix('{%- 캡처 myvar -%}', 'ko')).toBe('{%- capture myvar -%}')
1086+
})
10191087
})
10201088

10211089
// ─── GERMAN (de) ──────────────────────────────────────────────────

0 commit comments

Comments
 (0)