Documents

ppt-style-matcher

Try it

v4.1: 全局色板提取+智能采样颜色多样性+P0-P3验证+深色适配+sldIdLst重建法

What it does

**核心思路**:分析原PPT风格 → 锁定配色/字体/布局参数 → 用python-pptx生成新页面 → 完全重建sldIdLst → P0-P3分级验证 ⚠️ **v4.1关键改进**:色板提取用全局颜色频率(不再依赖采样页偏差)、智能采样增加颜色多样性、深色PPT文字色修正

The skill document

PPT风格匹配技能 v4.1

核心思路:分析原PPT风格 → 锁定配色/字体/布局参数 → 用python-pptx生成新页面 → 完全重建sldIdLst → P0-P3分级验证

⚠️ v4.1关键改进:色板提取用全局颜色频率(不再依赖采样页偏差)、智能采样增加颜色多样性、深色PPT文字色修正


⛔ 强制约束(7条,不可跳过)

#规则说明
R1颜色锁定只允许使用从原PPT提取的5色+2文字色,禁止编造hex
R2字体锁定三级分工(标题/正文/注释),禁止换字体
R3布局计算先行禁止凭感觉填坐标,所有位置必须从公式计算
R4只用形状+文本禁止外部图片、禁止pptxgenjs(它会丢中文和关系)
R5间距保护分栏间距0.6-1.0cm,内容距底≥0.15cm
R6每页≥20个shape低于此数为简单文本页,需重设计
R7验证读回生成完毕必须用python-pptx读回+validate_layout()检查

第一步:需求澄清(6问法,借鉴guizang)

在动手之前,先回答6个问题。不回答完不开始。

  1. 目标页:修改哪些页?(页码范围)
  2. 修改类型:新增页?替换页?还是美化已有页?
  3. 内容来源:内容是已存在的还是需要我搜索整理?
  4. 风格参考:是否有参考页?(如"像第8页那样的风格")
  5. 特殊要求:有无特殊布局需求?(如"数据要突出""要有流程图")
  6. 输出路径:修改后的文件保存到哪里?

第二步:风格分析

运行 scripts/analyze_style.py 提取风格参数:

python3 scripts/analyze_style.py  [--verbose]

必须确认以下参数后再继续(防幻觉):

2.1 5色锁定色板

脚本自动提取,输出格式:

COLOR_PRIMARY: #22C55E   ← 主色,最高频非白非黑填充色
COLOR_SECONDARY: #374151  ← 辅色,中性色优先(深灰/深蓝/深绿)
COLOR_ACCENT: #C00000     ← 强调色,高饱和色优先(红/橙/蓝)
COLOR_BG: #FFFFFF          ← 背景色
COLOR_TEXT: #1F2937        ← 主文字色(浅色PPT选深色,深色PPT选浅色)
COLOR_TEXT_LIGHT: #4B5563  ← 辅文字色
IS_DARK_THEME: False       ← 是否深色主题

⚠️ v4改进:

  • 深色PPT自动检测,TEXT色适配(选白色/浅灰而非红色)
  • SECONDARY优先中性色,ACCENT优先高饱和色,不再角色倒挂
  • 默认采样改为智能选择设计良好的页面(shape≥20优先)

2.2 字体三级分工

按字号范围推断:

  • 标题字体:≥20pt 的最高频字体
  • 正文字体:14-19pt 的最高频字体
  • 注释字体:<14pt 的最高频字体

⚠️ 如果三个级别是同一字体(常见于中文PPT),标题用加粗、正文用常规即可。

2.3 布局参数

从 --verbose 输出中提取:

  • MARGIN_L / MARGIN_R:左右安全边距
  • HEADER_H:标题区高度
  • FOOTER_H:底部装饰条高度
  • CONTENT_X/Y/W/H:内容区范围
  • has_left_right_split:是否左右分栏及比例
  • is_simple_page:是否简单页(shape<10,布局参数无参考价值)

⚠️ v4改进:简单页(shape<10)的布局参数自动清空,避免误导。参考页推荐在分析结果末尾输出。

2.4 节奏感

脚本自动检测节奏,根据PPT类型切换策略:

  • 深色/混合PPT:检测连续深/浅色页面,≥3页连续报视觉疲劳
  • 浅色PPT(>85%浅色页):检测章节分隔页间距和连续稀疏页,不再误报"连续浅色"

⚠️ v4改进:浅色PPT不再报"连续37页浅色=视觉疲劳",改用结构节奏检测。


第三步:内容确定

  1. 用python-pptx读取目标页的纯文本内容
  2. 如需新增内容,搜索整理后写入
  3. 按内容量选择合适的布局模式(见 design-patterns.md)

第四步:布局计算(核心!)

所有坐标必须从公式算出,禁止硬编码。

