@zzclub/pipeline 0.13.2 → 0.16.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/ARTICLE-THEMES.md +86 -0
- package/LICENSE +21 -0
- package/README.md +182 -788
- package/THIRD-PARTY-NOTICES.md +25 -0
- package/package.json +6 -2
- package/src/adapter-types.ts +3 -0
- package/src/adapters/builtin-markdown-renderer.ts +1 -0
- package/src/article-theme.test.ts +87 -0
- package/src/article-theme.ts +115 -0
- package/src/commands/abandon.test.ts +1 -1
- package/src/commands/article-theme.ts +16 -0
- package/src/commands/checkpoint.test.ts +2 -2
- package/src/commands/ingest-handoff.ts +6 -0
- package/src/commands/init.ts +10 -0
- package/src/commands/prepare.ts +5 -1
- package/src/commands/publish.ts +4 -0
- package/src/commands/reset.ts +2 -0
- package/src/commands/wechat-export.ts +4 -0
- package/src/commands/wechat-preview.ts +35 -0
- package/src/plugins.ts +2 -0
- package/src/providers/index.ts +17 -2
- package/src/providers/publish-core.ts +32 -1
- package/src/providers/wechat.test.ts +12 -0
- package/src/providers/wechat.ts +60 -39
- package/src/render-branding.ts +1 -1
- package/src/schema/config.ts +12 -0
- package/src/schema/state.ts +5 -0
- package/src/wechat-preview/assets/browser-dist/.vite/manifest.json +21 -1
- package/src/wechat-preview/assets/browser-dist/assets/style-C9-YtTIm.css +1 -0
- package/src/wechat-preview/assets/browser-dist/assets/wechat-renderer-D1jHoaM2.js +624 -0
- package/src/wechat-preview/assets/browser-dist/editor-export.js +1 -512
- package/src/wechat-preview/assets/browser-dist/src/wechat-preview/browser/studio/studio.html +293 -0
- package/src/wechat-preview/assets/browser-dist/studio.js +332 -0
- package/src/wechat-preview/browser/editor-export.ts +17 -2
- package/src/wechat-preview/browser/highlight.ts +2 -0
- package/src/wechat-preview/browser/studio/color-palettes.test.ts +31 -0
- package/src/wechat-preview/browser/studio/color-palettes.ts +115 -0
- package/src/wechat-preview/browser/studio/studio.css +638 -0
- package/src/wechat-preview/browser/studio/studio.html +292 -0
- package/src/wechat-preview/browser/studio/studio.ts +721 -0
- package/src/wechat-preview/browser/studio/syntax-presets.test.ts +74 -0
- package/src/wechat-preview/browser/studio/syntax-presets.ts +590 -0
- package/src/wechat-preview/fixtures/all-nodes.md +38 -0
- package/src/wechat-preview/index.ts +36 -5
- package/src/wechat-preview/plugins/builtin-badge.ts +152 -0
- package/src/wechat-preview/plugins/builtin-callout.ts +261 -0
- package/src/wechat-preview/plugins/builtin-highlight.ts +46 -0
- package/src/wechat-preview/plugins/builtin-kbd.ts +133 -0
- package/src/wechat-preview/plugins/index.test.ts +313 -0
- package/src/wechat-preview/plugins/index.ts +6 -0
- package/src/wechat-preview/plugins/registry.ts +62 -0
- package/src/wechat-preview/plugins/types.ts +31 -0
- package/src/wechat-preview/server/http.ts +160 -3
- package/src/wechat-preview/server/paths.ts +2 -2
- package/src/wechat-preview/server/singleton.ts +14 -12
- package/src/wechat-preview/server/studio.test.ts +92 -0
- package/src/wechat-preview/server/ui.ts +1 -0
- package/src/wechat-preview/wechat-export.integration.test.ts +9 -1
- package/src/wechat-preview/wechat-renderer.ts +72 -7
- package/src/workflow.test.ts +1 -0
|
@@ -3,14 +3,18 @@ import { commonmark } from "@milkdown/kit/preset/commonmark";
|
|
|
3
3
|
import { gfm } from "@milkdown/kit/preset/gfm";
|
|
4
4
|
import { getHTML } from "@milkdown/kit/utils";
|
|
5
5
|
import articleCss from "@zzclub/milkdown-article-style/article.css?raw";
|
|
6
|
+
import { getCombinedMilkdownPlugins } from "../plugins/registry";
|
|
7
|
+
import type { ArticleStructure } from "../wechat-renderer";
|
|
6
8
|
import { renderWechatHtml } from "../wechat-renderer";
|
|
7
9
|
import type { WechatExportTheme } from "../themes";
|
|
8
10
|
|
|
9
11
|
interface BrowserPayload {
|
|
10
12
|
markdown: string;
|
|
13
|
+
assetBaseUrl?: string;
|
|
11
14
|
editorVars: Record<string, string>;
|
|
12
15
|
exportTheme: WechatExportTheme;
|
|
13
16
|
customCss?: string;
|
|
17
|
+
structure?: ArticleStructure;
|
|
14
18
|
}
|
|
15
19
|
|
|
16
20
|
type BrowserResult =
|
|
@@ -41,13 +45,24 @@ async function main(): Promise<void> {
|
|
|
41
45
|
ctx.set(defaultValueCtx, payload.markdown);
|
|
42
46
|
})
|
|
43
47
|
.use(commonmark)
|
|
44
|
-
.use(gfm)
|
|
48
|
+
.use(gfm)
|
|
49
|
+
.use(getCombinedMilkdownPlugins());
|
|
45
50
|
await editor.create();
|
|
46
|
-
|
|
51
|
+
// 在解析后处理真实图片节点,引用式图片也生效,代码中的图片语法不被改写。
|
|
52
|
+
const semantic = new DOMParser().parseFromString(editor.action(getHTML()), "text/html");
|
|
53
|
+
for (const image of semantic.querySelectorAll("img")) {
|
|
54
|
+
const src = image.getAttribute("src") || "";
|
|
55
|
+
if (src && payload.assetBaseUrl && !/^(?:[a-z][a-z0-9+.-]*:|\/)/i.test(src)) {
|
|
56
|
+
const url = new URL(src, payload.assetBaseUrl);
|
|
57
|
+
image.setAttribute("src", url.protocol === "file:" ? decodeURIComponent(url.pathname) : url.href);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const semanticHtml = semantic.body.innerHTML;
|
|
47
61
|
const html = await renderWechatHtml({
|
|
48
62
|
semanticHtml,
|
|
49
63
|
baseCss: articleCss,
|
|
50
64
|
customCss: payload.customCss,
|
|
65
|
+
structure: payload.structure,
|
|
51
66
|
editorVars: payload.editorVars,
|
|
52
67
|
theme: payload.exportTheme,
|
|
53
68
|
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { COLOR_PALETTES } from "./color-palettes";
|
|
3
|
+
|
|
4
|
+
describe("color palettes module", () => {
|
|
5
|
+
test("defines at least 7 curated palettes", () => {
|
|
6
|
+
expect(COLOR_PALETTES.length).toBeGreaterThanOrEqual(7);
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
test("each palette contains valid 6-digit hex color codes for all required keys", () => {
|
|
10
|
+
const hexPattern = /^#[0-9a-f]{6}$/i;
|
|
11
|
+
for (const p of COLOR_PALETTES) {
|
|
12
|
+
expect(p.id).toBeTruthy();
|
|
13
|
+
expect(p.name).toBeTruthy();
|
|
14
|
+
expect(p.category).toBeTruthy();
|
|
15
|
+
expect(p.description).toBeTruthy();
|
|
16
|
+
|
|
17
|
+
expect(p.colors.brand).toMatch(hexPattern);
|
|
18
|
+
expect(p.colors.text).toMatch(hexPattern);
|
|
19
|
+
expect(p.colors.h2).toMatch(hexPattern);
|
|
20
|
+
expect(p.colors.h3).toMatch(hexPattern);
|
|
21
|
+
expect(p.colors.quote).toMatch(hexPattern);
|
|
22
|
+
expect(p.colors.divider).toMatch(hexPattern);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test("contains distinct IDs across all palettes", () => {
|
|
27
|
+
const ids = COLOR_PALETTES.map((p) => p.id);
|
|
28
|
+
const uniqueIds = new Set(ids);
|
|
29
|
+
expect(uniqueIds.size).toBe(ids.length);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
export interface ColorPalette {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
category: string;
|
|
5
|
+
description: string;
|
|
6
|
+
colors: {
|
|
7
|
+
brand: string;
|
|
8
|
+
text: string;
|
|
9
|
+
h2: string;
|
|
10
|
+
h3: string;
|
|
11
|
+
quote: string;
|
|
12
|
+
divider: string;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const COLOR_PALETTES: ColorPalette[] = [
|
|
17
|
+
{
|
|
18
|
+
id: "forest-sage",
|
|
19
|
+
name: "🌿 森林墨绿 (Kinfolk / 少数派)",
|
|
20
|
+
category: "生活方式与编辑部",
|
|
21
|
+
description: "《Kinfolk》生活美学:沉稳深松绿强调色,搭配松针深黑与浅灰绿分割线",
|
|
22
|
+
colors: {
|
|
23
|
+
brand: "#1f6f4a",
|
|
24
|
+
text: "#1f2320",
|
|
25
|
+
h2: "#154c33",
|
|
26
|
+
h3: "#2e7d58",
|
|
27
|
+
quote: "#3d8e64",
|
|
28
|
+
divider: "#e1ebe5",
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
id: "oatmeal-earth",
|
|
33
|
+
name: "☕ 燕麦大地 (理想国 / 暖调成衣)",
|
|
34
|
+
category: "时尚与书籍出版",
|
|
35
|
+
description: "Loro Piana 暖调成衣美学:深焦糖陶土棕、浓咖啡黑与温润燕麦米灰",
|
|
36
|
+
colors: {
|
|
37
|
+
brand: "#945938",
|
|
38
|
+
text: "#2b2623",
|
|
39
|
+
h2: "#1f1b18",
|
|
40
|
+
h3: "#6b3f27",
|
|
41
|
+
quote: "#b37954",
|
|
42
|
+
divider: "#eae4dd",
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
id: "slate-indigo",
|
|
47
|
+
name: "🏛️ 石板深蓝 (纽约客 / Substack)",
|
|
48
|
+
category: "深度专栏与智识",
|
|
49
|
+
description: "经典严肃刊物:午夜深藏青做标识,石板灰文字与干净蓝灰分割",
|
|
50
|
+
colors: {
|
|
51
|
+
brand: "#2563eb",
|
|
52
|
+
text: "#1e293b",
|
|
53
|
+
h2: "#0f172a",
|
|
54
|
+
h3: "#334155",
|
|
55
|
+
quote: "#3b82f6",
|
|
56
|
+
divider: "#e2e8f0",
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: "burgundy-velvet",
|
|
61
|
+
name: "🍷 勃艮第红 (Vogue / 先锋艺术)",
|
|
62
|
+
category: "高级时尚与设计",
|
|
63
|
+
description: "复古先锋美学:丝绒绛红做点睛,黑绒字色与淡玫瑰粉灰底线",
|
|
64
|
+
colors: {
|
|
65
|
+
brand: "#881337",
|
|
66
|
+
text: "#231f20",
|
|
67
|
+
h2: "#1a1617",
|
|
68
|
+
h3: "#4c1d2e",
|
|
69
|
+
quote: "#9f1239",
|
|
70
|
+
divider: "#f2e5ea",
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: "matcha-bamboo",
|
|
75
|
+
name: "🍵 极简煎茶 (无印良品 / 东方和风)",
|
|
76
|
+
category: "极简器物与禅意",
|
|
77
|
+
description: "日系器物美学:深橄榄煎茶色、竹炭色正文与和纸灰底线",
|
|
78
|
+
colors: {
|
|
79
|
+
brand: "#556b2f",
|
|
80
|
+
text: "#262923",
|
|
81
|
+
h2: "#1c211a",
|
|
82
|
+
h3: "#435528",
|
|
83
|
+
quote: "#708846",
|
|
84
|
+
divider: "#e7eae1",
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
id: "titanium-cyan",
|
|
89
|
+
name: "🌌 极客钛灰 (Linear / Arc 现代界面)",
|
|
90
|
+
category: "现代数字与 App",
|
|
91
|
+
description: "当代高端数字界面:极光冷青点缀、深空曜黑文字与钛金属浅灰",
|
|
92
|
+
colors: {
|
|
93
|
+
brand: "#0284c7",
|
|
94
|
+
text: "#18181b",
|
|
95
|
+
h2: "#09090b",
|
|
96
|
+
h3: "#27272a",
|
|
97
|
+
quote: "#0ea5e9",
|
|
98
|
+
divider: "#e4e4e7",
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
id: "rose-ledger",
|
|
103
|
+
name: "🌸 晚樱柔粉 (古一软件经典标配)",
|
|
104
|
+
category: "人文与故事叙述",
|
|
105
|
+
description: "经典温润配色:干枯玫瑰粉与深铅黑文字,温柔克制",
|
|
106
|
+
colors: {
|
|
107
|
+
brand: "#ca6093",
|
|
108
|
+
text: "#292526",
|
|
109
|
+
h2: "#1f1b1c",
|
|
110
|
+
h3: "#5c5658",
|
|
111
|
+
quote: "#ca6093",
|
|
112
|
+
divider: "#dadce0",
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
];
|