86 lines
3.6 KiB
JavaScript
86 lines
3.6 KiB
JavaScript
import { readFile, writeFile, mkdir } from "node:fs/promises";
|
||||
|
|
import path from "node:path";
|
|||
|
|
import { kingWenEntries, validateContentPackage } from "./content-contract.mjs";
|
|||
|
|
import { repositoryRoot } from "./repository-files.mjs";
|
|||
|
|
import { lingjiPlain } from "../content/plain/lingji-plain.mjs";
|
|||
|
|
|
|||
|
|
const names = [
|
|||
|
|
"乾", "坤", "屯", "蒙", "需", "讼", "师", "比",
|
|||
|
|
"小畜", "履", "泰", "否", "同人", "大有", "谦", "豫",
|
|||
|
|
"随", "蛊", "临", "观", "噬嗑", "贲", "剥", "复",
|
|||
|
|
"无妄", "大畜", "颐", "大过", "坎", "离", "咸", "恒",
|
|||
|
|
"遁", "大壮", "晋", "明夷", "家人", "睽", "蹇", "解",
|
|||
|
|
"损", "益", "夬", "姤", "萃", "升", "困", "井",
|
|||
|
|
"革", "鼎", "震", "艮", "渐", "归妹", "丰", "旅",
|
|||
|
|
"巽", "兑", "涣", "节", "中孚", "小过", "既济", "未济",
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
if (lingjiPlain.length !== 64) {
|
|||
|
|
throw new Error(`lingji plain table must contain 64 hexagrams, got ${lingjiPlain.length}`);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const jingPath = path.join(repositoryRoot, "content", "raw", "zhouyi-wikisource-jing.json");
|
|||
|
|
const jing = JSON.parse(await readFile(jingPath, "utf8"));
|
|||
|
|
if (!Array.isArray(jing) || jing.length !== 64) {
|
|||
|
|
throw new Error("Wikisource jing import must contain 64 hexagrams; run scripts/import-zhouyi-wikisource.mjs");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const jingById = new Map(jing.map((item) => [item.kingWenNumber, item]));
|
|||
|
|
const entries = kingWenEntries();
|
|||
|
|
const originalSource = "wikisource-zhouyi-jing-zh-Hans";
|
|||
|
|
const plainSource = "lingji-plain-zh-Hans-2026.1";
|
|||
|
|
|
|||
|
|
const contentPackage = {
|
|||
|
|
schemaVersion: 1,
|
|||
|
|
contentVersion: "zh-Hans-2026.1",
|
|||
|
|
specialUsageTexts: { qian: true, kun: true },
|
|||
|
|
sources: [
|
|||
|
|
{
|
|||
|
|
id: originalSource,
|
|||
|
|
title: "维基文库《周易》易经",
|
|||
|
|
edition: "仅卦辞、爻辞与乾用九、坤用六,不含十翼;由 zh.wikisource.org 导入并经 Wikimedia zh-hans 转换",
|
|||
|
|
license: "公版(Wikimedia PD-old)",
|
|||
|
|
url: "https://zh.wikisource.org/wiki/周易",
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: plainSource,
|
|||
|
|
title: "灵机本地白话",
|
|||
|
|
edition: "2026.1 项目自撰草稿,待内容负责人审校后视为可再分发",
|
|||
|
|
license: "项目自撰;审校完成前仅用于本机构建,不以现代译注冒充公版",
|
|||
|
|
url: "https://creativecommons.org/licenses/by/4.0/deed.zh-Hans",
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
hexagrams: entries.map((entry) => {
|
|||
|
|
const original = jingById.get(entry.kingWenNumber);
|
|||
|
|
if (!original) {
|
|||
|
|
throw new Error(`Missing jing text for King Wen ${entry.kingWenNumber}`);
|
|||
|
|
}
|
|||
|
|
const plain = lingjiPlain[entry.kingWenNumber - 1];
|
|||
|
|
if (!Array.isArray(plain) || plain.length !== 7 || plain.some((text) => !String(text).trim())) {
|
|||
|
|
throw new Error(`Plain text for King Wen ${entry.kingWenNumber} must contain 7 non-blank strings`);
|
|||
|
|
}
|
|||
|
|
return {
|
|||
|
|
...entry,
|
|||
|
|
name: names[entry.kingWenNumber - 1],
|
|||
|
|
symbol: String.fromCodePoint(0x4DC0 + entry.kingWenNumber - 1),
|
|||
|
|
judgmentOriginal: original.judgmentOriginal,
|
|||
|
|
judgmentPlain: plain[0],
|
|||
|
|
lineTextsBottomUp: original.lineTextsBottomUp,
|
|||
|
|
linePlainBottomUp: plain.slice(1),
|
|||
|
|
specialUsageText: original.specialUsageText ?? null,
|
|||
|
|
sourceRefs: [originalSource, plainSource],
|
|||
|
|
};
|
|||
|
|
}),
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const errors = validateContentPackage(contentPackage);
|
|||
|
|
if (errors.length > 0) {
|
|||
|
|
throw new Error(`Built content package failed validation:\n${errors.join("\n")}`);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const outputDirectory = path.join(repositoryRoot, "content", "packages");
|
|||
|
|
await mkdir(outputDirectory, { recursive: true });
|
|||
|
|
const outputPath = path.join(outputDirectory, "hexagram-content.json");
|
|||
|
|
await writeFile(outputPath, `${JSON.stringify(contentPackage, null, 2)}\n`);
|
|||
|
|
process.stdout.write(`wrote ${outputPath}\n`);
|