Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions website/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,18 @@ 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";
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());
Expand Down
92 changes: 92 additions & 0 deletions website/src/utils/translationStatus.ts
Original file line number Diff line number Diff line change
@@ -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;
};
195 changes: 195 additions & 0 deletions website/translation-status.json
Original file line number Diff line number Diff line change
@@ -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"
}
17 changes: 17 additions & 0 deletions website/translation-status.schema.json
Original file line number Diff line number Diff line change
@@ -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": "ページの翻訳状態"
}
}
Loading