From 9abb2771fe4d4e66707a7c9a9c497ae7f829cdb6 Mon Sep 17 00:00:00 2001 From: 3w36zj6 <52315048+3w36zj6@users.noreply.github.com> Date: Tue, 20 May 2025 22:33:04 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=E7=BF=BB=E8=A8=B3=E7=8A=B6?= =?UTF-8?q?=E6=85=8B=E3=81=AE=E7=AE=A1=E7=90=86=E6=A9=9F=E8=83=BD=E3=82=92?= =?UTF-8?q?=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- website/src/index.tsx | 5 ++ website/src/utils/translationStatus.ts | 92 ++++++++++++++++++++++++++ website/translation-status.schema.json | 17 +++++ 3 files changed, 114 insertions(+) create mode 100644 website/src/utils/translationStatus.ts create mode 100644 website/translation-status.schema.json diff --git a/website/src/index.tsx b/website/src/index.tsx index 90b9f473e3..b48aada1ee 100644 --- a/website/src/index.tsx +++ b/website/src/index.tsx @@ -11,6 +11,7 @@ import { import type { Body, Page } from "./types/model"; import { flattenDocs } from "./utils/flattenDocs"; import { isPageOfKind } from "./utils/isPageOfKind"; +import { registerRoutes } from "./utils/translationStatus"; // typst-docsが生成したドキュメント import docsJson from "../../assets/docs.json"; @@ -18,6 +19,10 @@ const docs = docsJson as unknown as Page[]; const [flattenedPages, pagePaths] = flattenDocs(docs); +// 未知のページを未翻訳として登録する +const allRoutes = flattenedPages.map((page) => page.route); +registerRoutes(allRoutes); + const app = new Hono(); app.use(appendTrailingSlash()); app.use(trimTrailingSlash()); diff --git a/website/src/utils/translationStatus.ts b/website/src/utils/translationStatus.ts new file mode 100644 index 0000000000..144d856915 --- /dev/null +++ b/website/src/utils/translationStatus.ts @@ -0,0 +1,92 @@ +import fs from "node:fs"; +import path from "node:path"; + +export type TranslationStatus = + | "translated" + | "partially_translated" + | "untranslated"; + +export type TranslationStatusMap = { + [route: string]: TranslationStatus; +}; + +const TRANSLATION_STATUS_FILE = path.resolve( + process.cwd(), + "translation-status.json", +); + +/** + * ページの翻訳状態を管理しているJSONファイルを読み込む。ファイルが存在しない場合は空のオブジェクトを返す。 + * @returns ページの翻訳状態を示すオブジェクト。 + */ +export const loadTranslationStatus = (): TranslationStatusMap => { + if (fs.existsSync(TRANSLATION_STATUS_FILE)) { + const content = fs.readFileSync(TRANSLATION_STATUS_FILE, "utf-8"); + return JSON.parse(content); + } + + return {}; +}; + +/** + * ページの翻訳状態を管理しているJSONファイルに書き込む。 + * @param status ページの翻訳状態を示すオブジェクト。 + */ +export const saveTranslationStatus = (status: TranslationStatusMap): void => { + const json = { + $schema: "./translation-status.schema.json", + ...status, + }; + fs.writeFileSync( + TRANSLATION_STATUS_FILE, + JSON.stringify(json, null, 2), + "utf-8", + ); +}; + +/** + * 新規ページのルートを未翻訳として登録する。既に登録されているルートは無視される。 + * @param routes 登録するページのルートの配列。 + */ +export const registerRoutes = (routes: string[]): void => { + const status = loadTranslationStatus(); + let changed = false; + + for (const route of routes) { + if (!(route in status)) { + status[route] = "untranslated"; + changed = true; + } + } + + if (changed) { + saveTranslationStatus(status); + } +}; + +/** + * 翻訳の進捗率を計算する。 + * `translated`は1.0、`partially_translated`は0.5の重みを持つ。 + * @returns [0.0, 1.0]の範囲で表される翻訳率 + */ +export const calculateTranslationProgressRate = (): number => { + const status = loadTranslationStatus(); + const routes = Object.keys(status).filter((key) => key !== "$schema"); + + if (routes.length === 0) { + return 0; + } + + let translationScore = 0; + + for (const route of routes) { + const currentStatus = status[route]; + if (currentStatus === "translated") { + translationScore += 1; + } else if (currentStatus === "partially_translated") { + translationScore += 0.5; + } + } + + return translationScore / routes.length; +}; diff --git a/website/translation-status.schema.json b/website/translation-status.schema.json new file mode 100644 index 0000000000..2bbdb95ee2 --- /dev/null +++ b/website/translation-status.schema.json @@ -0,0 +1,17 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ページの翻訳状態", + "description": "各ページの翻訳状態を管理するためのJSONファイル", + "type": "object", + "properties": { + "$schema": { + "type": "string", + "description": "このJSONファイルで使用されるJSONスキーマへの参照" + } + }, + "additionalProperties": { + "type": "string", + "enum": ["translated", "partially_translated", "untranslated"], + "description": "ページの翻訳状態" + } +} From 6e1f23f78ac772d9c9cb72ae57a42b9025d7b5d9 Mon Sep 17 00:00:00 2001 From: 3w36zj6 <52315048+3w36zj6@users.noreply.github.com> Date: Tue, 20 May 2025 22:33:28 +0900 Subject: [PATCH 2/3] =?UTF-8?q?chore:=20=E7=BF=BB=E8=A8=B3=E7=8A=B6?= =?UTF-8?q?=E6=85=8B=E3=82=92=E7=AE=A1=E7=90=86=E3=81=99=E3=82=8B=E3=83=95?= =?UTF-8?q?=E3=82=A1=E3=82=A4=E3=83=AB=E3=82=92=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- website/translation-status.json | 195 ++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 website/translation-status.json diff --git a/website/translation-status.json b/website/translation-status.json new file mode 100644 index 0000000000..026e5988c5 --- /dev/null +++ b/website/translation-status.json @@ -0,0 +1,195 @@ +{ + "$schema": "./translation-status.schema.json", + "/docs/": "translated", + "/docs/tutorial/": "translated", + "/docs/tutorial/writing-in-typst/": "translated", + "/docs/tutorial/formatting/": "translated", + "/docs/tutorial/advanced-styling/": "translated", + "/docs/tutorial/making-a-template/": "translated", + "/docs/reference/": "translated", + "/docs/reference/syntax/": "translated", + "/docs/reference/styling/": "translated", + "/docs/reference/scripting/": "translated", + "/docs/reference/context/": "translated", + "/docs/reference/foundations/": "untranslated", + "/docs/reference/foundations/arguments/": "untranslated", + "/docs/reference/foundations/array/": "untranslated", + "/docs/reference/foundations/assert/": "untranslated", + "/docs/reference/foundations/auto/": "untranslated", + "/docs/reference/foundations/bool/": "untranslated", + "/docs/reference/foundations/bytes/": "untranslated", + "/docs/reference/foundations/calc": "untranslated", + "/docs/reference/foundations/content/": "untranslated", + "/docs/reference/foundations/datetime/": "untranslated", + "/docs/reference/foundations/decimal/": "untranslated", + "/docs/reference/foundations/dictionary/": "untranslated", + "/docs/reference/foundations/duration/": "untranslated", + "/docs/reference/foundations/eval/": "untranslated", + "/docs/reference/foundations/float/": "untranslated", + "/docs/reference/foundations/function/": "untranslated", + "/docs/reference/foundations/int/": "untranslated", + "/docs/reference/foundations/label/": "untranslated", + "/docs/reference/foundations/module/": "untranslated", + "/docs/reference/foundations/none/": "untranslated", + "/docs/reference/foundations/panic/": "untranslated", + "/docs/reference/foundations/plugin/": "untranslated", + "/docs/reference/foundations/regex/": "untranslated", + "/docs/reference/foundations/repr/": "untranslated", + "/docs/reference/foundations/selector/": "untranslated", + "/docs/reference/foundations/str/": "untranslated", + "/docs/reference/foundations/symbol/": "untranslated", + "/docs/reference/foundations/sys": "untranslated", + "/docs/reference/foundations/target/": "untranslated", + "/docs/reference/foundations/type/": "untranslated", + "/docs/reference/foundations/version/": "untranslated", + "/docs/reference/model/": "untranslated", + "/docs/reference/model/bibliography/": "translated", + "/docs/reference/model/list/": "translated", + "/docs/reference/model/cite/": "translated", + "/docs/reference/model/document/": "untranslated", + "/docs/reference/model/emph/": "translated", + "/docs/reference/model/figure/": "translated", + "/docs/reference/model/footnote/": "translated", + "/docs/reference/model/heading/": "untranslated", + "/docs/reference/model/link/": "translated", + "/docs/reference/model/enum/": "translated", + "/docs/reference/model/numbering/": "untranslated", + "/docs/reference/model/outline/": "untranslated", + "/docs/reference/model/par/": "untranslated", + "/docs/reference/model/parbreak/": "untranslated", + "/docs/reference/model/quote/": "untranslated", + "/docs/reference/model/ref/": "translated", + "/docs/reference/model/strong/": "untranslated", + "/docs/reference/model/table/": "untranslated", + "/docs/reference/model/terms/": "untranslated", + "/docs/reference/text/": "untranslated", + "/docs/reference/text/highlight/": "untranslated", + "/docs/reference/text/linebreak/": "untranslated", + "/docs/reference/text/lorem/": "untranslated", + "/docs/reference/text/lower/": "untranslated", + "/docs/reference/text/overline/": "untranslated", + "/docs/reference/text/raw/": "untranslated", + "/docs/reference/text/smallcaps/": "untranslated", + "/docs/reference/text/smartquote/": "untranslated", + "/docs/reference/text/strike/": "untranslated", + "/docs/reference/text/sub/": "untranslated", + "/docs/reference/text/super/": "untranslated", + "/docs/reference/text/text/": "untranslated", + "/docs/reference/text/underline/": "untranslated", + "/docs/reference/text/upper/": "untranslated", + "/docs/reference/math/": "untranslated", + "/docs/reference/math/accent/": "untranslated", + "/docs/reference/math/attach": "untranslated", + "/docs/reference/math/binom/": "untranslated", + "/docs/reference/math/cancel/": "untranslated", + "/docs/reference/math/cases/": "untranslated", + "/docs/reference/math/class/": "untranslated", + "/docs/reference/math/equation/": "untranslated", + "/docs/reference/math/frac/": "untranslated", + "/docs/reference/math/lr": "untranslated", + "/docs/reference/math/mat/": "untranslated", + "/docs/reference/math/primes/": "untranslated", + "/docs/reference/math/roots": "untranslated", + "/docs/reference/math/sizes": "untranslated", + "/docs/reference/math/stretch/": "untranslated", + "/docs/reference/math/styles": "untranslated", + "/docs/reference/math/op/": "untranslated", + "/docs/reference/math/underover": "untranslated", + "/docs/reference/math/variants": "untranslated", + "/docs/reference/math/vec/": "untranslated", + "/docs/reference/symbols/": "untranslated", + "/docs/reference/symbols/sym/": "untranslated", + "/docs/reference/symbols/emoji/": "untranslated", + "/docs/reference/layout/": "untranslated", + "/docs/reference/layout/align/": "untranslated", + "/docs/reference/layout/alignment/": "untranslated", + "/docs/reference/layout/angle/": "untranslated", + "/docs/reference/layout/block/": "untranslated", + "/docs/reference/layout/box/": "untranslated", + "/docs/reference/layout/colbreak/": "untranslated", + "/docs/reference/layout/columns/": "untranslated", + "/docs/reference/layout/direction/": "untranslated", + "/docs/reference/layout/fraction/": "untranslated", + "/docs/reference/layout/grid/": "untranslated", + "/docs/reference/layout/hide/": "untranslated", + "/docs/reference/layout/layout/": "untranslated", + "/docs/reference/layout/length/": "untranslated", + "/docs/reference/layout/measure/": "untranslated", + "/docs/reference/layout/move/": "untranslated", + "/docs/reference/layout/pad/": "untranslated", + "/docs/reference/layout/page/": "untranslated", + "/docs/reference/layout/pagebreak/": "untranslated", + "/docs/reference/layout/place/": "untranslated", + "/docs/reference/layout/ratio/": "untranslated", + "/docs/reference/layout/relative/": "untranslated", + "/docs/reference/layout/repeat/": "untranslated", + "/docs/reference/layout/rotate/": "untranslated", + "/docs/reference/layout/scale/": "untranslated", + "/docs/reference/layout/skew/": "untranslated", + "/docs/reference/layout/h/": "untranslated", + "/docs/reference/layout/v/": "untranslated", + "/docs/reference/layout/stack/": "untranslated", + "/docs/reference/visualize/": "untranslated", + "/docs/reference/visualize/circle/": "untranslated", + "/docs/reference/visualize/color/": "untranslated", + "/docs/reference/visualize/curve/": "untranslated", + "/docs/reference/visualize/ellipse/": "untranslated", + "/docs/reference/visualize/gradient/": "untranslated", + "/docs/reference/visualize/image/": "partially_translated", + "/docs/reference/visualize/line/": "untranslated", + "/docs/reference/visualize/path/": "untranslated", + "/docs/reference/visualize/polygon/": "untranslated", + "/docs/reference/visualize/rect/": "untranslated", + "/docs/reference/visualize/square/": "untranslated", + "/docs/reference/visualize/stroke/": "untranslated", + "/docs/reference/visualize/tiling/": "untranslated", + "/docs/reference/introspection/": "untranslated", + "/docs/reference/introspection/counter/": "untranslated", + "/docs/reference/introspection/here/": "untranslated", + "/docs/reference/introspection/locate/": "untranslated", + "/docs/reference/introspection/location/": "untranslated", + "/docs/reference/introspection/metadata/": "untranslated", + "/docs/reference/introspection/query/": "untranslated", + "/docs/reference/introspection/state/": "untranslated", + "/docs/reference/data-loading/": "untranslated", + "/docs/reference/data-loading/cbor/": "untranslated", + "/docs/reference/data-loading/csv/": "untranslated", + "/docs/reference/data-loading/json/": "untranslated", + "/docs/reference/data-loading/read/": "untranslated", + "/docs/reference/data-loading/toml/": "untranslated", + "/docs/reference/data-loading/xml/": "untranslated", + "/docs/reference/data-loading/yaml/": "untranslated", + "/docs/reference/pdf/": "untranslated", + "/docs/reference/pdf/embed/": "untranslated", + "/docs/reference/html/": "untranslated", + "/docs/reference/html/elem/": "untranslated", + "/docs/reference/html/frame/": "untranslated", + "/docs/reference/png/": "untranslated", + "/docs/reference/svg/": "untranslated", + "/docs/guides/": "untranslated", + "/docs/guides/guide-for-latex-users/": "untranslated", + "/docs/guides/page-setup-guide/": "untranslated", + "/docs/guides/table-guide/": "untranslated", + "/docs/changelog/": "untranslated", + "/docs/changelog/0.13.1/": "untranslated", + "/docs/changelog/0.13.0/": "untranslated", + "/docs/changelog/0.12.0/": "untranslated", + "/docs/changelog/0.11.1/": "untranslated", + "/docs/changelog/0.11.0/": "untranslated", + "/docs/changelog/0.10.0/": "untranslated", + "/docs/changelog/0.9.0/": "untranslated", + "/docs/changelog/0.8.0/": "untranslated", + "/docs/changelog/0.7.0/": "untranslated", + "/docs/changelog/0.6.0/": "untranslated", + "/docs/changelog/0.5.0/": "untranslated", + "/docs/changelog/0.4.0/": "untranslated", + "/docs/changelog/0.3.0/": "untranslated", + "/docs/changelog/0.2.0/": "untranslated", + "/docs/changelog/0.1.0/": "untranslated", + "/docs/changelog/earlier/": "untranslated", + "/docs/japanese/": "translated", + "/docs/japanese/templates/": "translated", + "/docs/japanese/packages/": "translated", + "/docs/japanese/articles/": "translated", + "/docs/glossary/": "translated" +} From 9bd453e65c63ee29b38362c3f7586b53af04a6a9 Mon Sep 17 00:00:00 2001 From: 3w36zj6 <52315048+3w36zj6@users.noreply.github.com> Date: Thu, 22 May 2025 01:26:32 +0900 Subject: [PATCH 3/3] =?UTF-8?q?chore:=20`reference/visualize/image/`?= =?UTF-8?q?=E3=81=AE=E7=BF=BB=E8=A8=B3=E7=8A=B6=E6=85=8B=E3=82=92=E7=BF=BB?= =?UTF-8?q?=E8=A8=B3=E6=B8=88=E3=81=AB=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- website/translation-status.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/translation-status.json b/website/translation-status.json index 026e5988c5..d929dcf279 100644 --- a/website/translation-status.json +++ b/website/translation-status.json @@ -135,7 +135,7 @@ "/docs/reference/visualize/curve/": "untranslated", "/docs/reference/visualize/ellipse/": "untranslated", "/docs/reference/visualize/gradient/": "untranslated", - "/docs/reference/visualize/image/": "partially_translated", + "/docs/reference/visualize/image/": "translated", "/docs/reference/visualize/line/": "untranslated", "/docs/reference/visualize/path/": "untranslated", "/docs/reference/visualize/polygon/": "untranslated",