Bilibili-Evolved/utils/i18n/i18n.md
2019-05-23 19:45:01 +08:00

7.0 KiB
Raw Blame History

翻译指南

翻译程序能够将特定的文本替换成您的翻译, 作用范围为网页中所有文本节点(nodeType === Node.TEXT_NODE), 文本框的提示文字(placeholder), 以及鼠标停留时弹出的提示文字(title).

文件目录

  • i18n.css 界面元素调整样式
  • i18n.js 主程序
  • i18n.ts 主程序(TypeScript)
  • i18n.ja-JP.js 日语翻译
  • i18n.en-US.js 英语翻译
  • i18n.de-DE.js 德语翻译
  • i18n.md 本说明文档

即翻译文本均存放在i18n.[ISO语言代码].js中.

添加翻译文本

  1. 用代码编辑器打开相应的翻译文件, 以英语为例, 则打开i18n.en-US.js.
  2. 文件结构大致为:
export const map = new Map([
    /* Your translation here */
    [`*`, [
        /* CSS translation here */
    ]],
]);
export const regex = new Map([
    /* Regex translation here */
]);
export default {
    export: { map, regex },
};
  1. /* Your translation here */上方添加翻译, 或在/* CSS translation here */上方添加选择器翻译, 在/* Regex translation here */上方添加正则翻译, 详细语法见下一节.

翻译语法

有多种翻译方式可供选择.

直接翻译

格式为[`原文本`,`翻译后文本`],.

例如, 将主站翻译为Home, 则添加:

[`主站`, `Home`],

添加后的文件大致如下:

export const map = new Map([
    /* 其他翻译... */
    [`主站`, `Home`],
]);
export default {
    export: { map },
};

特殊翻译

可以为特定元素的文本特别指定一种翻译, 通常用于特殊语境下词语的翻译, 但是需要翻译者对CSS选择器语法有一定了解.

格式为:

[`原文本`, {
    selector: `CSS选择器`,
    text: `翻译后文本`,
}],

例如:

[`主站`, {
    selector: `.xxx.yyy`,
    text: `Home2`,
}],

将在文本所属节点匹配.xxx.yyy选择器时, 将主站翻译为Home2.

按照上面的例子, 以下的元素

<a class="xxx yyy">主站</a>
<a class="zzz">主站</a>

将翻译为

<a class="xxx yyy">Home2</a>
<a class="zzz">主站</a>

如果希望不匹配选择器的文本接受翻译, 只需添加一行not,:

[`主站`, {
    not,
    selector: `.xxx.yyy`,
    text: `Home2`,
}],

这样, 所有不匹配这个选择器的文本都将被翻译.

混合翻译

可以组合以上两种翻译方式, 为同一词语使用多种翻译.

格式为:

[`原文本`, [
    `直接翻译`,
    {
        selector: `CSS选择器1`,
        text: `特殊翻译1`,
    },
    {
        selector: `CSS选择器2`,
        text: `特殊翻译2`,
    },
]],

即存放翻译文本的地方改成一个数组[], 其中存放多种翻译, 用逗号,隔开每一项.

  • 直接翻译只能有一个, 而特殊翻译可以有多个.
  • 越在后面的特殊翻译优先级越高, 如果一个元素同时满足两种翻译里的选择器, 程序会使用较后面出现的翻译.
  • 程序其实不会检查直接翻译到底有几个, 要是真的有多个, 只有最后一个出现的直接翻译被采用.

例如以下混合翻译:

[`主站`, [
    `Home`,
    {
        text: `Home2`,
        selector: `.xxx.yyy`
    },
]]

能够将

<a class="xxx yyy">主站</a>
<a class="zzz">主站</a>

翻译为

<a class="xxx yyy">Home2</a>
<a class="zzz">Home</a>

使用选择器翻译

当原文本很长或很复杂时, 放在翻译文件里会影响易读性, 这时可以用CSS选择器选择该节点进行翻译. 这种翻译统一放在原文本为*的一节翻译中.

⚠ 这种翻译方式不管原文本是什么, 只要匹配了选择器就执行翻译.

格式为:

[`*`, [
    {
        selector: `CSS选择器1`,
        text: `翻译文本1`,
    },
    {
        selector: `CSS选择器2`,
        text: `翻译文本2`,
    },
]],

例如以下选择器翻译:

[`*`, [
    {
        selector: `.xxx.yyy`,
        text: `Home3`,
    },
]]

能够将

<a class="xxx yyy">very very long text very very long text very very long text very very long text very very long text</a>

翻译为

<a class="xxx yyy">Home3</a>

使用正则翻译

当原文本包含一段不确定内容时, 可以使用正则翻译来匹配, 需要翻译者对正则表达式有一定了解. 这种翻译放在这一区域: (export const regex)

export const regex = new Map([
    /* Regex translation here */
]);

例如, 要将浏览23.3w翻译为Read: 23.3w, 则添加:

[/浏览:([0-9\.a-z])/, `Read: $1`],

第一个元素是正则表达式, 用一对斜杠(/)包围, 语法可在MDN文档中学习. 第二个元素是替换文本. 在这个例子中, $1指代原文本中的浏览量数字, 利用了正则表达式的分组功能, 详见文档中的"使用括号的子字符串匹配"一节.

调整界面元素

一些界面元素的尺寸是固定大小, 如果添加翻译后, 无法适应翻译后的文本长度, 可以在i18n.css中添加CSS样式来调整.

示例翻译文件

此文件简单展示了一下每一种翻译方式. 其中所有的CSS选择器和翻译文本仅作示例使用, 并不代表实际情况.

export const map = new Map([
    [`主站`, `Home`], // 直接翻译
    [`大会员`, { // 特殊翻译, 只有匹配.aaa的元素会被翻译
        selector: `.aaa`,
        text: `VIP`,
    }],
    [`关注`, [ // 混合翻译:
        `Follow`, // 直接翻译, 适用于"关注"的动词形式
        { // 特殊翻译, 适用于"关注"的名词形式
            selector: `.bbb`,
            text: `Following`,
        },
    ]],
    /* Your translation here */
    [`*`, [ // 选择器翻译
        { // 选择匹配.xxx的元素, 翻译为XXX
            selector: `.xxx`,
            text: `XXX`,
        },
        { // 选择匹配.xxx的元素, 翻译为YYY
            selector: `.yyy`,
            text: `YYY`,
        },
        /* CSS translation here */
    ]],
]);
export const regex = new Map([
    [/(\d+)次播放/, `Played $1 times`],
    /* Regex translation here */
]);
export default {
    export: { map, regex },
};

该文件能够将类似以下的网页内容

<a class="home1">主站</a>
<a class="home2">主站</a>
<a class="aaa">大会员</a>
<a class="aaaa">大会员</a>
<a class="bbb">关注</a>
<a class="ccc">关注</a>
<a class="xxx">其他</a>
<a class="yyy">其他</a>
<a class="zzz">其他</a>
<a>233次播放</a>

翻译为

<a class="home1">Home</a>
<a class="home2">Home</a>
<a class="aaa">VIP</a>
<a class="aaaa">大会员</a>
<a class="bbb">Following</a>
<a class="ccc">Follow</a>
<a class="xxx">XXX</a>
<a class="yyy">YYY</a>
<a>Played 233 times</a>