一键导入
potx-to-marp-theme
Extract design tokens from .potx/.pptx PowerPoint templates into Marp CSS themes
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Extract design tokens from .potx/.pptx PowerPoint templates into Marp CSS themes
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
{what this skill teaches agents}
Apply an existing Marp theme to an existing deck without breaking theme-coupled slide content
Validate Marp themes with Marp CLI builds plus Playwright browser checks
| name | potx-to-marp-theme |
| description | Extract design tokens from .potx/.pptx PowerPoint templates into Marp CSS themes |
| domain | marp-theming |
| confidence | high |
| source | verbal (2026-05-11) |
Speaker-conference templates come as .potx (PowerPoint template) files. This skill captures the repeatable process for turning one into a working Marp CSS theme.
A .potx file is a ZIP archive. Unzip it to inspect design XML, extract color tokens, identify structural images, and map them to CSS variables.
# NOTE: /tmp is forbidden in this project. Use a path inside the repo.
mkdir -p slides/themes/.potx-extract
unzip -q "path/to/Template.potx" -d slides/themes/.potx-extract
Clean up after you're done:
rm -rf slides/themes/.potx-extract
ppt/theme/theme1.xmlThe key color nodes inside <a:clrScheme>:
dk1 → darkest text (usually windowText / #000000)
lt1 → lightest bg (usually window / #FFFFFF)
dk2 → primary dark background accent (a:srgbClr val="XXXXXX")
lt2 → secondary light background
accent1-6 → brand palette colors
hlink → hyperlink color
Use Python to extract quickly:
import re
with open('slides/themes/.potx-extract/ppt/theme/theme1.xml') as f:
data = f.read()
colors = re.findall(r'<a:srgbClr val="([A-Fa-f0-9]{6})"', data)
print(sorted(set(colors)))
In <a:fontScheme>:
<a:majorFont> → heading/display font (e.g., "Aptos Display")<a:minorFont> → body font (e.g., "Aptos")Map majorFont to the custom display font you're bringing in (e.g., DS Wallau).
Map minorFont → safe system font stack fallback.
import xml.etree.ElementTree as ET
# Resolve which images each layout uses via its _rels file
tree = ET.parse('slides/themes/.potx-extract/ppt/slideLayouts/_rels/slideLayout1.xml.rels')
root = tree.getroot()
for rel in root:
print(rel.attrib.get('Id'), rel.attrib.get('Target'))
Common pattern:
slideLayout1 = Title slide → typically uses 2 images (full-bg + decorative graphic)slideLayout2-3 = Section/content backgrounds → 1-2 imagesslideLayout4+ = Standard content → shared footer/accent stripWhen images carry brand color (not just stock photos), sample them:
import zlib, struct
def find_nonblack_colors(path, max_check=5000):
with open(path, 'rb') as f:
data = f.read()
w = struct.unpack('>I', data[16:20])[0]
h = struct.unpack('>I', data[20:24])[0]
color_type = data[25]
idat = b''
pos = 8
while pos < len(data) - 12:
length = struct.unpack('>I', data[pos:pos+4])[0]
chunk_type = data[pos+4:pos+8]
if chunk_type == b'IDAT':
idat += data[pos+8:pos+8+length]
pos += 12 + length
raw = zlib.decompress(idat)
bpp = 4 if color_type == 6 else 3
row_size = 1 + w * bpp
colors = {}
checked = 0
for i in range(h):
for x in range(0, w, max(1, w//50)):
px = i * row_size + 1 + x * bpp
r, g, b = raw[px], raw[px+1], raw[px+2]
a = raw[px+3] if bpp == 4 else 255
if a > 10 and (r > 5 or g > 5 or b > 5):
hex_c = f'#{r:02X}{g:02X}{b:02X}'
colors[hex_c] = colors.get(hex_c, 0) + 1
checked += 1
if checked > max_check:
break
if checked > max_check:
break
return sorted(colors.items(), key=lambda x: -x[1])[:10]
Large files (>1MB) are almost always stock photos — skip them.
Copy to slides/themes/<conference-name>/:
.emf vector files (not supported in CSS/HTML)Follow the custom-mitre-attack.css structure:
/* @theme custom-XXXX */@import 'default'; as base@font-face blocks for custom fonts (relative paths):root {} CSS variables for all design tokenssection base styles (font, size, padding, border-top accent)section.title, section.section, section.lead, section.invertnpx --yes @marp-team/marp-cli \
--theme-set slides/themes/custom-XXXX.css \
--output slides/preview.html \
slides/sample.md
A clean exit (no errors in stderr) confirms the CSS is valid and the theme registers correctly.
.emf files — not renderable in browser/CSSslides/themes/
├── custom-XXXX.css ← theme CSS (registered via --theme-set)
├── fonts/
│ └── CustomFont.ttf ← display font
└── XXXX/
├── title-bg.png ← title slide background
├── content-bg.png ← content slide background
├── footer-strip.jpg ← accent strip
└── logo.png ← conference logo
slides/
└── XXXX-sample.md ← sample deck for preview