基础参数(从第二步提取)

SLIDE_W = 33.87  # cm, 从分析结果
SLIDE_H = 19.05  # cm
MARGIN_L = 2.1
MARGIN_R = 1.8
HEADER_H = 3.5   # 标题区
FOOTER_H = 3.0   # 底部装饰条(如有)

CONTENT_X = MARGIN_L
CONTENT_Y = HEADER_H + 0.5  # 标题下方0.5cm
CONTENT_W = SLIDE_W - MARGIN_L - MARGIN_R
CONTENT_H = SLIDE_H - CONTENT_Y - FOOTER_H - 0.3

双栏布局公式

GAP = 0.8  # 分栏间距,0.6-1.0cm范围

# 根据内容量选择比例
# 文字密集 → 0.58 | 适中 → 0.6 | 精简 → 0.5
ratio_left = 0.6

LEFT_W  = (CONTENT_W - GAP) * ratio_left
RIGHT_W = (CONTENT_W - GAP) * (1 - ratio_left)
LEFT_X  = CONTENT_X
RIGHT_X = CONTENT_X + LEFT_W + GAP

# ⚠️ 验证:LEFT_X + LEFT_W + GAP + RIGHT_W 应 ≈ CONTENT_X + CONTENT_W

三栏布局公式

COL3_GAP = 0.6
COL3_W = (CONTENT_W - 2 * COL3_GAP) / 3
COL3_X = [CONTENT_X + i * (COL3_W + COL3_GAP) for i in range(3)]

卡片内部结构

# 左装饰条
DECOR_W = 0.2  # cm
decor_x = card_x
decor_w = DECOR_W
decor_h = card_h

# 标题
title_x = card_x + DECOR_W + 0.2
title_w = card_w - DECOR_W - 0.4
title_pt = 14  # 三级标题

# 描述
desc_x = title_x
desc_w = title_w
desc_pt = 12  # 注释字号

第五步:节奏感规划

参考第二步的节奏感检测结果:

  • 如果目标页前后都是浅色页,考虑给新页加一个深色强调元素
  • 连续新增多页时,交替使用深色和浅色背景
  • 深色页定义:深色面积占比 > 25%

第六步:python-pptx创建新页面

6.1 创建shape的标准代码

from pptx import Presentation
from pptx.util import Cm, Pt, Emu
from pptx.enum.text import PP_PARAGRAPH_ALIGNMENT
from pptx.dml.color import RGBColor

# ⚠️ PP_PARAGRAPH_ALIGNMENT 用法:
# PP_PARAGRAPH_ALIGNMENT.LEFT    左对齐
# PP_PARAGRAPH_ALIGNMENT.CENTER  居中
# PP_PARAGRAPH_ALIGNMENT.RIGHT   右对齐
# PP_PARAGRAPH_ALIGNMENT.JUSTIFY 两端对齐
# 不要用 pp.ALIGN_LEFT 等旧写法!

def add_shape(slide, left, top, width, height, fill_color=None):
    """添加矩形shape"""
    shape = slide.shapes.add_shape(
        1,  # MSO_SHAPE.RECTANGLE
        Cm(left), Cm(top), Cm(width), Cm(height)
    )
    shape.line.fill.background()  # 无边框
    
    if fill_color:
        shape.fill.solid()
        shape.fill.fore_color.rgb = RGBColor.from_string(fill_color)
    
    return shape

def add_textbox(slide, left, top, width, height, text, font_name='Noto Sans SC',
                font_size=14, bold=False, color='1F2937', align='left'):
    """添加文本框"""
    txBox = slide.shapes.add_textbox(
        Cm(left), Cm(top), Cm(width), Cm(height)
    )
    tf = txBox.text_frame
    tf.word_wrap = True
    
    p = tf.paragraphs[0]
    p.text = text
    
    # 对齐方式
    align_map = {
        'left': PP_PARAGRAPH_ALIGNMENT.LEFT,
        'center': PP_PARAGRAPH_ALIGNMENT.CENTER,
        'right': PP_PARAGRAPH_ALIGNMENT.RIGHT,
        'justify': PP_PARAGRAPH_ALIGNMENT.JUSTIFY,
    }
    p.alignment = align_map.get(align, PP_PARAGRAPH_ALIGNMENT.LEFT)
    
    run = p.runs[0]
    run.font.name = font_name
    run.font.size = Pt(font_size)
    run.font.bold = bold
    run.font.color.rgb = RGBColor.from_string(color)
    
    # ⚠️ 设置东亚字体(解决中文渲染问题)
    set_ea_font(run, font_name)
    
    return txBox

6.2 中文字体处理方案(必做!)

from scripts.analyze_style import set_ea_font, set_line_spacing, clean_shape

