@topmindspace/tms-skills 0.1.2 → 0.1.4
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 +46 -1
- package/README.md +14 -4
- package/bin/tms-skills.js +7 -2
- package/package.json +2 -2
- package/top-ppt-html/README.md +40 -27
- package/top-ppt-html/SKILL.md +20 -16
- package/top-ppt-html/agents/openai.yaml +5 -0
- package/top-ppt-html/assets/pptx-export.js +69 -25
- package/top-ppt-html/assets/style-gallery.html +1 -1
- package/top-ppt-html/assets/templates/architecture.html +69 -25
- package/top-ppt-html/assets/templates/presentation.html +69 -25
- package/top-ppt-html/assets/templates/research.html +69 -25
- package/top-ppt-html/evals/trigger-queries.json +181 -0
- package/top-ppt-html/package.json +4 -3
- package/top-ppt-html/references/chart-decision-tree.md +42 -0
- package/top-ppt-html/references/default-surface.md +3 -2
- package/top-ppt-html/references/illustration-layout.md +39 -0
- package/top-ppt-html/references/modes.md +1 -1
- package/top-ppt-html/references/outline-design.md +24 -0
- package/top-ppt-html/references/page-type-matrix.md +35 -0
- package/top-ppt-html/references/playbook.md +28 -89
- package/top-ppt-html/references/pptx-export.md +1 -1
- package/top-ppt-html/references/presentation-craft.md +11 -2
- package/top-ppt-html/references/tech-design.md +6 -0
- package/top-ppt-html/scripts/audit_docs.py +1 -1
- package/top-ppt-html/scripts/audit_skill.py +43 -4
- package/top-ppt-html/scripts/build_pptx.js +24 -10
- package/top-ppt-html/scripts/check_triggers.py +153 -0
- package/top-ppt-html/scripts/negative_tests.py +10 -0
- package/top-ppt-html/scripts/package_skill.py +17 -1
- package/top-ppt-html/scripts/quality_gate.py +30 -19
- package/top-ppt-html/scripts/test_feedback_gates.py +180 -0
- package/top-ppt-html/scripts/validate_pptx.py +157 -0
- package/top-ppt-html/scripts/validate_report.py +27 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,49 @@
|
|
|
1
|
-
##
|
|
1
|
+
## 0.1.4 — 2026-09-25
|
|
2
|
+
|
|
3
|
+
### top-ppt-html · craft + quality + docs + perf close-out
|
|
4
|
+
|
|
5
|
+
- **P0 效率 / agent 工作流**(usage-feedback):
|
|
6
|
+
- 默认交付 **仅 B 通道 PPTX**(`build_pptx.js`);A 通道(`pptx-export.js` / `gen_channel_a.js`)限预览与 `cross_verify` / 回归。
|
|
7
|
+
- `extract_snippet` 强制 + **整读大 L2 = FAIL / 不合格**(SKILL + playbook);`audit_skill` 新增对应门禁。
|
|
8
|
+
- `quality_gate` 对互不依赖子进程(HTML strict / PPTX strict / evals)**并行**执行。
|
|
9
|
+
- Fast / 轻量路径强化 **HTML-first**;PPTX 显式 opt-in(用户要 PPT 或交付含 PPTX)。
|
|
10
|
+
- **未削弱**红线:反截断、图表多样性(`minTypes.presentation=4` / registry)、Mode A 大气正式工艺、Gate 0 语义。
|
|
11
|
+
- **质量 / 规范**:对齐 SKILL frontmatter、双 `package.json`、README 钉版本、PUBLISHING、安装说明;跑通 check / audit / feedback gates。
|
|
12
|
+
- **docs 工艺改写**:定位强调优雅·美观·大气·演讲/正式场合;版式/排版/色彩/内容组织 + 质检与高保真导出;L0 仍瘦、L2 按需。
|
|
13
|
+
- **此前 #7(validator / engine)**:`shape_bounds` 读 `p:xfrm`、`TEXT_OVERFLOW_VERTICAL`、`ANNOTATION_BAND_OVERLAP`、`FONT_SIZE_NOT_SNAPPED`、多系列 vbar、streamgraph 图例内收、image caption `capYImg`——随本版一并发布。
|
|
14
|
+
|
|
15
|
+
### Installer
|
|
16
|
+
|
|
17
|
+
- `@topmindspace/tms-skills` → **0.1.4**(整仓同 tag)。
|
|
18
|
+
|
|
19
|
+
### Intentional leftovers
|
|
20
|
+
|
|
21
|
+
- 不引入 Claude-only `when_to_use` / 跨端风险 `allowed-tools`(同 0.1.3)。
|
|
22
|
+
- `skills-ref validate` 仍为可选,非发布硬依赖。
|
|
23
|
+
- layout-constants / model-schema 事实源版本线仍为 `0.1`(patch 记在 package / metadata)。
|
|
24
|
+
|
|
25
|
+
## 0.1.3 — 2026-09-24
|
|
26
|
+
|
|
27
|
+
### top-ppt-html · QA close-out + docs
|
|
28
|
+
|
|
29
|
+
- **P2-4 playbook 拆表**:意图→页型穷举 → `references/page-type-matrix.md`;图表决策表+七种误用 → `references/chart-decision-tree.md`。playbook 保留 Mode 契约 / V1–V4 / 组合 / **图表多样性摘要** / **反截断** / 路径·命令·L2 路由(体积 22KB→~17KB)。
|
|
30
|
+
- **版本对齐**:根 README / 技能 README / PUBLISHING / `metadata.version` / 双 `package.json` → **0.1.3**(消除残留 0.1.0 横幅)。
|
|
31
|
+
- **IMAGE_CAPTION**:配图页亦认 so-what/lead/figcaption;新增 WARN `IMAGE_NEAR_EMPTY`(近图过空)。
|
|
32
|
+
- **P2-2/P2-3**:不引入 Claude-only `when_to_use`、不写跨端风险 `allowed-tools`(`skills-ref validate` 已通过开放标准字段;扩展字段留给宿主实验)。
|
|
33
|
+
- **P2-5**:可选 `npx skills-ref@0.1.5 validate ./top-ppt-html`(不作为发布硬依赖;主门禁仍 `audit_skill`)。
|
|
34
|
+
- **docs**:根 README 安装表/钉版本/`@0.1.3`;技能 README 改为人类维护指南并指向 SKILL;package REQUIRED + MIN refs ≥25。
|
|
35
|
+
|
|
36
|
+
### Installer
|
|
37
|
+
|
|
38
|
+
- `@topmindspace/tms-skills` → **0.1.3**(整仓同 tag)。
|
|
39
|
+
|
|
40
|
+
### 此前 Unreleased(agent-compat,随 0.1.3 一并发布)
|
|
41
|
+
|
|
42
|
+
- **P0-1 Trigger eval**:`evals/trigger-queries.json` + `scripts/check_triggers.py`;`package_skill.py --check` 门禁。
|
|
43
|
+
- **P0-2 Mode A 读预算诚实**:L0+L1=2;Mode A/Fast 可加 L1.5(`default-surface` + `presentation-craft`)。
|
|
44
|
+
- **P0-3 反过读**:禁止整读清单 + 强制 `extract_snippet.py`。
|
|
45
|
+
- **P1 Frontmatter / 安装路径 / Fast 最小大纲 / 插画 brief**:license·compatibility·metadata;Cursor/Codex 路径;`illustration-layout.md`;`agents/openai.yaml`。
|
|
46
|
+
|
|
2
47
|
|
|
3
48
|
## 0.1.2 — 2026-09-24
|
|
4
49
|
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# tms-skills
|
|
2
2
|
|
|
3
|
-
**TopMindspace 智能体技能 monorepo** — 可安装的智能体技能集合,当前包含 **top-ppt-html
|
|
3
|
+
**TopMindspace 智能体技能 monorepo** — 可安装的智能体技能集合,当前包含 **top-ppt-html**(优雅、大气、正式场合演讲/汇报甲板)。
|
|
4
4
|
|
|
5
5
|
让 idea 飞,好想法被看见。
|
|
6
6
|
|
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
|
|
9
9
|
| 技能 | 版本 | 做什么 |
|
|
10
10
|
|------|------|--------|
|
|
11
|
-
| [`top-ppt-html`](./top-ppt-html/) | 0.1.
|
|
11
|
+
| [`top-ppt-html`](./top-ppt-html/) | 0.1.4 | 优雅大气的正式场合演讲/汇报甲板:单文件 HTML + 版式保真可编辑 16:9 PPTX |
|
|
12
12
|
|
|
13
|
-
安装器包 [`@topmindspace/tms-skills`](https://www.npmjs.com/package/@topmindspace/tms-skills) 亦为 **0.1.
|
|
13
|
+
安装器包 [`@topmindspace/tms-skills`](https://www.npmjs.com/package/@topmindspace/tms-skills) 亦为 **0.1.4**(整仓发版:安装器与当前技能同 tag;未来多技能仍可各自演进,默认随仓库 release)。
|
|
14
14
|
|
|
15
15
|
更多技能以仓库根目录下的技能目录加入(每个目录含 `SKILL.md`)。
|
|
16
16
|
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
npx @topmindspace/tms-skills list
|
|
31
31
|
npx @topmindspace/tms-skills install top-ppt-html
|
|
32
32
|
npx @topmindspace/tms-skills install top-ppt-html --to ./.claude/skills
|
|
33
|
-
npx @topmindspace/tms-skills@0.1.
|
|
33
|
+
npx @topmindspace/tms-skills@0.1.4 install top-ppt-html # 钉版本
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
### GitHub 直装
|
|
@@ -48,6 +48,16 @@ node tms-skills/bin/tms-skills.js install top-ppt-html
|
|
|
48
48
|
|
|
49
49
|
安装器把根目录下的技能目录 `<id>/`(含 `SKILL.md`)复制到目标目录;智能体通过 frontmatter(`name` + `description`)发现技能。
|
|
50
50
|
|
|
51
|
+
默认探测顺序(`resolveDefaultTarget`):项目级 `./.agents` → `./.claude` → `./.cursor` → `./.codex` → `./.mimocode`;再用户级 `~/.claude` → `~/.agents` → `~/.cursor` → `~/.codex`;都没有则落 `./.agents/skills`。也可用 `--to` 显式指定。
|
|
52
|
+
|
|
53
|
+
| 宿主 | 项目级 | 用户级 |
|
|
54
|
+
|------|--------|--------|
|
|
55
|
+
| 通用 / Codex | `.agents/skills` | `~/.agents/skills` |
|
|
56
|
+
| Claude Code | `.claude/skills` | `~/.claude/skills` |
|
|
57
|
+
| Cursor | `.cursor/skills`(兼读 `.agents`) | `~/.cursor/skills` |
|
|
58
|
+
| Codex 兼容 | `.codex/skills` | `~/.codex/skills` |
|
|
59
|
+
| 本仓库另含 | `.mimocode/skills` | — |
|
|
60
|
+
|
|
51
61
|
> **排错**:不要 `npm install <skill-id>`(技能 id 不是独立 npm 包)。「找不到包」→ 换 GitHub 直装,或 `--registry https://registry.npmjs.org/`。
|
|
52
62
|
|
|
53
63
|
### 可选依赖(仅 PPTX 精导)
|
package/bin/tms-skills.js
CHANGED
|
@@ -70,12 +70,17 @@ function readSkillMeta(skillId) {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
function resolveDefaultTarget() {
|
|
73
|
+
const home = process.env.HOME || process.env.USERPROFILE || '';
|
|
73
74
|
const candidates = [
|
|
74
75
|
path.join(process.cwd(), '.agents', 'skills'),
|
|
75
76
|
path.join(process.cwd(), '.claude', 'skills'),
|
|
77
|
+
path.join(process.cwd(), '.cursor', 'skills'),
|
|
78
|
+
path.join(process.cwd(), '.codex', 'skills'),
|
|
76
79
|
path.join(process.cwd(), '.mimocode', 'skills'),
|
|
77
|
-
path.join(
|
|
78
|
-
path.join(
|
|
80
|
+
path.join(home, '.claude', 'skills'),
|
|
81
|
+
path.join(home, '.agents', 'skills'),
|
|
82
|
+
path.join(home, '.cursor', 'skills'),
|
|
83
|
+
path.join(home, '.codex', 'skills'),
|
|
79
84
|
];
|
|
80
85
|
for (const dir of candidates) {
|
|
81
86
|
if (dir && fs.existsSync(path.dirname(dir))) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@topmindspace/tms-skills",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "TopMindspace 智能体技能 monorepo — 通过 npm / GitHub npx 安装技能(top-ppt-html
|
|
3
|
+
"version": "0.1.4",
|
|
4
|
+
"description": "TopMindspace 智能体技能 monorepo — 通过 npm / GitHub npx 安装技能(top-ppt-html:优雅大气正式场合演讲/汇报甲板等)。",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "TopMindspace",
|
|
7
7
|
"repository": {
|
package/top-ppt-html/README.md
CHANGED
|
@@ -1,28 +1,23 @@
|
|
|
1
1
|
# TopPPT HTML
|
|
2
2
|
|
|
3
|
-
**让 idea 飞,好想法被看见。**
|
|
3
|
+
**让 idea 飞,好想法被看见。** 面向**演讲与正式场合**的高品质甲板技能:把主张、调研、分析、架构方案,生成为**优雅、美观、大气**的可翻页 HTML + **版式保真可编辑 PPTX**。核心工艺是版式、排版、色彩与内容组织——克制图标/图表配文,而非 gadget 堆砌或咨询 dump 默认。
|
|
4
4
|
|
|
5
5
|
- 技能标识:`top-ppt-html`(安装/打包目录名与此一致);品牌名:**TopPPT HTML**
|
|
6
|
-
- 版本:**v0.1.
|
|
6
|
+
- 版本:**v0.1.4**(与 `@topmindspace/tms-skills@0.1.4` 同 tag)
|
|
7
|
+
- **智能体入口**:`SKILL.md` → `references/playbook.md`(L1)→ L2 按需
|
|
8
|
+
- **人类维护者**:本 README(安装 / 命令 / 目录);勿把本文件当生成规范
|
|
7
9
|
|
|
8
|
-
##
|
|
10
|
+
## 一、技能简介(人类速览)
|
|
9
11
|
|
|
10
12
|
| 维度 | 能力 |
|
|
11
13
|
|------|------|
|
|
12
|
-
|
|
|
13
|
-
|
|
|
14
|
-
|
|
|
15
|
-
|
|
|
16
|
-
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
| 素材图片 | **六版式**:full 版心全宽 3:1 / half 左图右注 4:3 / bleed 通栏出血 21:9 / grid 多图网格 4:3(2·3·4·6 张)/ compare 双图 A/B / wall Logo 墙;比例由 `imageSpec` 单源锁定(HTML 用 `.media--r*` 类、PPTX 用同一比例算高度并居中)——**两通道比例一致**;`src` 仅 data: 内联或相对路径;PPTX 声明式放行 |
|
|
20
|
-
| 配图占位 | 无素材时不省略图也不塞无关图:`.media--ph`(虚线框 + 斜纹 + 图标 + 尺寸提示)+ 模型 `image.placeholder` → PPTX 出**原生圆角矩形占位框**(可编辑、`pictures` 不增),交付前替换 `src` 即可;预览模态会把图位替换成真实图片 |
|
|
21
|
-
| 用户图片准备 | `scripts/prepare_images.py <图片\|目录> --layout full\|half\|grid…`:读尺寸/格式/体积 → 按版式建议尺寸缩放压缩(有 Pillow 时)→ 自动选 data: 内联或相对路径 → 产出可粘贴的 `.media` HTML 片段与 `image` 模型对象 |
|
|
22
|
-
| 36 种图表 | 环形 / 多段环形 / 饼图 / 柱状 / 堆叠 / 100% 堆叠条 / 折线 / 双折线 / 面积 / 横向条形 / 双向条形 / 雷达 / 仪表盘 / 玫瑰 / 瀑布 / 漏斗 / 甘特 / 散点 / 气泡 / 矩形树图 / 马赛克 / 进度条组 / 迷你趋势线 / 桑基 / 斜率 / 哑铃 / 棒棒糖 / 点图 / 子弹图 / 华夫 / 箱线 / 帕累托 / 径向条 / 流图 / K 线 / 关系网络(全内联 SVG,随主题与风格变色;**16 类走 PPTX 原生图表,其余形状还原 + 数据表**) |
|
|
23
|
-
| 按需深度模式 | 命中「高保真/1:1/精确还原/正式交付」或含复杂信息图时自动升级:`--deep` 把连续文本流与空间锚点纳入 strict,`--emit-manifest` 产出锚点/容器/数据表/图表通道/图片资产登记,`render_compare.py` 准备渲染对照材料(缺依赖自动跳过) |
|
|
24
|
-
| 质量闭环 | `validate_report.py`(HTML strict 全 PASS,含强调带约束/待核实标注/素材图片与配图占位/图表数据表策略)+ `validate_pptx.py --strict`(0 错误 0 警告,含容器级溢出/表格语义字号与密度/未声明图片硬拦/图片版式·裁切·多图数量·相对路径文件存在性)+ WCAG 对比度与单源完整性审计 + 双通道回归双裁判 + 素材图片导出探针 |
|
|
25
|
-
| 设计标准 | Material Design 3 对齐(克制执行);研究模式对齐咨询机构实践 |
|
|
14
|
+
| 产出 | 单文件 HTML(可翻页、亮暗双主题、header 工具栏)+ 16:9 可编辑 PPTX(精导通道) |
|
|
15
|
+
| 三模式 | A 演示 · B 研究 · C 架构(页型/字号/密度契约见 `playbook.md` §一) |
|
|
16
|
+
| 风格 | 9 套(`styles.md`);编码色板 c1–c5 随风格 |
|
|
17
|
+
| 图表 | 核图 8 默认 + registry 全量;多样性 / 反截断 / Mode A 工艺见 playbook + `presentation-craft.md` |
|
|
18
|
+
| 质量 | `validate_report --strict`(A 隐含 layout-qa)· `validate_pptx --strict` · `quality_gate --deliver` |
|
|
19
|
+
|
|
20
|
+
生成规范、页型/图表穷举、铁律 **不在本文件**——智能体读 `SKILL.md` / playbook;选型大表见 `page-type-matrix.md` / `chart-decision-tree.md`。
|
|
26
21
|
|
|
27
22
|
**核心架构**:HTML 与 PPTX 出自同一内容模型 `window.REPORT_MODEL`(唯一事实源);页面只预览不导出,PPTX 由智能体走「精导通道」生成(extract → build → strict 校验)。阈值与几何全部单源化:`scripts/layout-constants.json`(常量)+ `scripts/model-schema.json`(页型 DSL)。
|
|
28
23
|
|
|
@@ -48,6 +43,16 @@ node tms-skills/bin/tms-skills.js install top-ppt-html
|
|
|
48
43
|
|
|
49
44
|
> **GitHub 更新不会自动进 npm。** 日常可钉 npm 版本;要最新技能用 GitHub 直装,或等 maintainer 打 tag 发版。
|
|
50
45
|
>
|
|
46
|
+
|
|
47
|
+
### 触发词回归(维护者)
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
python3 scripts/check_triggers.py # keyword/heuristic vs SKILL description
|
|
51
|
+
# 扩展:编辑 evals/trigger-queries.json(how_to_extend)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
`package_skill.py --check` 会自动跑 trigger coverage。
|
|
55
|
+
|
|
51
56
|
> 「找不到这个包」→ 换 GitHub 直装,或 `--registry https://registry.npmjs.org/`(镜像索引可能滞后)。不要 `npm install top-ppt-html`(技能 id 不是独立 npm 包)。
|
|
52
57
|
|
|
53
58
|
也可将本目录(或 GitHub Release 附件 `top-ppt-html.zip` 解压结果)复制到智能体技能目录,目录名保持 `top-ppt-html`。技能识别面为 `SKILL.md`(frontmatter 的 `name` / `description` 即触发描述)。
|
|
@@ -73,11 +78,11 @@ npm install # 依 package.json 安装 pptxgenjs(^4)
|
|
|
73
78
|
```
|
|
74
79
|
听意图 → Gate 0 参考图 → 六项问询 → 路径判定(轻量默认 / 完整走 outline-design.md 七步法)
|
|
75
80
|
→ scaffold_report.py 起骨架(勿整读/复制模板)→ **只填 window.REPORT_MODEL** → `render_from_model.py --inplace`
|
|
76
|
-
→ validate_report.py --strict 全 PASS →
|
|
77
|
-
|
|
81
|
+
→ validate_report.py --strict 全 PASS → 交付(默认 HTML)
|
|
82
|
+
→(用户要 PPTX 时 · **仅 B 通道**)extract_model.py → build_pptx.js --model → validate_pptx.py --strict 0/0
|
|
78
83
|
```
|
|
79
84
|
|
|
80
|
-
**渐进式披露三档**(详见 `SKILL.md` 阶段路由表):`L0` = `SKILL.md`(路由 + 门禁 + 铁律,加载即用);`L1` = `references/playbook.md`(**唯一常读入口**:模式契约 / 页型选型 / 组合版式矩阵 / 图表选型决策树 / 内容规则 / 配色 / 校验命令);`L2` =
|
|
85
|
+
**渐进式披露三档**(详见 `SKILL.md` 阶段路由表):`L0` = `SKILL.md`(路由 + 门禁 + 铁律,加载即用);`L1` = `references/playbook.md`(**唯一常读入口**:模式契约 / 页型选型 / 组合版式矩阵 / 图表选型决策树 / 内容规则 / 配色 / 校验命令);`L2` = 深度规范,**只在命中条件时读、读完即停**;**取码必须 `extract_snippet.py`**(整读大 L2 = FAIL);`components.md`/`charts.md` 为逻辑索引,自动路由到物理拆分文件。
|
|
81
86
|
|
|
82
87
|
## 三、目录结构
|
|
83
88
|
|
|
@@ -106,9 +111,12 @@ top-ppt-html/
|
|
|
106
111
|
│ ├─ infographics.md # 铁律与边界(逻辑入口);代码已拆分见下两行 │
|
|
107
112
|
│ ├─ infographics-stats.md # 统计图形族 §1–§6 / §71–§77 │
|
|
108
113
|
│ ├─ infographics-structure.md # 结构图形族 §78–§82 │
|
|
114
|
+
│ ├─ page-type-matrix.md # L2 意图→页型穷举(playbook §三 速记) │
|
|
115
|
+
│ ├─ chart-decision-tree.md # L2 图表决策表+误用(playbook §五 摘要) │
|
|
116
|
+
│ ├─ illustration-layout.md # L2 插画/配图 brief │
|
|
109
117
|
│ └─ …(modes / styles / design-system / content-rules / icons / default-surface / │
|
|
110
|
-
│ outline-design / pptx-export / high-fidelity /
|
|
111
|
-
│
|
|
118
|
+
│ outline-design / pptx-export / high-fidelity / failure-modes / tech-design; │
|
|
119
|
+
│ 归档见 docs/archive/refs/) │
|
|
112
120
|
├─ evals/ # Eval 框架(结果/过程/风格/效率四类目标) │
|
|
113
121
|
│ ├─ prompts.csv # 14 条 prompt(显式/隐式/上下文/负对照) │
|
|
114
122
|
│ ├─ rubric.schema.json # 风格目标结构化评分契约 │
|
|
@@ -145,18 +153,23 @@ python scripts/package_skill.py --check
|
|
|
145
153
|
python scripts/audit_skill.py && python scripts/audit_docs.py
|
|
146
154
|
python scripts/audit_styles.py && python scripts/audit_css.py
|
|
147
155
|
python scripts/negative_tests.py
|
|
156
|
+
python scripts/check_triggers.py
|
|
157
|
+
# 可选第三方:npx --yes skills-ref@0.1.5 validate .
|
|
148
158
|
```
|
|
149
159
|
|
|
150
160
|
## 目录要点
|
|
151
161
|
|
|
152
162
|
| 路径 | 用途 |
|
|
153
163
|
|------|------|
|
|
154
|
-
| `SKILL.md` | L0 路由(≤13KB
|
|
155
|
-
| `references/playbook.md` | L1
|
|
156
|
-
| `references/
|
|
164
|
+
| `SKILL.md` | L0 路由(≤13KB);智能体唯一入口 |
|
|
165
|
+
| `references/playbook.md` | L1 决策层(Mode / 路径 / V1–V4 / 组合 / 多样性摘要 / 命令 / 路由) |
|
|
166
|
+
| `references/page-type-matrix.md` | L2 页型穷举表 |
|
|
167
|
+
| `references/chart-decision-tree.md` | L2 图表决策树 + 七种误用 |
|
|
168
|
+
| `references/default-surface.md` | Mode A L1.5:12 页型 + 核图 8 + V1–V4 |
|
|
169
|
+
| `references/presentation-craft.md` | Mode A L1.5 工艺(反截断 / 大气正式) |
|
|
157
170
|
| `assets/examples/` | 3 份黄金样张(每模式 1) |
|
|
158
|
-
| `
|
|
159
|
-
| `docs/archive/` | 历史规范 / 旧示例
|
|
171
|
+
| `evals/trigger-queries.json` | description 触发正/负例;`check_triggers.py` |
|
|
172
|
+
| `docs/archive/` | 历史规范 / 旧示例 |
|
|
160
173
|
|
|
161
174
|
风格画廊与主题参考图:`assets/theme-overview*.png`(Gate 0)。完整规范索引见 playbook §十。
|
|
162
175
|
|
package/top-ppt-html/SKILL.md
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: top-ppt-html
|
|
3
|
-
description: "
|
|
3
|
+
description: "Use when 用户要做报告、演示、汇报、PPT、slides、deck、路演,或写研究报告、分析报告、咨询报告、白皮书、调研、评测、对标、经营分析、复盘、项目汇报、商务/HTML/网页报告,或做架构图、拓扑图、流程图、泳道图、方案图,或把材料做成可视化报告并导出 HTML/PPT/PPTX,或优化排版/版式/配色/图文布局,或要快速模式/fast/直接生成/一键出稿/少问一句。TopPPT HTML:优雅大气的正式场合演讲/汇报甲板——零外链可翻页 HTML(亮暗双主题)+ 版式保真可编辑 16:9 PPTX;核心=版式·排版·色彩·内容组织;三模式(A 演示·每屏一主张 / B 研究·咨询密排 / C 架构·图为王)× 9 风格。Do NOT use for 纯代码工程、非报告类网页或应用开发、视频/图片生成、直接改写已有 Word/PPT 源文件本身。"
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: "Python 3 stdlib for HTML generation; Node >=18 + pptxgenjs for PPTX; optional playwright for browser regression / theme captures."
|
|
6
|
+
metadata:
|
|
7
|
+
version: "0.1.4"
|
|
8
|
+
author: TopMindspace
|
|
4
9
|
---
|
|
5
|
-
|
|
6
10
|
# TopPPT HTML
|
|
7
11
|
|
|
8
|
-
**让 idea 飞,好想法被看见。**
|
|
12
|
+
**让 idea 飞,好想法被看见。** 面向**演讲与正式场合**的优雅、大气甲板——非 gadget 堆砌、非咨询 dump 默认。三种模式、两种交付:**单文件 HTML**(可翻页演示)+ **版式保真可编辑 PPTX**(**B 通道** `build_pptx.js` 为唯一交付;**A 通道**仅预览/`cross_verify`)。同源 `REPORT_MODEL`。设计对齐 MD3,执行克制;研究模式可对齐咨询密度,但**克制优先**——少装饰、一屏一重心。
|
|
9
13
|
|
|
10
14
|
## Gate 0 · 先给参考图(**标准模式**硬门禁)
|
|
11
15
|
|
|
@@ -30,9 +34,9 @@ description: "TopPPT HTML:报告 / 演示 / 信息架构图生成器。单文
|
|
|
30
34
|
| style | B→mckinsey · A→business-blue · C→graphite-dark | |
|
|
31
35
|
| theme | light(graphite→dark) | |
|
|
32
36
|
| 篇幅 | A=10 / B=12 / C=6 | |
|
|
33
|
-
| format | html only
|
|
37
|
+
| format | **html only**(默认;**仅当用户要 PPT / 交付含 PPTX 才开** B 通道) | |
|
|
34
38
|
|
|
35
|
-
流程:一行宣布「Fast 选用:…」→
|
|
39
|
+
流程:一行宣布「Fast 选用:…」→ **最小大纲**(`outline-design.md`「轻量最小集」)→ playbook §二轻量链(骨架→模型单写→回填→strict→`quality_gate --deliver`;**PPTX 显式 opt-in**)。路径轻量;末可附 `assets/style-gallery.html`。开场声明「已跳过参考图」。**标准模式**仍强制 Gate 0 + 六项。
|
|
36
40
|
|
|
37
41
|
## 唯一入口流程
|
|
38
42
|
|
|
@@ -42,7 +46,7 @@ description: "TopPPT HTML:报告 / 演示 / 信息架构图生成器。单文
|
|
|
42
46
|
(命令链见 playbook §二/§九;PPTX 见 pptx-export)
|
|
43
47
|
```
|
|
44
48
|
|
|
45
|
-
**预算(硬)**:交互轮次 **≤3
|
|
49
|
+
**预算(硬)**:交互轮次 **≤3**;**L0+L1 共 2 份**(本文件 + `playbook.md`)。**Mode A/Fast**可加 L1.5:`default-surface.md`+`presentation-craft.md`(非违约)。其余 L2 命中才读、不预读。
|
|
46
50
|
|
|
47
51
|
## 六项问询(标准模式 · 一次问完 · 唯一一次形式参数确认)
|
|
48
52
|
|
|
@@ -52,7 +56,7 @@ description: "TopPPT HTML:报告 / 演示 / 信息架构图生成器。单文
|
|
|
52
56
|
2. **篇幅**——A 8–15 页(图文 V1–V4,简单图禁全幅)/ B 12–25 页 / C 1–3 张图共 6–8 页;有材料按材料量推荐。
|
|
53
57
|
3. **风格(始终选择)**——默认商务蓝;B 推荐麦肯锡/墨绿/暖沙金;C 推荐石墨深灰/商务蓝/彩色;拿不准给 Gate 0 参考图。
|
|
54
58
|
4. **亮暗主题(始终确认)**——浅色默认(打印/外发)/ 深色(沉浸/发布会/大屏);石墨深灰出厂深色;双主题经 `REPORT_MODEL.theme` 贯穿 HTML 与导出。
|
|
55
|
-
5. **交付格式**——仅 HTML(默认)/ HTML+PPTX
|
|
59
|
+
5. **交付格式**——仅 HTML(默认)/ HTML+PPTX(用户要可编辑甲板时;PPTX 走 **B 通道**)。
|
|
56
60
|
6. **参考图确认**——复述 Gate 0 路径,确认用户已看到。
|
|
57
61
|
|
|
58
62
|
**载体**:优先结构化选项卡一次收集,否则对话文本一次列全。此后形式层面不再反复确认(内容层面按需一次大纲确认,见下)。
|
|
@@ -61,7 +65,7 @@ description: "TopPPT HTML:报告 / 演示 / 信息架构图生成器。单文
|
|
|
61
65
|
|
|
62
66
|
| 路径 | 何时 | 多做什么 |
|
|
63
67
|
|------|------|---------|
|
|
64
|
-
| **轻量**(默认) | 页数不多、材料单一完整、关键判断已敲定 |
|
|
68
|
+
| **轻量**(默认) | 页数不多、材料单一完整、关键判断已敲定 | 最小大纲→1 张规划卡(`outline-design.md`「轻量最小集」) |
|
|
65
69
|
| **完整** | 长篇、材料量大且杂、含未敲定关键判断、用户要看框架 | 证据盘点 → 故事线 → 主张树 → 逐页规划卡 → 大纲确认(1 轮) |
|
|
66
70
|
|
|
67
71
|
两条路径的**精确判定条件与完整步骤以 `references/playbook.md` §二为准**。完整路径确认只做一次,用户说"调整"只改指定处;确认后不再有内容层面的反复确认。
|
|
@@ -80,21 +84,21 @@ description: "TopPPT HTML:报告 / 演示 / 信息架构图生成器。单文
|
|
|
80
84
|
|
|
81
85
|
> 披露分层(机器可读):`L0=SKILL.md` · `L1=references/playbook.md` · `L2=按需`
|
|
82
86
|
>
|
|
83
|
-
> **纪律**:L0+L1 是默认全部所需;**只在命中"何时读"时才打开 L2
|
|
87
|
+
> **纪律**:L0+L1 是默认全部所需;**只在命中"何时读"时才打开 L2,读完即执行、不预读下一份**。需要代码时**一律** `extract_snippet.py`(`--list` / `--task` / `--chart` / `--page-type` / `--file --section`)。**整读大 L2 文件 = FAIL / 不合格**(禁令清单见下与 playbook §十)。
|
|
84
88
|
|
|
85
89
|
**L2 一览**(命中条件与逐任务只读清单的**详表以 playbook §十为准**,此处仅索引):
|
|
86
90
|
|
|
87
91
|
- 模式契约与锁定版式 → `references/modes.md` · 完整路径七步 → `references/outline-design.md`
|
|
88
|
-
- **A/Fast
|
|
89
|
-
- 组件/版式**代码** → `components.md` · 图表门面 `charts.md
|
|
92
|
+
- **A/Fast L1.5 → `default-surface.md` + `presentation-craft.md`** · 骨架 `layout-grammar.md` §七 · 插画 `illustration-layout.md`
|
|
93
|
+
- 组件/版式**代码** → `components.md` · 页型表 `page-type-matrix.md` · 图表门面 `charts.md` + 决策树 `chart-decision-tree.md`(extended 按需)· 信息图 → `infographics.md`
|
|
90
94
|
- 配色/主题/字阶 → `styles.md` + `design-system.md` · 写作 → `content-rules.md` · 图标语义 → `icons.md`
|
|
91
95
|
- PPTX 精导 → `references/pptx-export.md` · 深度高保真 → `references/high-fidelity.md` · 修复顺序 → `references/failure-modes.md` · 技能维护 → `references/tech-design.md`
|
|
92
96
|
|
|
93
|
-
**操作方式**:定模式/页型/组合/图 → 只读 `playbook.md`;取代码 → `extract_snippet.py
|
|
97
|
+
**操作方式**:定模式/页型/组合/图 → 只读 `playbook.md`;取代码 → **必须** `extract_snippet.py`。**整读下列文件 = FAIL**:`layouts-combo` / `components-atoms` / `charts-basic` / `charts-extended` / `content-rules` 全文 / `pptx-export` / 模式模板 HTML(走 scaffold)。详表 playbook §十。同阶段不重读。
|
|
94
98
|
|
|
95
99
|
## 铁律(12 条 · 交付硬门禁)
|
|
96
100
|
|
|
97
|
-
> 门禁语义;阈值见 playbook / layout 常量 JSON。排版读 `layout-grammar.md`。**motion=none
|
|
101
|
+
> 门禁语义;阈值见 playbook / layout 常量 JSON。排版读 `layout-grammar.md`。**motion=none**(无炫技转场;`presentation-craft.md`)。
|
|
98
102
|
|
|
99
103
|
1. **单文件零外链**——无 CDN/外部字体/外部图片,图形一律内联 SVG;`<img src>` 仅 `data:` 或相对路径且必带 `alt`(单图 ≤1.5MB、全篇 ≤8MB);无素材图不留空不省略,用配图占位(`components.md` §11c-3)。
|
|
100
104
|
2. **模式先定后写**——从对应模式模板起步;`data-mode` = `REPORT_MODEL.mode`,页面无模式切换;MD3 映射;PPTX 字号走三模式独立比例尺。
|
|
@@ -112,9 +116,9 @@ description: "TopPPT HTML:报告 / 演示 / 信息架构图生成器。单文
|
|
|
112
116
|
## 交付物与验收
|
|
113
117
|
|
|
114
118
|
- **HTML**:单文件零外链、可翻页可演示、每页一屏高;header 工具栏(T 亮暗 / 9 风格即切 / P 预览 / H 指引 / F 全屏 / B 折叠)。
|
|
115
|
-
- **PPTX
|
|
116
|
-
- **验收**:HTML strict 0
|
|
117
|
-
- **交付说明**:`quality_gate.py
|
|
119
|
+
- **PPTX(B 通道交付)**:`extract_model` → `build_pptx.js` → `validate_pptx --strict`;16:9 全原生可编辑。**A 通道不交付**(仅预览 / `cross_verify`;细则 playbook §九)。
|
|
120
|
+
- **验收**:HTML strict 0/0;含 PPTX 再加 PPTX 0/0;失败给**定向修复指引**。
|
|
121
|
+
- **交付说明**:`quality_gate.py --deliver`(含 PPTX 带 `--pptx/--model`;子门禁并行)出七要素,缺一 FAIL——勿手拼。
|
|
118
122
|
|
|
119
123
|
## 环境依赖
|
|
120
124
|
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Codex / ChatGPT Skills UI metadata (optional)
|
|
2
|
+
display_name: "TopPPT HTML"
|
|
3
|
+
short_description: "Elegant, atmospheric formal decks for speeches — HTML + editable 16:9 PPTX."
|
|
4
|
+
default_prompt: "Generate an elegant formal presentation or report as HTML (PPTX on request via B-channel)."
|
|
5
|
+
allow_implicit_invocation: true
|
|
@@ -79,7 +79,7 @@ var STYLE_DATA_COLORS = {"business-blue":["1a73e8","3526bb","21a199","b77148","9
|
|
|
79
79
|
var STYLE_DATA_COLORS_DARK = {"business-blue":["8ab4f8","7966e0","88e7e5","d4ad91","cbce83"],"apple-mono":["f5f5f7","2997ff","2dd4bf","ff9f0a","bf5af2"],"mckinsey":["7fb2e5","6f6bdb","8ce3d8","d1a694","cbc586"],"brand-red":["ff5a66","e09e66","e788cb","91d4c2","83b4ce"],"warm-sand":["d9b36a","c2d571","df9391","97b5ce","8e89c7"],"deep-teal":["4fc3b0","7aaecd","97d8a4","c99cac","c29c8f"],"graphite-dark":["4da3ff","6c66e0","88e7dc","d4a691","cec983"],"indigo-violet":["a5a4f0","a967e0","89c3e7","d3c792","aece83"],"spectrum":["8ba0f8","9066e0","88d6e7","d4ba91","bdce83"]};
|
|
80
80
|
var GRID = {"columns":12,"gutter":0.16,"colW":0.8644,"x":[0.6,1.6244,2.6488,3.6732,4.6976,5.722,6.7464,7.7708,8.7952,9.8196,10.844,11.8684,12.733],"y":[2.35,3.27,4.19,5.11,6.03,6.9],"safe":{"top":0.4,"bottom":0.4,"left":0.6,"right":0.6}};
|
|
81
81
|
var TYPO = {"levels":[{"id":"C0","name":"封面/章节幕标题","role":"coverTitle","usage":"封面主标题、章节幕标题"},{"id":"T1","name":"页码/章节徽章","role":"caption","usage":"页码徽章、章节编号"},{"id":"T2","name":"页面主标题/结论标题","role":"h1","usage":"每页顶部结论句(research 行动标题)"},{"id":"T3","name":"副标题/语境说明","role":"lead","usage":"主标题下方导语"},{"id":"T4","name":"模块标题/图表标题","role":"h2","usage":"卡片标题、图表标题、面板标题"},{"id":"T5","name":"证据编号/轻量标签","role":"micro","usage":"Exhibit 编号、状态标签"},{"id":"T6","name":"证据块标题/小节标题","role":"h2","usage":"分栏小标题、证据块标题"},{"id":"T7","name":"正文解释段落","role":"body","usage":"证据解释、管理解读正文、表格正文"},{"id":"T8","name":"结论条文字","role":"body","usage":"so-what 结论条、核心结论框"},{"id":"T9","name":"SO WHAT 标签","role":"caption","usage":"so-what 标签行"},{"id":"T10","name":"SO WHAT 正文/业务含义","role":"body","usage":"so-what 正文、行动含义、表格行动项"},{"id":"T11","name":"图表轴/图例/刻度/微标签","role":"micro","usage":"坐标轴、图例、刻度、单位(禁用于表格正文与完整短句)"},{"id":"T12","name":"图表数据标签","role":"caption","usage":"折线点值、柱形标签、百分比标注"},{"id":"T13","name":"关键 KPI 大数字","role":"h1","usage":"KPI 大数字、hero 数值"},{"id":"T14","name":"注释/口径/来源/页脚","role":"micro","usage":"footnote、来源行、页脚、小页码"}],"tableSemanticRule":{"body":["T7","T10"],"microAllowed":["T11"],"microForbiddenFor":["表格正文","行动项","风险项","解释句","建议句","长项目符号","完整短句"]}};
|
|
82
|
-
var CONT = {"pad":{"card":0.18,"panel":0.2,"cell":0.08,"band":0.16,"soWhat":0.16,"kpi":0.18,"chart":0.1,"head":0.05,"footer":0.05,"node":0.06},"minPad":0.06,"textMetrics":{"lineFactor":1.45,"emAsciiRatio":0.52},"overflowRule":"
|
|
82
|
+
var CONT = {"pad":{"card":0.18,"panel":0.2,"cell":0.08,"band":0.16,"soWhat":0.16,"kpi":0.18,"chart":0.1,"head":0.05,"footer":0.05,"node":0.06},"minPad":0.06,"textMetrics":{"lineFactor":1.45,"emAsciiRatio":0.52},"overflowRule":"溢出处置优先级(禁静默截断):① 重构承载(列表/卡片/表/图/组合版式)→ ② 拆页/分章(议程→主张→证据卡→明细;01a/01b;信息须完整)→ ③ 换布局形态(V1–V4/多列/卡栅格)→ ④ 有限 fontShrink(阶梯内、模式 floor 以上、最多 4 档)→ ⑤ 禁止:静默截断、砍 so-what/证据/口径、为审美稀疏删决策必需信息。单页字数预算是预警不是删字许可证。","fontShrink":{"ladder":[15,14,13.5,13,12.5,12,11.5,11,10.5,10,9.5,9,8.5],"maxShrinkSteps":4,"floorPt":{"presentation":10,"research":9,"architecture":10},"preferContentFirst":true,"warnBelow":9.5},"continuousTextRule":"语义连续的一句话 / so-what 主句 / 结论句 / 表格单元格正文不得拆成多个独立文本框(避免异常空格、断句、基线漂移);局部加粗高亮必须用同一文本框内富文本。"};
|
|
83
83
|
var REG = {"bar":{"html":"svg-bars","pptx":"native","nativeType":"bar","dataTable":"notes","min":{"vbHeightMin":160}},"hbar":{"html":"svg-hbars","pptx":"native","nativeType":"bar","dataTable":"notes","min":{"vbHeightMin":100}},"stack":{"html":"svg-stack","pptx":"native","nativeType":"bar","dataTable":"notes","min":{"vbHeightMin":160},"nativeOpt":{"barGrouping":"stacked"}},"stackline":{"html":"svg-stackline","pptx":"native","nativeType":"bar","dataTable":"notes","min":{"vbHeightMin":40},"nativeOpt":{"barGrouping":"percentStacked"}},"line":{"html":"svg-line","pptx":"native","nativeType":"line","dataTable":"notes","min":{"vbHeightMin":160}},"dualline":{"html":"svg-dualline","pptx":"native","nativeType":"line","dataTable":"notes","min":{"vbHeightMin":160}},"area":{"html":"svg-area","pptx":"native","nativeType":"area","dataTable":"notes","min":{"vbHeightMin":160}},"donut":{"html":"svg-donut","pptx":"native","nativeType":"doughnut","dataTable":"notes","min":{"pxWidthMin":140}},"multidonut":{"html":"svg-mdonut","pptx":"native","nativeType":"doughnut","dataTable":"notes","min":{"pxWidthMin":140}},"pie":{"html":"svg-pie","pptx":"native","nativeType":"pie","dataTable":"notes","min":{"pxWidthMin":140}},"radar":{"html":"svg-radar","pptx":"native","nativeType":"radar","dataTable":"notes","min":{"pxWidthMin":220}},"scatter":{"html":"svg-scatter","pptx":"native","nativeType":"scatter","dataTable":"notes","min":{"vbHeightMin":180}},"bubble":{"html":"svg-bubble","pptx":"native","nativeType":"bubble","dataTable":"notes","min":{"vbHeightMin":180}},"waterfall":{"html":"svg-wf","pptx":"native","nativeType":"bar","dataTable":"notes","min":{"vbHeightMin":170},"nativeTrick":"stacked+hiddenBase+connector"},"gauge":{"html":"svg-gauge","pptx":"native","nativeType":"doughnut","dataTable":"notes","min":{"pxWidthMin":180},"nativeTrick":"doughnut+firstSliceAng+hiddenRemainder"},"pareto":{"html":"svg-pareto","pptx":"native","nativeType":"bar","dataTable":"notes","min":{"vbHeightMin":180},"nativeTrick":"multiType+bar+line"},"gantt":{"html":"svg-gantt","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":130},"path":{"forbidPresetShapes":true}},"vsbar":{"html":"svg-vsbar","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":100},"path":{"forbidPresetShapes":true}},"progress":{"html":"svg-progress","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":100},"path":{"forbidPresetShapes":true}},"sparkline":{"html":"svg-spark","pptx":"shape","dataTable":"off","min":{"vbHeightMin":20},"path":{"forbidPresetShapes":true}},"funnel":{"html":"svg-funnel","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":160},"path":{"minSamplePoints":8,"forbidPresetShapes":true}},"treemap":{"html":"svg-treemap","pptx":"shape","dataTable":"appendix","min":{"vbHeightMin":170},"path":{"forbidPresetShapes":true}},"marimekko":{"html":"svg-marimekko","pptx":"shape","dataTable":"appendix","min":{"vbHeightMin":160},"path":{"forbidPresetShapes":true}},"boxplot":{"html":"svg-boxplot","pptx":"shape","dataTable":"appendix","min":{"vbHeightMin":180},"path":{"forbidPresetShapes":true}},"network":{"html":"svg-network","pptx":"shape","dataTable":"appendix","min":{"vbHeightMin":200},"path":{"forbidPresetShapes":true}},"sankey":{"html":"svg-sankey","pptx":"shape","dataTable":"appendix","min":{"vbHeightMin":200},"path":{"minSamplePoints":16,"trackBothEdges":true,"forbidPresetShapes":true}},"streamgraph":{"html":"svg-stream","pptx":"shape","dataTable":"appendix","min":{"vbHeightMin":160},"path":{"minSamplePoints":24,"trackBothEdges":true,"forbidPresetShapes":true}},"slope":{"html":"svg-slope","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":180},"path":{"forbidPresetShapes":true}},"dumbbell":{"html":"svg-dumbbell","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":160},"path":{"forbidPresetShapes":true}},"lollipop":{"html":"svg-lollipop","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":140},"path":{"forbidPresetShapes":true}},"dotplot":{"html":"svg-dotplot","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":120},"path":{"forbidPresetShapes":true}},"bulletchart":{"html":"svg-bullet","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":140},"path":{"forbidPresetShapes":true}},"waffle":{"html":"svg-waffle","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":160},"path":{"forbidPresetShapes":true}},"radialbar":{"html":"svg-radialbar","pptx":"shape","dataTable":"notes","min":{"pxWidthMin":200},"path":{"minSamplePoints":16,"forbidPresetShapes":true}},"rose":{"html":"svg-rose","pptx":"shape","dataTable":"notes","min":{"pxWidthMin":180},"path":{"minSamplePoints":16,"forbidPresetShapes":true}},"candlestick":{"html":"svg-candle","pptx":"shape","dataTable":"appendix","min":{"vbHeightMin":180},"path":{"forbidPresetShapes":true}}};
|
|
84
84
|
var DEEP = {"triggers":["高保真","1:1","一比一","精确还原","按图还原","正式交付","不能偏移","像素级","严格对照","逐页验收"],"complexCharts":["sankey","streamgraph","treemap","marimekko","boxplot","network","rose","radialbar","candlestick","funnel"],"checks":{"anchors":true,"containerOverflow":true,"renderCompare":true,"manifest":true},"renderCompare":{"engine":"soffice","fallback":"powerpoint-com","skipIfMissing":true,"dpi":96}};
|
|
85
85
|
var IMG = {"layouts":["full","half","bleed","grid","compare","wall"],"multiLayouts":["grid","compare","wall"],"fitEnum":["cover","contain"],"fitDefault":"cover","formats":["png","jpeg","jpg","webp","svg"],"ratioDefault":{"full":"3:1","half":"4:3","bleed":"21:9","grid":"4:3","compare":"4:3","wall":"1:1"},"ratioCssClass":{"full":"media--r3-1","half":"media--r4-3","bleed":"media--r21-9","grid":"media--r4-3","compare":"media--r4-3","wall":"media--r1-1"},"recommendedSizePx":{"full":"2400×800","half":"1400×1050","bleed":"2560×1100","grid":"900×675","compare":"1400×1050","wall":"480×480"},"maxInlineBytes":1572864,"maxTotalInlineBytes":8388608,"maxPerPage":6,"placeholderLabel":"配图占位","placeholderHintPrefix":"建议 ","placeholderHintSuffix":"px","zeroExternal":true,"qualityRule":"位图优先提供 ≥2× 显示尺寸;截图用 16:9 或 4:3 锁定比例;数据图不要用截图(应用内联 SVG 图表,可随主题变色)。"};
|
|
@@ -276,6 +276,16 @@ function modeFloorPtA(mode) {
|
|
|
276
276
|
var m = String(mode || 'presentation');
|
|
277
277
|
return (floors[m] != null) ? floors[m] : 10;
|
|
278
278
|
}
|
|
279
|
+
function snapFont(pt, ladder, floor) {
|
|
280
|
+
var lad = (ladder || FONT_LADDER).filter(function (v) { return v >= (floor == null ? 0 : floor); });
|
|
281
|
+
if (!lad.length) return floor == null ? pt : Math.max(floor, pt);
|
|
282
|
+
var best = lad[0], bd = Math.abs(lad[0] - pt);
|
|
283
|
+
for (var i = 1; i < lad.length; i++) {
|
|
284
|
+
var d = Math.abs(lad[i] - pt);
|
|
285
|
+
if (d < bd) { bd = d; best = lad[i]; }
|
|
286
|
+
}
|
|
287
|
+
return best;
|
|
288
|
+
}
|
|
279
289
|
function fitFont(items, widthIn, availIn, opts) {
|
|
280
290
|
opts = opts || {};
|
|
281
291
|
var max = (opts.max == null) ? 99 : opts.max, lf = opts.lineFactor || 1.45;
|
|
@@ -620,7 +630,7 @@ function imageLayoutShapes(sh, S, layout, img, items, points, isPh, fit, y0, y1)
|
|
|
620
630
|
sh.push(shape('rect', rxI, lyI + rowHI / 2 - 0.06, 0.12, 0.12, S.accent));
|
|
621
631
|
sh.push(txSp(rxI + 0.26, lyI, rwI - 0.3, rowHI - 0.04,
|
|
622
632
|
[[{ t: (pt[0] || '') + ' ', sz: fzI, b: 1, col: S.ink, font: S.font },
|
|
623
|
-
{ t: pt[1] || '', sz: fzI - 1, col: S.body, font: S.font }]], { anchor: 't' }));
|
|
633
|
+
{ t: pt[1] || '', sz: snapFont(fzI - 1), col: S.body, font: S.font }]], { anchor: 't' }));
|
|
624
634
|
});
|
|
625
635
|
capY = iy + Math.max(ihh, ih * 0.5);
|
|
626
636
|
} else if (layout === 'bleed') {
|
|
@@ -669,24 +679,55 @@ function hbarRows(sh, ec, S, y0, y1, dcols, x0, w) {
|
|
|
669
679
|
}
|
|
670
680
|
/* 竖柱 / 堆叠柱 */
|
|
671
681
|
function vbarShapes(sh, ec, S, x, y, w, h, dcols) {
|
|
672
|
-
|
|
682
|
+
/* Multi-series aware (mirrors lineShapes): ec.series[{name,values}] or single ec.values. */
|
|
683
|
+
var labels = ec.labels || [];
|
|
684
|
+
var series = (ec.series && ec.series.length)
|
|
685
|
+
? ec.series
|
|
686
|
+
: [{ name: '数值', values: ec.values || [] }];
|
|
673
687
|
var nb = Math.max(1, labels.length);
|
|
688
|
+
var ns = Math.max(1, series.length);
|
|
674
689
|
var baseY = y + h, plotW = w, step = plotW / nb;
|
|
675
|
-
var
|
|
676
|
-
var
|
|
677
|
-
var
|
|
690
|
+
var cluster = Math.min(1.1, step * (ns > 1 ? 0.78 : 0.55));
|
|
691
|
+
var bw = cluster / ns;
|
|
692
|
+
var all = [];
|
|
693
|
+
series.forEach(function (se) {
|
|
694
|
+
(se.values || []).forEach(function (v) { all.push(Number(v) || 0); });
|
|
695
|
+
});
|
|
696
|
+
var vmax = ec.max || Math.max.apply(null, all.concat([1]));
|
|
697
|
+
var top = all.length ? Math.max.apply(null, all) : 0;
|
|
678
698
|
sh.push(shape('rect', x, baseY, plotW, 0.02, S.line));
|
|
679
|
-
|
|
680
|
-
var
|
|
681
|
-
var
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
699
|
+
series.forEach(function (se, si) {
|
|
700
|
+
var vals = se.values || [];
|
|
701
|
+
var col = dcols ? dcols[si % 5] : (si === 0 ? S.accent : S.faint);
|
|
702
|
+
vals.forEach(function (v, i) {
|
|
703
|
+
var num = Number(v) || 0;
|
|
704
|
+
var hh = Math.max(0.05, num / vmax * (h - 0.5));
|
|
705
|
+
var bx = x + i * step + (step - cluster) / 2 + si * bw;
|
|
706
|
+
var hot = ns === 1 && num === top;
|
|
707
|
+
sh.push(shape('roundRect', bx, baseY - hh, Math.max(0.04, bw * 0.92), hh,
|
|
708
|
+
hot ? (dcols ? dcols[i % 5] : S.accent) : col, { adj: 6000 }));
|
|
709
|
+
if (ns === 1) {
|
|
710
|
+
sh.push(txSp(bx - 0.3, baseY - hh - 0.4, bw + 0.6, 0.32,
|
|
711
|
+
[[{ t: valText(num, ec.unit), sz: 12.5, b: 1, col: hot ? S.accent : S.body, font: S.font }]], { align: 'ctr' }));
|
|
712
|
+
}
|
|
713
|
+
});
|
|
689
714
|
});
|
|
715
|
+
labels.forEach(function (lb, i) {
|
|
716
|
+
var lx = x + i * step;
|
|
717
|
+
sh.push(txSp(lx, baseY + 0.08, step, 0.32,
|
|
718
|
+
[[{ t: lb, sz: 10.5, col: S.faint, font: S.font }]], { align: 'ctr' }));
|
|
719
|
+
});
|
|
720
|
+
/* Multi-series legend along top of plot (keeps category labels; avoids blank chart). */
|
|
721
|
+
if (ns > 1) {
|
|
722
|
+
var lx2 = x;
|
|
723
|
+
series.forEach(function (se, si) {
|
|
724
|
+
var col2 = dcols ? dcols[si % 5] : (si === 0 ? S.accent : S.faint);
|
|
725
|
+
sh.push(shape('rect', lx2, y, 0.12, 0.12, col2));
|
|
726
|
+
sh.push(txSp(lx2 + 0.16, y - 0.02, 1.4, 0.24,
|
|
727
|
+
[[{ t: String(se.name || ('系列' + (si + 1))), sz: 10, col: S.body, font: S.font }]]));
|
|
728
|
+
lx2 += 1.6;
|
|
729
|
+
});
|
|
730
|
+
}
|
|
690
731
|
}
|
|
691
732
|
/* 折线 / 双折线 / 面积 */
|
|
692
733
|
function lineShapes(sh, ec, S, x, y, w, h, dcols) {
|
|
@@ -1093,8 +1134,11 @@ function infoApprox(sh, sec, S, y0, y1) {
|
|
|
1093
1134
|
totals.push(tt);
|
|
1094
1135
|
}
|
|
1095
1136
|
var maxTot = Math.max.apply(null, totals.concat([1]));
|
|
1096
|
-
|
|
1097
|
-
var
|
|
1137
|
+
/* Reserve legend INSIDE the plot box so 6-series pages do not crush the annotation band. */
|
|
1138
|
+
var legH = Math.min(1.2, Math.max(0.28, series.length * 0.22 + 0.08));
|
|
1139
|
+
var plotBottom = P.y1 - legH;
|
|
1140
|
+
var plotH3 = Math.max(0.6, plotBottom - P.y0);
|
|
1141
|
+
var cyMid = P.y0 + plotH3 / 2;
|
|
1098
1142
|
var base = totals.map(function (tv) { return cyMid - tv / maxTot * plotH3 / 2; });
|
|
1099
1143
|
series.forEach(function (se, si) {
|
|
1100
1144
|
var upper = base.map(function (bv, i3) { return bv + (values[si][i3] || 0) / maxTot * plotH3 / 2; });
|
|
@@ -1104,12 +1148,12 @@ function infoApprox(sh, sec, S, y0, y1) {
|
|
|
1104
1148
|
sh.push(shape('rect', MX + i4 * stepX, (base[i4] + base[i4 + 1]) / 2, stepX, hgt, palette[si % palette.length]));
|
|
1105
1149
|
}
|
|
1106
1150
|
base = upper;
|
|
1107
|
-
sh.push(shape('rect', MX,
|
|
1108
|
-
sh.push(txSp(MX + 0.16,
|
|
1151
|
+
sh.push(shape('rect', MX, plotBottom + 0.04 + si * 0.2, 0.12, 0.12, palette[si % palette.length]));
|
|
1152
|
+
sh.push(txSp(MX + 0.16, plotBottom + 0.02 + si * 0.2, 1.5, 0.2,
|
|
1109
1153
|
[[{ t: String(se.name || ('系列' + (si + 1))), sz: 10, col: S.body, font: S.font }]], { anchor: 'ctr' }));
|
|
1110
1154
|
});
|
|
1111
1155
|
labels.forEach(function (lb, i5) {
|
|
1112
|
-
sh.push(txSp(MX + (nPts > 1 ? i5 / (nPts - 1) : 0.5) * CW - 0.4,
|
|
1156
|
+
sh.push(txSp(MX + (nPts > 1 ? i5 / (nPts - 1) : 0.5) * CW - 0.4, plotBottom - 0.22, 0.8, 0.2,
|
|
1113
1157
|
[[{ t: String(lb), sz: 9.5, col: S.faint, font: S.font }]], { align: 'ctr' }));
|
|
1114
1158
|
});
|
|
1115
1159
|
}
|
|
@@ -1301,8 +1345,8 @@ function slidesOf(model, S) {
|
|
|
1301
1345
|
var iy = iR.y;
|
|
1302
1346
|
var capH2 = img.caption ? 0.32 : 0;
|
|
1303
1347
|
var ih = Math.max(1.2, iR.h);
|
|
1304
|
-
imageLayoutShapes(sh, S, layout, img, items, sec.points || [], isPh, fit, iy, iy + ih);
|
|
1305
|
-
if (img.caption) sh.push(txSp(MX,
|
|
1348
|
+
var capYImg = imageLayoutShapes(sh, S, layout, img, items, sec.points || [], isPh, fit, iy, iy + ih);
|
|
1349
|
+
if (img.caption) sh.push(txSp(MX, capYImg + 0.04, CW, capH2, [[{ t: img.caption, sz: 10.5, col: S.faint, font: S.font }]]));
|
|
1306
1350
|
} else if (type === 'donut') {
|
|
1307
1351
|
var dcn = sec.chart || {};
|
|
1308
1352
|
if (dcn.labels && dcn.values) donutChart(sh, dcn, S, dcn.colors || donutColors(model.style, S, model.theme));
|
|
@@ -1619,7 +1663,7 @@ function slidesOf(model, S) {
|
|
|
1619
1663
|
sh.push(shape('rect', x, ly2 + rowHP / 2 - 0.06, 0.12, 0.12, S.accent));
|
|
1620
1664
|
sh.push(txSp(x + 0.28, ly2, w - 0.4, rowHP - 0.04,
|
|
1621
1665
|
[[{ t: pt[0] + ' ', sz: fzP, b: 1, col: S.ink, font: S.font },
|
|
1622
|
-
{ t: pt[1], sz: fzP - 1, col: S.body, font: S.font }]]));
|
|
1666
|
+
{ t: pt[1], sz: snapFont(fzP - 1), col: S.body, font: S.font }]]));
|
|
1623
1667
|
});
|
|
1624
1668
|
};
|
|
1625
1669
|
if (lt2 === 'table') {
|
|
@@ -1740,7 +1784,7 @@ function slidesOf(model, S) {
|
|
|
1740
1784
|
sh.push(shape('rect', ptsR.x, y11 + rowHPt / 2 - P2.markSize / 2, P2.markSize, P2.markSize, S.accent));
|
|
1741
1785
|
sh.push(txSp(ptsR.x + 0.32, y11, textW, rowHPt - 0.04,
|
|
1742
1786
|
[[{ t: p[0] + ' ', sz: fzP, b: 1, col: S.ink, font: S.font },
|
|
1743
|
-
{ t: p[1], sz: fzP - 1, col: S.body, font: S.font }]]));
|
|
1787
|
+
{ t: p[1], sz: snapFont(fzP - 1), col: S.body, font: S.font }]]));
|
|
1744
1788
|
});
|
|
1745
1789
|
if (hasM) {
|
|
1746
1790
|
var gx2 = PW - MX - nm2 * mw2;
|