dsh-fishpai 1.0.2
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/LICENSE +22 -0
- package/NOTICE.md +46 -0
- package/README.md +169 -0
- package/cordis.patch.yml +10 -0
- package/lib/client.js +2770 -0
- package/package.json +65 -0
- package/plugin/core/diff.mjs +208 -0
- package/plugin/core/markdown.mjs +450 -0
- package/plugin/core/notes.mjs +151 -0
- package/plugin/core/patch.mjs +93 -0
- package/plugin/core/render.mjs +906 -0
- package/plugin/core/runtime.mjs +83 -0
- package/plugin/core/theme-info.mjs +80 -0
- package/plugin/core/theme-spec.mjs +276 -0
- package/plugin/host/assets.mjs +120 -0
- package/plugin/host/custom-theme.mjs +121 -0
- package/plugin/host/routes.mjs +494 -0
- package/plugin/host/store.mjs +719 -0
- package/plugin/host/tools.mjs +573 -0
- package/plugin/index.mjs +127 -0
- package/plugin/vendor/highlight.min.js +1213 -0
- package/plugin/vendor/hljs-map.json +202 -0
- package/plugin/vendor/markdown-it.min.js +2 -0
- package/plugin/vendor/themes.js +414 -0
- package/skills/fishpai/SKILL.md +146 -0
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
// ============================================
|
|
2
|
+
// 样式主题配置 — 11 种精美主题
|
|
3
|
+
// ============================================
|
|
4
|
+
|
|
5
|
+
const themes = {
|
|
6
|
+
// ─── 经典公众号系列 ─────────────────────
|
|
7
|
+
default: {
|
|
8
|
+
name: '默认公众号',
|
|
9
|
+
emoji: '📱',
|
|
10
|
+
desc: '经典微信公众号排版',
|
|
11
|
+
category: 'classic',
|
|
12
|
+
styles: {
|
|
13
|
+
wrapper: 'font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Microsoft YaHei", sans-serif; color: #333; line-height: 1.75; padding: 16px 20px; font-size: 15px;',
|
|
14
|
+
h1: 'font-size: 22px; font-weight: bold; text-align: center; margin: 24px 0 16px; color: #1a1a1a; border-bottom: 2px solid {{PRIMARY}}; padding-bottom: 12px;',
|
|
15
|
+
h2: 'font-size: 18px; font-weight: bold; margin: 20px 0 12px; color: #1a1a1a; border-left: 4px solid {{PRIMARY}}; padding-left: 12px;',
|
|
16
|
+
h3: 'font-size: 16px; font-weight: bold; margin: 16px 0 8px; color: #333;',
|
|
17
|
+
p: 'margin: 8px 0; line-height: 1.8; letter-spacing: 0.5px;',
|
|
18
|
+
blockquote: 'border-left: 4px solid {{PRIMARY}}; background: {{PRIMARY_BG}}; padding: 12px 16px; margin: 12px auto; color: #555; border-radius: 0 4px 4px 0;',
|
|
19
|
+
code_inline: 'background: #fff5f5; color: #c7254e; padding: 2px 6px; border-radius: 3px; font-size: 90%;',
|
|
20
|
+
code_block: 'background: #282c34; color: #abb2bf; padding: 16px; border-radius: 8px; font-size: 13px; line-height: 1.6; overflow-x: auto;',
|
|
21
|
+
ul: 'margin: 8px 0; padding-left: 24px;',
|
|
22
|
+
ol: 'margin: 8px 0; padding-left: 24px;',
|
|
23
|
+
li: 'margin: 4px 0; line-height: 1.8;',
|
|
24
|
+
img: 'max-width: 100%; border-radius: 8px; margin: 12px auto; display: block;',
|
|
25
|
+
a: 'color: {{PRIMARY}}; text-decoration: none; border-bottom: 1px solid {{PRIMARY}};',
|
|
26
|
+
table: 'width: 100%; border-collapse: collapse; margin: 12px auto; font-size: 14px;',
|
|
27
|
+
th: 'background: {{PRIMARY_BG}}; padding: 10px 12px; border: 1px solid #e8e8e8; font-weight: bold; text-align: left;',
|
|
28
|
+
td: 'padding: 10px 12px; border: 1px solid #e8e8e8;',
|
|
29
|
+
hr: 'border: none; height: 1px; background: linear-gradient(to right, transparent, {{PRIMARY}}, transparent); margin: 24px 0;',
|
|
30
|
+
strong: 'color: {{PRIMARY}}; font-weight: bold;',
|
|
31
|
+
em: 'font-style: italic; color: #666;',
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
tech: {
|
|
36
|
+
name: '技术风格',
|
|
37
|
+
emoji: '💻',
|
|
38
|
+
desc: '适合技术文章',
|
|
39
|
+
category: 'classic',
|
|
40
|
+
styles: {
|
|
41
|
+
wrapper: 'font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", sans-serif; color: #2d3748; line-height: 1.8; padding: 16px 20px; font-size: 15px;',
|
|
42
|
+
h1: 'font-size: 24px; font-weight: 700; margin: 28px 0 16px; color: #1a202c; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; padding-bottom: 8px;',
|
|
43
|
+
h2: 'font-size: 19px; font-weight: 600; margin: 22px 0 12px; color: #2d3748; border-left: 4px solid #667eea; padding-left: 12px; background: linear-gradient(to right, #f0f0ff, transparent); padding: 8px 12px; border-radius: 0 4px 4px 0;',
|
|
44
|
+
h3: 'font-size: 16px; font-weight: 600; margin: 16px 0 8px; color: #4a5568;',
|
|
45
|
+
p: 'margin: 8px 0; line-height: 1.8; color: #4a5568;',
|
|
46
|
+
blockquote: 'border-left: 4px solid #667eea; background: linear-gradient(135deg, #f5f3ff, #ede9fe); padding: 14px 18px; margin: 14px auto; color: #5b21b6; border-radius: 0 8px 8px 0; font-style: italic;',
|
|
47
|
+
code_inline: 'background: #edf2f7; color: #553c9a; padding: 2px 8px; border-radius: 4px; font-size: 90%;',
|
|
48
|
+
code_block: 'background: #1a1b26; color: #a9b1d6; padding: 18px; border-radius: 10px; font-size: 13px; line-height: 1.7; overflow-x: auto; border: 1px solid #2d3748;',
|
|
49
|
+
ul: 'margin: 8px 0; padding-left: 24px;',
|
|
50
|
+
ol: 'margin: 8px 0; padding-left: 24px;',
|
|
51
|
+
li: 'margin: 4px 0; line-height: 1.8; color: #4a5568;',
|
|
52
|
+
img: 'max-width: 100%; border-radius: 10px; margin: 14px auto; display: block; box-shadow: 0 4px 12px rgba(0,0,0,0.1);',
|
|
53
|
+
a: 'color: #667eea; text-decoration: none; border-bottom: 1px dashed #667eea;',
|
|
54
|
+
table: 'width: 100%; border-collapse: collapse; margin: 14px auto; font-size: 14px;',
|
|
55
|
+
th: 'background: linear-gradient(135deg, #667eea, #764ba2); color: white; padding: 10px 14px; border: 1px solid #e2e8f0; text-align: left;',
|
|
56
|
+
td: 'padding: 10px 14px; border: 1px solid #e2e8f0;',
|
|
57
|
+
hr: 'border: none; height: 2px; background: linear-gradient(to right, #667eea, #764ba2); margin: 24px 0; border-radius: 1px;',
|
|
58
|
+
strong: 'color: #553c9a; font-weight: 700;',
|
|
59
|
+
em: 'font-style: italic; color: #718096;',
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
elegant: {
|
|
64
|
+
name: '优雅简约',
|
|
65
|
+
emoji: '✨',
|
|
66
|
+
desc: '精致杂志风排版',
|
|
67
|
+
category: 'classic',
|
|
68
|
+
styles: {
|
|
69
|
+
wrapper: 'font-family: "Georgia", "Noto Serif SC", "Source Han Serif SC", serif; color: #3c3c3c; line-height: 1.9; padding: 20px 24px; font-size: 16px;',
|
|
70
|
+
h1: 'font-size: 26px; font-weight: 700; text-align: center; margin: 32px 0 20px; color: #1a1a1a; letter-spacing: 2px;',
|
|
71
|
+
h2: 'font-size: 20px; font-weight: 600; margin: 24px 0 14px; color: #2c2c2c; text-align: center;',
|
|
72
|
+
h3: 'font-size: 17px; font-weight: 600; margin: 18px 0 10px; color: #444;',
|
|
73
|
+
p: 'margin: 10px 0; line-height: 2; text-indent: 2em; letter-spacing: 0.5px;',
|
|
74
|
+
blockquote: 'border-left: 3px solid #c9a96e; background: #fdf8f0; padding: 16px 20px; margin: 16px auto; color: #6b5b3e; font-style: italic; border-radius: 0 6px 6px 0;',
|
|
75
|
+
code_inline: 'background: #f8f5f0; color: #8b6914; padding: 2px 6px; border-radius: 3px; font-size: 90%;',
|
|
76
|
+
code_block: 'background: #2b2b2b; color: #d4d4d4; padding: 18px; border-radius: 8px; font-size: 13px; line-height: 1.6; overflow-x: auto;',
|
|
77
|
+
ul: 'margin: 10px 0; padding-left: 20px;',
|
|
78
|
+
ol: 'margin: 10px 0; padding-left: 24px;',
|
|
79
|
+
li: 'margin: 6px 0; line-height: 1.9;',
|
|
80
|
+
img: 'max-width: 100%; border-radius: 6px; margin: 16px auto; display: block; box-shadow: 0 2px 12px rgba(0,0,0,0.08);',
|
|
81
|
+
a: 'color: #c9a96e; text-decoration: none; border-bottom: 1px solid #c9a96e;',
|
|
82
|
+
table: 'width: 100%; border-collapse: collapse; margin: 16px auto; font-size: 14px;',
|
|
83
|
+
th: 'background: #fdf8f0; padding: 12px 14px; border: 1px solid #e8dcc8; font-weight: bold;',
|
|
84
|
+
td: 'padding: 12px 14px; border: 1px solid #e8dcc8;',
|
|
85
|
+
hr: 'border: none; height: 1px; background: linear-gradient(to right, transparent, #c9a96e, transparent); margin: 28px 0;',
|
|
86
|
+
strong: 'color: #8b6914; font-weight: 700;',
|
|
87
|
+
em: 'font-style: italic; color: #777;',
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
deep_read: {
|
|
92
|
+
name: '深度阅读',
|
|
93
|
+
emoji: '📖',
|
|
94
|
+
desc: '适合长文阅读',
|
|
95
|
+
category: 'classic',
|
|
96
|
+
styles: {
|
|
97
|
+
wrapper: 'font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", sans-serif; color: #374151; line-height: 2; padding: 20px 24px; font-size: 16px;',
|
|
98
|
+
h1: 'font-size: 28px; font-weight: 800; margin: 36px 0 20px; color: #111827; letter-spacing: -0.5px;',
|
|
99
|
+
h2: 'font-size: 22px; font-weight: 700; margin: 28px 0 14px; color: #1f2937; padding-bottom: 8px; border-bottom: 1px solid #e5e7eb;',
|
|
100
|
+
h3: 'font-size: 18px; font-weight: 600; margin: 20px 0 10px; color: #374151;',
|
|
101
|
+
p: 'margin: 12px 0; line-height: 2; color: #4b5563; letter-spacing: 0.3px;',
|
|
102
|
+
blockquote: 'border-left: 3px solid #6366f1; background: #eef2ff; padding: 16px 20px; margin: 16px auto; color: #4338ca; border-radius: 0 8px 8px 0;',
|
|
103
|
+
code_inline: 'background: #f3f4f6; color: #dc2626; padding: 2px 6px; border-radius: 4px; font-size: 90%;',
|
|
104
|
+
code_block: 'background: #111827; color: #e5e7eb; padding: 20px; border-radius: 12px; font-size: 14px; line-height: 1.7; overflow-x: auto;',
|
|
105
|
+
ul: 'margin: 10px 0; padding-left: 24px;',
|
|
106
|
+
ol: 'margin: 10px 0; padding-left: 24px;',
|
|
107
|
+
li: 'margin: 6px 0; line-height: 2; color: #4b5563;',
|
|
108
|
+
img: 'max-width: 100%; border-radius: 12px; margin: 20px auto; display: block;',
|
|
109
|
+
a: 'color: #6366f1; text-decoration: none; font-weight: 500;',
|
|
110
|
+
table: 'width: 100%; border-collapse: collapse; margin: 16px auto;',
|
|
111
|
+
th: 'background: #f9fafb; padding: 12px 16px; border: 1px solid #e5e7eb; font-weight: 600;',
|
|
112
|
+
td: 'padding: 12px 16px; border: 1px solid #e5e7eb;',
|
|
113
|
+
hr: 'border: none; text-align: center; margin: 32px 0; height: auto;',
|
|
114
|
+
strong: 'color: #111827; font-weight: 700;',
|
|
115
|
+
em: 'font-style: italic; color: #6b7280;',
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
// ─── 媒体风格系列 ─────────────────────
|
|
120
|
+
nyt: {
|
|
121
|
+
name: '纽约时报',
|
|
122
|
+
emoji: '📰',
|
|
123
|
+
desc: '经典报刊风格',
|
|
124
|
+
category: 'media',
|
|
125
|
+
styles: {
|
|
126
|
+
wrapper: 'font-family: "Georgia", "Noto Serif SC", serif; color: #333; line-height: 1.8; padding: 20px 24px; font-size: 17px;',
|
|
127
|
+
h1: 'font-family: "Georgia", serif; font-size: 32px; font-weight: 900; margin: 32px 0 8px; color: #121212; letter-spacing: -0.5px; line-height: 1.2;',
|
|
128
|
+
h2: 'font-family: "Georgia", serif; font-size: 22px; font-weight: 700; margin: 28px 0 10px; color: #121212;',
|
|
129
|
+
h3: 'font-size: 18px; font-weight: 700; margin: 20px 0 8px; color: #333; font-style: italic;',
|
|
130
|
+
p: 'margin: 8px 0; line-height: 1.85; color: #333;',
|
|
131
|
+
blockquote: 'border-left: 3px solid #121212; padding: 0 0 0 20px; margin: 16px auto; color: #555; font-style: italic; font-size: 18px;',
|
|
132
|
+
code_inline: 'background: #f7f7f7; color: #333; padding: 2px 6px; border-radius: 2px; font-size: 88%;',
|
|
133
|
+
code_block: 'background: #f7f7f7; color: #333; padding: 20px; border-radius: 4px; font-size: 14px; line-height: 1.6; overflow-x: auto; border: 1px solid #e0e0e0;',
|
|
134
|
+
ul: 'margin: 8px 0; padding-left: 20px;',
|
|
135
|
+
ol: 'margin: 8px 0; padding-left: 20px;',
|
|
136
|
+
li: 'margin: 4px 0; line-height: 1.85;',
|
|
137
|
+
img: 'max-width: 100%; margin: 16px auto; display: block;',
|
|
138
|
+
a: 'color: #326891; text-decoration: underline;',
|
|
139
|
+
table: 'width: 100%; border-collapse: collapse; margin: 16px auto;',
|
|
140
|
+
th: 'background: #f7f7f7; padding: 10px 14px; border-bottom: 2px solid #121212; font-weight: bold; text-align: left;',
|
|
141
|
+
td: 'padding: 10px 14px; border-bottom: 1px solid #e0e0e0;',
|
|
142
|
+
hr: 'border: none; border-top: 1px solid #ccc; margin: 28px 0;',
|
|
143
|
+
strong: 'font-weight: 900; color: #121212;',
|
|
144
|
+
em: 'font-style: italic;',
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
|
|
148
|
+
// 上游的「金融时报(ft)」与「Medium」两套主题已移除(实测后决定,非上游行为):
|
|
149
|
+
// · ft 的特点就是整页粉橙异色底(background: #fff1e5),而公众号文章不适合整页底色;
|
|
150
|
+
// 去掉底之后它与相邻的衬线主题几乎一样,没有单独存在的价值。
|
|
151
|
+
// · medium 与 nyt 的差别只剩字号与字体栈,实际观感重合。
|
|
152
|
+
// 上游原版 themes.js 仍完整保留在 legacy-site/ 里,需要逐字节比对时看那边。
|
|
153
|
+
|
|
154
|
+
// ─── 现代数字系列 ─────────────────────
|
|
155
|
+
apple: {
|
|
156
|
+
name: 'Apple 极简',
|
|
157
|
+
emoji: '🍎',
|
|
158
|
+
desc: '苹果风格极简设计',
|
|
159
|
+
category: 'modern',
|
|
160
|
+
styles: {
|
|
161
|
+
wrapper: 'font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", "PingFang SC", sans-serif; color: #1d1d1f; line-height: 1.75; padding: 20px 28px; font-size: 17px;',
|
|
162
|
+
h1: 'font-size: 32px; font-weight: 700; margin: 40px 0 16px; color: #1d1d1f; letter-spacing: -0.5px; line-height: 1.15;',
|
|
163
|
+
h2: 'font-size: 24px; font-weight: 600; margin: 32px 0 12px; color: #1d1d1f;',
|
|
164
|
+
h3: 'font-size: 19px; font-weight: 600; margin: 24px 0 8px; color: #1d1d1f;',
|
|
165
|
+
p: 'margin: 10px 0; line-height: 1.75; color: #1d1d1f;',
|
|
166
|
+
blockquote: 'border-left: 3px solid #0071e3; padding: 12px 20px; margin: 16px auto; color: #6e6e73; background: #f5f5f7; border-radius: 0 12px 12px 0;',
|
|
167
|
+
code_inline: 'background: #f5f5f7; color: #1d1d1f; padding: 3px 8px; border-radius: 6px; font-size: 88%;',
|
|
168
|
+
code_block: 'background: #1d1d1f; color: #f5f5f7; padding: 20px; border-radius: 14px; font-size: 14px; line-height: 1.7; overflow-x: auto;',
|
|
169
|
+
ul: 'margin: 10px 0; padding-left: 24px;',
|
|
170
|
+
ol: 'margin: 10px 0; padding-left: 24px;',
|
|
171
|
+
li: 'margin: 6px 0; line-height: 1.75;',
|
|
172
|
+
img: 'max-width: 100%; border-radius: 16px; margin: 20px auto; display: block;',
|
|
173
|
+
a: 'color: #0071e3; text-decoration: none;',
|
|
174
|
+
table: 'width: 100%; border-collapse: collapse; margin: 16px auto;',
|
|
175
|
+
th: 'background: #f5f5f7; padding: 12px 16px; border-bottom: 1px solid #d2d2d7; font-weight: 600; text-align: left;',
|
|
176
|
+
td: 'padding: 12px 16px; border-bottom: 1px solid #d2d2d7;',
|
|
177
|
+
hr: 'border: none; height: 1px; background: #d2d2d7; margin: 32px 0;',
|
|
178
|
+
strong: 'font-weight: 600;',
|
|
179
|
+
em: 'font-style: italic; color: #6e6e73;',
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
|
|
183
|
+
claude: {
|
|
184
|
+
name: 'Claude',
|
|
185
|
+
emoji: '🤖',
|
|
186
|
+
desc: 'Anthropic Claude 风格',
|
|
187
|
+
category: 'modern',
|
|
188
|
+
styles: {
|
|
189
|
+
wrapper: 'font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", sans-serif; color: #2d2b2a; line-height: 1.8; padding: 20px 24px; font-size: 16px;',
|
|
190
|
+
h1: 'font-size: 26px; font-weight: 700; margin: 32px 0 16px; color: #c96442; letter-spacing: -0.3px;',
|
|
191
|
+
h2: 'font-size: 21px; font-weight: 600; margin: 24px 0 12px; color: #c96442; border-bottom: 2px solid #f0dcc8; padding-bottom: 8px;',
|
|
192
|
+
h3: 'font-size: 17px; font-weight: 600; margin: 18px 0 8px; color: #8b5c3e;',
|
|
193
|
+
p: 'margin: 10px 0; line-height: 1.85; color: #2d2b2a;',
|
|
194
|
+
blockquote: 'border-left: 3px solid #c96442; background: #faf3ea; padding: 14px 20px; margin: 14px auto; color: #5c4a3a; border-radius: 0 8px 8px 0;',
|
|
195
|
+
code_inline: 'background: #f5ede4; color: #c96442; padding: 2px 8px; border-radius: 5px; font-size: 90%;',
|
|
196
|
+
code_block: 'background: #2d2b2a; color: #f5ede4; padding: 18px; border-radius: 12px; font-size: 13.5px; line-height: 1.7; overflow-x: auto; border: 1px solid #e8dcc8;',
|
|
197
|
+
ul: 'margin: 10px 0; padding-left: 24px;',
|
|
198
|
+
ol: 'margin: 10px 0; padding-left: 24px;',
|
|
199
|
+
li: 'margin: 5px 0; line-height: 1.85;',
|
|
200
|
+
img: 'max-width: 100%; border-radius: 12px; margin: 18px auto; display: block; box-shadow: 0 2px 8px rgba(150,100,60,0.1);',
|
|
201
|
+
a: 'color: #c96442; text-decoration: none; border-bottom: 1px solid #c96442;',
|
|
202
|
+
table: 'width: 100%; border-collapse: collapse; margin: 16px auto;',
|
|
203
|
+
th: 'background: #faf3ea; padding: 10px 14px; border: 1px solid #e8dcc8; font-weight: 600; text-align: left;',
|
|
204
|
+
td: 'padding: 10px 14px; border: 1px solid #e8dcc8;',
|
|
205
|
+
hr: 'border: none; height: 2px; background: linear-gradient(to right, transparent, #c96442, transparent); margin: 28px 0;',
|
|
206
|
+
strong: 'color: #c96442; font-weight: 600;',
|
|
207
|
+
em: 'font-style: italic; color: #8b7b6b;',
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
|
|
211
|
+
// ─── V3 新增主题 ─────────────────────
|
|
212
|
+
sspai: {
|
|
213
|
+
name: '少数派',
|
|
214
|
+
emoji: '🔮',
|
|
215
|
+
desc: 'sspai 清新科技风',
|
|
216
|
+
category: 'modern',
|
|
217
|
+
styles: {
|
|
218
|
+
wrapper: 'font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Noto Sans SC", sans-serif; color: #2b2b2b; line-height: 1.8; padding: 20px 24px; font-size: 16px;',
|
|
219
|
+
h1: 'font-size: 26px; font-weight: 700; margin: 32px 0 16px; color: #d71a18; letter-spacing: -0.3px;',
|
|
220
|
+
h2: 'font-size: 20px; font-weight: 600; margin: 24px 0 12px; color: #2b2b2b; border-left: 4px solid #d71a18; padding-left: 12px;',
|
|
221
|
+
h3: 'font-size: 16px; font-weight: 600; margin: 18px 0 8px; color: #444;',
|
|
222
|
+
p: 'margin: 10px 0; line-height: 1.85; color: #2b2b2b;',
|
|
223
|
+
blockquote: 'border-left: 4px solid #d71a18; background: #fef5f5; padding: 14px 18px; margin: 14px auto; color: #666; border-radius: 0 6px 6px 0;',
|
|
224
|
+
code_inline: 'background: #f4f4f4; color: #d71a18; padding: 2px 8px; border-radius: 4px; font-size: 90%;',
|
|
225
|
+
code_block: 'background: #1e1e1e; color: #d4d4d4; padding: 18px; border-radius: 10px; font-size: 13px; line-height: 1.7; overflow-x: auto;',
|
|
226
|
+
ul: 'margin: 10px 0; padding-left: 24px;',
|
|
227
|
+
ol: 'margin: 10px 0; padding-left: 24px;',
|
|
228
|
+
li: 'margin: 5px 0; line-height: 1.8;',
|
|
229
|
+
img: 'max-width: 100%; border-radius: 8px; margin: 16px auto; display: block;',
|
|
230
|
+
a: 'color: #d71a18; text-decoration: none;',
|
|
231
|
+
table: 'width: 100%; border-collapse: collapse; margin: 16px auto;',
|
|
232
|
+
th: 'background: #fef5f5; padding: 10px 14px; border: 1px solid #eee; font-weight: 600; text-align: left;',
|
|
233
|
+
td: 'padding: 10px 14px; border: 1px solid #eee;',
|
|
234
|
+
hr: 'border: none; height: 2px; background: linear-gradient(to right, #d71a18, transparent); margin: 28px 0;',
|
|
235
|
+
strong: 'color: #d71a18; font-weight: 700;',
|
|
236
|
+
em: 'font-style: italic; color: #888;',
|
|
237
|
+
}
|
|
238
|
+
},
|
|
239
|
+
|
|
240
|
+
bamboo: {
|
|
241
|
+
name: '竹林',
|
|
242
|
+
emoji: '🎋',
|
|
243
|
+
desc: '中国风绿色雅致',
|
|
244
|
+
category: 'creative',
|
|
245
|
+
styles: {
|
|
246
|
+
wrapper: 'font-family: "STKaiti", "KaiTi", "Noto Serif SC", "Georgia", serif; color: #2c3e2d; line-height: 1.9; padding: 20px 24px; font-size: 16px;',
|
|
247
|
+
h1: 'font-size: 28px; font-weight: 700; text-align: center; margin: 36px 0 20px; color: #1a472a; letter-spacing: 4px;',
|
|
248
|
+
h2: 'font-size: 20px; font-weight: 600; margin: 24px 0 14px; color: #2c5f3a; padding-bottom: 8px; border-bottom: 2px solid #8fbc8f;',
|
|
249
|
+
h3: 'font-size: 17px; font-weight: 600; margin: 18px 0 10px; color: #3a7d44;',
|
|
250
|
+
p: 'margin: 10px 0; line-height: 2; text-indent: 2em; color: #2c3e2d;',
|
|
251
|
+
blockquote: 'border-left: 4px solid #8fbc8f; background: #f0f8f0; padding: 16px 20px; margin: 16px auto; color: #3a7d44; border-radius: 0 8px 8px 0; font-style: italic;',
|
|
252
|
+
code_inline: 'background: #e8f5e9; color: #2e7d32; padding: 2px 6px; border-radius: 4px; font-size: 90%;',
|
|
253
|
+
code_block: 'background: #1b2a1b; color: #a5d6a7; padding: 18px; border-radius: 8px; font-size: 13px; line-height: 1.7; overflow-x: auto;',
|
|
254
|
+
ul: 'margin: 10px 0; padding-left: 24px;',
|
|
255
|
+
ol: 'margin: 10px 0; padding-left: 24px;',
|
|
256
|
+
li: 'margin: 6px 0; line-height: 1.9;',
|
|
257
|
+
img: 'max-width: 100%; border-radius: 8px; margin: 16px auto; display: block; box-shadow: 0 2px 12px rgba(60,120,60,0.1);',
|
|
258
|
+
a: 'color: #2e7d32; text-decoration: none; border-bottom: 1px dashed #8fbc8f;',
|
|
259
|
+
table: 'width: 100%; border-collapse: collapse; margin: 16px auto;',
|
|
260
|
+
th: 'background: #f0f8f0; padding: 10px 14px; border: 1px solid #c8e6c9; font-weight: 600; text-align: left;',
|
|
261
|
+
td: 'padding: 10px 14px; border: 1px solid #c8e6c9;',
|
|
262
|
+
hr: 'border: none; height: 1px; background: linear-gradient(to right, transparent, #8fbc8f, transparent); margin: 28px 0;',
|
|
263
|
+
strong: 'color: #1b5e20; font-weight: 700;',
|
|
264
|
+
em: 'font-style: italic; color: #689f63;',
|
|
265
|
+
}
|
|
266
|
+
},
|
|
267
|
+
|
|
268
|
+
dark_night: {
|
|
269
|
+
name: '暗夜模式',
|
|
270
|
+
emoji: '🌃',
|
|
271
|
+
desc: '暗色背景高对比',
|
|
272
|
+
category: 'creative',
|
|
273
|
+
styles: {
|
|
274
|
+
wrapper: 'font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", sans-serif; color: #e0e0e0; line-height: 1.8; padding: 20px 24px; font-size: 16px; background: #1a1a2e;',
|
|
275
|
+
h1: 'font-size: 26px; font-weight: 700; margin: 32px 0 16px; color: #e94560; letter-spacing: -0.3px;',
|
|
276
|
+
h2: 'font-size: 20px; font-weight: 600; margin: 24px 0 12px; color: #e94560; border-left: 4px solid #e94560; padding-left: 12px;',
|
|
277
|
+
h3: 'font-size: 17px; font-weight: 600; margin: 18px 0 8px; color: #ff8a80;',
|
|
278
|
+
p: 'margin: 10px 0; line-height: 1.85; color: #c0c0c0;',
|
|
279
|
+
blockquote: 'border-left: 4px solid #e94560; background: rgba(233,69,96,0.08); padding: 14px 18px; margin: 14px auto; color: #ff8a80; border-radius: 0 8px 8px 0;',
|
|
280
|
+
code_inline: 'background: rgba(255,255,255,0.08); color: #64ffda; padding: 2px 8px; border-radius: 4px; font-size: 90%;',
|
|
281
|
+
code_block: 'background: #0f0f1a; color: #a9b1d6; padding: 18px; border-radius: 10px; font-size: 13px; line-height: 1.7; overflow-x: auto; border: 1px solid #16213e;',
|
|
282
|
+
ul: 'margin: 10px 0; padding-left: 24px;',
|
|
283
|
+
ol: 'margin: 10px 0; padding-left: 24px;',
|
|
284
|
+
li: 'margin: 5px 0; line-height: 1.85; color: #c0c0c0;',
|
|
285
|
+
img: 'max-width: 100%; border-radius: 10px; margin: 16px auto; display: block;',
|
|
286
|
+
a: 'color: #64ffda; text-decoration: none;',
|
|
287
|
+
table: 'width: 100%; border-collapse: collapse; margin: 16px auto;',
|
|
288
|
+
th: 'background: rgba(233,69,96,0.15); padding: 10px 14px; border: 1px solid #16213e; font-weight: 600; text-align: left; color: #e94560;',
|
|
289
|
+
td: 'padding: 10px 14px; border: 1px solid #16213e; color: #c0c0c0;',
|
|
290
|
+
hr: 'border: none; height: 2px; background: linear-gradient(to right, #e94560, #0f3460, #e94560); margin: 28px 0;',
|
|
291
|
+
strong: 'color: #e94560; font-weight: 700;',
|
|
292
|
+
em: 'font-style: italic; color: #888;',
|
|
293
|
+
}
|
|
294
|
+
},
|
|
295
|
+
|
|
296
|
+
gradient: {
|
|
297
|
+
name: '渐变彩虹',
|
|
298
|
+
emoji: '🌈',
|
|
299
|
+
desc: '标题彩色渐变效果',
|
|
300
|
+
category: 'creative',
|
|
301
|
+
styles: {
|
|
302
|
+
wrapper: 'font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", sans-serif; color: #333; line-height: 1.8; padding: 20px 24px; font-size: 16px;',
|
|
303
|
+
h1: 'font-size: 28px; font-weight: 800; margin: 32px 0 16px; background: linear-gradient(135deg, #f093fb 0%, #f5576c 50%, #4facfe 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; text-align: center;',
|
|
304
|
+
h2: 'font-size: 21px; font-weight: 700; margin: 24px 0 12px; background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent;',
|
|
305
|
+
h3: 'font-size: 17px; font-weight: 600; margin: 18px 0 8px; background: linear-gradient(135deg, #fa709a 0%, #fee140 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent;',
|
|
306
|
+
p: 'margin: 10px 0; line-height: 1.85; color: #444;',
|
|
307
|
+
blockquote: 'border-left: 4px solid; border-image: linear-gradient(to bottom, #f093fb, #f5576c) 1; background: linear-gradient(135deg, #fdf2f8, #fce7f3); padding: 14px 18px; margin: 14px auto; color: #9b2c6c; border-radius: 0;',
|
|
308
|
+
code_inline: 'background: linear-gradient(135deg, #e0c3fc, #8ec5fc); color: #5b21b6; padding: 2px 8px; border-radius: 4px; font-size: 90%;',
|
|
309
|
+
code_block: 'background: #1a1a2e; color: #e0e0e0; padding: 18px; border-radius: 12px; font-size: 13px; line-height: 1.7; overflow-x: auto; border: 2px solid; border-image: linear-gradient(135deg, #f093fb, #f5576c, #4facfe) 1;',
|
|
310
|
+
ul: 'margin: 10px 0; padding-left: 24px;',
|
|
311
|
+
ol: 'margin: 10px 0; padding-left: 24px;',
|
|
312
|
+
li: 'margin: 5px 0; line-height: 1.85;',
|
|
313
|
+
img: 'max-width: 100%; border-radius: 12px; margin: 16px auto; display: block;',
|
|
314
|
+
a: 'background: linear-gradient(135deg, #f093fb, #f5576c); -webkit-background-clip: text; -webkit-text-fill-color: transparent; text-decoration: none; font-weight: 600;',
|
|
315
|
+
table: 'width: 100%; border-collapse: collapse; margin: 16px auto;',
|
|
316
|
+
th: 'background: linear-gradient(135deg, #e0c3fc, #8ec5fc); padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600; text-align: left;',
|
|
317
|
+
td: 'padding: 10px 14px; border: 1px solid #e2e8f0;',
|
|
318
|
+
hr: 'border: none; height: 3px; background: linear-gradient(to right, #f093fb, #f5576c, #ffecd2, #43e97b, #4facfe); margin: 28px 0; border-radius: 2px;',
|
|
319
|
+
strong: 'background: linear-gradient(135deg, #f5576c, #ff6b6b); -webkit-background-clip: text; -webkit-text-fill-color: transparent; font-weight: 800;',
|
|
320
|
+
em: 'font-style: italic; color: #888;',
|
|
321
|
+
}
|
|
322
|
+
},
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
// ─── 预设颜色板 ─────────────────────
|
|
326
|
+
const colorPresets = [
|
|
327
|
+
{ name: '翡翠绿', color: '#10b981' },
|
|
328
|
+
{ name: '天空蓝', color: '#3b82f6' },
|
|
329
|
+
{ name: '靛蓝', color: '#4f6ef7' },
|
|
330
|
+
{ name: '薰衣紫', color: '#8b5cf6' },
|
|
331
|
+
{ name: '玫瑰粉', color: '#ec4899' },
|
|
332
|
+
{ name: '珊瑚红', color: '#ef4444' },
|
|
333
|
+
{ name: '琥珀橙', color: '#f59e0b' },
|
|
334
|
+
{ name: '青碧', color: '#0d9488' },
|
|
335
|
+
{ name: '海军蓝', color: '#1e40af' },
|
|
336
|
+
{ name: '深玫瑰', color: '#be185d' },
|
|
337
|
+
{ name: '石墨灰', color: '#4b5563' },
|
|
338
|
+
{ name: '经典蓝', color: '#1890ff' },
|
|
339
|
+
];
|
|
340
|
+
|
|
341
|
+
// ─── 示例 Markdown 内容 ─────────────────
|
|
342
|
+
const sampleMarkdown = `# MoPai 墨排 V3
|
|
343
|
+
|
|
344
|
+
欢迎使用 **MoPai 墨排** V3!✒️ 优雅高效的多平台 Markdown 排版工具。
|
|
345
|
+
|
|
346
|
+
## 🎯 核心功能
|
|
347
|
+
|
|
348
|
+
### 1. 实时预览
|
|
349
|
+
左侧输入 Markdown,右侧即时查看排版效果。
|
|
350
|
+
|
|
351
|
+
### 2. 13 种精美主题
|
|
352
|
+
> 💡 支持 13 种专业设计主题,涵盖经典公众号、媒体风格、现代数字、创意系列。
|
|
353
|
+
|
|
354
|
+
### 3. 暗色模式
|
|
355
|
+
点击右上角 🌙 图标切换暗色界面,减轻眼睛疲劳。
|
|
356
|
+
|
|
357
|
+
### 4. 自定义样式
|
|
358
|
+
- 🎨 12 种预设颜色 + 自定义取色器
|
|
359
|
+
- 🔤 3 种字体风格 + 5 档字号
|
|
360
|
+
- 💻 Mac 风格代码块
|
|
361
|
+
|
|
362
|
+
## 📝 排版示例
|
|
363
|
+
|
|
364
|
+
### 文字样式
|
|
365
|
+
|
|
366
|
+
**加粗文字** 和 *斜体文字*,以及 \`行内代码\`。
|
|
367
|
+
|
|
368
|
+
### 信息卡片
|
|
369
|
+
|
|
370
|
+
:::tip 💡 使用提示
|
|
371
|
+
你可以使用 \`:::info\`、\`:::warning\`、\`:::tip\` 来创建漂亮的信息卡片。
|
|
372
|
+
:::
|
|
373
|
+
|
|
374
|
+
:::warning ⚠️ 注意事项
|
|
375
|
+
复制到公众号时,请确保使用「复制到公众号」按钮。
|
|
376
|
+
:::
|
|
377
|
+
|
|
378
|
+
### 代码块
|
|
379
|
+
|
|
380
|
+
\`\`\`python
|
|
381
|
+
def hello():
|
|
382
|
+
"""Mac 风格代码块,带三色圆点"""
|
|
383
|
+
print("Hello, Markdown! 🎉")
|
|
384
|
+
return True
|
|
385
|
+
\`\`\`
|
|
386
|
+
|
|
387
|
+
\`\`\`javascript
|
|
388
|
+
const themes = ['默认', '技术', '优雅', 'Claude', '暗夜'];
|
|
389
|
+
themes.forEach(theme => console.log(\`🎨 \${theme}\`));
|
|
390
|
+
\`\`\`
|
|
391
|
+
|
|
392
|
+
### 表格
|
|
393
|
+
|
|
394
|
+
| 功能 | 说明 | 状态 |
|
|
395
|
+
|------|------|------|
|
|
396
|
+
| 13 种主题 | 经典 + 媒体 + 现代 + 创意 | ✅ |
|
|
397
|
+
| 暗色模式 | 一键切换 | ✅ |
|
|
398
|
+
| 自定义颜色 | 12 预设 + 自选 | ✅ |
|
|
399
|
+
| Mac 代码块 | 三色圆点标题栏 | ✅ |
|
|
400
|
+
| 格式工具栏 | 快捷插入语法 | ✅ |
|
|
401
|
+
| 导出 HTML | 下载排版文件 | ✅ |
|
|
402
|
+
|
|
403
|
+
### 有序列表
|
|
404
|
+
|
|
405
|
+
1. 编写 Markdown 内容
|
|
406
|
+
2. 选择心仪的样式主题
|
|
407
|
+
3. 调整字体和颜色
|
|
408
|
+
4. 点击复制到公众号
|
|
409
|
+
5. 粘贴到微信编辑器 🎉
|
|
410
|
+
|
|
411
|
+
---
|
|
412
|
+
|
|
413
|
+
*由 MoPai 墨排 V3 生成 · 优雅高效的排版工具*
|
|
414
|
+
`;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fishpai
|
|
3
|
+
description: 把 Markdown 排成可直接粘进微信公众号编辑器的内联样式 HTML,并在 DSH 右侧栏的「鱼排编辑器」面板里与人协同改稿(11 套主题 + 微信脚注 + 代码块高亮)。当用户要求「公众号排版」「微信排版」「把这篇 Markdown 排好看点」「套个主题」「复制到公众号」「改这篇公众号文章」,或提到鱼排 / FishPai / 墨排 / MoPai / mopai-markdown 时使用;也用于人在鱼排面板里改过稿、加了批注或行内占位之后,需要读懂 diff 再改稿的场合。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 鱼排 FishPai(公众号排版与协同改稿)
|
|
7
|
+
|
|
8
|
+
鱼排把 Markdown 排成**内联样式 HTML**:整段粘进微信公众号编辑器就得到成品排版。
|
|
9
|
+
它的渲染内核与 [MoPai 墨排](https://github.com/ye4wzp/mopai-markdown) 的「复制到公众号」输出逐字节一致
|
|
10
|
+
(真实剪贴板内容规范化后零差异)。主题清单有意不同:上游的「金融时报」「Medium」已移除,「Claude」去掉了整页异色底。
|
|
11
|
+
|
|
12
|
+
## 什么时候用
|
|
13
|
+
|
|
14
|
+
- 用户要把一篇 Markdown(活动通告、文章、说明)排成公众号样式
|
|
15
|
+
- 用户想换主题、调字号、调主题色,或要「复制到公众号」
|
|
16
|
+
- 用户在**鱼排面板里改过稿、加过批注/占位**,要你把他的改动读进来再改
|
|
17
|
+
- 用户提到鱼排 / FishPai / 墨排 / MoPai / mopai-markdown
|
|
18
|
+
|
|
19
|
+
**不适用**:需要真的发布到公众号后台(要走微信官方 API 或人工粘贴)。鱼排只产出可粘贴的 HTML,
|
|
20
|
+
发布永远由人复制粘贴完成。
|
|
21
|
+
|
|
22
|
+
## 五个工具与正确顺序
|
|
23
|
+
|
|
24
|
+
| 工具 | 用途 |
|
|
25
|
+
|---|---|
|
|
26
|
+
| `fishpai_open` | 打开/新建文档并在右侧栏弹出面板。传 `markdown` 新建;传 `path` 打开已有的 `.md`(**不覆盖**已有内容;`path` 可省略扩展名,会自动补 `.md`) |
|
|
27
|
+
| `fishpai_read` | **改稿前必做**。返回:与"你上次写入的版本"的**块级 diff**、人的**批注**、**行内占位**、图片提醒、全文与块 id |
|
|
28
|
+
| `fishpai_write` | 改稿。必须带 `base_revision`;优先 `mode:"patch"` 只改指定块,`mode:"replace"` 才整篇换 |
|
|
29
|
+
| `fishpai_render` | 导出可粘贴/归档用的自包含 HTML 文件(本地图片内嵌 base64;`out_path` 可省略扩展名) |
|
|
30
|
+
| `fishpai_theme` | 存/看/删**工作目录级**的那一套「自定义主题」(`set` / `show` / `clear`)。用户要"某种观感"时用,见下面「自定义主题」一节 |
|
|
31
|
+
|
|
32
|
+
标准流程:
|
|
33
|
+
|
|
34
|
+
1. 用户要写/改一篇公众号文章 → `fishpai_open({ markdown })`(或 `{ path: 'in/x.md' }` 打开现成的)
|
|
35
|
+
2. 告诉用户「右侧栏的「鱼排编辑器」已打开,你可以直接改字、选中块加批注」,然后**停下等他**
|
|
36
|
+
3. 用户说"我改了,你看看" → `fishpai_read`
|
|
37
|
+
4. 按 diff + 批注改稿 → `fishpai_write({ base_revision, mode:'patch', patches:[…] })`
|
|
38
|
+
5. 用户满意 → 他自己点面板上的「复制到公众号」;需要成品文件时用 `fishpai_render`
|
|
39
|
+
|
|
40
|
+
## 铁律
|
|
41
|
+
|
|
42
|
+
1. **先读后写**。`fishpai_write` 不带 `base_revision` 或版本不匹配会被**拒绝**——这是为了不覆盖人的手改。
|
|
43
|
+
被拒绝时不要硬来:重新 `fishpai_read`,看清人又改了什么,再用新 revision 提交。
|
|
44
|
+
2. **只改要改的块**。`mode:"patch"` 配 `block_id`(来自 `fishpai_read` 的 diff 或 `outline`)局部改;
|
|
45
|
+
整篇 `replace` 会覆盖人其它位置的改动,只在确实需要重写时用。
|
|
46
|
+
3. **块 id 是内容寻址的**:人改了某块内容,它的 id 就变了。所以要用**最近一次 `read` 的结果**里的 id,
|
|
47
|
+
不要复用上一轮的 id。
|
|
48
|
+
4. **批注是对你的指令**。`fishpai_read` 里 `[块 xxx]:正文` 形式的批注就是人让他改哪块、怎么改。
|
|
49
|
+
标了「锚点已失效」的批注说明那块被大改过,按 `quote` 片段自行判断位置。
|
|
50
|
+
5. **行内占位要清掉**。`<!-- 鱼排: … -->` 是人留的待补记号;处理完对应正文后把那行注释一并删除。
|
|
51
|
+
|
|
52
|
+
## 排版口径
|
|
53
|
+
|
|
54
|
+
- **默认用「默认公众号」**:它才是给微信做的(浅底、内联样式最稳)。只有当用户明确要某种观感、
|
|
55
|
+
或明确说"只是要一份 HTML"时才换主题。
|
|
56
|
+
- **主题色只对「默认公众号」生效**:只有它用了主题色占位符,换到别的主题点了也不会变
|
|
57
|
+
(面板在这种情况下已经把取色控件藏起来)。别向用户承诺"换个主题色"。
|
|
58
|
+
- **微信风险主题**:`tech`、`gradient` 用渐变文字(`background-clip: text` + 透明字色),
|
|
59
|
+
微信编辑器可能重写掉渐变导致标题异常(平台结构校验也会直接标出 `darkmode-no-gradient`);
|
|
60
|
+
`dark_night` 是深色底,粘进公众号会是一整块深色。要发公众号就先提醒用户;
|
|
61
|
+
需要这些风格时走「导出 HTML」拿文件。
|
|
62
|
+
- **复制/导出会加一层结构兼容层**:把文字包进 `<span>`(微信自己插入内容后的形态),
|
|
63
|
+
这样公众号编辑器的结构校验不会把"含行内元素的段落"误报成行高过小;同时把 `background:`
|
|
64
|
+
简写拆成 `background-color:` / `background-image:`(微信按属性名过滤,简写会被整条丢掉,
|
|
65
|
+
于是引用块的框、表头底色在公众号里消失);选定的字号也会从最外层 wrapper 推进到
|
|
66
|
+
p / 列表项 / 引用块上(微信会剥掉最外层 wrapper 的样式,字号只挂在它上面等于没设)。
|
|
67
|
+
默认渲染路径不受影响,面板的预览不经过这三层——
|
|
68
|
+
所以别拿"预览的 HTML"去判断粘进微信后的样子。
|
|
69
|
+
- **字号**:正文 16px 起步,长文 17px 更好读
|
|
70
|
+
- **字体**:面板上的「字体」预设(黑体 / 衬线 / 等宽)**总会覆盖主题自带的字体栈**——所以
|
|
71
|
+
"这套主题是衬线的"能不能成立,取决于这个预设,而不是主题里写了什么。让用户切到「衬线」而不是向他保证主题自带衬线。
|
|
72
|
+
**公众号编辑器只认黑体**(iOS 设备上才是苹方):衬线 / 等宽只在「导出 HTML」里有效,粘进编辑器会退回黑体,
|
|
73
|
+
而面板预览里看不出这个差别。用户要的是"公众号里也衬线"时,说明实际得用导出,别让他以为坏了。
|
|
74
|
+
- **段落**:段落之间空一行;`breaks` 已开启,单换行即换行
|
|
75
|
+
- **图片**:``。复制到公众号时本地图会自动内嵌成 base64,**粘进编辑器不需要手动重传**
|
|
76
|
+
(编辑器接收后由微信自行转存)。会被微信拦掉的是 `http(s)://` 的**外链图**,以及内嵌不了的本地图
|
|
77
|
+
(文件不存在、在工作目录之外、超过 5 MB)——这几类要在编辑器里手动上传,`fishpai_read` 会把它们单独列出来
|
|
78
|
+
- **外链**:正文里的 `[文字](url)` 会自动转成文末「参考资料」脚注(微信正文不支持外链)
|
|
79
|
+
|
|
80
|
+
## 自定义主题
|
|
81
|
+
|
|
82
|
+
用户说"想要 XX 那种观感"(衬线、灰底引用、行距更大、标题不要主题色…)时,在**某套内置主题上改几个槽位**就行。
|
|
83
|
+
|
|
84
|
+
两条路,按"要不要留下"选:
|
|
85
|
+
|
|
86
|
+
| 想要 | 用什么 | 落不落盘 |
|
|
87
|
+
|---|---|---|
|
|
88
|
+
| 先试一下、看效果 | `fishpai_render({ theme_spec })` | **不落盘**,只写进那份 HTML |
|
|
89
|
+
| 用户认可、以后一直用 | `fishpai_theme({ action:'set', theme_spec })` | 落盘到 `<工作目录>/.fishpai/theme.json` |
|
|
90
|
+
|
|
91
|
+
`fishpai_theme` 存的是**工作目录级的一套**(不是主题库):面板主题列表里只有**一个**「自定义主题」占位,
|
|
92
|
+
再 `set` 一次就是覆盖。`set` 之后会把当前文档切到它(若本会话已打开文档),用户在面板里立刻能看到;`action:'show'` 读回当前规格
|
|
93
|
+
(要改就在那份规格上改),`action:'clear'` 删掉(文档自动退回「默认公众号」;面板主题列表「我的」
|
|
94
|
+
那一组右边也有个 ×,效果一样)。
|
|
95
|
+
**别跟用户说"存了好几套"**——只有一套。
|
|
96
|
+
|
|
97
|
+
```json
|
|
98
|
+
{ "name": "我的·灰底衬线",
|
|
99
|
+
"base": "elegant",
|
|
100
|
+
"styles": {
|
|
101
|
+
"p": "line-height: 2; color: #2b2b2b;",
|
|
102
|
+
"h2": "font-size: 19px; border-left: 4px solid {{PRIMARY}}; padding-left: 12px;",
|
|
103
|
+
"blockquote": "background: #f4f4f5; border-left: 3px solid #a1a1aa; color: #3f3f46;"
|
|
104
|
+
} }
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
规矩(写错会被拒绝,并在返回里说明原因,改对再来一次):
|
|
108
|
+
|
|
109
|
+
- **只写想改的槽位**,其余自动从 `base` 继承。19 个槽位:
|
|
110
|
+
`wrapper` `h1` `h2` `h3` `p` `blockquote` `code_inline` `code_block` `ul` `ol` `li` `img` `a`
|
|
111
|
+
`table` `th` `td` `hr` `strong` `em`
|
|
112
|
+
- **属性白名单**(就是内置主题实际用过的那批):`color` `background` `font-family` `font-size`
|
|
113
|
+
`font-weight` `font-style` `line-height` `letter-spacing` `text-align` `text-decoration` `text-indent`
|
|
114
|
+
`margin` `padding` `padding-left` `padding-bottom` `border` `border-top` `border-bottom` `border-left`
|
|
115
|
+
`border-radius` `border-collapse` `border-image` `width` `height` `max-width` `display` `overflow-x`
|
|
116
|
+
`box-shadow` `-webkit-background-clip` `-webkit-text-fill-color`
|
|
117
|
+
- **`wrapper` 里必须同时有 `font-family` 与 `font-size`**,否则面板的「字体」「字号」调节失效(漏了会自动补上)
|
|
118
|
+
- 想跟「主题色」联动就用 `{{PRIMARY}}` / `{{PRIMARY_BG}}` 占位符
|
|
119
|
+
- 不许出现 `{}` `<` `>` `"`(双引号;单引号可以,`font-family: 'Georgia', serif` 这类字体栈没问题)`url(...)` `expression(...)` `@import` `javascript:`;`!important` 写了会被自动去掉(微信不保留它)。不要写图标或 emoji
|
|
120
|
+
(图标由鱼排统一给)
|
|
121
|
+
- 白色/深色底、渐变文字这类**微信会掉样式**的组合:`fishpai_render` 会照做,但你要当场提醒用户
|
|
122
|
+
"这套更适合导出 HTML,发公众号可能变形"
|
|
123
|
+
|
|
124
|
+
## 支持的 Markdown(比标准多几种)
|
|
125
|
+
|
|
126
|
+
| 语法 | 效果 |
|
|
127
|
+
|---|---|
|
|
128
|
+
| `#`…`######` | 六级标题(h4–h6 套 h3 样式,与墨排一致) |
|
|
129
|
+
| `>` 引用 | 主题色左边框块 |
|
|
130
|
+
| `-` / `1.` | 列表,支持嵌套 |
|
|
131
|
+
| `\| 表格 \|` | 主题化表格 |
|
|
132
|
+
| ` ```python ` | 代码块 + highlight.js 高亮(mac 标题栏形态) |
|
|
133
|
+
| `[文字](url)` | 自动转文末「参考资料」 |
|
|
134
|
+
| `<strong>文字</strong>` | 原样透传的粗体:**不加主题色**(写 `**文字**` 会套主题的 strong 样式,多数主题会染成主题色)。要"黑粗"就用它 |
|
|
135
|
+
| `` | 图片 |
|
|
136
|
+
| `:::tip 标题` … `:::` | 信息卡片,四型:`info` `warning` `tip` `danger` |
|
|
137
|
+
| `---` | 主题色分隔线 |
|
|
138
|
+
| ` ```mermaid ` | 图表占位(预览里不渲染,保留代码原文) |
|
|
139
|
+
|
|
140
|
+
## 与人协作的说法
|
|
141
|
+
|
|
142
|
+
- 面板里能看到实时预览、主题/字号/手机宽度切换、批注抽屉(可一键定位到引用它的那段)、历史回滚
|
|
143
|
+
- 面板的编辑器支持 Markdown 快捷键(`Ctrl/⌘+B` 加粗等,右上角「快捷键」里有速查表),
|
|
144
|
+
截图可以直接 `Ctrl/⌘+V` 粘进去(存到文档同级的 `assets/` 并在正文插入 ``)
|
|
145
|
+
- 你改完之后,明确告诉用户"改了什么、在哪一块",而不是只说"已更新"
|
|
146
|
+
- 如果人的批注互相冲突或指向不存在的块,直接说出来,不要猜着改
|