# 每个文字run都必须设置东亚字体
run.font.name = "Noto Sans SC"  # 西文字体
set_ea_font(run, "Noto Sans SC")  # 东亚字体(必做!)

# 显式设置行距
p = tf.paragraphs[0]
set_line_spacing(p, font_size_pt=14, ratio=1.35)

# 创建shape后清理自动样式
shape = add_shape(...)
clean_shape(shape)

⚠️ 踩坑记录:PP_PARAGRAPH_ALIGNMENT 是枚举类,不是模块常量。正确写法是 PP_PARAGRAPH_ALIGNMENT.LEFT,不是 PP_PARAGRAPH_ALIGNMENT.LEFT 从 pptx.enum 直接导入。


第七步:替换、排序、残留修复

7.1 sldIdLst操作(⚠️ 最大坑!必须用完全重建法)

python-pptx 的 slide 顺序由 presentation.xml 中的 `` 控制。 不能用 addprevious/addnext 连续操作(索引会变导致顺序错乱)。 唯一可靠方法:清空sldIdLst → 按新顺序append。

from lxml import etree

# ✅ 正确的API(python-pptx没有 prs.presentation.sldIdLst 属性!)
ns = '{http://schemas.openxmlformats.org/presentationml/2006/main}'
sldIdLst = prs.part._element.find(f'{ns}sldIdLst')

# 1. 创建新slide(python-pptx会自动追加到末尾)
for i in range(4):  # 4页新slide
    prs.slides.add_slide(prs.slide_layouts[6])

# 2. 记录当前sldIdLst的所有元素
all_ids = list(sldIdLst)

# 3. 确定新的页面顺序
# 假设:原PPT有63页,新4页在末尾(-4),要替换第2-5页(index 1-4)
new_ids = all_ids[-4:]          # 新页面
keep_ids = [all_ids[0]] + all_ids[5:-4]  # 第1页 + 第6-63页

desired_order = keep_ids[:1] + new_ids + keep_ids[1:]
# 结果:[原1, 新1, 新2, 新3, 新4, 原6, 原7, ..., 原63]

# 4. 完全重建sldIdLst(⚠️ 不要用addprevious/addnext!)
for sid in list(sldIdLst):
    sldIdLst.remove(sid)
for sid in desired_order:
    sldIdLst.append(sid)

# 5. 保存
prs.save(output_path)

⚠️ 常见错误:

  • prs.presentation.sldIdLst → API不存在,必须用 prs.part._element.find()
  • sldIdLst.insert(idx, elem) → lxml虽然支持,但连续insert索引会变
  • 只删除sldId但不删除底层slide part → 文件会膨胀(目前未自动清理)

7.2 模板残留修复

扫描所有页文字,替换模板残留关键词:

RESIDUAL_KEYWORDS = ['OPPO', 'Tony', 'Alen', '逍遥子', '逍遥子班']
REPLACEMENTS = {
    'OPPO': '国药太极',
    'Tony': '导师A',
    'Alen': '导师B',
    '逍遥子班': '领航班',
    '逍遥子': '领航',
}

for slide in prs.slides:
    for shape in slide.shapes:
        if shape.has_text_frame:
            for para in shape.text_frame.paragraphs:
                for run in para.runs:
                    for old, new in REPLACEMENTS.items():
                        if old in run.text:
                            run.text = run.text.replace(old, new)

第八步:P0-P3分级质检

8.1 自动验证(脚本)

from scripts.analyze_style import validate_layout

result = validate_layout(
    prs,
    slide_indices=[1, 2, 3, 4],  # 新增/修改的页索引(0-based)
    palette=palette,              # 5色色板
    residual_keywords=['OPPO', 'Tony', 'Alen'],  # 残留关键词
)

print(f"P0通过: {result['passed']}")
for level in ['P0', 'P1', 'P2', 'P3']:
    if result[level]:
        print(f"\n{level}问题:")
        for issue in result[level]:
            print(f"  - {issue}")

8.2 分级标准

级别类型检查项不通过后果
P0阻断级越界/图片shape/shape<20/残留关键词不交付
P1功能级颜色一致性/底部留白/文字溢出需修复
P2品质级间距均匀/对齐/标题统一建议修复
P3润色级节奏感/信息密度/装饰元素可选

v4.1 修复/改进清单

