🐛 fix(vscode): 逻辑与、或译成「并且」「或者」
This commit is contained in:
1 parent
da632a1540
commit
5d2355748b
5 files changed
+20
-12
No files matched your search
@@ -77,7 +77,7 @@ export interface CodeBlock {
|
|||||||
export type TokenRole =
|
export type TokenRole =
|
||||||
| 'keyword' // 流程关键字:import from export if else for return try catch await …
|
| 'keyword' // 流程关键字:import from export if else for return try catch await …
|
||||||
| 'storage' // 声明关键字与字面量关键字:const function async class interface new true false null …
|
| 'storage' // 声明关键字与字面量关键字:const function async class interface new true false null …
|
||||||
| 'operator' // 被翻成文字的运算符:全等 与 或 非
|
| 'operator' // 被翻成文字的运算符:全等 并且 或者 非
|
||||||
| 'variable' | 'function' | 'type' | 'string' | 'number' | 'literal' | 'comment' | 'plain'
|
| 'variable' | 'function' | 'type' | 'string' | 'number' | 'literal' | 'comment' | 'plain'
|
||||||
|
|
||||||
export interface Segment { text: string, role: TokenRole }
|
export interface Segment { text: string, role: TokenRole }
|
||||||
@@ -157,7 +157,7 @@ export interface CodeReaderApi {
|
|||||||
|
|
||||||
1. 关键字:只认语法树里的关键字节点(匿名节点),所以属性名 `i.number`、对象键不会被误翻。
|
1. 关键字:只认语法树里的关键字节点(匿名节点),所以属性名 `i.number`、对象键不会被误翻。
|
||||||
2. 内置类型:只在类型位置翻(TS 的 `predefined_type`、Python 注解里的内置类型名)。
|
2. 内置类型:只在类型位置翻(TS 的 `predefined_type`、Python 注解里的内置类型名)。
|
||||||
3. 运算符:`===` 全等、`!==` 不全等、`==` 等于、`!=` 不等于、`&&` 与、`||` 或、`!` 非(Python 的 `not` / `and` / `or` 本身是关键字)。
|
3. 运算符:`===` 全等、`!==` 不全等、`==` 等于、`!=` 不等于、`&&` 并且、`||` 或者、`!` 非(Python 的 `not` / `and` / `or` 本身是关键字)。
|
||||||
|
|
||||||
其他规则:空数组字面量 → 空数组(Python 空列表 → 空列表、空字典 → 空字典);复合语句头部去掉结尾的 `{` 或 `:`;多行合成一行(连续空白压成一个空格,右括号前的尾逗号去掉);注释去掉注释符号,原文照搬。关键字与前后内容之间保留源码里的空格(`!` 翻成「非」后补一个空格)。
|
其他规则:空数组字面量 → 空数组(Python 空列表 → 空列表、空字典 → 空字典);复合语句头部去掉结尾的 `{` 或 `:`;多行合成一行(连续空白压成一个空格,右括号前的尾逗号去掉);注释去掉注释符号,原文照搬。关键字与前后内容之间保留源码里的空格(`!` 翻成「非」后补一个空格)。
|
||||||
|
|
||||||
@@ -178,7 +178,7 @@ TypeScript 关键字表(流程 = keyword,声明 = storage):
|
|||||||
|
|
||||||
TypeScript 内置类型:string 字符串、number 数值、boolean 布尔、any 任意、unknown 未知、never 永不、void 无、object 对象、bigint 大整数、symbol 符号。`Promise` 等库类型不翻。
|
TypeScript 内置类型:string 字符串、number 数值、boolean 布尔、any 任意、unknown 未知、never 永不、void 无、object 对象、bigint 大整数、symbol 符号。`Promise` 等库类型不翻。
|
||||||
|
|
||||||
Python 关键字:import 导入、from(导入)从 / (`raise … from`)源自 / (`yield from`)自、as(导入别名、`with … as`、`except … as`)作为、def 函数、async 异步、await 等待、class 类、return 返回、if 如果、elif 否则如果、else(`if` 后)否则 / (`for` / `while` 后,循环没被 break 才执行)未中断时 / (`try` 后,没出错才执行)未出错时、for 遍历、in(比较里)在 / (for 头部与推导式里)取自、while 当、try 尝试、except 捕获、finally 最终、raise 抛出、with 使用、yield 产出、lambda 匿名函数、pass 跳过、break 跳出、continue 继续、global 全局、nonlocal 非局部、del 删除、assert 断言、not 非、and 与、or 或、is 是、not in 不在、is not 不是、None 空、True 真、False 假、match 匹配、case 情况。
|
Python 关键字:import 导入、from(导入)从 / (`raise … from`)源自 / (`yield from`)自、as(导入别名、`with … as`、`except … as`)作为、def 函数、async 异步、await 等待、class 类、return 返回、if 如果、elif 否则如果、else(`if` 后)否则 / (`for` / `while` 后,循环没被 break 才执行)未中断时 / (`try` 后,没出错才执行)未出错时、for 遍历、in(比较里)在 / (for 头部与推导式里)取自、while 当、try 尝试、except 捕获、finally 最终、raise 抛出、with 使用、yield 产出、lambda 匿名函数、pass 跳过、break 跳出、continue 继续、global 全局、nonlocal 非局部、del 删除、assert 断言、not 非、and 并且、or 或者、is 是、not in 不在、is not 不是、None 空、True 真、False 假、match 匹配、case 情况。
|
||||||
|
|
||||||
Python 内置类型(仅注解里):str 字符串、int 整数、float 浮点数、bool 布尔、list 列表、dict 字典、set 集合、tuple 元组、bytes 字节串。
|
Python 内置类型(仅注解里):str 字符串、int 整数、float 浮点数、bool 布尔、list 列表、dict 字典、set 集合、tuple 元组、bytes 字节串。
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export interface CodeBlock {
|
|||||||
export type TokenRole
|
export type TokenRole
|
||||||
= | 'keyword' // 流程关键字:import from export if else for return try catch await …
|
= | 'keyword' // 流程关键字:import from export if else for return try catch await …
|
||||||
| 'storage' // 声明关键字与字面量关键字:const function async class interface new true false null …
|
| 'storage' // 声明关键字与字面量关键字:const function async class interface new true false null …
|
||||||
| 'operator' // 被翻成文字的运算符:全等 与 或 非
|
| 'operator' // 被翻成文字的运算符:全等 并且 或者 非
|
||||||
| 'variable' | 'function' | 'type' | 'string' | 'number' | 'literal' | 'comment' | 'plain'
|
| 'variable' | 'function' | 'type' | 'string' | 'number' | 'literal' | 'comment' | 'plain'
|
||||||
|
|
||||||
export interface Segment { text: string, role: TokenRole }
|
export interface Segment { text: string, role: TokenRole }
|
||||||
|
|||||||
@@ -56,8 +56,8 @@ export const pythonZhTranslator: Translator = createZhTemplateTranslator({
|
|||||||
'del': '删除',
|
'del': '删除',
|
||||||
'assert': '断言',
|
'assert': '断言',
|
||||||
'not': '非',
|
'not': '非',
|
||||||
'and': '与',
|
'and': '并且',
|
||||||
'or': '或',
|
'or': '或者',
|
||||||
'is': '是',
|
'is': '是',
|
||||||
'not in': '不在',
|
'not in': '不在',
|
||||||
'is not': '不是',
|
'is not': '不是',
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ export const typescriptZhTranslator: Translator = createZhTemplateTranslator({
|
|||||||
symbol: '符号',
|
symbol: '符号',
|
||||||
},
|
},
|
||||||
isTypePosition: leaf => leaf.parent?.type === 'predefined_type',
|
isTypePosition: leaf => leaf.parent?.type === 'predefined_type',
|
||||||
operators: { '===': '全等', '!==': '不全等', '==': '等于', '!=': '不等于', '&&': '与', '||': '或', '!': '非' },
|
operators: { '===': '全等', '!==': '不全等', '==': '等于', '!=': '不等于', '&&': '并且', '||': '或者', '!': '非' },
|
||||||
operatorParents: ['binary_expression', 'unary_expression'],
|
operatorParents: ['binary_expression', 'unary_expression'],
|
||||||
emptyLiterals: { array: '空数组' },
|
emptyLiterals: { array: '空数组' },
|
||||||
stringNodes: ['string', 'template_string', 'regex'],
|
stringNodes: ['string', 'template_string', 'regex'],
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ describe('typeScript 中文直译', () => {
|
|||||||
expect(issue[1]).toBe('导入 类型 { Issue } 来自 \'../gitea/types\'')
|
expect(issue[1]).toBe('导入 类型 { Issue } 来自 \'../gitea/types\'')
|
||||||
expect(issue[5]).toBe('prerequisiteNumber?: 数值')
|
expect(issue[5]).toBe('prerequisiteNumber?: 数值')
|
||||||
expect(issue[9]).toBe('纯判定:工单被未完成的前置挡住才算锁定。快照里找不到工单或前置一律放行, 与 webview 的 `isIssueLocked` 保持同一语义。')
|
expect(issue[9]).toBe('纯判定:工单被未完成的前置挡住才算锁定。快照里找不到工单或前置一律放行, 与 webview 的 `isIssueLocked` 保持同一语义。')
|
||||||
expect(issue[15]).toBe('如果 (非 issue 或 issue.prerequisite 全等 未定义)')
|
expect(issue[15]).toBe('如果 (非 issue 或者 issue.prerequisite 全等 未定义)')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('每个被翻的词单独成段,着色取语法树词性', async () => {
|
it('每个被翻的词单独成段,着色取语法树词性', async () => {
|
||||||
@@ -112,11 +112,15 @@ describe('typeScript 中文直译', () => {
|
|||||||
].join('\n')
|
].join('\n')
|
||||||
const map = texts(await translateAll(ts, 'typescript', typescriptZhTranslator, source))
|
const map = texts(await translateAll(ts, 'typescript', typescriptZhTranslator, source))
|
||||||
expect(map[1]).toBe('常量 o = { if: 1, return: i.number, string: x!.type, new: a.default }')
|
expect(map[1]).toBe('常量 o = { if: 1, return: i.number, string: x!.type, new: a.default }')
|
||||||
expect(map[2]).toBe('变量 n = a 不全等 b 与 非 c 或 d 等于 e 不等于 f')
|
expect(map[2]).toBe('变量 n = a 不全等 b 并且 非 c 或者 d 等于 e 不等于 f')
|
||||||
// eslint-disable-next-line no-template-curly-in-string -- 模板字符串原样照抄进译文
|
// eslint-disable-next-line no-template-curly-in-string -- 模板字符串原样照抄进译文
|
||||||
expect(map[3]).toBe('常量 s: 字符串 | 无 = 如果 类型为 v 全等 \'string\' 则 `${v}` 否则 \'number\'')
|
expect(map[3]).toBe('常量 s: 字符串 | 无 = 如果 类型为 v 全等 \'string\' 则 `${v}` 否则 \'number\'')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('逻辑与、或译成「并且」「或者」', async () => {
|
||||||
|
expect(texts(await translateAll(ts, 'typescript', typescriptZhTranslator, 'a && b || c'))).toEqual({ 1: 'a 并且 b 或者 c' })
|
||||||
|
})
|
||||||
|
|
||||||
it('多行合成一行、去掉右括号前的尾逗号、行中注释不进译文', async () => {
|
it('多行合成一行、去掉右括号前的尾逗号、行中注释不进译文', async () => {
|
||||||
const source = [
|
const source = [
|
||||||
'call(',
|
'call(',
|
||||||
@@ -172,7 +176,7 @@ describe('typeScript 中文直译', () => {
|
|||||||
1: '如果 err 属于 Error 则 err.message 否则 String(err)',
|
1: '如果 err 属于 Error 则 err.message 否则 String(err)',
|
||||||
2: 'z = 如果 x 则 (如果 y 则 1 否则 2) 否则 3',
|
2: 'z = 如果 x 则 (如果 y 则 1 否则 2) 否则 3',
|
||||||
3: '常量 w = 如果 a 则 b 否则 如果 c 则 d 否则 e',
|
3: '常量 w = 如果 a 则 b 否则 如果 c 则 d 否则 e',
|
||||||
4: '常量 v = 如果 a 不全等 b 与 非 c 则 类型为 d 否则 等待 e',
|
4: '常量 v = 如果 a 不全等 b 并且 非 c 则 类型为 d 否则 等待 e',
|
||||||
})
|
})
|
||||||
expect(map.get(1)?.segments.filter(segment => segment.role === 'keyword')).toEqual([
|
expect(map.get(1)?.segments.filter(segment => segment.role === 'keyword')).toEqual([
|
||||||
{ text: '如果', role: 'keyword' },
|
{ text: '如果', role: 'keyword' },
|
||||||
@@ -195,7 +199,7 @@ describe('python 中文直译', () => {
|
|||||||
10: '函数 find_env_files(root: 字符串) -> 列表[字符串]',
|
10: '函数 find_env_files(root: 字符串) -> 列表[字符串]',
|
||||||
11: 'Return every .env file under root.',
|
11: 'Return every .env file under root.',
|
||||||
12: '跳过备份文件',
|
12: '跳过备份文件',
|
||||||
13: 'found = [p 遍历 p 取自 os.listdir(root) 如果 p.startswith(\'.env\') 与 非 p.endswith(\'.bak\')]',
|
13: 'found = [p 遍历 p 取自 os.listdir(root) 如果 p.startswith(\'.env\') 并且 非 p.endswith(\'.bak\')]',
|
||||||
14: '如果 非 found',
|
14: '如果 非 found',
|
||||||
15: '返回 空列表',
|
15: '返回 空列表',
|
||||||
16: '否则如果 len(found) > MAX_DEPTH',
|
16: '否则如果 len(found) > MAX_DEPTH',
|
||||||
@@ -234,6 +238,10 @@ describe('python 中文直译', () => {
|
|||||||
expect(map[2]).toBe('返回 [str(k) 遍历 k 取自 items 如果 k 不在 list]')
|
expect(map[2]).toBe('返回 [str(k) 遍历 k 取自 items 如果 k 不在 list]')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('逻辑与、或译成「并且」「或者」', async () => {
|
||||||
|
expect(texts(await translateAll(py, 'python', pythonZhTranslator, 'a and b or c'))).toEqual({ 1: 'a 并且 b 或者 c' })
|
||||||
|
})
|
||||||
|
|
||||||
it('from:导入里「从」,raise … from 里「源自」,yield from 里「自」', async () => {
|
it('from:导入里「从」,raise … from 里「源自」,yield from 里「自」', async () => {
|
||||||
const source = [
|
const source = [
|
||||||
'from typing import Annotated',
|
'from typing import Annotated',
|
||||||
@@ -286,7 +294,7 @@ describe('python 中文直译', () => {
|
|||||||
1: '_default_port = 如果 _role 等于 "beat" 则 5680 否则 5679',
|
1: '_default_port = 如果 _role 等于 "beat" 则 5680 否则 5679',
|
||||||
2: 'y = 如果 x 则 a 否则 如果 y 则 b 否则 c',
|
2: 'y = 如果 x 则 a 否则 如果 y 则 b 否则 c',
|
||||||
3: 'z = 如果 y 则 (如果 x 则 a 否则 b) 否则 c',
|
3: 'z = 如果 y 则 (如果 x 则 a 否则 b) 否则 c',
|
||||||
4: 'v = 如果 非 done 与 ok 则 [k 遍历 k 取自 items 如果 k 不在 seen] 否则 空',
|
4: 'v = 如果 非 done 并且 ok 则 [k 遍历 k 取自 items 如果 k 不在 seen] 否则 空',
|
||||||
})
|
})
|
||||||
expect(map.get(1)?.segments.filter(segment => segment.role === 'keyword' || segment.role === 'operator')).toEqual([
|
expect(map.get(1)?.segments.filter(segment => segment.role === 'keyword' || segment.role === 'operator')).toEqual([
|
||||||
{ text: '如果', role: 'keyword' },
|
{ text: '如果', role: 'keyword' },
|
||||||
|
|||||||
Reference in new issue
Block a user