This is an automated email from the ASF dual-hosted git repository.

morningman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris-website.git


The following commit(s) were added to refs/heads/master by this push:
     new 54237d9b6ae [fix](i18n) Distinguish process identifiers from English 
be (#4364)
54237d9b6ae is described below

commit 54237d9b6ae5f6f2bed49f0a660cd3d61b4b95ce
Author: Mingyu Chen (Rayner) <[email protected]>
AuthorDate: Sun Oct 18 22:12:12 2026 +0100

    [fix](i18n) Distinguish process identifiers from English be (#4364)
    
    Whole-document glossary validation matched terms case-insensitively, so
    ordinary English “be” and “Be” incorrectly required the Doris backend
    identifier “BE”. In the real manual Korean batch, retries responded by
    inserting backend references absent from both English community sources.
    The generated candidate was rejected before merge. Lowercase target
    prose could also incorrectly satisfy an actual uppercase process
    identifier.
    
    Match FE/BE process identifiers case-sensitively while preserving
    existing Latin boundaries and other glossary matching. A regression
    proves that a faithful Korean translation of a normal “can be” sentence
    completes in one request without inventing BE. Another verifies that
    real FE/BE remain required with their uppercase spelling, including next
    to Japanese text.
    
    Validation: both new regressions failed before the fix. Afterward, the
    complete i18n/PoC/publish test command passed (209 passed, zero
    failures, one existing Apache test skipped), and git diff checks passed.
    This changes no rendered content, locale routing, translation state,
    workflow triggers, permissions, or credentials. Korean generation
    remains manual-only; the real bounded batch will be regenerated from
    merged master for acceptance.
    
    Co-authored-by: morningman <[email protected]>
---
 scripts/i18n/__tests__/translate-document.test.cjs | 27 ++++++++++++++++++++++
 scripts/i18n/document-checks.cjs                   |  6 +++--
 2 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/scripts/i18n/__tests__/translate-document.test.cjs 
b/scripts/i18n/__tests__/translate-document.test.cjs
index c37ac6159d0..1f587626062 100644
--- a/scripts/i18n/__tests__/translate-document.test.cjs
+++ b/scripts/i18n/__tests__/translate-document.test.cjs
@@ -92,6 +92,33 @@ test('Latin word matching permits BEFORE and prose number 
localization; code sta
     assert(wrongNumber.issues.some(item => item.check === 'protected-content' 
&& /numeric values/.test(item.message)));
 });
 
+test('ordinary English be does not request a backend term or a translation 
retry', async () => {
+    let requests = 0;
+    const result = await translateWholeDocument({...options,
+        source: '# Guide\n\nBe aware that the email subject can be 
anything.\n',
+        targetLocale: 'ko', targetScriptPattern: '[가-힣]',
+        adapter: {translateDocument: async ({feedback}) => {
+            requests++;
+            assert.deepEqual(feedback, []);
+            return {translation: '# 안내\n\n이메일 제목은 아무 내용이나 입력해도 됩니다.\n'};
+        }}});
+    assert.equal(requests, 1);
+    assert.deepEqual(result.generation.warnings, []);
+    assert(!result.target.includes('BE'));
+});
+
+test('actual FE and BE identifiers must retain their uppercase spelling', 
async () => {
+    const input = {...options, source: '# Guide\n\nRestart FE and BE.\n',
+        glossary: {...glossary, keep: ['FE', 'BE']}};
+    const valid = await inspectDocument({...input, translation: '# 
ガイド\n\nFEとBEを再起動します。\n'});
+    assert.deepEqual(valid.issues, []);
+    for (const term of ['FE', 'BE']) {
+        const invalid = await inspectDocument({...input,
+            translation: '# ガイド\n\n' + ['FE', 'BE'].map(item => item === term 
? item.toLowerCase() : item).join('と') + 'を再起動します。\n'});
+        assert(invalid.issues.some(issue => issue.check === 'glossary' && 
issue.message === `Preserve product term: ${term}`));
+    }
+});
+
 test('whole-document MDX accepts existing explicit heading IDs', async () => {
     const source = '# Guide {#guide}\n\n<Widget label="Details" mode={1} />\n';
     const result = await translateWholeDocument({...options, source, 
extension: '.mdx',
diff --git a/scripts/i18n/document-checks.cjs b/scripts/i18n/document-checks.cjs
index 249a4a748bf..4a3f56900f7 100644
--- a/scripts/i18n/document-checks.cjs
+++ b/scripts/i18n/document-checks.cjs
@@ -118,8 +118,10 @@ async function inspectDocument({source, translation, 
extension, glossary, target
             throw new Error(`Translate the complete document into 
${targetLocale}`);
     });
     // Word boundaries apply to Latin identifiers, including those next to
-    // Japanese text. BEFORE must never count as the product term BE.
-    const contains = (text, term) => new 
RegExp(`(?<![A-Za-z0-9_])${term.replace(/[.*+?^${}()|[\]\\]/g, 
'\\$&')}(?![A-Za-z0-9_])`, 'i').test(text);
+    // Japanese text. FE/BE process names are case-sensitive: ordinary English
+    // "be" and "Be" must not force a backend reference into a translation.
+    const contains = (text, term) => new 
RegExp(`(?<![A-Za-z0-9_])${term.replace(/[.*+?^${}()|[\]\\]/g, 
'\\$&')}(?![A-Za-z0-9_])`,
+        ['FE', 'BE'].includes(term) ? '' : 'i').test(text);
     for (const term of glossary.keep) {
         if (contains(source, term) && !contains(target, term))
             issues.push({check: 'glossary', message: `Preserve product term: 
${term}`});


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to