bit-ppt-generator 0.3.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/AI_CONTENT_GUIDE.md +661 -0
- package/LICENSE +21 -0
- package/README.md +620 -0
- package/assets/bit-campus-line.png +0 -0
- package/assets/bit-campus-photo.png +0 -0
- package/assets/bit-emblem-gray.png +0 -0
- package/assets/bit-seal-small.png +0 -0
- package/assets/bit-wordmark-white.png +0 -0
- package/bin/bit-ppt-http.mjs +58 -0
- package/bin/bit-ppt-mcp.mjs +27 -0
- package/bin/bit-ppt.mjs +480 -0
- package/content/body-layout-test.yaml +112 -0
- package/content/chart-flow-test.yaml +82 -0
- package/content/example.yaml +193 -0
- package/content/extended-layout-test.yaml +120 -0
- package/content/formula-test.yaml +31 -0
- package/content/image-layout-demo.yaml +64 -0
- package/content/inline-formula-test.yaml +62 -0
- package/content/invalid-deck-test.yaml +25 -0
- package/content/overflow-test.yaml +77 -0
- package/content/placeholder-image-demo.yaml +59 -0
- package/content/speaker-notes-demo.yaml +30 -0
- package/content/table-formula-test.yaml +21 -0
- package/package.json +42 -0
- package/src/core/layouts.mjs +58 -0
- package/src/core/preflight.mjs +263 -0
- package/src/core/validation.mjs +372 -0
- package/src/core/yaml-parse.mjs +80 -0
- package/src/generate.mjs +1708 -0
- package/src/http-server.mjs +1201 -0
- package/src/layout-guides.mjs +315 -0
- package/src/mcp-server.mjs +197 -0
package/README.md
ADDED
|
@@ -0,0 +1,620 @@
|
|
|
1
|
+
# BIT PPT 模板生成器
|
|
2
|
+
|
|
3
|
+
这是一个无需 LaTeX 的北京理工大学风格 PPTX 生成器。它读取 YAML
|
|
4
|
+
内容描述,输出可编辑的 PowerPoint 文件。
|
|
5
|
+
|
|
6
|
+
项目目标不是把幻灯片截图塞进 PPT,而是尽量生成原生 Office 对象:
|
|
7
|
+
文本框、形状、表格、图表、图片和 Office Math 公式都应保持可编辑。
|
|
8
|
+
|
|
9
|
+
代码使用 MIT License。北京理工大学名称、标识和视觉参考归其各自权利人所有。
|
|
10
|
+
|
|
11
|
+
## 特性
|
|
12
|
+
|
|
13
|
+
- Node.js ESM CLI
|
|
14
|
+
- YAML 输入,PPTX 输出
|
|
15
|
+
- 基于 `pptxgenjs` 生成可编辑 PPTX
|
|
16
|
+
- 基于 `jszip` 做 OpenXML 后处理
|
|
17
|
+
- 基于 `latex-to-omml` 将公式转换为原生 Office Math
|
|
18
|
+
- 支持渐进式 guide,方便 Codex / Claude Code 等本地 agent 查询能力
|
|
19
|
+
- 支持 `--json` 和 `--strict`,便于脚本、CI 和 AI agent 自动调用
|
|
20
|
+
- 支持图片尺寸读取和 `imageText` 自动排版
|
|
21
|
+
|
|
22
|
+
## 安装
|
|
23
|
+
|
|
24
|
+
发布到 npm 后,普通用户可直接启动本地网页:
|
|
25
|
+
|
|
26
|
+
```powershell
|
|
27
|
+
npx bit-ppt-generator
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
然后打开命令行输出的本地地址,默认是:
|
|
31
|
+
|
|
32
|
+
```text
|
|
33
|
+
http://127.0.0.1:3000/
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
本地网页默认不需要登录;只有部署者配置了鉴权环境变量时才会显示登录区。
|
|
37
|
+
|
|
38
|
+
全局安装:
|
|
39
|
+
|
|
40
|
+
```powershell
|
|
41
|
+
npm install -g bit-ppt-generator
|
|
42
|
+
bit-ppt-generator
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
仓库开发:
|
|
46
|
+
|
|
47
|
+
```powershell
|
|
48
|
+
npm install
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
本地开发可以直接使用 Node 入口:
|
|
52
|
+
|
|
53
|
+
```powershell
|
|
54
|
+
node bin/bit-ppt.mjs --help
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
也可以链接为全局命令:
|
|
58
|
+
|
|
59
|
+
```powershell
|
|
60
|
+
npm link
|
|
61
|
+
bit-ppt --help
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## 快速开始
|
|
65
|
+
|
|
66
|
+
启动本地网页:
|
|
67
|
+
|
|
68
|
+
```powershell
|
|
69
|
+
npm run serve
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
生成示例 PPT:
|
|
73
|
+
|
|
74
|
+
```powershell
|
|
75
|
+
npm run build:ppt
|
|
76
|
+
npm run build:body-layouts
|
|
77
|
+
npm run build:charts
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
输出文件位于:
|
|
81
|
+
|
|
82
|
+
```text
|
|
83
|
+
output/example.pptx
|
|
84
|
+
output/body-layout-test.pptx
|
|
85
|
+
output/chart-flow-test.pptx
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
手动指定输入和输出:
|
|
89
|
+
|
|
90
|
+
```powershell
|
|
91
|
+
node bin/bit-ppt.mjs generate content/example.yaml output/example.pptx
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
先检查再生成:
|
|
95
|
+
|
|
96
|
+
```powershell
|
|
97
|
+
node bin/bit-ppt.mjs check content/example.yaml --json
|
|
98
|
+
node bin/bit-ppt.mjs generate content/example.yaml output/example.pptx --json
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
严格模式会把 warning 也视为失败:
|
|
102
|
+
|
|
103
|
+
```powershell
|
|
104
|
+
node bin/bit-ppt.mjs check content/formula-test.yaml --json --strict
|
|
105
|
+
node bin/bit-ppt.mjs generate content/example.yaml output/example.pptx --json --strict
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Release Targets
|
|
109
|
+
|
|
110
|
+
本仓库采用单主干、多入口策略。CLI、MCP 和 Node HTTP 服务都复用同一套核心生成逻辑。
|
|
111
|
+
|
|
112
|
+
当前状态:
|
|
113
|
+
|
|
114
|
+
- Web UI:默认入口为 `bit-ppt-generator`,适合 npm 用户本地打开网页
|
|
115
|
+
- CLI:已支持,入口为 `bit-ppt` 或 `node bin/bit-ppt.mjs`
|
|
116
|
+
- MCP:已支持,入口为 `bit-ppt-mcp` 或 `node bin/bit-ppt-mcp.mjs`
|
|
117
|
+
- Node HTTP API:已支持,入口为 `bit-ppt-http` 或 `node bin/bit-ppt-http.mjs`
|
|
118
|
+
|
|
119
|
+
当前 npm 包名预定为 `bit-ppt-generator`。一个 npm release 同时包含 Web UI、CLI 和 MCP 三个入口,不拆成三个包。
|
|
120
|
+
|
|
121
|
+
## CLI 命令
|
|
122
|
+
|
|
123
|
+
```text
|
|
124
|
+
bit-ppt-generator
|
|
125
|
+
bit-ppt generate <input.yaml> <output.pptx> [--json] [--strict] [font options]
|
|
126
|
+
bit-ppt check <input.yaml> [--json] [--strict]
|
|
127
|
+
bit-ppt list-layouts [--json]
|
|
128
|
+
bit-ppt guide [topic] [name] [--json]
|
|
129
|
+
bit-ppt doctor [--json]
|
|
130
|
+
bit-ppt-mcp
|
|
131
|
+
bit-ppt-http
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
常用命令:
|
|
135
|
+
|
|
136
|
+
```powershell
|
|
137
|
+
node bin/bit-ppt.mjs list-layouts
|
|
138
|
+
node bin/bit-ppt.mjs list-layouts --json
|
|
139
|
+
node bin/bit-ppt.mjs doctor
|
|
140
|
+
node bin/bit-ppt.mjs doctor --json
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
`doctor` 会检查 Node 版本、依赖、关键素材、示例 deck、输出目录可写性。
|
|
144
|
+
|
|
145
|
+
## MCP Server
|
|
146
|
+
|
|
147
|
+
项目同时提供 stdio MCP 入口,供 Codex、Claude Code 等本地 agent 调用。
|
|
148
|
+
MCP 只是 adapter,仍复用 CLI 背后的同一套生成和校验函数。
|
|
149
|
+
|
|
150
|
+
本地运行:
|
|
151
|
+
|
|
152
|
+
```powershell
|
|
153
|
+
node bin/bit-ppt-mcp.mjs
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
全局链接后:
|
|
157
|
+
|
|
158
|
+
```powershell
|
|
159
|
+
bit-ppt-mcp
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
MCP 客户端配置示例:
|
|
163
|
+
|
|
164
|
+
```json
|
|
165
|
+
{
|
|
166
|
+
"mcpServers": {
|
|
167
|
+
"bit-ppt": {
|
|
168
|
+
"command": "node",
|
|
169
|
+
"args": ["D:/atuodl/presentation-slide/bit-ppt-template/bin/bit-ppt-mcp.mjs"],
|
|
170
|
+
"cwd": "D:/atuodl/presentation-slide/bit-ppt-template"
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
提供的 MCP tools:
|
|
177
|
+
|
|
178
|
+
- `list_layouts`
|
|
179
|
+
- `get_guide`
|
|
180
|
+
- `validate_deck`
|
|
181
|
+
- `preflight_deck`
|
|
182
|
+
- `get_repair_prompt`
|
|
183
|
+
- `generate_pptx`
|
|
184
|
+
|
|
185
|
+
`validate_deck`、`preflight_deck` 和 `get_repair_prompt` 支持 `inputPath`
|
|
186
|
+
或 `deckYaml`。`generate_pptx` 使用文件路径:
|
|
187
|
+
|
|
188
|
+
```json
|
|
189
|
+
{
|
|
190
|
+
"inputPath": "content/example.yaml",
|
|
191
|
+
"outputPath": "output/example-from-mcp.pptx",
|
|
192
|
+
"strict": true
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Node HTTP API
|
|
197
|
+
|
|
198
|
+
项目提供一个轻量 Node HTTP 服务,用于上传 YAML 并下载生成的 PPTX。
|
|
199
|
+
|
|
200
|
+
普通本地用户启动网页:
|
|
201
|
+
|
|
202
|
+
```powershell
|
|
203
|
+
npx bit-ppt-generator
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
全局安装后:
|
|
207
|
+
|
|
208
|
+
```powershell
|
|
209
|
+
bit-ppt-generator
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
仓库开发启动:
|
|
213
|
+
|
|
214
|
+
```powershell
|
|
215
|
+
npm run serve
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
或指定地址:
|
|
219
|
+
|
|
220
|
+
```powershell
|
|
221
|
+
node bin/bit-ppt-http.mjs --host 127.0.0.1 --port 3000
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
本地模式未设置鉴权环境变量时不需要登录,网页也不会显示登录框。公网部署时建议启用鉴权和生成并发上限:
|
|
225
|
+
|
|
226
|
+
```powershell
|
|
227
|
+
$env:BIT_PPT_AUTH_SECRET="change-this-long-random-secret"
|
|
228
|
+
$env:BIT_PPT_SESSION_TTL_SECONDS="604800"
|
|
229
|
+
$env:BIT_PPT_TOKEN="change-this-token"
|
|
230
|
+
$env:BIT_PPT_MAX_GENERATE_CONCURRENCY="1"
|
|
231
|
+
npm run serve
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Linux systemd 可设置同名环境变量。
|
|
235
|
+
|
|
236
|
+
- 设置 `BIT_PPT_AUTH_SECRET` 后,网页会显示北理工登录,登录成功后使用签名 token。
|
|
237
|
+
- 设置 `BIT_PPT_TOKEN` 后,HTTP API 也接受固定 Bearer token。
|
|
238
|
+
- 两者都不设置时,适合本机使用,`/check` 和 `/generate` 不需要鉴权。
|
|
239
|
+
|
|
240
|
+
固定 token 调用示例:
|
|
241
|
+
|
|
242
|
+
```http
|
|
243
|
+
Authorization: Bearer change-this-token
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
端点:
|
|
247
|
+
|
|
248
|
+
- `GET /`
|
|
249
|
+
- `GET /health`
|
|
250
|
+
- `POST /auth/bit-login`
|
|
251
|
+
- `POST /auth/verify`
|
|
252
|
+
- `POST /check`
|
|
253
|
+
- `POST /generate`
|
|
254
|
+
|
|
255
|
+
请求体支持 raw YAML,或 JSON:
|
|
256
|
+
|
|
257
|
+
```json
|
|
258
|
+
{
|
|
259
|
+
"deckYaml": "slides:\n - layout: bullets\n title: Demo\n bullets:\n - Upload YAML\n - Download PPTX\n",
|
|
260
|
+
"outputName": "demo"
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
PowerShell 示例:
|
|
265
|
+
|
|
266
|
+
```powershell
|
|
267
|
+
Invoke-RestMethod `
|
|
268
|
+
-Method Post `
|
|
269
|
+
-Uri http://127.0.0.1:3000/check `
|
|
270
|
+
-ContentType "application/json" `
|
|
271
|
+
-Headers @{ Authorization = "Bearer change-this-token" } `
|
|
272
|
+
-Body '{"deckYaml":"slides:\n - layout: bullets\n title: Demo\n bullets:\n - Upload YAML\n"}'
|
|
273
|
+
|
|
274
|
+
Invoke-WebRequest `
|
|
275
|
+
-Method Post `
|
|
276
|
+
-Uri http://127.0.0.1:3000/generate `
|
|
277
|
+
-ContentType "application/json" `
|
|
278
|
+
-Headers @{ Authorization = "Bearer change-this-token" } `
|
|
279
|
+
-Body '{"deckYaml":"slides:\n - layout: bullets\n title: Demo\n bullets:\n - Upload YAML\n - Download PPTX\n","outputName":"demo"}' `
|
|
280
|
+
-OutFile output/demo.pptx
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
YAML 语法错误会返回结构化诊断,适合网页直接展示给用户复制回大模型:
|
|
284
|
+
|
|
285
|
+
```json
|
|
286
|
+
{
|
|
287
|
+
"error": "deckYaml syntax error at line 2, column 5: ...",
|
|
288
|
+
"syntax": {
|
|
289
|
+
"errors": [
|
|
290
|
+
{
|
|
291
|
+
"level": "error",
|
|
292
|
+
"code": "MULTILINE_IMPLICIT_KEY",
|
|
293
|
+
"message": "Implicit keys need to be on a single line",
|
|
294
|
+
"line": 2,
|
|
295
|
+
"column": 5,
|
|
296
|
+
"context": "1 | slides:\n2 | - layout bullets\n3 | title: Broken",
|
|
297
|
+
"pointer": " ^"
|
|
298
|
+
}
|
|
299
|
+
]
|
|
300
|
+
},
|
|
301
|
+
"repairPrompt": "deckYaml syntax error at line 2, column 5: ...\nFix the YAML syntax first, then keep the deck schema unchanged."
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
## 给 AI Agent 的渐进式 Guide
|
|
306
|
+
|
|
307
|
+
不要一次性把完整文档塞给 AI。推荐让 agent 按需查询:
|
|
308
|
+
|
|
309
|
+
```powershell
|
|
310
|
+
node bin/bit-ppt.mjs guide
|
|
311
|
+
node bin/bit-ppt.mjs guide workflow --json
|
|
312
|
+
node bin/bit-ppt.mjs guide layouts
|
|
313
|
+
node bin/bit-ppt.mjs guide layout imageText
|
|
314
|
+
node bin/bit-ppt.mjs guide schema chart --json
|
|
315
|
+
node bin/bit-ppt.mjs guide example flowchart --json
|
|
316
|
+
node bin/bit-ppt.mjs guide speaker-notes
|
|
317
|
+
node bin/bit-ppt.mjs guide image-placeholder
|
|
318
|
+
node bin/bit-ppt.mjs guide writing-rules
|
|
319
|
+
node bin/bit-ppt.mjs guide all --json
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
推荐 agent 工作流:
|
|
323
|
+
|
|
324
|
+
```text
|
|
325
|
+
1. guide / list-layouts 查询能力
|
|
326
|
+
2. guide schema <layout> 获取结构化字段
|
|
327
|
+
3. 生成 YAML deck
|
|
328
|
+
4. check --json --strict
|
|
329
|
+
5. 根据 repairPrompt 修改 YAML
|
|
330
|
+
6. generate --json --strict
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
目前结构化 guide 重点覆盖:
|
|
334
|
+
|
|
335
|
+
- `imageText`
|
|
336
|
+
- `chart`
|
|
337
|
+
- `flowchart`
|
|
338
|
+
- `table`
|
|
339
|
+
- `formula`
|
|
340
|
+
|
|
341
|
+
通用字段可通过 `guide speaker-notes` 渐进式查询;`guide schema <layout> --json`
|
|
342
|
+
也会在 `commonFields` 中返回 `speakerNotes`。
|
|
343
|
+
|
|
344
|
+
暂无图片时可通过 `guide image-placeholder` 查询占位图写法。
|
|
345
|
+
|
|
346
|
+
完整写作约束见 [AI_CONTENT_GUIDE.md](AI_CONTENT_GUIDE.md)。
|
|
347
|
+
|
|
348
|
+
## YAML 输入结构
|
|
349
|
+
|
|
350
|
+
输入文件包含两个顶层字段:
|
|
351
|
+
|
|
352
|
+
- `meta`:标题、副标题、作者、日期、字体等元信息
|
|
353
|
+
- `slides`:按顺序排列的幻灯片定义
|
|
354
|
+
|
|
355
|
+
示例:
|
|
356
|
+
|
|
357
|
+
```yaml
|
|
358
|
+
meta:
|
|
359
|
+
title: 示例报告
|
|
360
|
+
subtitle: BIT PPT Generator
|
|
361
|
+
author: Your Name
|
|
362
|
+
date: 2026
|
|
363
|
+
|
|
364
|
+
slides:
|
|
365
|
+
- layout: title
|
|
366
|
+
|
|
367
|
+
- layout: bullets
|
|
368
|
+
title: 核心观点
|
|
369
|
+
bullets:
|
|
370
|
+
- 输出是可编辑 PPTX。
|
|
371
|
+
- YAML 更适合 AI 生成和修复。
|
|
372
|
+
- check 命令会返回 repairPrompt。
|
|
373
|
+
|
|
374
|
+
- layout: closing
|
|
375
|
+
title: 谢谢
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
每页都可以添加 PowerPoint/WPS 演讲者备注。备注不会出现在页面画布上,会写入 PPT 的备注区:
|
|
379
|
+
|
|
380
|
+
```yaml
|
|
381
|
+
- layout: bullets
|
|
382
|
+
title: 核心观点
|
|
383
|
+
bullets:
|
|
384
|
+
- 输出是可编辑 PPTX。
|
|
385
|
+
speakerNotes: |
|
|
386
|
+
这一页先解释为什么选择 YAML 到 PPTX 的路线。
|
|
387
|
+
公式暂时按普通文本保留,例如 $L(\theta)$。
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
也可以用字符串数组:
|
|
391
|
+
|
|
392
|
+
```yaml
|
|
393
|
+
speakerNotes:
|
|
394
|
+
- 第一段演讲稿。
|
|
395
|
+
- 第二段演讲稿。
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
## 字体
|
|
399
|
+
|
|
400
|
+
默认字体:
|
|
401
|
+
|
|
402
|
+
- 中文:`微软雅黑`
|
|
403
|
+
- 中文 Light:`微软雅黑 Light`
|
|
404
|
+
- 英文:`Arial`
|
|
405
|
+
- 衬线:`SimSun`
|
|
406
|
+
- 代码:`Consolas`
|
|
407
|
+
|
|
408
|
+
可以在 YAML 中设置:
|
|
409
|
+
|
|
410
|
+
```yaml
|
|
411
|
+
meta:
|
|
412
|
+
fonts:
|
|
413
|
+
cn: 微软雅黑
|
|
414
|
+
cnLight: 微软雅黑 Light
|
|
415
|
+
en: Arial
|
|
416
|
+
serif: SimSun
|
|
417
|
+
code: Consolas
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
也可以用 CLI 覆盖:
|
|
421
|
+
|
|
422
|
+
```powershell
|
|
423
|
+
node bin/bit-ppt.mjs generate input.yaml output.pptx --font-cn "Noto Sans CJK SC" --font-code "Cascadia Mono"
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
注意:项目不会打包微软雅黑 TTF 文件,避免字体授权问题。
|
|
427
|
+
|
|
428
|
+
## 支持布局
|
|
429
|
+
|
|
430
|
+
查看当前支持布局:
|
|
431
|
+
|
|
432
|
+
```powershell
|
|
433
|
+
node bin/bit-ppt.mjs list-layouts
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
当前支持:
|
|
437
|
+
|
|
438
|
+
- `title`
|
|
439
|
+
- `agenda`
|
|
440
|
+
- `section`
|
|
441
|
+
- `bullets`
|
|
442
|
+
- `claim`
|
|
443
|
+
- `twoColumn`
|
|
444
|
+
- `cards`
|
|
445
|
+
- `table`
|
|
446
|
+
- `comparison`
|
|
447
|
+
- `timeline`
|
|
448
|
+
- `process`
|
|
449
|
+
- `architecture`
|
|
450
|
+
- `ablation`
|
|
451
|
+
- `caseStudy`
|
|
452
|
+
- `imageGrid`
|
|
453
|
+
- `code`
|
|
454
|
+
- `appendix`
|
|
455
|
+
- `flowchart`
|
|
456
|
+
- `chart`
|
|
457
|
+
- `problemSolution`
|
|
458
|
+
- `painOpportunity`
|
|
459
|
+
- `experimentDesign`
|
|
460
|
+
- `resultAnalysis`
|
|
461
|
+
- `riskMitigation`
|
|
462
|
+
- `contribution`
|
|
463
|
+
- `summary`
|
|
464
|
+
- `metrics`
|
|
465
|
+
- `matrix`
|
|
466
|
+
- `quote`
|
|
467
|
+
- `formula`
|
|
468
|
+
- `references`
|
|
469
|
+
- `imageText`
|
|
470
|
+
- `closing`
|
|
471
|
+
|
|
472
|
+
## 图片排版
|
|
473
|
+
|
|
474
|
+
图片路径默认相对项目根目录。
|
|
475
|
+
|
|
476
|
+
`imageText` 支持字符串路径:
|
|
477
|
+
|
|
478
|
+
```yaml
|
|
479
|
+
- layout: imageText
|
|
480
|
+
title: 图文说明
|
|
481
|
+
image: assets/bit-campus-photo.png
|
|
482
|
+
text:
|
|
483
|
+
- 说明一。
|
|
484
|
+
- 说明二。
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
也支持对象写法:
|
|
488
|
+
|
|
489
|
+
```yaml
|
|
490
|
+
- layout: imageText
|
|
491
|
+
title: 图文说明
|
|
492
|
+
image:
|
|
493
|
+
path: assets/bit-campus-photo.png
|
|
494
|
+
placement: auto # auto | top | side
|
|
495
|
+
fit: contain # contain | cover
|
|
496
|
+
caption: 图片说明。
|
|
497
|
+
text:
|
|
498
|
+
- 图像展示关键现象。
|
|
499
|
+
- 文本保持简洁。
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
自动规则:
|
|
503
|
+
|
|
504
|
+
- 明显超宽图自动采用上图下字
|
|
505
|
+
- 普通横图、方图、竖图默认保留侧图侧字
|
|
506
|
+
- `placement: top` / `placement: side` 可手动覆盖
|
|
507
|
+
- `fit: contain` 避免裁切,`fit: cover` 填满图片框
|
|
508
|
+
|
|
509
|
+
项目包含一个图片排版示例:
|
|
510
|
+
|
|
511
|
+
```powershell
|
|
512
|
+
node bin/bit-ppt.mjs generate content/image-layout-demo.yaml output/image-layout-demo.pptx
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
暂无图片时,可以让 AI 生成图片描述并写入可编辑占位框:
|
|
516
|
+
|
|
517
|
+
```yaml
|
|
518
|
+
- layout: imageText
|
|
519
|
+
title: 系统架构示意
|
|
520
|
+
image:
|
|
521
|
+
mode: placeholder
|
|
522
|
+
aspectRatio: "16:9" # 也可省略;未知比例会生成候选页
|
|
523
|
+
placement: top
|
|
524
|
+
prompt: 展示 YAML 输入、结构校验、PPTX 生成、OMML 后处理的流程图。
|
|
525
|
+
text:
|
|
526
|
+
- 用户后续可在 WPS / PowerPoint 中替换占位框。
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
如果 `imageText` 的占位图没有明确 `aspectRatio`,预检会自动生成两页候选:
|
|
530
|
+
|
|
531
|
+
- 横图方案:上图下文
|
|
532
|
+
- 侧图方案:左图右文
|
|
533
|
+
|
|
534
|
+
占位图也支持 `caseStudy` 和 `imageGrid`。示例:
|
|
535
|
+
|
|
536
|
+
```powershell
|
|
537
|
+
node bin/bit-ppt.mjs check content/placeholder-image-demo.yaml --json
|
|
538
|
+
node bin/bit-ppt.mjs generate content/placeholder-image-demo.yaml output/placeholder-image-demo.pptx
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
## 公式
|
|
542
|
+
|
|
543
|
+
`formula` 布局会将 LaTeX 风格公式转换为原生 Office Math / OMML:
|
|
544
|
+
|
|
545
|
+
```yaml
|
|
546
|
+
- layout: formula
|
|
547
|
+
title: 优化目标
|
|
548
|
+
formula:
|
|
549
|
+
latex: "\\mathcal{L}=\\sum_i (y_i-\\hat{y}_i)^2"
|
|
550
|
+
explanation:
|
|
551
|
+
- 目标函数衡量预测误差。
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
普通文本中也支持 inline math:
|
|
555
|
+
|
|
556
|
+
```yaml
|
|
557
|
+
bullets:
|
|
558
|
+
- 使用 $E=mc^2$ 作为示例公式。
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
公式不是图片,生成后仍尽量保持 Office 可编辑。
|
|
562
|
+
|
|
563
|
+
## 校验与修复
|
|
564
|
+
|
|
565
|
+
`check` 会返回:
|
|
566
|
+
|
|
567
|
+
- `validation.errors`:阻止生成的硬错误
|
|
568
|
+
- `validation.warnings`:可能影响版面的风险
|
|
569
|
+
- `repairPrompt`:可直接反馈给 AI 的修复提示
|
|
570
|
+
- `actions`:预检自动动作,例如拆分长列表或长表格
|
|
571
|
+
|
|
572
|
+
示例:
|
|
573
|
+
|
|
574
|
+
```powershell
|
|
575
|
+
node bin/bit-ppt.mjs check content/invalid-deck-test.yaml --json
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
生成时遇到 errors 会停止。默认情况下 warnings 不阻止生成;使用
|
|
579
|
+
`--strict` 后 warnings 也会导致失败。
|
|
580
|
+
|
|
581
|
+
## 测试
|
|
582
|
+
|
|
583
|
+
```powershell
|
|
584
|
+
npm test
|
|
585
|
+
npm run check:ppt
|
|
586
|
+
npm run check:body-layouts
|
|
587
|
+
npm run check:charts
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
打包检查:
|
|
591
|
+
|
|
592
|
+
```powershell
|
|
593
|
+
npm pack --dry-run
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
## 项目结构
|
|
597
|
+
|
|
598
|
+
```text
|
|
599
|
+
bin/bit-ppt.mjs CLI 入口
|
|
600
|
+
bin/bit-ppt-http.mjs Web UI / Node HTTP 入口,也是 bit-ppt-generator 默认命令
|
|
601
|
+
bin/bit-ppt-mcp.mjs MCP 入口
|
|
602
|
+
src/core/ 纯校验和预检 core
|
|
603
|
+
src/generate.mjs 核心生成器
|
|
604
|
+
src/http-server.mjs Node HTTP 服务
|
|
605
|
+
src/layout-guides.mjs 面向 AI 的结构化 guide
|
|
606
|
+
content/ 示例 YAML 和测试 fixture
|
|
607
|
+
assets/ BIT 风格素材
|
|
608
|
+
output/ 本地生成结果,默认不提交
|
|
609
|
+
test/ node:test 测试
|
|
610
|
+
AI_CONTENT_GUIDE.md 完整内容写作指南
|
|
611
|
+
AGENTS.md 给 coding agent 的项目交接说明
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
## 设计原则
|
|
615
|
+
|
|
616
|
+
- 不依赖 Pandoc、LaTeX、Beamer
|
|
617
|
+
- 不把整页幻灯片渲染成截图
|
|
618
|
+
- 优先生成可编辑 PPTX 对象
|
|
619
|
+
- CLI、MCP、Node HTTP 和其他集成都复用同一套核心实现
|
|
620
|
+
- 对 AI 友好:结构化 guide、JSON 输出、strict 模式、repairPrompt
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { startHttpServer } from "../src/http-server.mjs";
|
|
3
|
+
|
|
4
|
+
const args = process.argv.slice(2);
|
|
5
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
6
|
+
console.log(`BIT PPT Generator Web UI
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
bit-ppt-generator [--host <host>] [--port <port>]
|
|
10
|
+
bit-ppt-http [--host <host>] [--port <port>]
|
|
11
|
+
|
|
12
|
+
Examples:
|
|
13
|
+
bit-ppt-generator
|
|
14
|
+
bit-ppt-generator --port 3001
|
|
15
|
+
bit-ppt-http --host 0.0.0.0 --port 3001
|
|
16
|
+
|
|
17
|
+
Environment:
|
|
18
|
+
HOST Default: 127.0.0.1
|
|
19
|
+
PORT Default: 3000
|
|
20
|
+
BIT_PPT_AUTH_SECRET Enables BIT login and signed web sessions
|
|
21
|
+
BIT_PPT_SESSION_TTL_SECONDS Signed web session lifetime
|
|
22
|
+
BIT_PPT_TOKEN Enables fixed Bearer-token API auth
|
|
23
|
+
`);
|
|
24
|
+
process.exit(0);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const portArgIndex = process.argv.findIndex((arg) => arg === "--port" || arg === "-p");
|
|
28
|
+
const hostArgIndex = process.argv.findIndex((arg) => arg === "--host");
|
|
29
|
+
const explicitPort = portArgIndex >= 0 || Boolean(process.env.PORT);
|
|
30
|
+
const port = portArgIndex >= 0 ? process.argv[portArgIndex + 1] : process.env.PORT || 3000;
|
|
31
|
+
const host = hostArgIndex >= 0 ? process.argv[hostArgIndex + 1] : process.env.HOST || "127.0.0.1";
|
|
32
|
+
|
|
33
|
+
async function startWithFallback() {
|
|
34
|
+
let currentPort = Number(port);
|
|
35
|
+
const maxPort = explicitPort ? currentPort : currentPort + 10;
|
|
36
|
+
while (currentPort <= maxPort) {
|
|
37
|
+
try {
|
|
38
|
+
await startHttpServer({ port: currentPort, host });
|
|
39
|
+
return currentPort;
|
|
40
|
+
} catch (error) {
|
|
41
|
+
if (error.code !== "EADDRINUSE" || explicitPort || currentPort >= maxPort) throw error;
|
|
42
|
+
currentPort += 1;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return currentPort;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
startWithFallback()
|
|
49
|
+
.then((actualPort) => {
|
|
50
|
+
const url = `http://${host}:${actualPort}/`;
|
|
51
|
+
console.log(`BIT PPT Generator running at ${url}`);
|
|
52
|
+
console.log("Open the URL in your browser. Local mode does not require login unless auth environment variables are set.");
|
|
53
|
+
console.log("Endpoints: GET /health, POST /check, POST /generate");
|
|
54
|
+
})
|
|
55
|
+
.catch((error) => {
|
|
56
|
+
console.error(error);
|
|
57
|
+
process.exitCode = 1;
|
|
58
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { startStdioMcpServer } from "../src/mcp-server.mjs";
|
|
3
|
+
|
|
4
|
+
if (process.argv.includes("--help") || process.argv.includes("-h")) {
|
|
5
|
+
console.log(`bit-ppt-mcp
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
bit-ppt-mcp
|
|
9
|
+
|
|
10
|
+
Starts the BIT PPT MCP server over stdio. Configure your MCP client to launch
|
|
11
|
+
this command from the project root or from the installed npm package.
|
|
12
|
+
|
|
13
|
+
Tools:
|
|
14
|
+
list_layouts
|
|
15
|
+
get_guide
|
|
16
|
+
validate_deck
|
|
17
|
+
preflight_deck
|
|
18
|
+
get_repair_prompt
|
|
19
|
+
generate_pptx
|
|
20
|
+
`);
|
|
21
|
+
process.exit(0);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
startStdioMcpServer().catch((error) => {
|
|
25
|
+
console.error(error);
|
|
26
|
+
process.exitCode = 1;
|
|
27
|
+
});
|