skills/ppt-station-skill/ppt_station/composer/layouts/diagram.py
wangyitong a65adcc2e5 Initial commit: merged, deduplicated, and vetted skill collection
Sources: extracted from two upstream archives (skill-repo, skills-main),
merged with the following policy:

- 15 broken symlinks (pointing to /Users/jameslee/.cc-switch/skills or
  ../../.agents/skills on a foreign machine) discarded
- 3 real name collisions with identical content (ai-pair, ifind-http-api,
  zhipu-websearch) kept as one copy
- Functional overlaps deduped keeping the strongest variant:
  - docx family: kept docx (official, full toolchain) + docx-cn
    (GB/T 9704 Chinese official-document constants),
    dropped docx_writer (no scripts, name collided with docx)
  - humanizer family: kept humanizer-zh (6 zh reference docs),
    dropped humanizer (en, redundant for CN workflow)
- Skills that only ran in a foreign environment removed:
  ablemind-ops, app-publish, hlb-design-system, openclaw-adj-skill,
  claude-driver
- alphapai excluded from this public repo because its SKILL.md hard-coded
  live credentials

Result: 25 skills, 572 files, ~7.5 MB.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 14:47:12 +08:00

147 lines
4.8 KiB
Python

"""图表布局 — 基于 blocks 的可组合页面
提供两类布局:
1. 单 block 快捷布局 (layout_process_flow, layout_timeline, ...)
2. 自由组合布局 (layout_composite) — 在一页上放置多个 blocks
"""
from ..helpers import setup_content_page
from ..blocks import BLOCK_REGISTRY, render_block
# ── 通用: 单 block 页面渲染 ──────────────────────────────────────────
def _single_block_page(slide, data, theme, block_type):
"""通用模式: 页面框架 + 单个 block 填满内容区域"""
m, sw, content_y, content_w, footer_y = setup_content_page(slide, data, theme)
block_data = {k: v for k, v in data.items() if k not in ("title", "footnote")}
fn = BLOCK_REGISTRY[block_type]
fn(slide, block_data, theme,
x=m, y=content_y, w=content_w, h=footer_y - content_y - 0.15)
# ── 快捷布局 ─────────────────────────────────────────────────────────
def layout_process_flow(slide, data, theme):
"""流程图页 — 步骤框 + 箭头连接
data keys:
title (str): 页面标题
items (list): [{"label": str, "desc": str?, "icon": str?}]
direction (str): "horizontal" | "vertical" (默认 horizontal)
style (str): "box" | "chevron" (默认 box)
footnote (str, optional): 脚注
"""
_single_block_page(slide, data, theme, "process_flow")
def layout_timeline(slide, data, theme):
"""时间线页 — 水平轴 + 上下交替的里程碑
data keys:
title (str): 页面标题
items (list): [{"date": str, "label": str, "desc": str?}]
footnote (str, optional): 脚注
"""
_single_block_page(slide, data, theme, "timeline")
def layout_pyramid(slide, data, theme):
"""金字塔页 — 从上到下逐层加宽
data keys:
title (str): 页面标题
items (list): [{"label": str, "desc": str?}] (从塔尖到塔底)
inverted (bool): True 则为漏斗(上宽下窄)
footnote (str, optional): 脚注
"""
_single_block_page(slide, data, theme, "pyramid")
def layout_comparison(slide, data, theme):
"""对比栏页 — 2~4 列并排对比
data keys:
title (str): 页面标题
columns (list): [{"title": str, "items": [str], "highlight": bool?}]
footnote (str, optional): 脚注
"""
_single_block_page(slide, data, theme, "comparison")
def layout_icon_grid(slide, data, theme):
"""图标网格页 — 网格排列的图标+文字卡片
data keys:
title (str): 页面标题
items (list): [{"icon": str, "label": str, "desc": str?}]
cols (int, optional): 列数
footnote (str, optional): 脚注
"""
_single_block_page(slide, data, theme, "icon_grid")
def layout_matrix(slide, data, theme):
"""2x2 矩阵/象限页
data keys:
title (str): 页面标题
quadrants (list): 4 项 [{"label": str, "desc": str?}]
x_label (str, optional): X 轴标签
y_label (str, optional): Y 轴标签
footnote (str, optional): 脚注
"""
_single_block_page(slide, data, theme, "matrix")
# ── 自由组合布局 ─────────────────────────────────────────────────────
def layout_composite(slide, data, theme):
"""自由组合页 — 在一页上放置多个 blocks
data keys:
title (str): 页面标题
blocks (list): [
{
"type": str, # BLOCK_REGISTRY 中的名称
"area": [x, y, w, h], # 渲染区域(英寸)
... # 其余字段透传给 block
},
...
]
footnote (str, optional): 脚注
示例 — 上半部流程图 + 下半部左金字塔右对比:
{
"title": "投资分析框架",
"blocks": [
{
"type": "process_flow",
"area": [0.6, 1.0, 12.1, 2.2],
"items": [...]
},
{
"type": "pyramid",
"area": [0.6, 3.5, 5.5, 3.5],
"items": [...]
},
{
"type": "comparison",
"area": [6.5, 3.5, 6.2, 3.5],
"columns": [...]
}
]
}
"""
from ..helpers import set_slide_bg, add_page_header
m = theme["margin"]
sw = theme.get("slide_w", 13.333)
set_slide_bg(slide, theme["bg_light"])
add_page_header(slide, data["title"], theme)
for block_spec in data["blocks"]:
render_block(slide, block_spec, theme)