@godcreator/word-report 0.4.1 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{assemble-BpllQNVY.mjs → assemble-BEt9_xsB.mjs} +23 -0
- package/dist/cli.d.mts +1 -7
- package/dist/cli.mjs +4 -30
- package/dist/core.d.mts +2 -22
- package/dist/core.mjs +3 -3
- package/dist/{convert-o7bPWP9A.mjs → export-CGvF3Wz-.mjs} +12 -160
- package/dist/{export-Da4yhrZa.d.mts → export-DMKj4gl2.d.mts} +2 -18
- package/dist/{mdx-4Rs1N1nv.mjs → mdx-B1V34o8x.mjs} +84 -337
- package/dist/node.d.mts +3 -3
- package/dist/node.mjs +3 -3
- package/dist/{page-data-CJ6nCBnW.d.mts → page-data-C1veAE55.d.mts} +1 -1
- package/dist/{report-files-BsIvifZe.mjs → report-files-DyPBOCgh.mjs} +2 -2
- package/dist/site-server.d.mts +1 -1
- package/dist/site-server.mjs +3 -3
- package/dist/site.d.mts +2 -2
- package/dist/site.mjs +1 -1
- package/dist/{types-Bcl48xQN.d.mts → types-Ea2OT6Ac.d.mts} +7 -1
- package/engine/README.md +3 -3
- package/engine/schemas/report-content.schema.json +42 -0
- package/engine/src/docreport/__main__.py +18 -2
- package/engine/src/docreport/compose.py +51 -17
- package/engine/src/docreport/mathtype.py +3 -2
- package/engine/src/docreport/plain_math.py +53 -0
- package/engine/src/docreport/verify.py +39 -0
- package/engine/src/docreport/word.py +23 -0
- package/engine/templates/project-report.dotx +0 -0
- package/package.json +1 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { a as walk, r as stableValue, s as ReportContentError, t as assembleDocument } from "./assemble-
|
|
1
|
+
import { a as walk, r as stableValue, s as ReportContentError, t as assembleDocument } from "./assemble-BEt9_xsB.mjs";
|
|
2
2
|
import remarkFrontmatter from "remark-frontmatter";
|
|
3
3
|
import remarkGfm from "remark-gfm";
|
|
4
4
|
import remarkMath from "remark-math";
|
|
5
5
|
import remarkMdx from "remark-mdx";
|
|
6
6
|
import remarkParse from "remark-parse";
|
|
7
7
|
import { unified } from "unified";
|
|
8
|
-
import { parse
|
|
8
|
+
import { parse } from "yaml";
|
|
9
9
|
//#region src/core/mdx/parse.ts
|
|
10
10
|
const mdxParser = unified().use(remarkParse).use(remarkFrontmatter, ["yaml"]).use(remarkMdx).use(remarkGfm).use(remarkMath);
|
|
11
11
|
/** 源位置写成「行:列」,放在 ReportContentError 的 pointer 里 */
|
|
@@ -169,14 +169,14 @@ const MARK_ELEMENTS = {
|
|
|
169
169
|
};
|
|
170
170
|
/** 只能单独成段的组件:写进一段文字中间时报错 */
|
|
171
171
|
const BLOCK_COMPONENTS = /* @__PURE__ */ new Set([
|
|
172
|
-
"
|
|
173
|
-
"
|
|
174
|
-
"
|
|
175
|
-
"
|
|
176
|
-
"
|
|
177
|
-
"
|
|
178
|
-
"
|
|
179
|
-
"
|
|
172
|
+
"WordFigure",
|
|
173
|
+
"WordFigures",
|
|
174
|
+
"WordTable",
|
|
175
|
+
"WordAbstract",
|
|
176
|
+
"WordBibliography",
|
|
177
|
+
"WordReference",
|
|
178
|
+
"WordCaption",
|
|
179
|
+
"WordPanel",
|
|
180
180
|
"table",
|
|
181
181
|
"tr",
|
|
182
182
|
"th",
|
|
@@ -253,7 +253,7 @@ function collectInlines(context, nodes, marks, out) {
|
|
|
253
253
|
if (!isCommentOnlyExpression(node)) failAt(context, node, "正文里不能写 {…} 表达式;只想写花括号就写成 \\{ \\},注释写成 {/* … */}");
|
|
254
254
|
break;
|
|
255
255
|
case "image":
|
|
256
|
-
case "imageReference": failAt(context, node, "Markdown 图片  不收:图写成 <
|
|
256
|
+
case "imageReference": failAt(context, node, "Markdown 图片  不收:图写成 <WordFigure src=\"assets/…\">图题</WordFigure>");
|
|
257
257
|
case "linkReference": failAt(context, node, "不支持引用式链接 [文字][名字]:链接写成 [文字](https://…)");
|
|
258
258
|
case "delete": failAt(context, node, "不支持删除线 ~~…~~");
|
|
259
259
|
case "html": failAt(context, node, "不支持原始 HTML");
|
|
@@ -268,16 +268,16 @@ function collectElement(context, element, marks, out) {
|
|
|
268
268
|
return;
|
|
269
269
|
}
|
|
270
270
|
switch (name) {
|
|
271
|
-
case "
|
|
271
|
+
case "WordRef": {
|
|
272
272
|
const attributes = attributesOf(context, element, {
|
|
273
273
|
to: "required",
|
|
274
274
|
show: "optional"
|
|
275
275
|
});
|
|
276
276
|
rejectChildren(context, element);
|
|
277
|
-
if (/\s/.test(attributes["to"].trim())) failAt(context, element, "<
|
|
277
|
+
if (/\s/.test(attributes["to"].trim())) failAt(context, element, "<WordRef> 的 to 只能写一个 id");
|
|
278
278
|
const [target] = idTargetsOf(context, element, attributes["to"]);
|
|
279
279
|
const show = attributes["show"];
|
|
280
|
-
if (show !== void 0 && show !== "number" && show !== "title") failAt(context, element, `<
|
|
280
|
+
if (show !== void 0 && show !== "number" && show !== "title") failAt(context, element, `<WordRef> 的 show 只能是 number 或 title(不写就显示「图 3-2」这种全称),这里写的是「${show}」`);
|
|
281
281
|
const display = show ?? "label";
|
|
282
282
|
out.push(located(context, context.ids.request({
|
|
283
283
|
type: "ref",
|
|
@@ -287,7 +287,7 @@ function collectElement(context, element, marks, out) {
|
|
|
287
287
|
}, "ref"), element));
|
|
288
288
|
return;
|
|
289
289
|
}
|
|
290
|
-
case "
|
|
290
|
+
case "WordCite": {
|
|
291
291
|
const attributes = attributesOf(context, element, { to: "required" });
|
|
292
292
|
rejectChildren(context, element);
|
|
293
293
|
out.push(located(context, context.ids.request({
|
|
@@ -297,6 +297,17 @@ function collectElement(context, element, marks, out) {
|
|
|
297
297
|
}, "cite"), element));
|
|
298
298
|
return;
|
|
299
299
|
}
|
|
300
|
+
case "WordPlainMath": {
|
|
301
|
+
const attributes = attributesOf(context, element, { tex: "required" });
|
|
302
|
+
const plainText = plainMathRunsOf(context, element);
|
|
303
|
+
out.push(located(context, context.ids.request({
|
|
304
|
+
type: "math",
|
|
305
|
+
id: "",
|
|
306
|
+
latex: attributes["tex"],
|
|
307
|
+
plainText
|
|
308
|
+
}, "m"), element));
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
300
311
|
case "br":
|
|
301
312
|
attributesOf(context, element, {});
|
|
302
313
|
rejectChildren(context, element);
|
|
@@ -304,9 +315,36 @@ function collectElement(context, element, marks, out) {
|
|
|
304
315
|
return;
|
|
305
316
|
default:
|
|
306
317
|
if (name !== null && BLOCK_COMPONENTS.has(name)) failAt(context, element, `<${name}> 要单独成段,前后空一行,不写在一段文字中间`);
|
|
307
|
-
failAt(context, element,
|
|
318
|
+
failAt(context, element, unknownComponentMessage(name ?? "", "行内只能用 WordRef、WordCite、WordPlainMath 与 HTML 标签 sub、sup、strong、em、br"));
|
|
308
319
|
}
|
|
309
320
|
}
|
|
321
|
+
/** 认不出的元素:大写开头、不以 Word 开头的单独说明——报告的组件名都以 Word 开头,小写的只认几个 HTML 标签 */
|
|
322
|
+
function unknownComponentMessage(name, allowed) {
|
|
323
|
+
if (/^[A-Z]/.test(name) && !name.startsWith("Word")) return `报告里的组件都以 Word 开头,<${name}> 不认:${allowed}`;
|
|
324
|
+
return `认不出组件 <${name}>:${allowed}`;
|
|
325
|
+
}
|
|
326
|
+
const PLAIN_MATH_MARKS = [
|
|
327
|
+
"em",
|
|
328
|
+
"sub",
|
|
329
|
+
"sup"
|
|
330
|
+
];
|
|
331
|
+
/** <WordPlainMath> 里写给 Word 的文字:只收文字、斜体、下标、上标 */
|
|
332
|
+
function plainMathRunsOf(context, element) {
|
|
333
|
+
const usage = "<WordPlainMath tex=\"…\"> 里写 Word 用的文字,只能用文字、*斜体*、<sub>、<sup>";
|
|
334
|
+
const inlines = inlinesOf(context, element.children);
|
|
335
|
+
if (!inlines.length) failAt(context, element, `${usage},这里是空的`);
|
|
336
|
+
return inlines.map((inline) => {
|
|
337
|
+
if (inline.type !== "text") failAt(context, element, `${usage},这里出现了 ${inline.type}`);
|
|
338
|
+
const marks = inline.marks ?? [];
|
|
339
|
+
const unsupported = marks.find((mark) => !PLAIN_MATH_MARKS.includes(mark));
|
|
340
|
+
if (unsupported !== void 0) failAt(context, element, `${usage},这里出现了 ${unsupported}`);
|
|
341
|
+
if (marks.includes("sub") && marks.includes("sup")) failAt(context, element, "<WordPlainMath> 里同一段文字不能既是下标又是上标");
|
|
342
|
+
return marks.length ? {
|
|
343
|
+
text: inline.text,
|
|
344
|
+
marks
|
|
345
|
+
} : { text: inline.text };
|
|
346
|
+
});
|
|
347
|
+
}
|
|
310
348
|
function linkTextOf(context, link) {
|
|
311
349
|
const inlines = [];
|
|
312
350
|
collectInlines(context, link.children, [], inlines);
|
|
@@ -343,7 +381,7 @@ function plainTextOf(inlines) {
|
|
|
343
381
|
return inlines.map((inline) => {
|
|
344
382
|
switch (inline.type) {
|
|
345
383
|
case "text": return inline.text;
|
|
346
|
-
case "math": return `$${inline.latex}$`;
|
|
384
|
+
case "math": return inline.plainText ? inline.plainText.map((run) => run.text).join("") : `$${inline.latex}$`;
|
|
347
385
|
case "link": return inline.text;
|
|
348
386
|
case "break": return " ";
|
|
349
387
|
default: return "";
|
|
@@ -386,15 +424,15 @@ const BLOCK_NAMES = {
|
|
|
386
424
|
table: "表",
|
|
387
425
|
equation: "公式",
|
|
388
426
|
code: "代码块",
|
|
389
|
-
bibliography: "<
|
|
390
|
-
abstract: "<
|
|
427
|
+
bibliography: "<WordBibliography />",
|
|
428
|
+
abstract: "<WordAbstract>"
|
|
391
429
|
};
|
|
392
430
|
const PLACE_NAMES = {
|
|
393
431
|
top: "正文",
|
|
394
432
|
listItem: "列表项",
|
|
395
433
|
cell: "表格单元格",
|
|
396
434
|
note: "脚注",
|
|
397
|
-
abstract: "<
|
|
435
|
+
abstract: "<WordAbstract>"
|
|
398
436
|
};
|
|
399
437
|
const explicitOrRequested = (context, node, rawId, source, kind) => {
|
|
400
438
|
if (rawId !== void 0) node.id = explicitIdOf(rawId, context.file, positionOf(source));
|
|
@@ -542,25 +580,25 @@ function codeOf(context, node) {
|
|
|
542
580
|
}
|
|
543
581
|
function componentOf(context, element, place) {
|
|
544
582
|
switch (element.name) {
|
|
545
|
-
case "
|
|
546
|
-
case "
|
|
547
|
-
case "
|
|
548
|
-
case "
|
|
549
|
-
case "
|
|
583
|
+
case "WordFigure": return figureOf(context, element);
|
|
584
|
+
case "WordFigures": return multiFigureOf(context, element);
|
|
585
|
+
case "WordTable": return numberedTableOf(context, element);
|
|
586
|
+
case "WordAbstract": return abstractOf(context, element, place);
|
|
587
|
+
case "WordBibliography":
|
|
550
588
|
attributesOf(context, element, {});
|
|
551
|
-
if (element.children.some((child) => !isCommentOnlyExpression(child))) failAt(context, element, "<
|
|
589
|
+
if (element.children.some((child) => !isCommentOnlyExpression(child))) failAt(context, element, "<WordBibliography /> 不收子内容");
|
|
552
590
|
return located(context, context.ids.request({
|
|
553
591
|
type: "bibliography",
|
|
554
592
|
id: ""
|
|
555
593
|
}, "bib"), element);
|
|
556
|
-
case "
|
|
557
|
-
case "
|
|
558
|
-
case "
|
|
594
|
+
case "WordReference": return failAt(context, element, "<WordReference> 只能写在报告目录的 references.mdx 里");
|
|
595
|
+
case "WordCaption": return failAt(context, element, "<WordCaption> 只能写在 <WordTable> 或 <WordFigures> 里");
|
|
596
|
+
case "WordPanel": return failAt(context, element, "<WordPanel> 只能写在 <WordFigures> 里");
|
|
559
597
|
case "table":
|
|
560
598
|
case "tr":
|
|
561
599
|
case "th":
|
|
562
|
-
case "td": return failAt(context, element, `<${element.name}> 只能写在 <
|
|
563
|
-
default: return failAt(context, element,
|
|
600
|
+
case "td": return failAt(context, element, `<${element.name}> 只能写在 <WordTable> 里:不编号的简单表格直接写 GFM 表格`);
|
|
601
|
+
default: return failAt(context, element, unknownComponentMessage(element.name ?? "", "块级只能用 WordFigure、WordFigures、WordTable、WordAbstract、WordBibliography"));
|
|
564
602
|
}
|
|
565
603
|
}
|
|
566
604
|
function captionOf(context, element, what) {
|
|
@@ -574,7 +612,7 @@ function figureOf(context, element) {
|
|
|
574
612
|
src: "required",
|
|
575
613
|
alt: "optional"
|
|
576
614
|
});
|
|
577
|
-
const caption = captionOf(context, element, "<
|
|
615
|
+
const caption = captionOf(context, element, "<WordFigure> 的图题");
|
|
578
616
|
return explicitOrRequested(context, {
|
|
579
617
|
type: "figure",
|
|
580
618
|
id: "",
|
|
@@ -590,12 +628,12 @@ function multiFigureOf(context, element) {
|
|
|
590
628
|
columns: "required"
|
|
591
629
|
});
|
|
592
630
|
const children = elementChildrenOf(context, element);
|
|
593
|
-
const captions = children.filter((child) => child.name === "
|
|
594
|
-
if (captions.length !== 1) failAt(context, element, "<
|
|
595
|
-
for (const child of children) if (child.name !== "
|
|
631
|
+
const captions = children.filter((child) => child.name === "WordCaption");
|
|
632
|
+
if (captions.length !== 1) failAt(context, element, "<WordFigures> 里要有且只有一个 <WordCaption> 写整个图的图题");
|
|
633
|
+
for (const child of children) if (child.name !== "WordCaption" && child.name !== "WordPanel") failAt(context, child, `<WordFigures> 里只能放 <WordCaption> 与 <WordPanel>,不能放 <${child.name}>`);
|
|
596
634
|
attributesOf(context, captions[0], {});
|
|
597
|
-
const caption = captionOf(context, captions[0], "<
|
|
598
|
-
const panels = children.filter((child) => child.name === "
|
|
635
|
+
const caption = captionOf(context, captions[0], "<WordFigures> 的图题");
|
|
636
|
+
const panels = children.filter((child) => child.name === "WordPanel").map((panel) => panelOf(context, panel));
|
|
599
637
|
const figure = {
|
|
600
638
|
type: "figure",
|
|
601
639
|
id: "",
|
|
@@ -617,7 +655,7 @@ function panelOf(context, element) {
|
|
|
617
655
|
});
|
|
618
656
|
const caption = inlinesOf(context, phrasingChildrenOf(context, element));
|
|
619
657
|
const alt = attributes["alt"] ?? plainTextOf(caption);
|
|
620
|
-
if (!alt) failAt(context, element, "<
|
|
658
|
+
if (!alt) failAt(context, element, "<WordPanel> 没有小标题时要写 alt");
|
|
621
659
|
const panel = {
|
|
622
660
|
id: "",
|
|
623
661
|
row: positiveIntegerOf(context, element, "row", attributes["row"]),
|
|
@@ -633,12 +671,12 @@ function numberedTableOf(context, element) {
|
|
|
633
671
|
const attributes = attributesOf(context, element, { id: "optional" });
|
|
634
672
|
const parts = element.children.filter((child) => !isCommentOnlyExpression(child) && !isWhitespaceText(child)).flatMap((child) => child.type === "paragraph" ? child.children.filter((inner) => !isWhitespaceText(inner)) : [child]);
|
|
635
673
|
let caption;
|
|
636
|
-
if (parts[0]?.name === "
|
|
674
|
+
if (parts[0]?.name === "WordCaption") {
|
|
637
675
|
attributesOf(context, parts[0], {});
|
|
638
|
-
caption = captionOf(context, parts.shift(), "<
|
|
676
|
+
caption = captionOf(context, parts.shift(), "<WordCaption> 的表题");
|
|
639
677
|
}
|
|
640
678
|
const body = parts[0];
|
|
641
|
-
if (parts.length !== 1 || !body || !(body.type === "table" || body.name === "table")) failAt(context, element, "<
|
|
679
|
+
if (parts.length !== 1 || !body || !(body.type === "table" || body.name === "table")) failAt(context, element, "<WordTable> 里先写可省的 <WordCaption>,再写一张表(GFM 表格或 <table>),别的不放");
|
|
642
680
|
return body.type === "table" ? tableFromGfm(context, body, true, caption, attributes["id"] ?? null, element) : tableFromJsx(context, body, caption, attributes["id"] ?? null, element);
|
|
643
681
|
}
|
|
644
682
|
function finishedTable(context, table, caption, rawId, source) {
|
|
@@ -719,13 +757,13 @@ function tableFromJsx(context, element, caption, rawId, source) {
|
|
|
719
757
|
}, caption, rawId, source);
|
|
720
758
|
}
|
|
721
759
|
function abstractOf(context, element, place) {
|
|
722
|
-
if (context.role !== "index" || place !== "top") failAt(context, element, "<
|
|
760
|
+
if (context.role !== "index" || place !== "top") failAt(context, element, "<WordAbstract> 只能写在 index.mdx 的正文最前面");
|
|
723
761
|
const attributes = attributesOf(context, element, {
|
|
724
762
|
keywords: "required",
|
|
725
763
|
title: "optional"
|
|
726
764
|
});
|
|
727
765
|
const keywords = attributes["keywords"].split(";").map((keyword) => keyword.trim());
|
|
728
|
-
if (keywords.some((keyword) => !keyword)) failAt(context, element, "<
|
|
766
|
+
if (keywords.some((keyword) => !keyword)) failAt(context, element, "<WordAbstract> 的 keywords 用全角分号「;」隔开,每个关键词都不能空");
|
|
729
767
|
const abstract = {
|
|
730
768
|
type: "abstract",
|
|
731
769
|
id: "",
|
|
@@ -881,13 +919,13 @@ function referencesOf(context, root) {
|
|
|
881
919
|
for (const node of root.children) {
|
|
882
920
|
if (isCommentOnlyExpression(node)) continue;
|
|
883
921
|
const element = node.type === "paragraph" && node.children.length === 1 ? node.children[0] : node;
|
|
884
|
-
if (element.type !== "mdxJsxFlowElement" && element.type !== "mdxJsxTextElement" || element.name !== "
|
|
922
|
+
if (element.type !== "mdxJsxFlowElement" && element.type !== "mdxJsxTextElement" || element.name !== "WordReference") failAt(context, node, "references.mdx 里只能写 <WordReference id=\"…\" url=\"…\">著录文字</WordReference>,一条一段");
|
|
885
923
|
const attributes = attributesOf(context, element, {
|
|
886
924
|
id: "required",
|
|
887
925
|
url: "optional"
|
|
888
926
|
});
|
|
889
927
|
const text = inlinesOf(context, phrasingChildrenOf(context, element));
|
|
890
|
-
if (text.length !== 1 || text[0].type !== "text" || text[0].marks) failAt(context, element, "<
|
|
928
|
+
if (text.length !== 1 || text[0].type !== "text" || text[0].marks) failAt(context, element, "<WordReference> 的著录文字只能是一行纯文字");
|
|
891
929
|
const entry = {
|
|
892
930
|
id: explicitIdOf(attributes["id"], context.file, positionOf(element)),
|
|
893
931
|
text: text[0].text
|
|
@@ -995,295 +1033,4 @@ function assembleMdxReport(input, options = {}) {
|
|
|
995
1033
|
};
|
|
996
1034
|
}
|
|
997
1035
|
//#endregion
|
|
998
|
-
|
|
999
|
-
const UNICODE_PUNCTUATION = /[\p{P}\p{S}]/u;
|
|
1000
|
-
const MARK_WRAP_ORDER = [
|
|
1001
|
-
"code",
|
|
1002
|
-
"sub",
|
|
1003
|
-
"sup",
|
|
1004
|
-
"em",
|
|
1005
|
-
"strong"
|
|
1006
|
-
];
|
|
1007
|
-
/** Markdown 与 MDX 的特殊字符一律加反斜杠;GFM 会把网址与邮箱自动变成链接,冒号、点与 @ 也拆开 */
|
|
1008
|
-
function escapedText(text) {
|
|
1009
|
-
return text.replace(/[\\`*_{}[\]<>$|~&#@]/g, (character) => `\\${character}`).replace(/:\/\//g, "\\://").replace(/www\./gi, (match) => `${match.slice(0, 3)}\\.`);
|
|
1010
|
-
}
|
|
1011
|
-
/** 一段的开头像列表、标题、引用的,再加一层转义 */
|
|
1012
|
-
function escapedLineStart(line) {
|
|
1013
|
-
return line.replace(/^(\d+)([.)])/, "$1\\$2").replace(/^([-+])(\s|$)/, "\\$1$2");
|
|
1014
|
-
}
|
|
1015
|
-
function codeSpan(text) {
|
|
1016
|
-
const longest = Math.max(0, ...(text.match(/`+/g) ?? []).map((run) => run.length));
|
|
1017
|
-
const fence = "`".repeat(longest + 1);
|
|
1018
|
-
const padding = text.startsWith("`") || text.endsWith("`") ? " " : "";
|
|
1019
|
-
return `${fence}${padding}${text}${padding}${fence}`;
|
|
1020
|
-
}
|
|
1021
|
-
/** 加粗、斜体在内容首尾不是空白与标点时用 ** 与 *(中文旁边才认得出),否则用 <strong> 与 <em> */
|
|
1022
|
-
function wrappedWithMark(inner, plain, mark) {
|
|
1023
|
-
if (mark === "sub" || mark === "sup") return `<${mark}>${inner}</${mark}>`;
|
|
1024
|
-
const first = plain[0], last = plain.at(-1);
|
|
1025
|
-
if (first !== void 0 && last !== void 0 && !/\s/.test(first) && !/\s/.test(last) && !UNICODE_PUNCTUATION.test(first) && !UNICODE_PUNCTUATION.test(last)) return mark === "strong" ? `**${inner}**` : `*${inner}*`;
|
|
1026
|
-
return `<${mark}>${inner}</${mark}>`;
|
|
1027
|
-
}
|
|
1028
|
-
function attributeOf(name, value, problems, at) {
|
|
1029
|
-
if (!value.includes("\"")) return ` ${name}="${value}"`;
|
|
1030
|
-
if (!value.includes("'")) return ` ${name}='${value}'`;
|
|
1031
|
-
problems.push(`${at}:${name} 里同时有单引号和双引号,写不成组件属性`);
|
|
1032
|
-
return "";
|
|
1033
|
-
}
|
|
1034
|
-
var MdxWriter = class {
|
|
1035
|
-
problems = [];
|
|
1036
|
-
images = Object.create(null);
|
|
1037
|
-
keptIds;
|
|
1038
|
-
assets;
|
|
1039
|
-
constructor(keptIds, assets) {
|
|
1040
|
-
this.keptIds = keptIds;
|
|
1041
|
-
this.assets = assets;
|
|
1042
|
-
}
|
|
1043
|
-
idAttribute(id, at) {
|
|
1044
|
-
return id !== void 0 && this.keptIds.has(id) ? attributeOf("id", id, this.problems, at) : "";
|
|
1045
|
-
}
|
|
1046
|
-
/** 图片按文件名放进新报告的 assets/:同名不同图报错 */
|
|
1047
|
-
imagePath(src, at) {
|
|
1048
|
-
const original = this.assets[src] ?? src;
|
|
1049
|
-
const name = original.slice(original.lastIndexOf("/") + 1);
|
|
1050
|
-
const previous = this.images[name];
|
|
1051
|
-
if (previous !== void 0 && previous !== src) this.problems.push(`${at}:图片 ${name} 和 ${previous} 同名,放进同一个 assets/ 会互相覆盖`);
|
|
1052
|
-
this.images[name] = src;
|
|
1053
|
-
return `assets/${name}`;
|
|
1054
|
-
}
|
|
1055
|
-
inlines(inlines, at) {
|
|
1056
|
-
let previousWasMath = false;
|
|
1057
|
-
return inlines.map((inline, index) => {
|
|
1058
|
-
const here = `${at}/${index}`;
|
|
1059
|
-
if (inline.type === "math" && previousWasMath) this.problems.push(`${here}:两个行内公式紧挨着,写成 $…$$…$ 会被读成一个`);
|
|
1060
|
-
previousWasMath = inline.type === "math";
|
|
1061
|
-
switch (inline.type) {
|
|
1062
|
-
case "text": {
|
|
1063
|
-
let written = (inline.marks ?? []).includes("code") ? codeSpan(inline.text) : escapedText(inline.text);
|
|
1064
|
-
for (const mark of MARK_WRAP_ORDER) if (mark !== "code" && inline.marks?.includes(mark)) written = wrappedWithMark(written, inline.text, mark);
|
|
1065
|
-
return written;
|
|
1066
|
-
}
|
|
1067
|
-
case "math":
|
|
1068
|
-
if (inline.latex.includes("$") || /[\r\n]/.test(inline.latex)) this.problems.push(`${here}:行内公式里有 $ 或换行,写不成 $…$`);
|
|
1069
|
-
return `$${inline.latex}$`;
|
|
1070
|
-
case "ref": return `<Ref to="${inline.target}"${inline.display === "label" ? "" : ` show="${inline.display}"`} />`;
|
|
1071
|
-
case "cite": return `<Cite to="${inline.targets.join(" ")}" />`;
|
|
1072
|
-
case "link": return `[${escapedText(inline.text)}](${/[\s()<>]/.test(inline.href) ? `<${inline.href}>` : inline.href})`;
|
|
1073
|
-
case "note_ref": return `[^${inline.target}]`;
|
|
1074
|
-
case "break": return "<br />";
|
|
1075
|
-
}
|
|
1076
|
-
}).join("");
|
|
1077
|
-
}
|
|
1078
|
-
/** 段落各占一行写出;表格单元格里的段落不在行首,不用防它被读成列表,空段落就是空格子 */
|
|
1079
|
-
paragraph(content, at, insideCell = false) {
|
|
1080
|
-
if (!content.length && !insideCell) this.problems.push(`${at}:没有内容的段落在 MDX 里写不出来`);
|
|
1081
|
-
const written = this.inlines(content, `${at}/content`);
|
|
1082
|
-
return insideCell ? written : escapedLineStart(written);
|
|
1083
|
-
}
|
|
1084
|
-
/** 一个单元格:只有一段(含空段,即空格子)写成行内内容,否则 null(要写成块);没有块的格子编译回来是一个空段 */
|
|
1085
|
-
cellInline(blocks, at) {
|
|
1086
|
-
if (blocks.length === 0) return "";
|
|
1087
|
-
const only = blocks.length === 1 ? blocks[0] : void 0;
|
|
1088
|
-
return only?.type === "paragraph" ? this.paragraph(only.content, `${at}/blocks/0`, true) : null;
|
|
1089
|
-
}
|
|
1090
|
-
/** 块之间空一行;相邻两个同类列表中间放一个注释,否则会并成一个列表 */
|
|
1091
|
-
blocks(blocks, at, depth, parentNumbering) {
|
|
1092
|
-
const lines = [];
|
|
1093
|
-
blocks.forEach((block, index) => {
|
|
1094
|
-
const previous = blocks[index - 1];
|
|
1095
|
-
if (block.type === "list" && previous?.type === "list" && previous.ordered === block.ordered) lines.push("{/* 两个列表的分界 */}");
|
|
1096
|
-
lines.push(this.block(block, `${at}/${index}`, depth, parentNumbering));
|
|
1097
|
-
});
|
|
1098
|
-
return lines;
|
|
1099
|
-
}
|
|
1100
|
-
block(block, at, depth, parentNumbering) {
|
|
1101
|
-
switch (block.type) {
|
|
1102
|
-
case "section": return this.section(block, at, depth, parentNumbering);
|
|
1103
|
-
case "paragraph": return this.paragraph(block.content, at);
|
|
1104
|
-
case "list": return this.list(block, at, "");
|
|
1105
|
-
case "figure": return this.figure(block, at);
|
|
1106
|
-
case "table": return this.table(block, at);
|
|
1107
|
-
case "equation": {
|
|
1108
|
-
if (!block.numbered) {
|
|
1109
|
-
if (block.latex.includes("$$")) this.problems.push(`${at}:公式里有 $$,写不成 $$ 块`);
|
|
1110
|
-
if (this.keptIds.has(block.id)) this.problems.push(`${at}:不编号的公式被引用或写在 layout.json 里,MDX 里不编号的公式没有 id`);
|
|
1111
|
-
return `$$\n${block.latex}\n$$`;
|
|
1112
|
-
}
|
|
1113
|
-
const fence = "`".repeat(Math.max(3, ...(block.latex.match(/`{3,}/g) ?? []).map((run) => run.length + 1)));
|
|
1114
|
-
return `${fence}math${this.keptIds.has(block.id) ? ` ${block.id}` : ""}\n${block.latex}\n${fence}`;
|
|
1115
|
-
}
|
|
1116
|
-
case "code": {
|
|
1117
|
-
if (block.language === "math") this.problems.push(`${at}:语言是 math 的代码块在 MDX 里会被当成编号公式`);
|
|
1118
|
-
const fence = "`".repeat(Math.max(3, ...(block.text.match(/`{3,}/g) ?? []).map((run) => run.length + 1)));
|
|
1119
|
-
return `${fence}${block.language}\n${block.text}\n${fence}`;
|
|
1120
|
-
}
|
|
1121
|
-
case "bibliography":
|
|
1122
|
-
this.problems.push(`${at}:<Bibliography /> 只能放在文末(不写时组装会补上)`);
|
|
1123
|
-
return "";
|
|
1124
|
-
case "abstract": return this.abstract(block, at);
|
|
1125
|
-
}
|
|
1126
|
-
}
|
|
1127
|
-
abstract(block, at) {
|
|
1128
|
-
if (block.keywords.some((keyword) => keyword.includes(";"))) this.problems.push(`${at}:关键词里有全角分号,<Abstract keywords> 用它分隔`);
|
|
1129
|
-
const title = block.title !== void 0 ? attributeOf("title", block.title, this.problems, at) : "";
|
|
1130
|
-
const paragraphs = block.paragraphs.map((paragraph, index) => this.paragraph(paragraph.content, `${at}/paragraphs/${index}`));
|
|
1131
|
-
return `<Abstract keywords="${block.keywords.join(";")}"${title}>\n\n${paragraphs.join("\n\n")}\n\n</Abstract>`;
|
|
1132
|
-
}
|
|
1133
|
-
section(section, at, depth, parentNumbering) {
|
|
1134
|
-
if (depth > 6) this.problems.push(`${at}:标题超过六级`);
|
|
1135
|
-
const expected = parentNumbering === "none" ? "none" : "decimal";
|
|
1136
|
-
if (depth > 1 && section.numbering !== expected) this.problems.push(`${at}:${parentNumbering} 节下面的 ${section.numbering} 子节在 MDX 里写不出来(子节跟着上级编号)`);
|
|
1137
|
-
if (/\[#[^\]]*\]\s*$/.test(section.title)) this.problems.push(`${at}:标题末尾的 [#…] 会被当成节的 id`);
|
|
1138
|
-
return [`${"#".repeat(depth)} ${escapedText(section.title)}${this.keptIds.has(section.id) ? ` [#${section.id}]` : ""}`, ...this.blocks(section.children, `${at}/children`, depth + 1, section.numbering)].join("\n\n");
|
|
1139
|
-
}
|
|
1140
|
-
list(list, at, indent) {
|
|
1141
|
-
return list.items.map((item, index) => {
|
|
1142
|
-
const marker = list.ordered ? `${(list.start ?? 1) + index}. ` : "- ";
|
|
1143
|
-
const continuation = indent + " ".repeat(marker.length);
|
|
1144
|
-
return item.blocks.map((block, blockIndex) => {
|
|
1145
|
-
const here = `${at}/items/${index}/blocks/${blockIndex}`;
|
|
1146
|
-
return block.type === "list" ? this.list(block, here, continuation) : this.paragraph(block.content, here);
|
|
1147
|
-
}).map((part, partIndex) => partIndex === 0 ? `${indent}${marker}${part.trimStart()}` : part.startsWith(continuation) ? part : `${continuation}${part}`).join("\n\n");
|
|
1148
|
-
}).join("\n");
|
|
1149
|
-
}
|
|
1150
|
-
figure(figure, at) {
|
|
1151
|
-
const caption = this.inlines(figure.caption, `${at}/caption`);
|
|
1152
|
-
if (!figure.panels) {
|
|
1153
|
-
const alt = figure.alt === plainTextOf(figure.caption) ? "" : attributeOf("alt", figure.alt, this.problems, at);
|
|
1154
|
-
return `<Figure${this.idAttribute(figure.id, at)} src="${this.imagePath(figure.src, at)}"${alt}>${caption}</Figure>`;
|
|
1155
|
-
}
|
|
1156
|
-
const panels = figure.panels.map((panel, index) => {
|
|
1157
|
-
const here = `${at}/panels/${index}`;
|
|
1158
|
-
const panelCaption = panel.caption ? this.inlines(panel.caption, `${here}/caption`) : "";
|
|
1159
|
-
const alt = panel.caption && panel.alt === plainTextOf(panel.caption) ? "" : attributeOf("alt", panel.alt, this.problems, here);
|
|
1160
|
-
const open = ` <Panel${this.idAttribute(panel.id, here)} row="${panel.row}" column="${panel.column}"${attributeOf("label", panel.label, this.problems, here)} src="${this.imagePath(panel.src, here)}"${alt}`;
|
|
1161
|
-
return panelCaption ? `${open}>${panelCaption}</Panel>` : `${open} />`;
|
|
1162
|
-
});
|
|
1163
|
-
return [
|
|
1164
|
-
`<Figures${this.idAttribute(figure.id, at)} rows="${figure.rows}" columns="${figure.columns}">`,
|
|
1165
|
-
` <Caption>${caption}</Caption>`,
|
|
1166
|
-
...panels,
|
|
1167
|
-
"</Figures>"
|
|
1168
|
-
].join("\n");
|
|
1169
|
-
}
|
|
1170
|
-
table(table, at) {
|
|
1171
|
-
const caption = table.caption ? this.inlines(table.caption, `${at}/caption`) : void 0;
|
|
1172
|
-
if (!table.numbered) {
|
|
1173
|
-
if (caption !== void 0) this.problems.push(`${at}:带表题的不编号表格在 MDX 里写不出来`);
|
|
1174
|
-
if (!this.fitsGfm(table)) this.problems.push(`${at}:不编号的表格只能写成 GFM 表格,这张有合并单元格、多行表头或多段内容`);
|
|
1175
|
-
return this.gfmTable(table, at);
|
|
1176
|
-
}
|
|
1177
|
-
const body = this.fitsGfm(table) ? this.gfmTable(table, at) : this.jsxTable(table, at);
|
|
1178
|
-
return [
|
|
1179
|
-
`<Table${this.idAttribute(table.id, at)}>`,
|
|
1180
|
-
...caption !== void 0 ? [` <Caption>${caption}</Caption>`] : [],
|
|
1181
|
-
"",
|
|
1182
|
-
body,
|
|
1183
|
-
"",
|
|
1184
|
-
"</Table>"
|
|
1185
|
-
].join("\n");
|
|
1186
|
-
}
|
|
1187
|
-
fitsGfm(table) {
|
|
1188
|
-
const fitsOneGfmCell = (blocks) => blocks.length === 0 || blocks.length === 1 && blocks[0].type === "paragraph" && blocks[0].content.every((inline) => inline.type !== "break" && (inline.type !== "math" || !inline.latex.includes("|")));
|
|
1189
|
-
return table.headerRows === 1 && table.rows.every((row) => row.cells.length === table.columns.length && row.cells.every((cell) => !cell.rowSpan && !cell.colSpan && fitsOneGfmCell(cell.blocks)));
|
|
1190
|
-
}
|
|
1191
|
-
gfmTable(table, at) {
|
|
1192
|
-
const lines = table.rows.map((row, rowIndex) => `| ${row.cells.map((cell, cellIndex) => this.cellInline(cell.blocks, `${at}/rows/${rowIndex}/cells/${cellIndex}`) ?? "").join(" | ")} |`);
|
|
1193
|
-
lines.splice(1, 0, `| ${table.columns.map(() => "---").join(" | ")} |`);
|
|
1194
|
-
return lines.join("\n");
|
|
1195
|
-
}
|
|
1196
|
-
jsxTable(table, at) {
|
|
1197
|
-
return [
|
|
1198
|
-
"<table>",
|
|
1199
|
-
...table.rows.map((row, rowIndex) => {
|
|
1200
|
-
const tag = rowIndex < table.headerRows ? "th" : "td";
|
|
1201
|
-
return ` <tr>${row.cells.map((cell, cellIndex) => {
|
|
1202
|
-
const here = `${at}/rows/${rowIndex}/cells/${cellIndex}`;
|
|
1203
|
-
const spans = `${cell.rowSpan ? ` rowSpan="${cell.rowSpan}"` : ""}${cell.colSpan ? ` colSpan="${cell.colSpan}"` : ""}`;
|
|
1204
|
-
const inline = this.cellInline(cell.blocks, here);
|
|
1205
|
-
if (inline !== null) return `<${tag}${spans}>${inline}</${tag}>`;
|
|
1206
|
-
return `<${tag}${spans}>\n\n${this.blocks(cell.blocks, `${here}/blocks`, 7, "decimal").join("\n\n")}\n\n</${tag}>`;
|
|
1207
|
-
}).join("")}</tr>`;
|
|
1208
|
-
}),
|
|
1209
|
-
"</table>"
|
|
1210
|
-
].join("\n");
|
|
1211
|
-
}
|
|
1212
|
-
};
|
|
1213
|
-
const isGeneratedBibliography = (block, document) => block.type === "bibliography" && block.id === `${document.id.slice(0, 48)}_bibliography`;
|
|
1214
|
-
/** 哪些 id 要写出来:被 ref 指到的、layout.json 的键、文献与脚注(它们本来就靠 id 对应) */
|
|
1215
|
-
function keptIdsOf(document, layoutKeys) {
|
|
1216
|
-
const kept = new Set(layoutKeys);
|
|
1217
|
-
for (const { node } of walk(document)) if (node.type === "ref") kept.add(node.target);
|
|
1218
|
-
for (const reference of document.references ?? []) kept.add(reference.id);
|
|
1219
|
-
for (const note of document.notes ?? []) kept.add(note.id);
|
|
1220
|
-
return kept;
|
|
1221
|
-
}
|
|
1222
|
-
function chapterFileNames(sections) {
|
|
1223
|
-
const taken = /* @__PURE__ */ new Set([MDX_ENTRY_NAME, MDX_REFERENCES_NAME]);
|
|
1224
|
-
return sections.map((section, index) => {
|
|
1225
|
-
const preferred = /^[a-z0-9][a-z0-9-]{0,40}$/.test(section.id) ? `${section.id}.mdx` : `chapter-${index + 1}.mdx`;
|
|
1226
|
-
const name = taken.has(preferred) ? `chapter-${index + 1}.mdx` : preferred;
|
|
1227
|
-
taken.add(name);
|
|
1228
|
-
return name;
|
|
1229
|
-
});
|
|
1230
|
-
}
|
|
1231
|
-
/** GFM 只认同一个文件里的脚注定义:每条脚注的定义写进引用它的那个文件(入口正文或某一章)的末尾 */
|
|
1232
|
-
function notesByFile(document, frontBlocks, sections, names, writer) {
|
|
1233
|
-
const fileOfNote = /* @__PURE__ */ new Map();
|
|
1234
|
-
const collect = (value, file) => {
|
|
1235
|
-
for (const { node } of walk(value)) if (node.type === "note_ref") fileOfNote.set(node.target, file);
|
|
1236
|
-
};
|
|
1237
|
-
collect(frontBlocks, MDX_ENTRY_NAME);
|
|
1238
|
-
sections.forEach((section, index) => collect(section, names[index]));
|
|
1239
|
-
const byFile = /* @__PURE__ */ new Map();
|
|
1240
|
-
(document.notes ?? []).forEach((note, index) => {
|
|
1241
|
-
const at = `/notes/${index}`;
|
|
1242
|
-
const [first, ...rest] = note.blocks;
|
|
1243
|
-
if (first?.type !== "paragraph" || rest.length) writer.problems.push(`${at}:脚注只转一段文字的,这条有 ${note.blocks.length} 块`);
|
|
1244
|
-
const file = fileOfNote.get(note.id) ?? "index.mdx";
|
|
1245
|
-
byFile.set(file, [...byFile.get(file) ?? [], `[^${note.id}]: ${first?.type === "paragraph" ? writer.paragraph(first.content, `${at}/blocks/0`) : ""}`]);
|
|
1246
|
-
});
|
|
1247
|
-
return byFile;
|
|
1248
|
-
}
|
|
1249
|
-
/** 组装好的文档 → MDX 报告。assets 是组装结果的 assets(图在组装结果里的路径 → 原图路径) */
|
|
1250
|
-
function mdxReportPlanOf(document, assets, layoutKeys) {
|
|
1251
|
-
const keptIds = keptIdsOf(document, layoutKeys);
|
|
1252
|
-
const writer = new MdxWriter(keptIds, assets);
|
|
1253
|
-
const firstSection = document.blocks.findIndex((block) => block.type === "section");
|
|
1254
|
-
const frontBlocks = (firstSection < 0 ? document.blocks : document.blocks.slice(0, firstSection)).filter((block, index, all) => !(firstSection < 0 && index === all.length - 1 && isGeneratedBibliography(block, document)));
|
|
1255
|
-
const sections = [];
|
|
1256
|
-
document.blocks.forEach((block, index) => {
|
|
1257
|
-
if (index < firstSection || firstSection < 0) return;
|
|
1258
|
-
if (block.type === "section") sections.push(block);
|
|
1259
|
-
else if (!(index === document.blocks.length - 1 && isGeneratedBibliography(block, document))) writer.problems.push(`/blocks/${index}:第一章之后的顶层 ${block.type} 在 MDX 里写不出来(顶层内容只能写在 index.mdx 的正文、第一章之前)`);
|
|
1260
|
-
});
|
|
1261
|
-
const names = chapterFileNames(sections);
|
|
1262
|
-
const notesOf = notesByFile(document, frontBlocks, sections, names, writer);
|
|
1263
|
-
const files = Object.create(null);
|
|
1264
|
-
for (const [index, section] of sections.entries()) {
|
|
1265
|
-
const at = `/blocks/${firstSection + index}`;
|
|
1266
|
-
const frontmatter = section.numbering === "decimal" ? "" : `---\nnumbering: ${section.numbering}\n---\n\n`;
|
|
1267
|
-
files[names[index]] = `${frontmatter}${[writer.section(section, at, 1, "decimal"), ...notesOf.get(names[index]) ?? []].join("\n\n")}\n`;
|
|
1268
|
-
}
|
|
1269
|
-
const { metadata } = document;
|
|
1270
|
-
const header = { title: metadata.title };
|
|
1271
|
-
if (metadata.shortTitle !== void 0) header["shortTitle"] = metadata.shortTitle;
|
|
1272
|
-
header["language"] = metadata.language;
|
|
1273
|
-
if (metadata.authors !== void 0) header["authors"] = metadata.authors;
|
|
1274
|
-
if (metadata.date !== void 0) header["date"] = metadata.date;
|
|
1275
|
-
if (metadata.revision !== void 0) header["revision"] = metadata.revision;
|
|
1276
|
-
if (metadata.fields !== void 0) header["fields"] = metadata.fields;
|
|
1277
|
-
if (names.length) header["chapters"] = names;
|
|
1278
|
-
const body = [...writer.blocks(frontBlocks, "/blocks", 1, "decimal"), ...notesOf.get("index.mdx") ?? []].join("\n\n");
|
|
1279
|
-
files[MDX_ENTRY_NAME] = `---\n${stringify(header, { lineWidth: 0 })}---\n${body ? `\n${body}\n` : ""}`;
|
|
1280
|
-
if (document.references?.length) files[MDX_REFERENCES_NAME] = `${document.references.map((reference, index) => `<Reference${attributeOf("id", reference.id, writer.problems, `/references/${index}`)}${reference.url !== void 0 ? attributeOf("url", reference.url, writer.problems, `/references/${index}`) : ""}>${escapedText(reference.text)}</Reference>`).join("\n\n")}\n`;
|
|
1281
|
-
return {
|
|
1282
|
-
files,
|
|
1283
|
-
images: writer.images,
|
|
1284
|
-
keptIds,
|
|
1285
|
-
problems: writer.problems
|
|
1286
|
-
};
|
|
1287
|
-
}
|
|
1288
|
-
//#endregion
|
|
1289
|
-
export { assembleMdxReport as a, GENERATED_ID_PREFIX as c, MDX_REFERENCES_NAME as i, mdxReportPlanOf as n, compileMdxReport as o, MDX_ENTRY_NAME as r, mdxReportInputsOf as s, keptIdsOf as t };
|
|
1036
|
+
export { mdxReportInputsOf as a, compileMdxReport as i, MDX_REFERENCES_NAME as n, GENERATED_ID_PREFIX as o, assembleMdxReport as r, MDX_ENTRY_NAME as t };
|
package/dist/node.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as AssemblyOptions, r as AssemblyResult } from "./types-
|
|
2
|
-
import { a as
|
|
1
|
+
import { n as AssemblyOptions, r as AssemblyResult } from "./types-Ea2OT6Ac.mjs";
|
|
2
|
+
import { a as ReportCheckDiagnostic, i as reportExport, n as ReportExportResult, o as ReportCheckResult, r as reportEntry, s as checkReports, t as ReportExportOptions } from "./export-DMKj4gl2.mjs";
|
|
3
3
|
//#region src/node/read-report.d.ts
|
|
4
4
|
interface SnapshotEntry {
|
|
5
5
|
path: string;
|
|
@@ -38,4 +38,4 @@ declare function readReportFiles(siteDir: string, entry: string): Promise<Record
|
|
|
38
38
|
/** 读一份 MDX 报告的全部原文:入口、chapters 列的各章、存在时的 references.mdx,键是相对站点目录的路径,交给 assembleMdxReport */
|
|
39
39
|
declare function readMdxReportFiles(siteDir: string, entry: string): Promise<Record<string, string>>;
|
|
40
40
|
//#endregion
|
|
41
|
-
export {
|
|
41
|
+
export { JSON_ENTRY_NAME, REPORT_ID_PATTERN, type ReadReportResult, type ReportCheckDiagnostic, type ReportCheckResult, type ReportExportOptions, type ReportExportResult, type SnapshotEntry, checkReports, isMdxEntry, readMdxReportFiles, readReport, readReportFiles, reportEntry, reportEntryIn, reportEntryOf, reportExport, reportIdsOf, reportsDirName };
|
package/dist/node.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as readReportFiles, c as reportIdsOf, i as readMdxReportFiles, l as reportsDirName, n as REPORT_ID_PATTERN, o as reportEntryIn, r as isMdxEntry, s as reportEntryOf, t as JSON_ENTRY_NAME } from "./report-files-
|
|
3
|
-
export { JSON_ENTRY_NAME, REPORT_ID_PATTERN, checkReports,
|
|
1
|
+
import { i as readReport, n as reportExport, r as checkReports, t as reportEntry } from "./export-CGvF3Wz-.mjs";
|
|
2
|
+
import { a as readReportFiles, c as reportIdsOf, i as readMdxReportFiles, l as reportsDirName, n as REPORT_ID_PATTERN, o as reportEntryIn, r as isMdxEntry, s as reportEntryOf, t as JSON_ENTRY_NAME } from "./report-files-DyPBOCgh.mjs";
|
|
3
|
+
export { JSON_ENTRY_NAME, REPORT_ID_PATTERN, checkReports, isMdxEntry, readMdxReportFiles, readReport, readReportFiles, reportEntry, reportEntryIn, reportEntryOf, reportExport, reportIdsOf, reportsDirName };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as AssemblyResult } from "./types-
|
|
1
|
+
import { r as AssemblyResult } from "./types-Ea2OT6Ac.mjs";
|
|
2
2
|
import { CommentsAccess, PageThreadSummary } from "@godcreator/comments/site";
|
|
3
3
|
//#region src/site/page-data.d.ts
|
|
4
4
|
/** 报告列表里的一行:报告读不对时 problem 是原话,标题退回报告 id */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { i as validateDocument, n as safeRelativePath, o as parseReportJson, s as ReportContentError } from "./assemble-
|
|
2
|
-
import {
|
|
1
|
+
import { i as validateDocument, n as safeRelativePath, o as parseReportJson, s as ReportContentError } from "./assemble-BEt9_xsB.mjs";
|
|
2
|
+
import { a as mdxReportInputsOf, t as MDX_ENTRY_NAME } from "./mdx-B1V34o8x.mjs";
|
|
3
3
|
import { readFile, readdir, realpath, stat } from "node:fs/promises";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
//#region src/node/report-files.ts
|
package/dist/site-server.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as ReportTocItem, i as ReportSummary, n as ReportPageComments, r as ReportPageData, t as ReportListData } from "./page-data-
|
|
1
|
+
import { a as ReportTocItem, i as ReportSummary, n as ReportPageComments, r as ReportPageData, t as ReportListData } from "./page-data-C1veAE55.mjs";
|
|
2
2
|
//#region src/site/loaders.server.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* 报告功能的站点信息:站点目录(报告在它的 reports/ 下)、站名、报告页的地址前缀,
|
package/dist/site-server.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { t as assembleDocument } from "./assemble-
|
|
2
|
-
import { a as
|
|
3
|
-
import { a as readReportFiles, c as reportIdsOf, i as readMdxReportFiles, n as REPORT_ID_PATTERN, o as reportEntryIn, r as isMdxEntry, t as JSON_ENTRY_NAME } from "./report-files-
|
|
1
|
+
import { t as assembleDocument } from "./assemble-BEt9_xsB.mjs";
|
|
2
|
+
import { a as mdxReportInputsOf, r as assembleMdxReport, t as MDX_ENTRY_NAME } from "./mdx-B1V34o8x.mjs";
|
|
3
|
+
import { a as readReportFiles, c as reportIdsOf, i as readMdxReportFiles, n as REPORT_ID_PATTERN, o as reportEntryIn, r as isMdxEntry, t as JSON_ENTRY_NAME } from "./report-files-DyPBOCgh.mjs";
|
|
4
4
|
import { n as reportHrefOf } from "./page-data-DLPoVgXy.mjs";
|
|
5
5
|
import { readFile, realpath, stat } from "node:fs/promises";
|
|
6
6
|
import path from "node:path";
|