# 前言

之前写过《自由地给文章添加文章总结》,但是每次添加总结都需要粘贴十多行代码,十分麻烦,这里将代码与 butterfly 主题进行整合,因此本教程只适合 butterfly 或 butterfly 魔改的主题。

# 开始

首先在主题文件夹下的 /layout/includes/ 新建一个 custom 文件夹,然后在此文件夹下新建文件 ai.pug

文件内容如下,可根据实际情况进行修改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.post-ai
.ai-title
i.fa-solid.fa-robot
a.ai-title-left(data-pjax-state='')
.ai-title-text 文章摘要
.ai-link
i.heofont.icon-arrow-right-s-line
.ai-tag#ai-tag GoodBoyboyGPT
.ai-explanation(style='display: block;')
span.ai-typed-text
.ai-source-text
span=page.ai
.ai-suggestions
.ai-bottom
.ai-tips 此内容根据文章生成,并经过人工审核,仅用于文章内容的解释与总结

script(src='/js/typed/typed.umd.js',async)
script(src='/js/ai.js',async)

这里的引入的 JavaScript 有 typedjs 和一个自定义的 aijs,typedjs 和 aijs 引入链接可根据实际情况进行调整。

然后在主题目录下的 /source/js 新建文件 ai.js ,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function checkTyped() {
if (typeof Typed !== "undefined") {
var typed = new Typed(".ai-typed-text", {
stringsElement: ".ai-source-text",
typeSpeed: 25,
startDelay: 1000,
fadeOut: false,
});
} else {
setTimeout(checkTyped, 100);
}
}
checkTyped();

找到 主题目录/layout 文件夹下的 post.pug 文件,找到下面代码,第 6 行左右:

1
2
if top_img === false
include includes/header/post-info.pug

在下面添加以下代码,注意缩进格式:

1
2
if page.ai
include includes/custom/ai.pug

添加完后应该如下面所示:

1
2
3
4
if top_img === false
include includes/header/post-info.pug
if page.ai
include includes/custom/ai.pug

