玩一玩 Flutter 翻译项目, 用来学英语
需求
需要学一学 flutter 的东西, 发现中文文档翻译的挺好的: https://flutter-io.cn/docs
单击中文字的时候, 会在下方显示对应的英文.
正好可以拿来学习下英语, 不过我想要的效果是默认显示英文, 单击以后显示中文翻译.
搭建
找到了对应的翻译项目: https://github.com/cfug/flutter.cn.git
别完全按照 README 会有问题;
先 clone 下来, 并取下 submodule
git clone https://github.com/cfug/flutter.cn.git
cd flutter.cn
git submodule update --init --remote
然后安装
source ./tool/env-set.sh # initialize environment variables; install/use required Node & Ruby version
./tool/before-install.sh # install core set of required tools
./tool/install.sh # install everything else needed to build this site
注意这里不能用 zsh, zsh 下 env-set.sh 无法正确生效, 导致后面的 before-install.sh 报: travis_fold:command not found 折腾了我很久, 得切换到 bash 下来装
漫长的安装 ruby flutter sdk 等等各种东西都装了一遍, 简直了
./tool/serve.sh
启动起来, 访问 http://localhost:4002 应该能看到页面了, 如果报错, 那么等待一段时间, 可能是因为还在编译 html
看到的内容和 https://flutter-io.cn/docs 不一样, 英文在上, 中文在下, 而且不存在什么点击然后显示的特性
仔细研究网页, 根据关键词搜索, 发现点击的 js 和处理隐藏的 css 来自于 ./tool/translator 这个项目, 进去大致看了下, 猜测就是用来实现那个特性的东西.
执行 ./tool/translator/build.sh, 注意要在项目目录执行, 脚本里都是相对路径.
又是各种漫长的等待, 然后看到了各种 inject, 没跑了, 就是这货
执行的时候, 注意把刚才的 http://localhost:4002 服务开着别动, 再次访问, 页面乱了, 发现因为找不到需要的 css
真是不靠谱啊, 手工拷贝过去:
cd /Users/bigzhu/git/flutter.cn/_site/assets
cp -r ../../tool/translator/assets/translator ./
现在和在线网站感觉是一样的了, 单击显示英文
修改
尝试修改为默认英文, 单击显示中文
比较 inject 前后的 html, 中英文的对应的 p 位置还真交换了, 不是用 css 实现的. 我有点蒙.
找了半天, 这个项目里基本没啥东西. 发现了脚本里的 npm i -g @awesome-fe/[email protected]
顺藤摸瓜, 找到项目: https://github.com/asnowwolf/translate
取下来研究了一下, 哎
export function markAndSwap(element: Element, selector: string): void {
const elements = element.querySelectorAll(selector);
elements.forEach(element => {
if (containsChinese(element.innerHTML)) {
const prev = element.previousElementSibling!;
if (isPaired(prev, element) && !containsChinese(prev.innerHTML)) {
element.setAttribute('translation-result', 'on');
prev.setAttribute('translation-origin', 'off');
element.parentElement!.insertBefore(element, prev);
// 交换 id,中文内容应该占用原文的 id
const id = prev.getAttribute('id');
if (id) {
prev.removeAttribute('id');
element.setAttribute('id', id);
}
const href = prev.getAttribute('href');
if (href) {
element.setAttribute('href', href);
}
if (element.tagName.match(/(H[1-6]|li)/)) {
const prevAnchor = prev.querySelector('a[href]');
const thisAnchor = element.querySelector('a[href]');
if (prevAnchor && thisAnchor && containsChinese(decodeURIComponent(thisAnchor.getAttribute('href')!)!)) {
thisAnchor.setAttribute('href', prevAnchor.getAttribute('href')!);
}
}
}
}
});
}
真是出乎意料的简单粗暴啊, 还真去交换了中英文的翻译内容的位置
改为如下:
export function markAndSwap(element: Element, selector: string): void {
const elements = element.querySelectorAll(selector);
elements.forEach(element => {
if (containsChinese(element.innerHTML)) {
const prev = element.previousElementSibling!;
if (isPaired(prev, element) && !containsChinese(prev.innerHTML)) {
element.setAttribute('translation-result', 'off');
prev.setAttribute('translation-origin', 'on');
// 不要交换位置
// element.parentElement!.insertBefore(element, prev);
// 交换 id,中文内容应该占用原文的 id
/*
const id = prev.getAttribute('id');
if (id) {
prev.removeAttribute('id');
element.setAttribute('id', id);
}
*/
const href = prev.getAttribute('href');
if (href) {
element.setAttribute('href', href);
}
if (element.tagName.match(/(H[1-6]|li)/)) {
const prevAnchor = prev.querySelector('a[href]');
const thisAnchor = element.querySelector('a[href]');
if (prevAnchor && thisAnchor && containsChinese(decodeURIComponent(thisAnchor.getAttribute('href')!)!)) {
thisAnchor.setAttribute('href', prevAnchor.getAttribute('href')!);
}
}
}
}
});
}
修改的代码放在我 fork 的项目里: bigzhu/translate
修改 build.sh:
#!/usr/bin/env bash
set -x
set -e
bundle exec jekyll build
cp -r tool/translator/assets/* _site/assets/
npm i -g https://github.com/bigzhu/translate
nt inject '_site/**/*.html' -c /assets/translator/css/translator.css -s /assets/translator/js/translator.js -m ./tool/translator/url-map.json -t ./tool/translator/text-map.json
nt mark '_site/**/*.html'
npm 改为安装我修改后的项目
停止 ./tool/serve.sh 运行 npm run clean, 再次启动 ./tool/serve.sh, 重新生成修改前的 html
而后自然是执行 ./tool/translator/build.sh, inject 后访问, 依然是报对应的 js 和 css 找不到
cp 过去以后, 修改 translator.js 和 translator.css, 把 translation-origin 和 translation-result 交换一下就好了.
再次访问, 效果完美.
因为过程实在太麻烦了, 我干脆把编译好的网站传到了我的网站上: https://flutter.bigzhu.net
如果有不妥请联系我删除.