for-humanity 0.12.0 → 0.13.0
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/CHANGELOG.md +29 -0
- package/README.md +16 -9
- package/dist/browser.js +16 -16
- package/dist/cli.css +2 -968
- package/dist/cli.js +92 -2318
- package/dist/config.js +1 -0
- package/dist/constant/copy.d.ts +100 -0
- package/dist/constant/site.d.ts +20 -0
- package/dist/constant/status.d.ts +19 -0
- package/dist/copy-C1uzvEnr.js +103 -0
- package/dist/group-path-XAThmzvC.js +10 -0
- package/dist/load-site-CbpLEhwu.js +2379 -0
- package/dist/logger-Dv1i9xSV.js +9 -0
- package/dist/mermaid/THIRD-PARTY-NOTICES.txt +3134 -0
- package/dist/mermaid/chunk--TN-qHgG.js +2 -0
- package/dist/mermaid/chunk-0kM1Lv4D.js +2 -0
- package/dist/mermaid/chunk-3FHei3pH.js +2001 -0
- package/dist/mermaid/chunk-3_2p2GqN.js +2 -0
- package/dist/mermaid/chunk-6HLei9i0.js +84 -0
- package/dist/mermaid/chunk-7Sz3kAwl.js +2214 -0
- package/dist/mermaid/chunk-7Tarqbpa.js +18047 -0
- package/dist/mermaid/chunk-9kkt8lzL.js +10 -0
- package/dist/mermaid/chunk-B--pNBQF.js +884 -0
- package/dist/mermaid/chunk-B4F-pysn.js +4241 -0
- package/dist/mermaid/chunk-B58sEIY_.js +14 -0
- package/dist/mermaid/chunk-B9_UWzSH.js +1517 -0
- package/dist/mermaid/chunk-BB8uZHwY.js +75 -0
- package/dist/mermaid/chunk-BFfk0LEc.js +717 -0
- package/dist/mermaid/chunk-BKri0qr7.js +89 -0
- package/dist/mermaid/chunk-BL404pH5.js +26 -0
- package/dist/mermaid/chunk-BLeiQSWo.js +354 -0
- package/dist/mermaid/chunk-BOmH_UFd.js +2 -0
- package/dist/mermaid/chunk-BSej9Nhy.js +1361 -0
- package/dist/mermaid/chunk-BYzrzvCI.js +12 -0
- package/dist/mermaid/chunk-BariMtWr.js +3020 -0
- package/dist/mermaid/chunk-BcrBoMwH.js +2352 -0
- package/dist/mermaid/chunk-Bok8z-Yo.js +67 -0
- package/dist/mermaid/chunk-BpTHLKQM.js +1970 -0
- package/dist/mermaid/chunk-BqjuxRsC.js +733 -0
- package/dist/mermaid/chunk-BuvPd-s5.js +1073 -0
- package/dist/mermaid/chunk-BvVehae3.js +5069 -0
- package/dist/mermaid/chunk-C-JABYpd.js +3075 -0
- package/dist/mermaid/chunk-C9XlTm4w.js +2 -0
- package/dist/mermaid/chunk-CApNbSU9.js +6 -0
- package/dist/mermaid/chunk-CCM2AH-C.js +9 -0
- package/dist/mermaid/chunk-CD1E0F_N.js +2 -0
- package/dist/mermaid/chunk-CDWvKG7D.js +2 -0
- package/dist/mermaid/chunk-CEVPpC1F.js +34 -0
- package/dist/mermaid/chunk-CLDr12lf.js +47504 -0
- package/dist/mermaid/chunk-CLVYqOBI.js +61 -0
- package/dist/mermaid/chunk-CLeOkFb5.js +15 -0
- package/dist/mermaid/chunk-CLgRAtOz.js +37 -0
- package/dist/mermaid/chunk-CMqFNUBl.js +134 -0
- package/dist/mermaid/chunk-CTPaBJXB.js +2 -0
- package/dist/mermaid/chunk-CVi6IGBL.js +2 -0
- package/dist/mermaid/chunk-CWV_EN-4.js +4745 -0
- package/dist/mermaid/chunk-CZ0dAs3g.js +2 -0
- package/dist/mermaid/chunk-C_YGy4Fn.js +236 -0
- package/dist/mermaid/chunk-CcVH22Yt.js +100 -0
- package/dist/mermaid/chunk-CgG6CD9_.js +7175 -0
- package/dist/mermaid/chunk-CgOP6IDB.js +3397 -0
- package/dist/mermaid/chunk-Cgg2UTSf.js +13 -0
- package/dist/mermaid/chunk-ChJfJJ1A.js +214 -0
- package/dist/mermaid/chunk-Ck5XRA46.js +447 -0
- package/dist/mermaid/chunk-Ckuw16cl.js +203 -0
- package/dist/mermaid/chunk-CpAbRCbF.js +1880 -0
- package/dist/mermaid/chunk-CuYekbSv.js +2 -0
- package/dist/mermaid/chunk-CwS4wZ5a.js +2 -0
- package/dist/mermaid/chunk-D-bcrBO3.js +82 -0
- package/dist/mermaid/chunk-D3IEAkCW.js +76 -0
- package/dist/mermaid/chunk-D8XfBJ_K.js +645 -0
- package/dist/mermaid/chunk-D9Ddd9y4.js +2228 -0
- package/dist/mermaid/chunk-DBh1mIbK.js +12 -0
- package/dist/mermaid/chunk-DD6Df6Ic.js +5 -0
- package/dist/mermaid/chunk-DGVDaXjx.js +8 -0
- package/dist/mermaid/chunk-DK9KqIXj.js +632 -0
- package/dist/mermaid/chunk-DORnIAsy.js +4487 -0
- package/dist/mermaid/chunk-DU69_VcF.js +363 -0
- package/dist/mermaid/chunk-DVNvSFoz.js +2144 -0
- package/dist/mermaid/chunk-DZe-4kde.js +20 -0
- package/dist/mermaid/chunk-D_a06Rz4.js +287 -0
- package/dist/mermaid/chunk-DfyFJJi2.js +972 -0
- package/dist/mermaid/chunk-DhKYPp1Z.js +2 -0
- package/dist/mermaid/chunk-DjFqgNTG.js +94 -0
- package/dist/mermaid/chunk-DmbDDrr-.js +65 -0
- package/dist/mermaid/chunk-DpuxlyL_.js +696 -0
- package/dist/mermaid/chunk-DqGhppWe.js +2 -0
- package/dist/mermaid/chunk-DqPZxHXa.js +5 -0
- package/dist/mermaid/chunk-Dt_1Jyif.js +293 -0
- package/dist/mermaid/chunk-DyQBE_NW.js +1935 -0
- package/dist/mermaid/chunk-JckyC4mW.js +1009 -0
- package/dist/mermaid/chunk-K7Myuj2-.js +1334 -0
- package/dist/mermaid/chunk-KuPYb48V.js +275 -0
- package/dist/mermaid/chunk-MFVRUoO0.js +4020 -0
- package/dist/mermaid/chunk-MbInCS_6.js +28 -0
- package/dist/mermaid/chunk-MexOLyKV.js +355 -0
- package/dist/mermaid/chunk-NnbDtJzg.js +21856 -0
- package/dist/mermaid/chunk-SGpOYZbI.js +2139 -0
- package/dist/mermaid/chunk-TbxLDlcU.js +198 -0
- package/dist/mermaid/chunk-TftHqGLg.js +490 -0
- package/dist/mermaid/chunk-UjQ8vA_Z.js +4138 -0
- package/dist/mermaid/chunk-YgmVTKqc.js +16 -0
- package/dist/mermaid/chunk-_a9EZE1v.js +1798 -0
- package/dist/mermaid/chunk-dTb8jqeP.js +2 -0
- package/dist/mermaid/chunk-fFdMfF8S.js +2240 -0
- package/dist/mermaid/chunk-feYbMzBj.js +1267 -0
- package/dist/mermaid/chunk-g3Pn8DkW.js +46 -0
- package/dist/mermaid/chunk-hM77LvCb.js +19832 -0
- package/dist/mermaid/chunk-hUDb-eAW.js +527 -0
- package/dist/mermaid/chunk-tpABtZ-3.js +4252 -0
- package/dist/mermaid/chunk-xIbz3oFK.js +59 -0
- package/dist/mermaid/chunk-yBz-vst0.js +976 -0
- package/dist/mermaid/mermaid-BhtR3wyB.js +1145 -0
- package/dist/run-site-command-C80YoNOe.js +129 -0
- package/dist/site-config-bllORGpm.js +90 -0
- package/dist/site.js +1 -0
- package/dist/start-dev-server-C4_Lu1nZ.js +176 -0
- package/dist/to-change-queue-DbEnZGNK.js +34 -0
- package/dist/to-error-message-pF6_7wGK.js +16 -0
- package/dist/type/group-path.d.ts +7 -0
- package/dist/type/site-config.d.ts +57 -0
- package/package.json +34 -17
- package/src/component/widget/cursor-face/_constant/cursor-face.ts +0 -14
- package/src/component/widget/cursor-face/wg-cursor-face.css +0 -15
- package/src/component/widget/cursor-face/wg-cursor-face.tsx +0 -153
- package/src/component/widget/navigation/_constant/locale.ts +0 -9
- package/src/component/widget/navigation/_constant/navigation-data-schema.ts +0 -33
- package/src/component/widget/navigation/_constant/navigation.ts +0 -9
- package/src/component/widget/navigation/_constant/reading-line.ts +0 -4
- package/src/component/widget/navigation/_function/restore-navigation-scroll.ts +0 -59
- package/src/component/widget/navigation/_function/to-doc-groups/_to-doc-branches.ts +0 -15
- package/src/component/widget/navigation/_function/to-doc-groups/_to-doc-group-branches.ts +0 -70
- package/src/component/widget/navigation/_function/to-doc-groups/to-doc-groups.ts +0 -15
- package/src/component/widget/navigation/_function/to-navigation-data/_to-navigation-document.ts +0 -13
- package/src/component/widget/navigation/_function/to-navigation-data/_to-navigation-group.ts +0 -13
- package/src/component/widget/navigation/_function/to-navigation-data/to-navigation-data.ts +0 -18
- package/src/component/widget/navigation/_function/to-navigation-json.ts +0 -8
- package/src/component/widget/navigation/_function/to-toc-groups.ts +0 -38
- package/src/component/widget/navigation/_type/doc-branch.ts +0 -11
- package/src/component/widget/navigation/_type/doc-group.ts +0 -24
- package/src/component/widget/navigation/_type/navigation-data.ts +0 -75
- package/src/component/widget/navigation/_type/navigation-focus-snapshot.ts +0 -17
- package/src/component/widget/navigation/_type/toc-group.ts +0 -39
- package/src/component/widget/navigation/_wg-navigation-nav-list.css +0 -48
- package/src/component/widget/navigation/_wg-navigation-nav-list.tsx +0 -61
- package/src/component/widget/navigation/_wg-navigation-nav.css +0 -21
- package/src/component/widget/navigation/_wg-navigation-nav.tsx +0 -33
- package/src/component/widget/navigation/_wg-navigation-scroll.tsx +0 -117
- package/src/component/widget/navigation/_wg-navigation-toc.css +0 -91
- package/src/component/widget/navigation/_wg-navigation-toc.tsx +0 -114
- package/src/component/widget/navigation/wg-navigation.css +0 -282
- package/src/component/widget/navigation/wg-navigation.tsx +0 -420
- package/src/component/widget/prose/_constant/heading-highlight.ts +0 -4
- package/src/component/widget/prose/_constant/section.ts +0 -7
- package/src/component/widget/prose/_constant/status.ts +0 -9
- package/src/component/widget/prose/_function/has-block-content.ts +0 -30
- package/src/component/widget/prose/_function/rehype-head.ts +0 -31
- package/src/component/widget/prose/_function/rehype-sections/_to-section-headings.ts +0 -20
- package/src/component/widget/prose/_function/rehype-sections/rehype-sections.ts +0 -21
- package/src/component/widget/prose/_function/rehype-tables.ts +0 -22
- package/src/component/widget/prose/_function/remark-blocks.ts +0 -112
- package/src/component/widget/prose/_function/remark-flow.ts +0 -26
- package/src/component/widget/prose/_function/remark-links.ts +0 -33
- package/src/component/widget/prose/_function/remark-parts.ts +0 -26
- package/src/component/widget/prose/_function/remark-status.ts +0 -59
- package/src/component/widget/prose/_function/remark-swatch.ts +0 -16
- package/src/component/widget/prose/_function/remark-unknown-directives.ts +0 -25
- package/src/component/widget/prose/wg-prose.css +0 -484
- package/src/component/widget/prose/wg-prose.tsx +0 -43
- package/src/component/widget/shell/wg-shell.css +0 -63
- package/src/component/widget/shell/wg-shell.tsx +0 -88
- package/src/component/widget/shell-controls/wg-shell-controls.css +0 -4
- package/src/component/widget/shell-controls/wg-shell-controls.tsx +0 -170
- package/src/constant/asset.ts +0 -63
- package/src/constant/copy.ts +0 -133
- package/src/constant/doc.ts +0 -13
- package/src/constant/font.ts +0 -34
- package/src/constant/site.ts +0 -24
- package/src/constant/status.ts +0 -15
- package/src/entry/browser/browser.tsx +0 -22
- package/src/entry/cli/_constant/cli.ts +0 -19
- package/src/entry/cli/_constant/crawling.ts +0 -14
- package/src/entry/cli/_constant/snippet.ts +0 -21
- package/src/entry/cli/_function/create-app.tsx +0 -57
- package/src/entry/cli/_function/create-dev-app.ts +0 -87
- package/src/entry/cli/_function/create-processor/_rehype-assets.ts +0 -70
- package/src/entry/cli/_function/create-processor/_rehype-heading-ids.ts +0 -34
- package/src/entry/cli/_function/create-processor/_remark-report.ts +0 -15
- package/src/entry/cli/_function/create-processor/_remark-snippets.ts +0 -117
- package/src/entry/cli/_function/create-processor/_shiki-transformers.ts +0 -91
- package/src/entry/cli/_function/create-processor/create-processor.ts +0 -64
- package/src/entry/cli/_function/read-docs.ts +0 -128
- package/src/entry/cli/_function/read-home.ts +0 -32
- package/src/entry/cli/_function/to-crawling-app.ts +0 -42
- package/src/entry/cli/cli.test.ts +0 -804
- package/src/entry/cli/cli.ts +0 -206
- package/src/env.d.ts +0 -6
- package/src/page/doc/pg-doc.tsx +0 -35
- package/src/page/home/pg-home.tsx +0 -40
- package/src/store/navigation/create-navigation-stores.test.ts +0 -74
- package/src/store/navigation/create-navigation-stores.ts +0 -59
- package/src/store/navigation/navigation-state.ts +0 -36
- package/src/store/navigation/navigation-storage.ts +0 -9
- package/src/store/navigation/to-navigation-scroll-state.ts +0 -42
- package/src/style/base.css +0 -28
- package/src/style/token.css +0 -188
- package/src/type/doc-content.ts +0 -15
- package/src/type/doc-data.ts +0 -38
- package/src/type/doc-file-data.ts +0 -21
- package/src/type/doc-heading.ts +0 -17
- package/src/type/doc-outline.ts +0 -16
- package/src/type/doc-section.ts +0 -9
- package/src/type/doc.ts +0 -20
- package/src/type/group-path.ts +0 -7
- package/src/type/site-assets.ts +0 -25
- package/src/type/site-config.ts +0 -73
- package/src/type/vfile-data.d.ts +0 -10
- package/src/util/async/to-change-queue.test.ts +0 -58
- package/src/util/async/to-change-queue.ts +0 -43
- package/src/util/dom/find-hash-target.ts +0 -18
- package/src/util/dom/reveal-hash-target.ts +0 -15
- package/src/util/error/to-error-message.ts +0 -10
- package/src/util/file/to-asset-path.ts +0 -26
- package/src/util/font/to-font-css.test.ts +0 -41
- package/src/util/font/to-font-css.ts +0 -28
- package/src/util/mermaid/render-flow.js +0 -321
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 상태 문구 뒤 날짜 패턴 · YYYY-MM-DD
|
|
3
|
-
*/
|
|
4
|
-
export const status_date_pattern = String.raw`\d{4}-\d{2}-\d{2}`;
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* 미등록 날짜 상태 후보 · 등록 문구 치환 뒤 남은 괄호 문구
|
|
8
|
-
*/
|
|
9
|
-
export const status_candidate_pattern = new RegExp(String.raw`\([^()\n]*${status_date_pattern}\)`, "g");
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import type {Nodes} from "mdast";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* 부품 본문의 내용 판정 · 참조 정의·주석·빈 텍스트와 빈 구조 제외
|
|
5
|
-
* 이미지·표·구분선·주석 외 원시 HTML은 본문 요소
|
|
6
|
-
*/
|
|
7
|
-
export const hasBlockContent = (node: Nodes): boolean => {
|
|
8
|
-
if (node.type === "definition") {
|
|
9
|
-
return false;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
if (node.type === "html") {
|
|
13
|
-
// HTML의 빈 주석·대체 닫힘·미종결 주석 포함
|
|
14
|
-
return node.value.replace(/<!--(?:>|->|[\s\S]*?(?:--!?>|$))/g, "").trim() !== "";
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
if ("value" in node) {
|
|
18
|
-
return node.value.trim() !== "";
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
if (node.type === "table" || node.type === "textDirective") {
|
|
22
|
-
return true;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
if ("children" in node) {
|
|
26
|
-
return node.children.some(hasBlockContent);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return true;
|
|
30
|
-
};
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import type {Root} from "hast";
|
|
2
|
-
import type {VFile} from "vfile";
|
|
3
|
-
import {section_heading_depth} from "@/component/widget/prose/_constant/section";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* name 제목과 첫 절 앞 본문의 공통 머리 · README는 원문의 h1 사용
|
|
7
|
-
*/
|
|
8
|
-
export const rehypeHead = () => (tree: Root, file: VFile) => {
|
|
9
|
-
const frontmatter = file.data.fh?.frontmatter;
|
|
10
|
-
|
|
11
|
-
const firstSection = tree.children.findIndex((node) => node.type === "element" && node.tagName === `h${section_heading_depth.section}`);
|
|
12
|
-
const leadEnd = firstSection === -1 ? tree.children.length : firstSection;
|
|
13
|
-
|
|
14
|
-
if (frontmatter === undefined && leadEnd === 0) {
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
tree.children = [
|
|
19
|
-
{
|
|
20
|
-
type: "element",
|
|
21
|
-
tagName: "header",
|
|
22
|
-
properties: {className: ["wg_prose__head"]},
|
|
23
|
-
children: [...tree.children.slice(0, leadEnd).filter((node) => node.type !== "doctype")],
|
|
24
|
-
},
|
|
25
|
-
...tree.children.slice(leadEnd),
|
|
26
|
-
];
|
|
27
|
-
|
|
28
|
-
if (frontmatter !== undefined && tree.children[0].type === "element") {
|
|
29
|
-
tree.children[0].children.unshift({type: "element", tagName: "h1", properties: {}, children: [{type: "text", value: frontmatter.name}]});
|
|
30
|
-
}
|
|
31
|
-
};
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import type {Element, Root} from "hast";
|
|
2
|
-
import {section_heading_depth} from "@/component/widget/prose/_constant/section";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* 목차 대상 h2·h3 · 중첩 블록까지 문서 순서 수집
|
|
6
|
-
* rehype-heading-ids의 순회 순서와 일치
|
|
7
|
-
*/
|
|
8
|
-
export const toSectionHeadings = (node: Root | Element): Element[] => {
|
|
9
|
-
return node.children.flatMap((child) => {
|
|
10
|
-
if (child.type !== "element") {
|
|
11
|
-
return [];
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
if (child.tagName === `h${section_heading_depth.section}` || child.tagName === `h${section_heading_depth.sub}`) {
|
|
15
|
-
return [child];
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
return toSectionHeadings(child);
|
|
19
|
-
});
|
|
20
|
-
};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import type {Root} from "hast";
|
|
2
|
-
import type {VFile} from "vfile";
|
|
3
|
-
import {toSectionHeadings} from "@/component/widget/prose/_function/rehype-sections/_to-section-headings";
|
|
4
|
-
import type {DocSection} from "@/type/doc-section";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* h2·h3의 가름 메타데이터 수집 · 작성한 제목은 그대로 유지
|
|
8
|
-
* id·목차 텍스트는 앞 단계의 rehype-heading-ids 소유
|
|
9
|
-
* file.data.fh.sections는 headings의 h2·h3 순서와 일치
|
|
10
|
-
*/
|
|
11
|
-
export const rehypeSections = () => (tree: Root, file: VFile) => {
|
|
12
|
-
if (file.data.fh === undefined) {
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
file.data.fh.sections = toSectionHeadings(tree).map(
|
|
17
|
-
(heading): DocSection => ({
|
|
18
|
-
part: typeof heading.properties.dataPart === "string" ? heading.properties.dataPart : undefined,
|
|
19
|
-
}),
|
|
20
|
-
);
|
|
21
|
-
};
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type {Root} from "hast";
|
|
2
|
-
import {SKIP, visit} from "unist-util-visit";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* 넓은 표의 내부 가로 스크롤 래퍼
|
|
6
|
-
*/
|
|
7
|
-
export const rehypeTables = () => (tree: Root) => {
|
|
8
|
-
visit(tree, "element", (node, index, parent) => {
|
|
9
|
-
if (node.tagName !== "table" || parent === undefined || index === undefined) {
|
|
10
|
-
return;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
parent.children[index] = {
|
|
14
|
-
type: "element",
|
|
15
|
-
tagName: "div",
|
|
16
|
-
properties: {className: ["wg_prose__table"]},
|
|
17
|
-
children: [node],
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
return [SKIP, index + 1];
|
|
21
|
-
});
|
|
22
|
-
};
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import type {Root} from "mdast";
|
|
2
|
-
import {toString as toPlainText} from "mdast-util-to-string";
|
|
3
|
-
import {visit} from "unist-util-visit";
|
|
4
|
-
import type {VFile} from "vfile";
|
|
5
|
-
import {section_heading_depth} from "@/component/widget/prose/_constant/section";
|
|
6
|
-
import {hasBlockContent} from "@/component/widget/prose/_function/has-block-content";
|
|
7
|
-
import {copy_error_directive_syntax} from "@/constant/copy";
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Note·Details의 제목·본문·속성·닫힘 계약
|
|
11
|
-
* label은 첫 자식 · summary는 Details의 첫 요소 · 원문 위치는 오류 기준
|
|
12
|
-
*/
|
|
13
|
-
export const remarkBlocks = () => (tree: Root, file: VFile) => {
|
|
14
|
-
const source = String(file.value);
|
|
15
|
-
|
|
16
|
-
visit(tree, (node, _index, parent) => {
|
|
17
|
-
if (node.type === "leafDirective" && node.name === "part" && parent?.type !== "root") {
|
|
18
|
-
file.fail(`${copy_error_directive_syntax}: part · 문서 최상위에 작성`, node);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
if (node.type !== "containerDirective" && node.type !== "leafDirective" && node.type !== "textDirective") {
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
if (node.name !== "note" && node.name !== "details") {
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (node.type !== "containerDirective") {
|
|
30
|
-
file.fail(`${copy_error_directive_syntax}: ${node.name} · ::: 블록으로 작성`, node);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const label = node.children.at(0);
|
|
34
|
-
|
|
35
|
-
if (label?.type !== "paragraph" || label.data?.directiveLabel !== true || label.children.some((child) => child.type !== "text")) {
|
|
36
|
-
file.fail(`${copy_error_directive_syntax}: ${node.name} · 일반 텍스트 제목 필수`, node);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const title = toPlainText(label).trim();
|
|
40
|
-
|
|
41
|
-
if (title === "") {
|
|
42
|
-
file.fail(`${copy_error_directive_syntax}: ${node.name} · 비어 있지 않은 제목 필수`, node);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (!node.children.slice(1).some(hasBlockContent)) {
|
|
46
|
-
file.fail(`${copy_error_directive_syntax}: ${node.name} · 본문 필수`, node);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const unsupported = node.attributes ? Object.keys(node.attributes).find((key) => node.name !== "details" || key !== "open") : undefined;
|
|
50
|
-
|
|
51
|
-
if (unsupported !== undefined) {
|
|
52
|
-
file.fail(`${copy_error_directive_syntax}: ${node.name} · 미지원 속성 ${unsupported}`, node);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const open = node.attributes?.open;
|
|
56
|
-
const attributeSource = source.slice(label.position?.end.offset, node.position?.end.offset).split(/\r?\n/, 1)[0].trim();
|
|
57
|
-
|
|
58
|
-
// 속성 정규화 이전의 표기 · 중복 open과 open="" 거부
|
|
59
|
-
if (attributeSource !== "" && (node.name !== "details" || !/^\{[ \t]*open[ \t]*\}$/.test(attributeSource))) {
|
|
60
|
-
file.fail(`${copy_error_directive_syntax}: ${node.name} · 허용 속성은 Details의 {open}, 나머지는 생략`, node);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const original = source.slice(node.position?.start.offset, node.position?.end.offset);
|
|
64
|
-
const opening = /^(:{3,})/.exec(original);
|
|
65
|
-
const closing = /(?:^|\n)[ \t>]*(:{3,})[ \t]*\r?$/.exec(original);
|
|
66
|
-
|
|
67
|
-
if (
|
|
68
|
-
opening === null ||
|
|
69
|
-
closing === null ||
|
|
70
|
-
closing.index + closing[0].length !== original.length ||
|
|
71
|
-
closing[1].length < opening[1].length ||
|
|
72
|
-
node.position?.end.offset === node.children.at(-1)?.position?.end.offset
|
|
73
|
-
) {
|
|
74
|
-
file.fail(`${copy_error_directive_syntax}: ${node.name} · 블록을 닫는 fence 필수`, node);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
visit(node, "heading", (heading) => {
|
|
78
|
-
if (heading.depth <= section_heading_depth.section) {
|
|
79
|
-
file.fail(`${copy_error_directive_syntax}: ${node.name} · #·## 제목은 부품 밖에 작성`, heading);
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
// 코드 안의 :::가 container를 먼저 닫은 경우 · 더 긴 바깥 fence로 구분
|
|
84
|
-
visit(node, "code", (code) => {
|
|
85
|
-
const originalCode = source.slice(code.position?.start.offset, code.position?.end.offset);
|
|
86
|
-
const codeOpening = /^ {0,3}(`{3,}|~{3,})/.exec(originalCode);
|
|
87
|
-
const codeClosing = /(?:^|\n)[ \t>]*(`{3,}|~{3,})[ \t]*\r?$/.exec(originalCode);
|
|
88
|
-
|
|
89
|
-
if (
|
|
90
|
-
codeOpening !== null &&
|
|
91
|
-
(codeClosing === null ||
|
|
92
|
-
codeClosing.index + codeClosing[0].length !== originalCode.length ||
|
|
93
|
-
codeClosing[1][0] !== codeOpening[1][0] ||
|
|
94
|
-
codeClosing[1].length < codeOpening[1].length)
|
|
95
|
-
) {
|
|
96
|
-
file.fail(`${copy_error_directive_syntax}: ${node.name} · 코드 fence를 닫고, 코드 안의 :보다 긴 바깥 fence 사용`, code);
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
label.children = [{type: "text", value: title}];
|
|
101
|
-
label.data = {
|
|
102
|
-
...label.data,
|
|
103
|
-
hName: node.name === "note" ? "strong" : "summary",
|
|
104
|
-
hProperties: {className: [node.name === "note" ? "wg_prose__noteTitle" : "wg_prose__detailsSummary"]},
|
|
105
|
-
};
|
|
106
|
-
node.data = {
|
|
107
|
-
...node.data,
|
|
108
|
-
hName: node.name === "note" ? "aside" : "details",
|
|
109
|
-
hProperties: node.name === "note" ? {className: ["wg_prose__note"], ariaLabel: title} : {className: ["wg_prose__details"], open: open === ""},
|
|
110
|
-
};
|
|
111
|
-
});
|
|
112
|
-
};
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import type {Root} from "mdast";
|
|
2
|
-
import {visit} from "unist-util-visit";
|
|
3
|
-
import type {VFile} from "vfile";
|
|
4
|
-
import {copy_error_flow} from "@/constant/copy";
|
|
5
|
-
import {renderFlow} from "@/util/mermaid/render-flow";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Mermaid → 격자 SVG · beautiful-mermaid 기반
|
|
9
|
-
* 실패 시 파일·줄을 포함한 빌드 오류
|
|
10
|
-
*/
|
|
11
|
-
export const remarkFlow = () => (tree: Root, file: VFile) => {
|
|
12
|
-
visit(tree, "code", (node, index, parent) => {
|
|
13
|
-
if (node.lang !== "mermaid" || parent === undefined || index === undefined) {
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
try {
|
|
18
|
-
parent.children[index] = {
|
|
19
|
-
type: "html",
|
|
20
|
-
value: `<div class="wg_prose__flow">${renderFlow(node.value)}</div>`,
|
|
21
|
-
};
|
|
22
|
-
} catch (error) {
|
|
23
|
-
file.fail(`${copy_error_flow}: ${error instanceof Error ? error.message : String(error)}`, node);
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
-
};
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import {existsSync} from "node:fs";
|
|
2
|
-
import {dirname, posix, relative, resolve} from "node:path";
|
|
3
|
-
import type {Root} from "mdast";
|
|
4
|
-
import {visit} from "unist-util-visit";
|
|
5
|
-
import type {VFile} from "vfile";
|
|
6
|
-
import {copy_warn_broken_link} from "@/constant/copy";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* 상대 Markdown 링크 → 사이트 URL · query·hash 원문 유지
|
|
10
|
-
* 외부·절대 URL과 같은 페이지 hash 유지 · 없는 파일은 터미널 경고
|
|
11
|
-
*/
|
|
12
|
-
export const remarkLinks = (options: {root: string}) => (tree: Root, file: VFile) => {
|
|
13
|
-
const here = dirname(relative(options.root, file.path));
|
|
14
|
-
|
|
15
|
-
visit(tree, (node) => {
|
|
16
|
-
if (node.type !== "link" && node.type !== "definition") {
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// 셋째 capture: query·hash 접미사 · 파일 확인과 경로 정규화에서 제외
|
|
21
|
-
const match = /^(?![a-z]+:|\/|#)([^#?]+)(\.mdx?)([?#].*|)$/i.exec(node.url);
|
|
22
|
-
|
|
23
|
-
if (match) {
|
|
24
|
-
if (!existsSync(resolve(dirname(file.path), `${match[1]}${match[2]}`))) {
|
|
25
|
-
file.message(`${copy_warn_broken_link}: ${node.url}`, node);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const target = posix.join(here, `${match[1]}${match[2]}`).toLowerCase();
|
|
29
|
-
|
|
30
|
-
node.url = target === "readme.md" ? `/${match[3]}` : `/${posix.join(here, match[1]).toLowerCase()}/${match[3]}`;
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
};
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import type {Root} from "mdast";
|
|
2
|
-
import {toString as toPlainText} from "mdast-util-to-string";
|
|
3
|
-
import {section_heading_depth} from "@/component/widget/prose/_constant/section";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* ::part[이름]의 본문 가름과 다음 h2의 data-part
|
|
7
|
-
* rehype-sections에서 같은 지점의 목차 묶음 생성
|
|
8
|
-
*/
|
|
9
|
-
export const remarkParts = () => (tree: Root) => {
|
|
10
|
-
for (const [index, node] of tree.children.entries()) {
|
|
11
|
-
if (node.type !== "leafDirective" || node.name !== "part") {
|
|
12
|
-
continue;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const section = tree.children.slice(index + 1).find((next) => next.type === "heading" && next.depth === section_heading_depth.section);
|
|
16
|
-
|
|
17
|
-
node.data = {hName: "div", hProperties: {className: ["wg_prose__part"]}};
|
|
18
|
-
|
|
19
|
-
if (section) {
|
|
20
|
-
section.data = {
|
|
21
|
-
...section.data,
|
|
22
|
-
hProperties: {...section.data?.hProperties, dataPart: toPlainText(node).trim()},
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
};
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import {escape as escapeHtml, escapeRegExp} from "es-toolkit/string";
|
|
2
|
-
import type {Root} from "mdast";
|
|
3
|
-
import {findAndReplace, type RegExpMatchObject} from "mdast-util-find-and-replace";
|
|
4
|
-
import type {VFile} from "vfile";
|
|
5
|
-
import {status_candidate_pattern, status_date_pattern} from "@/component/widget/prose/_constant/status";
|
|
6
|
-
import {copy_warn_unknown_status} from "@/constant/copy";
|
|
7
|
-
import type {SiteConfig} from "@/type/site-config";
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* 설정 문구의 상태 표지 변환 · 괄호 제거 · 제목·링크 제외
|
|
11
|
-
* 미등록 날짜 문구는 파일 경고 · remark-report에서 출력
|
|
12
|
-
*/
|
|
13
|
-
export const remarkStatus = (options: {status: SiteConfig["status"]}) => {
|
|
14
|
-
const statuses = options.status.toSorted((a, b) => b.phrase.length - a.phrase.length);
|
|
15
|
-
const phrases = statuses.map((item) => [escapeRegExp(item.phrase), ...(item.date ? [`(?: ${status_date_pattern})?`] : [])].join("")).join("|");
|
|
16
|
-
const pattern = new RegExp(String.raw`\((${phrases})\)|(${phrases})`, "g");
|
|
17
|
-
const ignore = ["link", "linkReference", "heading"];
|
|
18
|
-
|
|
19
|
-
return (tree: Root, file: VFile) => {
|
|
20
|
-
findAndReplace(
|
|
21
|
-
tree,
|
|
22
|
-
[
|
|
23
|
-
pattern,
|
|
24
|
-
(_match: string, inParens: string | undefined, bare: string | undefined) => {
|
|
25
|
-
const text = inParens ?? bare;
|
|
26
|
-
const item = statuses.find((status) => text?.startsWith(status.phrase));
|
|
27
|
-
|
|
28
|
-
// findAndReplace의 false: 원문 유지
|
|
29
|
-
if (text === undefined || item === undefined) {
|
|
30
|
-
return false;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return {
|
|
34
|
-
type: "html",
|
|
35
|
-
value: `<span class="wg_prose__pill wg_prose__pill--${item.kind}">${escapeHtml(text)}</span>`,
|
|
36
|
-
};
|
|
37
|
-
},
|
|
38
|
-
],
|
|
39
|
-
{ignore},
|
|
40
|
-
);
|
|
41
|
-
|
|
42
|
-
findAndReplace(
|
|
43
|
-
tree,
|
|
44
|
-
[
|
|
45
|
-
status_candidate_pattern,
|
|
46
|
-
(match: string, info: RegExpMatchObject) => {
|
|
47
|
-
// 치환된 텍스트에 position 부재 · 위치가 남은 가까운 조상 기준
|
|
48
|
-
file.message(
|
|
49
|
-
`${copy_warn_unknown_status}: ${match}`,
|
|
50
|
-
info.stack.findLast((node) => node.position !== undefined),
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
return false;
|
|
54
|
-
},
|
|
55
|
-
],
|
|
56
|
-
{ignore},
|
|
57
|
-
);
|
|
58
|
-
};
|
|
59
|
-
};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type {Root} from "mdast";
|
|
2
|
-
import {visit} from "unist-util-visit";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* 인라인 hex 색 값의 칩 표시
|
|
6
|
-
* 문서별 색은 --wg-prose-chip-color로 전달 · 고정 스타일시트 값 불가
|
|
7
|
-
*/
|
|
8
|
-
export const remarkSwatch = () => (tree: Root) => {
|
|
9
|
-
visit(tree, "inlineCode", (node) => {
|
|
10
|
-
if (/^#[0-9a-f]{3,8}$/i.test(node.value.trim())) {
|
|
11
|
-
node.data = {
|
|
12
|
-
hProperties: {className: ["wg_prose__color"], style: `--wg-prose-chip-color: ${node.value.trim()}`},
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
});
|
|
16
|
-
};
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import type {Root} from "mdast";
|
|
2
|
-
import {SKIP, visit} from "unist-util-visit";
|
|
3
|
-
import type {VFile} from "vfile";
|
|
4
|
-
import {copy_error_unknown_directive} from "@/constant/copy";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* hName 없는 블록 지시문은 작성 오류
|
|
8
|
-
* textDirective는 원문 복원 · 예:이것 같은 일반 문장의 오인 방지
|
|
9
|
-
*/
|
|
10
|
-
export const remarkUnknownDirectives = () => (tree: Root, file: VFile) => {
|
|
11
|
-
visit(tree, (node, index, parent) => {
|
|
12
|
-
if (node.type === "textDirective" && parent !== undefined && index !== undefined) {
|
|
13
|
-
parent.children[index] = {
|
|
14
|
-
type: "text",
|
|
15
|
-
value: String(file.value).slice(node.position?.start.offset, node.position?.end.offset),
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
return SKIP;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
if ((node.type === "leafDirective" || node.type === "containerDirective") && node.data?.hName === undefined) {
|
|
22
|
-
file.fail(`${copy_error_unknown_directive}: ${node.name}`, node);
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
};
|