Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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/": "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