然后在 主题目录/source/css/_layout 下新建文件 ai.styl ,文件内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
:root {
--heo-white: #fff;
--heo-white-op: rgba(255, 255, 255, 0.2);
--heo-black: #000;
--heo-black-op: rgba(0, 0, 0, 0.2);
--heo-none: #00000000;
--heo-gray: #999999;
--heo-gray-op: #9999992b;
--heo-vip: #e5a80d;
--heo-main: var(--heo-theme);
--heo-main-op: var(--heo-theme-op);
--heo-main-op-deep: var(--heo-theme-op-deep);
--heo-main-none: var(--heo-theme-none);
--heo-shadow-theme: 0 8px 12px -3px var(--heo-theme-op);
--heo-shadow-blackdeep: 0 2px 16px -3px rgba(0, 0, 0, 0.15);
--heo-shadow-main: 0 8px 12px -3px var(--heo-main-op);
--heo-shadow-blue: 0 8px 12px -3px rgba(40, 109, 234, 0.2);
--heo-shadow-white: 0 8px 12px -3px rgba(255, 255, 255, 0.2);
--heo-shadow-black: 0 0 12px 4px rgba(0, 0, 0, 0.05);
--heo-shadow-yellow: 0px 38px 77px -26px rgba(255, 201, 62, 0.12);
--heo-shadow-red: 0 8px 12px -3px #ee7d7936;
--heo-shadow-green: 0 8px 12px -3px #87ee7936;
--heo-logo-color: linear-gradient(215deg, #4584ff 0%, #cf0db9 100%);
--heo-snackbar-time: 5s;
--heo-theme: #425AEF;
--heo-theme-op: #4259ef23;
--heo-theme-op-deep: #4259efdd;
--heo-theme-none: #4259ef01;
--heo-blue: #425AEF;
--heo-red: #f04a63;
--heo-pink: #FF7C7C;
--heo-green: #57bd6a;
--heo-yellow: #c28b00;
--heo-yellow-op: #d99c001a;
--heo-orange: #e38100;
--heo-fontcolor: #363636;
--heo-background: #f7f9fe;
--heo-reverse: #000;
--heo-maskbg: rgba(255, 255, 255, 0.6);
--heo-maskbgdeep: rgba(255, 255, 255, 0.85);
--heo-hovertext: var(--heo-main);
--heo-ahoverbg: #F7F7FA;
--heo-lighttext: var(--heo-main);
--heo-secondtext: rgba(60, 60, 67, 0.8);
--heo-scrollbar: rgba(60, 60, 67, 0.4);
--heo-card-btn-bg: #edf0f7;
--heo-post-blockquote-bg: #fafcff;
--heo-post-tabs-bg: #f2f5f8;
--heo-secondbg: #f1f3f8;
--heo-shadow-nav: 0 5px 12px -5px rgba(102, 68, 68, 0.05);
--heo-card-bg: #fff;
--heo-card-bg-op: var(--heo-black-op);
--heo-card-bg-none: rgba(255, 255, 255, 0);
--heo-shadow-lightblack: 0 5px 12px -5px rgba(102, 68, 68, 0);
--heo-shadow-light2black: 0 5px 12px -5px rgba(102, 68, 68, 0);
--heo-card-border: #e3e8f7;
--heo-shadow-border: 0 8px 16px -4px #2c2d300c;
--style-border: 1px solid var(--heo-card-border);
--style-border-always: 1px solid var(--heo-card-border);
--style-border-hover: 1px solid var(--heo-main);
--style-border-hover-always: 1px solid var(--heo-main);
--style-border-dashed: 1px dashed var(--heo-theme-op);
--style-border-forever: 2px solid var(--heo-main);
}

[data-theme=light] {
--heo-theme: #425AEF;
--heo-theme-op: #4259ef23;
--heo-theme-op-deep: #4259efdd;
--heo-theme-none: #4259ef01;
--heo-blue: #425AEF;
--heo-red: #f04a63;
--heo-pink: #FF7C7C;
--heo-green: #57bd6a;
--heo-yellow: #c28b00;
--heo-yellow-op: #d99c001a;
--heo-orange: #e38100;
--heo-fontcolor: #363636;
--heo-background: #f7f9fe;
--heo-reverse: #000;
--heo-maskbg: rgba(255, 255, 255, 0.6);
--heo-maskbgdeep: rgba(255, 255, 255, 0.85);
--heo-hovertext: var(--heo-main);
--heo-ahoverbg: #F7F7FA;
--heo-lighttext: var(--heo-main);
--heo-secondtext: rgba(60, 60, 67, 0.8);
--heo-scrollbar: rgba(60, 60, 67, 0.4);
--heo-card-btn-bg: #edf0f7;
--heo-post-blockquote-bg: #fafcff;
--heo-post-tabs-bg: #f2f5f8;
--heo-secondbg: #f1f3f8;
--heo-shadow-nav: 0 5px 12px -5px rgba(102, 68, 68, 0.05);
--heo-card-bg: #fff;
--heo-card-bg-op: var(--heo-black-op);
--heo-card-bg-none: rgba(255, 255, 255, 0);
--heo-shadow-lightblack: 0 5px 12px -5px rgba(102, 68, 68, 0);
--heo-shadow-light2black: 0 5px 12px -5px rgba(102, 68, 68, 0);
--heo-card-border: #e3e8f7;
--heo-shadow-border: 0 8px 16px -4px #2c2d300c;
--style-border: 1px solid var(--heo-card-border);
--style-border-always: 1px solid var(--heo-card-border);
--style-border-hover: 1px solid var(--heo-main);
--style-border-hover-always: 1px solid var(--heo-main);
--style-border-dashed: 1px dashed var(--heo-theme-op);
--style-border-forever: 2px solid var(--heo-main);
}

[data-theme=dark], body.dark, body.dark-theme {
--heo-theme: #f2b94b;
--heo-theme-op: #f2b94b23;
--heo-theme-op-deep: #f2b94bdd;
--heo-theme-none: #f2b94b00;
--heo-blue: #0084FF;
--heo-red: #FF3842;
--heo-pink: #d44040;
--heo-green: #3e9f50;
--heo-yellow: #ffc93e;
--heo-yellow-op: #ffc93e30;
--heo-orange: #ff953e;
--heo-fontcolor: #F7F7FA;
--heo-background: #18171d;
--heo-reverse: #fff;
--heo-maskbg: rgba(0, 0, 0, 0.6);
--heo-maskbgdeep: rgba(0, 0, 0, 0.85);
--heo-hovertext: #0A84FF;
--heo-ahoverbg: #fff;
--heo-lighttext: var(--heo-theme);
--heo-secondtext: #a1a2b8;
--heo-scrollbar: rgba(200, 200, 223, 0.4);
--heo-card-btn-bg: #30343f;
--heo-post-blockquote-bg: #000;
--heo-post-tabs-bg: #121212;
--heo-secondbg: #30343f;
--heo-shadow-nav: 0 5px 20px 0px rgba(28, 28, 28, 0.4);
--heo-card-bg: #1d1e22;
--heo-card-bg-op: var(--heo-white-op);
--heo-card-bg-none: #1d1b2600;
--heo-shadow-lightblack: 0 5px 12px -5px rgba(102, 68, 68, 0);
--heo-shadow-light2black: 0 5px 12px -5px rgba(102, 68, 68, 0);
--heo-card-border: #3d3d3f;
--heo-shadow-border: 0 8px 16px -4px #00000050;
--style-border: 1px solid var(--heo-card-border);
--style-border-always: 1px solid var(--heo-card-border);
--style-border-hover: 1px solid var(--heo-theme);
--style-border-hover-always: 1px solid var(--heo-theme);
--style-border-dashed: 1px dashed var(--heo-theme-op);
--style-border-forever: 2px solid var(--heo-lighttext);
}

.post-ai {
background: var(--heo-secondbg);
border-radius: 12px;
padding: 12px;
line-height: 1.3;
border: var(--style-border-always);
margin: 16px 0;
}

@media screen and (max-width: 768px) {
.post-ai {
margin-top: 22px;
}
}

.ai-title {
display: flex;
color: var(--heo-lighttext);
border-radius: 8px;
align-items: center;
padding: 0 12px;
cursor: default;
user-select: none;
position: relative;
}

.ai-title-text {
font-weight: 700;
margin-left: 8px;
line-height: 1;
}

.ai-explanation {
margin-top: 12px;
padding: 8px 12px;
background: var(--heo-card-bg);
border-radius: 8px;
border: var(--style-border-always);
font-size: 15px;
line-height: 1.4;
display: flex;
}

.ai-suggestions {
display: flex;
flex-wrap: wrap;

.ai-suggestions-item {
margin-top: 12px;
padding: 8px 12px;
background: var(--heo-card-bg);
border-radius: 8px 8px 8px 0;
border: var(--style-border-always);
font-size: 15px;
line-height: 1.4;
display: flex;
width: fit-content;
margin-right: 12px;
cursor: pointer;
transition: 0.3s;

&:hover {
background: var(--heo-main);
color: var(--heo-white);
}
}
}

.blinking-cursor {
background-color: var(--heo-main);
width: 10px;
height: 16px;
display: inline-block;
vertical-align: middle;
animation: blinking-cursor 0.5s infinite;
margin-left: 4px;
}

.ai-tips {
font-size: 12px;
color: var(--heo-secondtext);
margin-right: auto;
}

.ai-bottom {
width: 100%;
margin-top: 12px;
padding: 0 12px;
display: flex;
}

@keyframes blinking-cursor {
0% {
opacity: 1;
}

40% {
opacity: 1;
}

50% {
opacity: 0;
}

90% {
opacity: 0;
}

100% {
opacity: 1;
}
}

.ai-tag {
font-size: 12px;
background-color: var(--heo-lighttext);
color: var(--heo-card-bg);
font-weight: 700;
border-radius: 4px;
margin-left: auto;
line-height: 1;
padding: 4px;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s, background-color 0s;
position: absolute;
right: 12px;

svg {
fill: #7e8a97;
}

&.playing {
svg {
animation: 0.5s linear 0s infinite normal none running breathe;
transform-origin: center;
width: 20px;
height: 20px;
}
}
}

i {
&.fa-solid {
&.fa-robot {
width: 24px;
height: 24px;
display: flex;
background: var(--heo-lighttext);
color: var(--heo-card-bg);
font-size: 14px;
border-radius: 20px;
justify-content: center;
align-items: center;
}
}
}

ins {
&.adsbygoogle {
margin: 16px 0;
background: var(--heo-card-bg);
border-radius: 12px;
overflow: hidden;
border: var(--style-border-always);
}
}

#ai-Toggle {
font-size: 12px;
background: var(--heo-lighttext);
color: var(--heo-card-bg);
padding: 4px;
border-radius: 4px;
margin-left: 6px;
transform: scale(0.8);
cursor: pointer;
transition: 0.3s;
font-weight: 700;

&:hover {
background: var(--heo-fontcolor);
color: var(--heo-card-bg);
}
}

.ai-title-icon {
width: 20px;
height: 20px;

svg {
width: 20px;
height: 20px;
fill: var(--heo-main);

path {
fill: var(--heo-main);
}
}
}

@keyframes breathe {
0% {
transform: scale(0.97);
}

50% {
transform: scale(1.1);
}

100% {
transform: scale(0.97);
}
}

最后在需要启用 AI 总结的文章 md 文件里的 Front-matter 区域添加 ai: 总结内容 即可。