问题修复影响
智能采样只看shape数量,选出的页颜色偏红新增颜色多样性加分+贪心算法确保颜色覆盖色板无偏差
色板提取只用采样页频率(采样偏差)PRIMARY等核心角色改用全局颜色频率色板准确
validate_color_usage缩进bug(只检查最后一个slide)for循环体修正缩进P1颜色验证生效
SKILL.md sldIdLst API过时改为完全重建法 + prs.part._element.find()代码可运行
深色PPT TEXT色被识别为强调色检测深色主题后TEXT优先选浅色色板正确
SECONDARY/ACCENT角色倒挂SECONDARY优先中性色,ACCENT优先高饱和色角色语义正确
默认采样4页中3页是简单页智能采样:优先shape≥20的设计良好页+颜色多样性色板质量提升
简单页布局参数误导shape<10标记为简单页,清空布局参数避免误导
浅色PPT报"连续37页浅色=视觉疲劳"浅色PPT切换为结构节奏检测不误报
缺少参考页推荐analyze_ppt自动输出参考页免手动选择
validate_layout坐标计算bug改为Emu(left + width)越界检测准确
design-patterns.md缺sldIdLst操作指南新增第十节:清空+按序重建法最少踩坑

v3.1 修复清单(已包含在v4中)

问题修复影响
全屏背景色块被误判为"顶部装饰条"新增 _is_fullscreen_shape() 过滤布局参数准确
节奏感警告重复滑动窗口找最长连续区间输出简洁
5色色板PRIMARY和TEXT重复区分填充色和文字色角色色板可用
ACCENT提取到极浅色bg_colors排除 + 亮度>240跳过强调色有意义
字体三级分工只有1个字体按字号范围推断三级信息完整
底部装饰条全部0.0降低检测阈值可检测到
validate_layout不存在新增完整函数可用
PP_PARAGRAPH_ALIGNMENT用法未说明新增代码模板避免枚举错误
shape位置为None时崩溃统一过滤None位置shape稳定

文件结构

ppt-style-matcher/
├── SKILL.md                      # 本文件 (v4)
├── scripts/
│   └── analyze_style.py          # 风格分析工具 v4
└── references/
    └── design-patterns.md        # 设计模式参考

analyze_style.py 导出函数

函数用途
analyze_ppt(path, pages, verbose)完整风格分析(入口函数,含参考页推荐)
extract_color_palette(prs, pages)5色锁定色板提取(v4:深色适配+角色修正)
analyze_layout_ratios(slide, prs)单页布局比例参数(v4:简单页跳过)
analyze_rhythm(prs, pages)节奏感检测(v4:浅色PPT结构节奏)
validate_color_usage(prs, palette, indices)颜色一致性验证(v4:修复缩进bug)
validate_layout(prs, indices, palette, keywords)P0-P3分级质检
_is_dark_ppt(prs, pages)判断深色主题
_pick_best_sample_pages(prs, count)智能采样(优先设计良好页)
set_ea_font(run, font_name)设置东亚字体(辅助)
set_line_spacing(paragraph, pt, ratio)设置行距(辅助)
clean_shape(shape)清理自动样式(辅助)

Related skills

Generate and edit Draw.io, Mermaid, and Excalidraw diagrams from natural language using a structured JSON spec.

by nssa.io1.0k installs47 stars

Fetch raw ad creative, app, ranking, and revenue data from AdMapix as structured JSON.

by fly0pants4.3k installs296 stars

Join a video meeting as an AI bot with voice, avatar, and screenshare across four operating modes.

by johnpatternai22 installs8 stars

Find why your productivity system keeps failing, then apply the smallest fix — capacity math, bottleneck routing, durable local notes.

by Iván855 installs69 stars

Stores durable facts in a categorized, plain-markdown vault on disk, alongside your agent's built-in memory.

by Iván559 installs18 stars

More from tuobadaidai

Browse all skills

Convert fuzzy organizational problems into structured diagnostic reports with graded recommendations.

by tuobadaidai34 installs1 stars

Convert vague strategic questions into structured analysis with framework selection, audit gates, and explicit trade-offs.

by tuobadaidai15 installs

Grade AI-era candidates on a six-dimension L1–L4 scale from resumes and interview notes.

by tuobadaidai22 installs

工资数据审核系统,基于确定性规则引擎 + Python 脚本执行。 全量对齐《工资审核标准流程 SOP》6 步流程。v7.2 修复P0阻断bug:_get_pay_month() 支持 中文格式("2026年4月"/"2026年04月"/"202604"),RL-003/RL-007 排除逻辑完全生效。 v7.1...

by tuobadaidai30 installs

谛听培训专家。培训需求分析、培训方案设计、效果评估、能力建设。Use when 培训需求分析、培训方案设计、培训效果评估、能力建设体系、管理者赋能、新员工培训、领导力培训、技能培训体系、培训预算规划。不适用于薪酬结构、劳动法合规、绩效考核等非培训类问题。

by tuobadaidai21 installs

创建高质量 Skill 的技能。当用户说"创建技能""新建 Skill""把这个流程变成技能""做一个 XX 的 skill""帮我写个技能"时触发。不适用于使用已有技能执行任务——那是 use_skill 的工作。

by tuobadaidai17 installs1 stars