Update i18n:

Traditional Chinese by OpenCC conversion
Chinese translation of `jslicense.html` ahead of time
Replace (device) "refresh" as "scan"
Minor change to readme and a few other
I18n will also modify `<html lang="...">`
This commit is contained in:
NaitLee 2022-07-19 21:34:21 +08:00
parent 4e3a5f540d
commit e81553fcc5
15 changed files with 215 additions and 20 deletions

8
0-prepare.sh Executable file
View File

@ -0,0 +1,8 @@
#!/bin/sh
cd www/lang/
echo "opencc zh-CN to zh-TW..."
./0-opencc.sh
cd ..
echo "tsc bundle scripts..."
./0-transpile.sh
cd ..

View File

@ -133,12 +133,15 @@ All other parts, except which have special statements, are in Public Domain (`CC
-------- --------
## Development ## Contribution
You may interested in language support, anyway. See the translation files in directory `www/lang` and `readme.i18n`! You may interested in language support, anyway. There are translation files in directory `www/lang` and `readme.i18n/`!
Note: you can correct some mistakes in them, if there are any. Also feel free to make it (truly) better!
Also interested in code development? See [development.md](development.md)! You can correct mistakes here/there, if there are any. Also feel free to make it (truly) better!
Also interested in code development? See [CONTRIBUTING.md](CONTRIBUTING.md) and [development.md](development.md)!
After that, give yourself a credit in `www/about.html`, if you prefer.
### Credits ### Credits

4
TODO
View File

@ -8,16 +8,16 @@ Note: not ordered. do whatever I/you want
+ Even better CUPS/IPP support + Even better CUPS/IPP support
+ Even better frontend, language-friendly text printing + Even better frontend, language-friendly text printing
+ Tcl/Tk frontend. More in dev-diary.txt, July 7th. + Tcl/Tk frontend. More in dev-diary.txt, July 7th.
+ Re-style frontend to make it usable in e.g. Otter Browser
+ Make a build guide for android: + Make a build guide for android:
Summary the hacks to p4a, bleak p4a recipe, p4a webview bootstrap, and AdvancedWebView Summary the hacks to p4a, bleak p4a recipe, p4a webview bootstrap, and AdvancedWebView
+ Try to implement enough without more dependencies + Try to implement enough without more dependencies
+ More funny i18n + More funny "languages" (now there's lolcat; I think the next is 文言)
+ Arch Linux package / AUR, package for other distros + Arch Linux package / AUR, package for other distros
+ Service for other init systems (a systemd unit file is there) + Service for other init systems (a systemd unit file is there)
+ ... + ...
? Optimize PF2 text printing? It seems a bit slow (in algorithm). ? Optimize PF2 text printing? It seems a bit slow (in algorithm).
? Use Go as part of backend? It can boost things up, and build some (essential) image manipulation in, quicker. And strip some way-too-big Python libs away (for smaller Windows/Android dist).
? Built-in PostScript (Even if very basic) ? Built-in PostScript (Even if very basic)
? Data compression for GB03. Optional ? Data compression for GB03. Optional
? Plugin, for including community features (that involves usefulness but also bloatness) ? Plugin, for including community features (that involves usefulness but also bloatness)

View File

@ -133,14 +133,18 @@ Copyright © 2021-2022 NaitLee Soft. 保留一些权利。
## 开发 ## 开发
您可能对翻译工作感兴趣。可于目录 `www/lang``readme.i18n` 中查看翻译文件! 您可能对翻译工作感兴趣。可于目录 `www/lang``readme.i18n/` 中查看翻译文件!
注: 注:
1. 通常英语与简体中文同时更新。请考虑其他,如繁体中文(需注意在繁体中与简体的用字、技术术语差别)。 1. 通常英语与简体中文同时更新。请考虑其他,如繁体中文(需注意在繁体中与简体的用字、技术术语差别)。
2. 如果(真的)有能力,您也可以纠正/改善某些翻译! 2. 目前使用 [OpenCC](https://github.com/BYVoid/OpenCC) 转换简体到繁体(臺灣正體)。若有不当之处,请指出。
当前仅转换程序界面语言、暂不转换文档。
3. 如果(真的)有能力,您也可以纠正/改善某些翻译!
还想写代码?看看 [development.md](development.md)!(英文) 还想写代码?看看 [development.md](development.md)!(英文)
那之后,可以将您的贡献概括添加至 `www/about.html`
### 鸣谢 ### 鸣谢
- 当然不能没有 Python 和 Web 技术! - 当然不能没有 Python 和 Web 技术!

View File

@ -1,4 +1,2 @@
#!/bin/sh #!/bin/sh
cd www
npx tsc $@ --allowJs --outFile main.comp.js $(cat all_js.txt) npx tsc $@ --allowJs --outFile main.comp.js $(cat all_js.txt)
cd ..

View File

@ -43,6 +43,7 @@
<a target="_blank" href="https://github.com/sync1211">sync1211</a> <a target="_blank" href="https://github.com/sync1211">sync1211</a>
</dt> </dt>
<dd data-i18n="developer">Developer</dd> <dd data-i18n="developer">Developer</dd>
<dd data-i18n="translator">Translator</dd>
</dl> </dl>
<dl> <dl>
<dt data-i18n="all-users-and-developers">All testers & users</dt> <dt data-i18n="all-users-and-developers">All testers & users</dt>

View File

@ -19,7 +19,7 @@
<label for="device-options" data-i18n="device-">Device:</label> <label for="device-options" data-i18n="device-">Device:</label>
<select id="device-options" data-key> <select id="device-options" data-key>
</select> </select>
<button id="device-refresh" data-i18n="refresh" data-key>Refresh</button> <button id="device-refresh" data-i18n="scan" data-key>Scan</button>
<hr /> <hr />
</div> </div>
<div class="input-group"> <div class="input-group">

3
www/lang/0-opencc.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/sh
# convert with OpenCC: https://github.com/BYVoid/OpenCC
sed 's/中文(简体)/中文(臺灣正體)/' < zh-CN.json | opencc -c s2twp.json > zh-TW.json

View File

@ -139,5 +139,6 @@
"monospace": "Monospace", "monospace": "Monospace",
"rotate-image": "Rotate Image", "rotate-image": "Rotate Image",
"test-unknown-device": "Test Unknown Device", "test-unknown-device": "Test Unknown Device",
"scan": "Scan",
"now-will-scan-for-all-bluetooth-devices-nearby": "Now will scan for all bluetooth devices nearby." "now-will-scan-for-all-bluetooth-devices-nearby": "Now will scan for all bluetooth devices nearby."
} }

View File

@ -1,6 +1,7 @@
{ {
"en-US": "English (US)", "en-US": "English (US)",
"zh-CN": "中文(简体)", "zh-CN": "中文(简体)",
"zh-TW": "中文(臺灣正體)",
"de-DE": "Deutsch", "de-DE": "Deutsch",
"lolcat": "LOLCAT" "lolcat": "LOLCAT"
} }

View File

@ -134,5 +134,6 @@
"monospace": "H4CKY PAW", "monospace": "H4CKY PAW",
"rotate-image": "ROLL PIC", "rotate-image": "ROLL PIC",
"test-unknown-device": "I HAV STRENGE KITTE", "test-unknown-device": "I HAV STRENGE KITTE",
"now-will-scan-for-all-bluetooth-devices-nearby": "WIL FIND ALL THINY KITTE OR NOT" "now-will-scan-for-all-bluetooth-devices-nearby": "WIL FIND ALL THINY KITTE OR NOT",
"scan": "FIND"
} }

View File

@ -124,11 +124,28 @@
"text-size": "大小", "text-size": "大小",
"enter-text": "在此处输入文本", "enter-text": "在此处输入文本",
"wrap-words-by-spaces": "空格处换行(不建议用于汉语)", "wrap-words-by-spaces": "空格处换行(不建议用于汉语)",
"minor-tweaks": "小优化", "minor-tweaks": "细节调整",
"serif": "衬线字体", "serif": "衬线字体",
"sans-serif": "无衬线字体", "sans-serif": "无衬线字体",
"monospace": "等宽字体", "monospace": "等宽字体",
"rotate-image": "旋转图像", "rotate-image": "旋转图像",
"test-unknown-device": "测试未知设备", "test-unknown-device": "测试未知设备",
"now-will-scan-for-all-bluetooth-devices-nearby": "现在将搜索附近所有设备。" "now-will-scan-for-all-bluetooth-devices-nearby": "现在将搜索附近所有设备。",
"scan": "扫描",
"you-can-see-all-javascript-programs-used": "您可以看到此程序使用的 JavaScript 脚本均为自由软件。",
"javascript-resource": "资源",
"javascript-license": "许可",
"javascript-source": "源",
"javascript-description": "详述",
"javascript-everyjs-description": "所有开发脚本的动态联接",
"javascript-maincompjs-description": "经过转译的所有以下开发脚本包,起兼容作用",
"javascript-loaderjs-description": "动态加载其余脚本,并在出现问题时回退",
"javascript-polyfilljs-description": "添加不被旧浏览器支持的功能",
"javascript-i18nextjs-description": "国际化 (i18n)“扩展”",
"javascript-i18njs-description": "用于国际化(语言支持)",
"javascript-imagejs-description": "用于画布 (canvas) 上的图像处理",
"javascript-accessibilityjs-description": "一些无障碍功能",
"javascript-catprinter-description": "猫咪打印机 (Cat-Printer) 主脚本",
"free-software": "自由软件",
"free-software-description": "尊重您计算自由的软件。"
} }

151
www/lang/zh-TW.json Normal file
View File

@ -0,0 +1,151 @@
{
"$language": "中文(臺灣正體)",
"cat-printer": "貓咪印表機",
"printer": "印表機",
"device-": "裝置:",
"refresh": "重新整理",
"mode-": "模式:",
"canvas": "畫布",
"document": "文件",
"insert-picture": "插入圖片",
"insert-text": "輸入文字",
"help": "幫助",
"javascript-license-information": "JavaScript 許可證資訊",
"settings": "設定",
"image": "影象",
"threshold-": "閾值:",
"transparent-as-white": "透明為白色",
"misc": "雜項",
"system": "系統",
"disable-animation": "禁用動畫",
"exit": "退出",
"error-message": "錯誤訊息",
"preview": "預覽",
"print": "列印",
"expand": "擴大",
"crop": "裁減",
"scanning-for-devices": "正在掃描裝置……",
"scan-time-": "掃描時間:",
"-seconds": "秒",
"no-available-devices-found": "未發現可用裝置",
"found-0-available-devices": "發現 {0} 個可用裝置",
"please-check-if-the-printer-is-down": "請檢查印表機是否已關閉",
"printing": "列印中……",
"finished": "完成",
"coming-soon": "即將到來……",
"dry-run": "幹執行",
"dry-run-test-print-process-only": "幹執行:僅測試列印流程",
"you-can-close-this-page-manually": "您可手動關閉此頁面",
"please-enable-bluetooth": "請啟用藍芽",
"error-happened-please-check-error-message": "發生錯誤,請檢查錯誤訊息",
"you-can-seek-for-help-with-detailed-info-below": "您可以使用以下詳細資訊尋求幫助",
"or-try-to-scan-longer": "或者嘗試延長掃描時間",
"print-to-cat-printer": "列印到貓咪印表機。",
"supported-models-": "支援的型號:",
"path-to-input-file-dash-for-stdin": "輸入檔案的位置。使用 '-' 作為標準輸入",
"please-install-pyobjc-via-pip": "請從 pip 安裝 `pyobjc`",
"please-install-bleak-via-pip": "請從 pip 安裝 `bleak`",
"folder-printer_lib-is-incomplete-or-missing-please-check": "資料夾 `printer_lib` 不完整或丟失,請檢查",
"input-is-not-pbm-image": "輸入不是 PBM 影象",
"unsuitable-image-width-expected-0-got-1": "不適合的影象寬度,需要 {0}, 輸入為 {1}",
"broken-pbm-image": "損壞的 PBM 影象",
"input-is-not-text-file": "輸入不是文字檔案",
"match-printer-with-this-name-or-address": "使用符合此名稱或地址的印表機",
"virtual-run-on-specified-model": "在指定的型號模擬執行",
"font-size-0": "字型大小 {0}",
"stopping": "停止中",
"connecting": "正在連線",
"model-0-is-not-supported-yet": "型號 '{0}' 仍未支援",
"invalid-address-0": "無效的地址:'{0}'",
"will-listen-on-all-addresses": "將接受所有地址的連線",
"serving-at-0": "伺服器在 {0}",
"disconnecting-from-printer": "正在從印表機斷開連線",
"flip-horizontally": "水平翻轉",
"flip-vertically": "垂直翻轉",
"dump-traffic": "轉儲資料",
"right-to-left-text-order": "從右到左的文字順序",
"auto-wrap-line": "自動折行",
"process-as-": "處理方式:",
"text": "文字",
"picture": "照片",
"pattern": "圖案",
"large-font": "大字型",
"accessibility": "無障礙",
"language": "語言",
"layout": "佈局",
"ok": "確定",
"cancel": "取消",
"yes": "是",
"no": "否",
"about": "關於",
"home-page-": "主頁:",
"contributors": "貢獻者",
"developer": "開發者",
"translator": "翻譯",
"all-users-and-developers": "每位使用者及開發者",
"everyone-is-awesome": "每個人都是好樣的!",
"license": "許可證",
"exiting": "退出中……",
"dark-theme": "深色主題",
"high-contrast": "高對比度",
"welcome": "歡迎!",
"copyright-and-license": "版權與許可",
"some-rights-reserved": "保留一些權利。",
"ENTER": "回車",
"SPACE": "空格",
"ESCAPE": "ESC",
"TAB": "Tab",
"COMMA": "逗號",
"DOT": "句號",
"to-enter-keyboard-mode-press-tab": "要進入鍵盤模式,請按 Tab",
"usage-": "用法:",
"positional-arguments-": "引數:",
"options-": "選項:",
"show-this-help-message": "顯示此幫助資訊",
"do-nothing": "什麼也不做",
"scan-for-a-printer": "掃描印表機",
"text-printing-mode-with-options": "啟用文字列印並指定選項",
"image-printing-options": "圖片列印選項",
"convert-input-image-with-imagemagick": "使用 ImageMagick 轉換輸入圖片",
"reset-configuration-": "要重置配置嗎?",
"brightness-": "亮度:",
"text-printing-mode": "文字列印模式",
"internal-error-please-see-terminal": "內部錯誤,請檢查終端",
"control-printer-thermal-strength": "控制列印力度",
"strength-": "力度:",
"or-drag-file-to-below": "或拖拽檔案至下方",
"reset": "重置",
"cat-face-toward": "貓臉朝上",
"quality-": "質量:",
"print-quality": "列印質量",
"show-more-options": "顯示更多選項",
"text-font": "字型",
"text-size": "大小",
"enter-text": "在此處輸入文字",
"wrap-words-by-spaces": "空格處換行(不建議用於漢語)",
"minor-tweaks": "細節調整",
"serif": "襯線字型",
"sans-serif": "無襯線字型",
"monospace": "等寬字型",
"rotate-image": "旋轉影象",
"test-unknown-device": "測試未知裝置",
"now-will-scan-for-all-bluetooth-devices-nearby": "現在將搜尋附近所有裝置。",
"scan": "掃描",
"you-can-see-all-javascript-programs-used": "您可以看到此程式使用的 JavaScript 指令碼均為自由軟體。",
"javascript-resource": "資源",
"javascript-license": "許可",
"javascript-source": "源",
"javascript-description": "詳述",
"javascript-everyjs-description": "所有開發指令碼的動態聯接",
"javascript-maincompjs-description": "經過轉譯的所有以下開發指令碼包,起相容作用",
"javascript-loaderjs-description": "動態載入其餘指令碼,並在出現問題時回退",
"javascript-polyfilljs-description": "新增不被舊瀏覽器支援的功能",
"javascript-i18nextjs-description": "國際化 (i18n)“擴充套件”",
"javascript-i18njs-description": "用於國際化(語言支援)",
"javascript-imagejs-description": "用於畫布 (canvas) 上的影象處理",
"javascript-accessibilityjs-description": "一些無障礙功能",
"javascript-catprinter-description": "貓咪印表機 (Cat-Printer) 主指令碼",
"free-software": "自由軟體",
"free-software-description": "尊重您計算自由的軟體。"
}

View File

@ -59,10 +59,12 @@ body.android .hide-on-android {
transition-timing-function: ease-out; transition-timing-function: ease-out;
} }
button, input[type="number"], input[type="text"], select, button, input[type="number"], input[type="text"], select,
#dialog>.shade, #dialog>.content, #dialog>.shade, #dialog>.content, #canvas {
#canvas {
transition-timing-function: cubic-bezier(.08,.82,.17,1); transition-timing-function: cubic-bezier(.08,.82,.17,1);
} }
#dialog>.shade {
transition-duration: calc(var(--anim-time) / 2);
}
a { a {
transition: color var(--anim-time) ease-out; transition: color var(--anim-time) ease-out;
} }

View File

@ -452,7 +452,7 @@ class CanvasController {
threshold, threshold,
this.transparentAsWhite this.transparentAsWhite
) )
: this.grayscaleCache).slice(); : this.grayscaleCache).slice(0);
/** @type {Uint8ClampedArray} */ /** @type {Uint8ClampedArray} */
let result; let result;
switch (this.algorithm) { switch (this.algorithm) {
@ -475,6 +475,7 @@ class CanvasController {
let before = document.createElement('canvas'); let before = document.createElement('canvas');
let b_ctx = before.getContext('2d'); let b_ctx = before.getContext('2d');
let img = document.getElementById('img'); let img = document.getElementById('img');
img.src = ''; // trigger some dumb browser
img.src = url; img.src = url;
img.addEventListener('load', () => { img.addEventListener('load', () => {
let canvas = this.canvas; let canvas = this.canvas;
@ -631,11 +632,15 @@ class CanvasController {
} }
} }
/** Global variable indicating current language */
var language = navigator.language;
/** @param {Document} doc */ /** @param {Document} doc */
function applyI18nToDom(doc) { function applyI18nToDom(doc) {
doc = doc || document; doc = doc || document;
let elements = doc.querySelectorAll('*[data-i18n]'); let elements = doc.querySelectorAll('*[data-i18n]');
let i18n_data, translated_string; let i18n_data, translated_string;
doc.querySelector('html').lang = language;
elements.forEach(element => { elements.forEach(element => {
i18n_data = element.getAttribute('data-i18n'); i18n_data = element.getAttribute('data-i18n');
translated_string = i18n(i18n_data); translated_string = i18n(i18n_data);
@ -652,10 +657,10 @@ async function initI18n(current_language) {
/** @type {{ [code: string]: string }} */ /** @type {{ [code: string]: string }} */
let list = await fetch('/lang/list.json').then(r => r.json()); let list = await fetch('/lang/list.json').then(r => r.json());
let use_language = async (value) => { let use_language = async (value) => {
i18n.useLanguage(value); language = value;
i18n.useLanguage(language);
i18n.add(value, await fetch(`/lang/${value}.json`).then(r => r.json()), true); i18n.add(value, await fetch(`/lang/${value}.json`).then(r => r.json()), true);
applyI18nToDom(); applyI18nToDom();
document.querySelector('html').lang = value;
} }
language_select.addEventListener('change', () => use_language(language_select.value)); language_select.addEventListener('change', () => use_language(language_select.value));
for (let code in list) { for (let code in list) {