dom*_*kun 9 javascript localization gettext ecmascript-6 template-strings
我必须解决gettext识别ES6模板字符串的限制,并且我考虑将模板字符串的"非插值"作为编译步骤,以便在代码中只有"普通"字符串.
基本上我想要实现的是改变这一点
const adjective = 'wonderful'
const something = `Look, I am a ${adjective} string`
console.log(something)
> "Look, I am a wonderful string"
Run Code Online (Sandbox Code Playgroud)
进入这个
const adjective = 'wonderful'
const something = 'Look, I am a ${adjective} string'
console.log(something)
> "Look, I am a ${adjective} string"
Run Code Online (Sandbox Code Playgroud)
实现这一目标的一个残酷方法是使用sed,但它肯定不是更优雅(也可能是容易出错)
sed "s/\`/'/g" FILENAME
Run Code Online (Sandbox Code Playgroud)
想到任何更好,更清洁的想法?
小智 8
好问题.有四种解决方案可供考虑:
只要您了解风险,在扫描可翻译字符串之前,使用引号标记强制替换反引号,如您所知,并不是一个可怕的想法.例如,考虑:
"hello, this word is in `backticks`"
Run Code Online (Sandbox Code Playgroud)
另一个边缘案例是
`${`I am nested`}`
Run Code Online (Sandbox Code Playgroud)
这种方法也会破坏多行模板字符串.
xgettext当然,"正确"的解决方案是编写一个xgettext处理模板字符串的分支.然后你就可以写了
const something = _(`Look, I am a ${adjective} string`);
Run Code Online (Sandbox Code Playgroud)
不幸的是,这看起来可能更难.xgettext中有一堆与字符串相关的硬连线逻辑.如果你要承担这个项目,很多人会感谢你.
更强大的替代方法是使用诸如Esprima之类的JavaScript解析器.这些解析器提供了获取令牌的能力(例如模板字符串).正如您在http://esprima.org/demo/parse.html中看到的,要查找的相关令牌类型是TemplateLiteral.
另一个(糟糕的?)想法是将模板字符串编写为常规字符串,然后在运行时将它们视为模板字符串.我们定义一个函数eval_template:
const template = _("Look, I am a ${adjective} string");
const something = eval_template(template, {adjective});
Run Code Online (Sandbox Code Playgroud)
eval_template将字符串转换为评估模板.模板字符串中使用的局部作用域中的任何变量都需要eval_template作为第二个参数中传递的对象的一部分提供(因为使用的函数Function在全局作用域中并且不能访问局部变量,因此我们必须将它们传入).它实现如下:
function eval_template_(s, params) {
var keys = Object.keys(params);
var vals = keys.map(key => params[key]);
var f = Function(...keys, "return `" + s + "`");
return f(...vals);
}
Run Code Online (Sandbox Code Playgroud)
当然,这有点尴尬.这种方法的唯一优点是它不需要预扫描重写.
小点,但如果原始模板字符串是多行的,则不能直接将其重写为常规字符串.在这种情况下,你可以把它作为一个反向勾选的模板字符串,但逃避$as \$,一切都会很好:
结论:除非您想要重写xgettext,使用解析器或参与其他hackery,否则请进行强力替换.
| 归档时间: |
|
| 查看次数: |
1428 次 |
| 最近记录: |