@@ -31,6 +31,11 @@ const LANGUAGE_CONFIG = {
3131 folder : 'es' ,
3232 name : 'Español' ,
3333 pathPrefix : '/es'
34+ } ,
35+ 'pt-BR' : {
36+ folder : 'pt-BR' ,
37+ name : 'Português (Brasil)' ,
38+ pathPrefix : '/pt-br'
3439 }
3540} ;
3641
@@ -62,7 +67,7 @@ const PRESERVE_TERMS = {
6267} ;
6368
6469// 术语表:强制把英文术语译成指定目标语言短语(优先从 .github/scripts/glossary.json 读取;不存在则使用内置空表)
65- let GLOSSARY = { "zh-CN" : { } , "ja" : { } , "es" : { } } ;
70+ let GLOSSARY = { "zh-CN" : { } , "ja" : { } , "es" : { } , "pt-BR" : { } } ;
6671( async ( ) => {
6772 try {
6873 const gPath = path . join ( __dirname , 'glossary.json' ) ;
@@ -523,7 +528,7 @@ ${glossaryPairs}
523528 ' 输出;不得混用其它自然语言。若发生混用,改译为目标语言。\n' ;
524529 prompt = prompt . replace ( '<translation_rules>' , '<translation_rules>\n' + LANGUAGE_GUARD ) ;
525530
526- // === 按目标语言替换 <example> 为本地化示例(仅 es / ja 覆盖;默认保留中文示例) ===
531+ // === 按目标语言替换 <example> 为本地化示例(仅 es / ja / pt-BR 覆盖;默认保留中文示例) ===
527532 function getLocalizedExampleBlock ( lang ) {
528533 if ( lang === 'es' ) {
529534 return (
@@ -609,6 +614,50 @@ Salida incorrecta (prohibido):
609614[LINE_10] <TabItem value='Install through host'> ❌ label がない場合、value は翻訳する必要がある
610615[LINE_11] [イントロ](#/Sensor/Guide/ハードウェア概要) ❌ 「#」より前の URL 構造を変更しない
611616[LINE_12] <a href="https://wiki.seeedstudio.com/Sensor/ABC/#入门指南">Open</a> ❌ 中国語混在
617+ </example>`
618+ ) ;
619+ }
620+
621+ if ( lang === 'pt-BR' ) {
622+ return (
623+ `<example>
624+ Entrada:
625+ [LINE_0] ## Getting Started
626+ [LINE_1][EMPTY_LINE]
627+ [LINE_2] This is a tutorial about:
628+ [LINE_3] - First item
629+ [LINE_4] - [BLE Scanner](#ble-scanner)
630+ [LINE_5] - Nested item
631+ [LINE_6] <strong><span><font color={'FFFFFF'} size={"4"}> Get One Now 🖱️</font></span></strong>
632+ [LINE_7] Click "Settings" in the app (File > Preferences).
633+ [LINE_8] <a className="nav-item"><span className="text">Developer Center</span></a>
634+ [LINE_9] <TabItem value="For E1002" label="For E1002">
635+ [LINE_10] <TabItem value='Install through host'>
636+ [LINE_11] See more: [Intro](/Sensor/Guide/#hardware-overview)
637+ [LINE_12] <a href="https://wiki.seeedstudio.com/Sensor/ABC/#getting-started">Open</a>
638+
639+ Saída correta:
640+ [LINE_0] ## Introdução
641+ [LINE_1][EMPTY_LINE]
642+ [LINE_2] Este é um tutorial sobre:
643+ [LINE_3] - Primeiro item
644+ [LINE_4] - [Scanner BLE](#BLE-Scanner)
645+ [LINE_5] - Item aninhado
646+ [LINE_6] <strong><span><font color={'FFFFFF'} size={"4"}> Adquira agora 🖱️</font></span></strong>
647+ [LINE_7] Clique em "Settings" no aplicativo (File > Preferences).
648+ [LINE_8] <a className="nav-item"><span className="text">Central do Desenvolvedor</span></a>
649+ [LINE_9] <TabItem value="For E1002" label="Para E1002">
650+ [LINE_10] <TabItem value='Instalar pelo host'>
651+ [LINE_11] Veja mais: [Introdução](/Sensor/Guide/#visão-geral-do-hardware)
652+ [LINE_12] <a href="https://wiki.seeedstudio.com/Sensor/ABC/#Primeiros-passos">Open</a>
653+
654+ Saída incorreta (proibido):
655+ [LINE_3] - Primeiro item ❌ Recuo perdido
656+ [LINE_4] - [Scanner BLE](#BLE Scanner) ❌ Espaço no fragmento
657+ [LINE_9] <TabItem value="Para E1002" label="Para E1002"> ❌ Com label, não alterar value
658+ [LINE_10] <TabItem value='Install through host'> ❌ Sem label, value deve ser traduzido
659+ [LINE_11] [Introdução](#/Sensor/Guide/visão-geral-do-hardware) ❌ Não alterar nada antes de "#"
660+ [LINE_12] <a href="https://wiki.seeedstudio.com/Sensor/ABC/#入门指南">Open</a> ❌ Não misturar chinês
612661</example>`
613662 ) ;
614663 }
@@ -856,7 +905,8 @@ function generateCategoryPrompt(targetLang, pathPrefix) {
856905 const langFilePrefix =
857906 targetLang === 'zh-CN' ? 'cn_' :
858907 targetLang === 'ja' ? 'ja_' :
859- targetLang === 'es' ? 'es_' : '' ;
908+ targetLang === 'es' ? 'es_' :
909+ targetLang === 'pt-BR' ? 'pt_' : '' ;
860910
861911 return `你是一个专业的技术文档翻译专家。请将以下 _category_.yml 文件从英文翻译成${ langName } 。
862912
@@ -944,7 +994,7 @@ function processInternalLinks(content, targetLang) {
944994
945995 // 处理各种链接格式
946996 content = content . replace (
947- / h t t p s : \/ \/ w i k i \. s e e e d s t u d i o \. c o m \/ ( (? ! z h - C N | j a | e s | c n ) [ ^ # \s " ' ) ] * ) / gi,
997+ / h t t p s : \/ \/ w i k i \. s e e e d s t u d i o \. c o m \/ ( (? ! z h - C N | j a | e s | p t - B R | c n | p t - b r ) [ ^ # \s " ' ) ] * ) / gi,
948998 ( match , path ) => {
949999 const cleanPath = path . startsWith ( '/' ) ? path . slice ( 1 ) : path ;
9501000 return `https://wiki.seeedstudio.com${ pathPrefix } /${ cleanPath } ` ;
@@ -954,7 +1004,7 @@ function processInternalLinks(content, targetLang) {
9541004 content = content . replace (
9551005 / < a \s + ( [ ^ > ] * \s + ) ? h r e f = " ( \/ [ ^ " ] * ) " ( [ ^ > ] * ) > / gi,
9561006 ( match , beforeAttrs , url , afterAttrs ) => {
957- if ( url . startsWith ( 'http' ) || url . match ( / ^ \/ ( z h - C N | j a | e s | c n ) \/ / ) ) {
1007+ if ( url . startsWith ( 'http' ) || url . match ( / ^ \/ ( z h - C N | j a | e s | p t - B R | c n | p t - b r ) \/ / ) ) {
9581008 return match ;
9591009 }
9601010 const newUrl = pathPrefix + url ;
@@ -967,7 +1017,7 @@ function processInternalLinks(content, targetLang) {
9671017 content = content . replace (
9681018 / \[ ( [ ^ \] ] * ) \] \( ( \/ [ ^ ) ] * ) \) / gi,
9691019 ( match , text , url ) => {
970- if ( url . startsWith ( 'http' ) || url . match ( / ^ \/ ( z h - C N | j a | e s | c n ) \/ / ) ) {
1020+ if ( url . startsWith ( 'http' ) || url . match ( / ^ \/ ( z h - C N | j a | e s | p t - B R | c n | p t - b r ) \/ / ) ) {
9711021 return match ;
9721022 }
9731023 const newUrl = pathPrefix + url ;
@@ -1115,7 +1165,8 @@ function generateTargetPath(originalPath, targetLang) {
11151165
11161166 const langPrefix = targetLang === 'zh-CN' ? 'cn_' :
11171167 targetLang === 'ja' ? 'ja_' :
1118- targetLang === 'es' ? 'es_' : '' ;
1168+ targetLang === 'es' ? 'es_' :
1169+ targetLang === 'pt-BR' ? 'pt_' : '' ;
11191170
11201171 const newFileName = langPrefix + parsedPath . name + parsedPath . ext ;
11211172 const newRelativePath = path . join ( parsedPath . dir , newFileName ) ;
0 commit comments