├── zh-conv ├── patch-cn.txt ├── patch-twp.txt ├── patch-quotation.txt ├── 0-convert.sh ├── zh-HK.json ├── zh-TW.json └── zh-CN.json ├── static ├── pwabuilder-sw.js ├── favicon.ico ├── kitty.png ├── kitty-maskable.png ├── screenshots │ ├── wide.png │ ├── narrow.png │ ├── wide-dark.png │ └── narrow-dark.png ├── lang │ ├── languages.json │ ├── zh-CN.json │ ├── zh-HK.json │ ├── zh-TW.json │ ├── zh-Hant-CN.json │ └── en-US.json ├── accessibility.js ├── image_worker.js ├── kitty.svg └── styles.css ├── .vscode ├── extensions.json └── settings.json ├── dev.ts ├── .gitignore ├── islands ├── PwaUpdate.tsx ├── DynamicManifest.tsx ├── Nav.tsx └── KittyPrinter.tsx ├── common ├── utility.ts ├── constants.ts ├── dynamic-manifest.ts ├── hooks.ts ├── types.ts ├── i18n.tsx ├── icons.tsx └── cat-protocol.ts ├── i18nx ├── i18n.d.ts ├── common-extensions.ts └── i18n.ts ├── readme.i18n ├── readme.zh-CN.md ├── readme.zh-HK.md ├── readme.zh-TW.md └── readme.zh-Hant-CN.md ├── routes ├── index.tsx ├── api │ └── lang.ts ├── _404.tsx └── _app.tsx ├── main.ts ├── .github └── workflows │ └── deploy.yml ├── deno.json ├── README.md ├── Expat.txt ├── components ├── FontSelector.tsx ├── Settings.tsx ├── Preview.tsx ├── StuffPreview.tsx └── StuffWidget.tsx ├── fresh.gen.ts ├── CC0-1.0.txt └── LICENSE /zh-conv/patch-cn.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /zh-conv/patch-twp.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/pwabuilder-sw.js: -------------------------------------------------------------------------------- 1 | // TODO 2 | -------------------------------------------------------------------------------- /zh-conv/patch-quotation.txt: -------------------------------------------------------------------------------- 1 | 「 “ 2 | 」 ” 3 | -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NaitLee/kitty-printer/HEAD/static/favicon.ico -------------------------------------------------------------------------------- /static/kitty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NaitLee/kitty-printer/HEAD/static/kitty.png -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "denoland.vscode-deno" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /static/kitty-maskable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NaitLee/kitty-printer/HEAD/static/kitty-maskable.png -------------------------------------------------------------------------------- /static/screenshots/wide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NaitLee/kitty-printer/HEAD/static/screenshots/wide.png -------------------------------------------------------------------------------- /static/screenshots/narrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NaitLee/kitty-printer/HEAD/static/screenshots/narrow.png -------------------------------------------------------------------------------- /static/screenshots/wide-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NaitLee/kitty-printer/HEAD/static/screenshots/wide-dark.png -------------------------------------------------------------------------------- /static/screenshots/narrow-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NaitLee/kitty-printer/HEAD/static/screenshots/narrow-dark.png -------------------------------------------------------------------------------- /dev.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env -S deno run -A --watch=static/,routes/ 2 | 3 | import dev from "$fresh/dev.ts"; 4 | 5 | await dev(import.meta.url, "./main.ts"); 6 | -------------------------------------------------------------------------------- /static/lang/languages.json: -------------------------------------------------------------------------------- 1 | { 2 | "en-US": "English (US)", 3 | "zh-CN": "中文(简体字)", 4 | "zh-HK": "中文(香港字)", 5 | "zh-TW": "中文(正體字)", 6 | "zh-Hant-CN": "中文(傳統字)" 7 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # dotenv environment variable files 2 | .env 3 | .env.development.local 4 | .env.test.local 5 | .env.production.local 6 | .env.local 7 | 8 | # Fresh build directory 9 | _fresh/ 10 | 11 | *.kate-swp 12 | ca.crt 13 | ca.key 14 | -------------------------------------------------------------------------------- /islands/PwaUpdate.tsx: -------------------------------------------------------------------------------- 1 | // import "@pwabuilder/pwaupdate"; 2 | 3 | import { createElement } from "preact"; 4 | 5 | export default function PwaUpdate() { 6 | return <> 7 | 12 | {createElement('pwa-update', {})} 13 | ; 14 | } 15 | -------------------------------------------------------------------------------- /common/utility.ts: -------------------------------------------------------------------------------- 1 | 2 | export function mkcanvas(width: number) { 3 | const canvas = document.createElement('canvas'); 4 | canvas.width = width; 5 | const img = document.createElement('img'); 6 | const ctx = canvas.getContext('2d')!; 7 | return { canvas, width, img, ctx }; 8 | } 9 | 10 | export function round_to(n: number, d: number) { 11 | return Math.round(n * (10 * d)) / (10 * d); 12 | } 13 | -------------------------------------------------------------------------------- /zh-conv/0-convert.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | LANGDIR=../static/lang 4 | READMEDIR=../readme.i18n 5 | 6 | convert() { 7 | lang=${1} 8 | langname=${2} 9 | conf=$lang.json 10 | opencc -c $conf -i $READMEDIR/readme.zh-Hant-CN.md -o $READMEDIR/readme.$lang.md 11 | opencc -c $conf -i $LANGDIR/zh-Hant-CN.json -o $LANGDIR/$lang.json 12 | } 13 | 14 | convert zh-CN 中文(简体字) 15 | convert zh-HK 中文(香港字) 16 | convert zh-TW 中文(正體字) 17 | -------------------------------------------------------------------------------- /i18nx/i18n.d.ts: -------------------------------------------------------------------------------- 1 | 2 | type Thing = number | string; 3 | type Things = Thing[]; 4 | 5 | // https://tc39.es/ecma402/#sec-pluralruleselect 6 | type PluralKind = "zero" | "one" | "two" | "few" | "many" | "other"; 7 | 8 | type Variant = string | Record; 9 | type Variants = (string | Variant[]); 10 | 11 | type I18nData = Record; 12 | 13 | type ExtensionReturns = { 14 | key?: string, 15 | thing?: Thing 16 | } | string | undefined | false; 17 | type Extension = (thing: Thing, variant: Variant) => ExtensionReturns; 18 | -------------------------------------------------------------------------------- /zh-conv/zh-HK.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "To Traditional Chinese (Hong Kong variant)", 3 | "segmentation": { 4 | "type": "mmseg", 5 | "dict": { 6 | "type": "ocd2", 7 | "file": "HKVariants.ocd2" 8 | } 9 | }, 10 | "conversion_chain": [ 11 | { 12 | "dict": { 13 | "type": "group", 14 | "dicts": [ 15 | { 16 | "type": "ocd2", 17 | "file": "HKVariants.ocd2" 18 | }, { 19 | "type": "text", 20 | "file": "patch-quotation.txt" 21 | } 22 | ] 23 | } 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "deno.enable": true, 3 | "deno.lint": true, 4 | "editor.defaultFormatter": "denoland.vscode-deno", 5 | "[typescriptreact]": { 6 | "editor.defaultFormatter": "vscode.typescript-language-features" 7 | }, 8 | "[typescript]": { 9 | "editor.defaultFormatter": "denoland.vscode-deno" 10 | }, 11 | "[javascriptreact]": { 12 | "editor.defaultFormatter": "denoland.vscode-deno" 13 | }, 14 | "[javascript]": { 15 | "editor.defaultFormatter": "denoland.vscode-deno" 16 | }, 17 | "[css]": { 18 | "editor.defaultFormatter": "vscode.css-language-features" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /readme.i18n/readme.zh-CN.md: -------------------------------------------------------------------------------- 1 | 2 | # 猫猫打印机 3 | 4 | *用于蓝牙“猫咪打印机”的 Web 应用!* 打印文字、照片,以后还有更多支持! 5 | 6 | 释发您手中猫猫打印机的无穷可能! 7 | 8 | ## 关于 9 | 10 | 这是 [Cat-Printer](https://github.com/NaitLee/Cat-Printer) 的姊妹项目。跟随链接了解更多。 11 | 12 | [![Fresh 作品](https://fresh.deno.dev/fresh-badge.svg)](https://fresh.deno.dev) 13 | 14 | 此项目整体以 [GNU Affero 通用公共许可证,版本 3.0 或以后版本](https://www.gnu.org/licenses/agpl-3.0.html)释出,尊重您的[计算自由](https://fsfans.club/learn/free-software.html)。 15 | 16 | 一些部分使用 [CC0-1.0](https://directory.fsf.org/wiki/License:CC0) 放弃版权:目录 `i18nx` 和 `zh-conv` 下的文件,以及艺术作品 `static/kitty.svg` 及其衍生物。 17 | 18 | 各个库遵循不同的许可协议,请参见 `deno.json` 中的模块导入映射(Import Map)。 19 | -------------------------------------------------------------------------------- /readme.i18n/readme.zh-HK.md: -------------------------------------------------------------------------------- 1 | 2 | # 貓貓打印機 3 | 4 | *用於藍牙“貓咪打印機”的 Web 應用!* 打印文字、照片,以後還有更多支持! 5 | 6 | 釋發您手中貓貓打印機的無窮可能! 7 | 8 | ## 關於 9 | 10 | 這是 [Cat-Printer](https://github.com/NaitLee/Cat-Printer) 的姊妹項目。跟隨鏈接瞭解更多。 11 | 12 | [![Fresh 作品](https://fresh.deno.dev/fresh-badge.svg)](https://fresh.deno.dev) 13 | 14 | 此項目整體以 [GNU Affero 通用公共許可證,版本 3.0 或以後版本](https://www.gnu.org/licenses/agpl-3.0.html)釋出,尊重您的[計算自由](https://fsfans.club/learn/free-software.html)。 15 | 16 | 一些部分使用 [CC0-1.0](https://directory.fsf.org/wiki/License:CC0) 放棄版權:目錄 `i18nx` 和 `zh-conv` 下的文件,以及藝術作品 `static/kitty.svg` 及其衍生物。 17 | 18 | 各個庫遵循不同的許可協議,請參見 `deno.json` 中的模塊導入映射(Import Map)。 19 | -------------------------------------------------------------------------------- /readme.i18n/readme.zh-TW.md: -------------------------------------------------------------------------------- 1 | 2 | # 貓貓印表機 3 | 4 | *用於藍芽「貓咪印表機」的 Web 應用!* 列印文字、照片,以後還有更多支援! 5 | 6 | 釋發您手中貓貓印表機的無窮可能! 7 | 8 | ## 關於 9 | 10 | 這是 [Cat-Printer](https://github.com/NaitLee/Cat-Printer) 的姊妹專案。跟隨連結瞭解更多。 11 | 12 | [![Fresh 作品](https://fresh.deno.dev/fresh-badge.svg)](https://fresh.deno.dev) 13 | 14 | 此專案整體以 [GNU Affero 通用公共許可證,版本 3.0 或以後版本](https://www.gnu.org/licenses/agpl-3.0.html)釋出,尊重您的[計算自由](https://fsfans.club/learn/free-software.html)。 15 | 16 | 一些部分使用 [CC0-1.0](https://directory.fsf.org/wiki/License:CC0) 放棄版權:目錄 `i18nx` 和 `zh-conv` 下的檔案,以及藝術作品 `static/kitty.svg` 及其衍生物。 17 | 18 | 各個庫遵循不同的許可協議,請參見 `deno.json` 中的模組匯入對映(Import Map)。 19 | -------------------------------------------------------------------------------- /readme.i18n/readme.zh-Hant-CN.md: -------------------------------------------------------------------------------- 1 | 2 | # 貓貓打印機 3 | 4 | *用於藍牙「貓咪打印機」的 Web 應用!* 打印文字、照片,以後還有更多支持! 5 | 6 | 釋發您手中貓貓打印機的無窮可能! 7 | 8 | ## 關於 9 | 10 | 這是 [Cat-Printer](https://github.com/NaitLee/Cat-Printer) 的姊妹項目。跟隨鏈接瞭解更多。 11 | 12 | [![Fresh 作品](https://fresh.deno.dev/fresh-badge.svg)](https://fresh.deno.dev) 13 | 14 | 此項目整體以 [GNU Affero 通用公共許可證,版本 3.0 或以後版本](https://www.gnu.org/licenses/agpl-3.0.html)釋出,尊重您的[計算自由](https://fsfans.club/learn/free-software.html)。 15 | 16 | 一些部分使用 [CC0-1.0](https://directory.fsf.org/wiki/License:CC0) 放棄版權:目錄 `i18nx` 和 `zh-conv` 下的文件,以及藝術作品 `static/kitty.svg` 及其衍生物。 17 | 18 | 各個庫遵循不同的許可協議,請參見 `deno.json` 中的模塊導入映射(Import Map)。 19 | -------------------------------------------------------------------------------- /i18nx/common-extensions.ts: -------------------------------------------------------------------------------- 1 | 2 | /// 3 | 4 | const en: Extension = (thing, v) => { 5 | if (typeof v !== 'object') return undefined; 6 | if (typeof thing === 'string' && Object.hasOwn(v, 'an')) 7 | return 'aeiou'.includes(thing.toLowerCase()[0]) ? 'an' : 'a'; 8 | else if (typeof thing === 'number' && Object.hasOwn(v, '1st')) 9 | return (thing > 10 && thing < 20) || (thing < -10 && thing > -20) || thing % 10 > 4 10 | ? '4th' 11 | : [, '1st', '2nd', '3rd'][thing % 10]; 12 | } 13 | 14 | export const CommonExtensionsByLanguage: { [key: string]: Extension[] } = { 15 | 'en': [en], 16 | 'en-US': [en], 17 | 'en-GB': [en] 18 | }; 19 | -------------------------------------------------------------------------------- /zh-conv/zh-TW.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "To Traditional Chinese (Taiwan standard, with phrases)", 3 | "segmentation": { 4 | "type": "mmseg", 5 | "dict": { 6 | "type": "ocd2", 7 | "file": "STPhrases.ocd2" 8 | } 9 | }, 10 | "conversion_chain": [ 11 | { 12 | "dict": { 13 | "type": "group", 14 | "dicts": [ 15 | { 16 | "type": "text", 17 | "file": "patch-twp.txt" 18 | }, { 19 | "type": "ocd2", 20 | "file": "TWPhrases.ocd2" 21 | } 22 | ] 23 | } 24 | }, { 25 | "dict": { 26 | "type": "ocd2", 27 | "file": "TWVariants.ocd2" 28 | } 29 | } 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /routes/index.tsx: -------------------------------------------------------------------------------- 1 | import { Head } from "$fresh/runtime.ts"; 2 | import KittyPrinter from "../islands/KittyPrinter.tsx"; 3 | import { _ } from "../common/i18n.tsx"; 4 | import Nav from "../islands/Nav.tsx"; 5 | import PwaUpdate from "../islands/PwaUpdate.tsx"; 6 | import DynamicManifest from "../islands/DynamicManifest.tsx"; 7 | 8 | export { handler } from "../common/i18n.tsx"; 9 | 10 | export default function Home(request: Request) { 11 | return <> 12 | 13 | {_('kitty-printer')} 14 | {/* TODO: a service worker */} 15 | {/* */} 16 | 17 | 18 |