skills/pptx-generation/SKILL.md
Generate academic PowerPoint presentations (.pptx) using python-pptx. Use this skill for making PPT, slides, presentations, 生成PPT, 做PPT, 写PPT, 幻灯片. Provides complete helper functions and templates. Preferred over scientific-slides and frontend-slides for all PPTX generation.
npx skillsauth add Zaoqu-Liu/ScienceClaw pptx-generationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Create publication-quality academic presentations (.pptx) for group meetings, thesis defenses, conference talks, and product introductions.
pip install -q python-pptx Pillow
ALWAYS write the ENTIRE script FIRST, then run it. NEVER send text before running the script.
The script MUST be self-contained. Install deps, define helpers, build slides, save — all in ONE bash call:
pip install -q python-pptx Pillow 2>/dev/null && python3 << 'PPTXEOF'
# === FULL SCRIPT HERE (see template below) ===
PPTXEOF
Academic palettes — pick ONE and use consistently:
THEMES = {
"lancet": {
"primary": (0x00, 0x46, 0x8B),
"accent": (0xED, 0x00, 0x00),
"accent2": (0x42, 0xB5, 0x40),
"light": (0xE8, 0xEE, 0xF4),
"text": (0x33, 0x33, 0x33),
"muted": (0x88, 0x88, 0x88),
},
"npg": {
"primary": (0x3C, 0x54, 0x88),
"accent": (0xE6, 0x4B, 0x35),
"accent2": (0x00, 0xA0, 0x87),
"light": (0xEE, 0xF0, 0xF5),
"text": (0x33, 0x33, 0x33),
"muted": (0x84, 0x91, 0xB4),
},
"nejm": {
"primary": (0x00, 0x72, 0xB5),
"accent": (0xBC, 0x3C, 0x29),
"accent2": (0x20, 0x85, 0x4E),
"light": (0xE6, 0xF0, 0xF8),
"text": (0x33, 0x33, 0x33),
"muted": (0x6F, 0x99, 0xAD),
},
}
Copy this entire template. Fill in the SLIDES list with actual content. Do not restructure the helpers — just fill in content.
from pptx import Presentation
from pptx.util import Inches, Pt, Emu
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
from pptx.dml.color import RGBColor
import os
# --- CONFIG ---
OUTPUT_DIR = os.path.expanduser("~/.scienceclaw/workspace")
os.makedirs(OUTPUT_DIR, exist_ok=True)
FILENAME = "presentation.pptx" # <-- change this
OUTPUT_PATH = os.path.join(OUTPUT_DIR, FILENAME)
THEME = "lancet" # lancet | npg | nejm
T = {
"lancet": {"p":(0,70,139),"a":(237,0,0),"a2":(66,181,64),"l":(232,238,244),"t":(51,51,51),"m":(136,136,136)},
"npg": {"p":(60,84,136),"a":(230,75,53),"a2":(0,160,135),"l":(238,240,245),"t":(51,51,51),"m":(132,145,180)},
"nejm": {"p":(0,114,181),"a":(188,60,41),"a2":(32,133,78),"l":(230,240,248),"t":(51,51,51),"m":(111,153,173)},
}[THEME]
def rgb(key): return RGBColor(*T[key])
prs = Presentation()
prs.slide_width = Inches(13.333)
prs.slide_height = Inches(7.5)
W, H = prs.slide_width, prs.slide_height
def add_shape(slide, left, top, w, h, fill=None):
s = slide.shapes.add_shape(1, left, top, w, h)
s.line.fill.background()
if fill: s.fill.solid(); s.fill.fore_color.rgb = RGBColor(*fill)
else: s.fill.background()
return s
def add_text(slide, left, top, w, h, text, size=18, bold=False, color="t", align=PP_ALIGN.LEFT, anchor=MSO_ANCHOR.TOP):
box = slide.shapes.add_textbox(left, top, w, h)
box.text_frame.word_wrap = True
p = box.text_frame.paragraphs[0]
p.text = text
p.font.size = Pt(size)
p.font.bold = bold
p.font.color.rgb = rgb(color)
p.alignment = align
box.text_frame.paragraphs[0].space_after = Pt(4)
return box
def add_bullets(slide, left, top, w, h, items, size=16, color="t"):
box = slide.shapes.add_textbox(left, top, w, h)
tf = box.text_frame
tf.word_wrap = True
for i, item in enumerate(items):
p = tf.paragraphs[0] if i == 0 else tf.add_paragraph()
p.text = item
p.font.size = Pt(size)
p.font.color.rgb = rgb(color)
p.space_after = Pt(8)
p.level = 0
return box
def title_slide(title, subtitle="", presenter=""):
s = prs.slides.add_slide(prs.slide_layouts[6])
add_shape(s, 0, 0, W, H, fill=T["p"])
add_shape(s, 0, Inches(5.2), W, Inches(2.3), fill=(max(0,T["p"][0]-20), max(0,T["p"][1]-20), max(0,T["p"][2]-20)))
add_text(s, Inches(1), Inches(1.8), Inches(11), Inches(2), title, size=40, bold=True, color="l", align=PP_ALIGN.LEFT)
if subtitle:
add_text(s, Inches(1), Inches(3.8), Inches(11), Inches(1), subtitle, size=22, color="l")
if presenter:
add_text(s, Inches(1), Inches(5.6), Inches(11), Inches(0.8), presenter, size=16, color="l")
return s
def section_slide(title):
s = prs.slides.add_slide(prs.slide_layouts[6])
add_shape(s, 0, 0, W, H, fill=T["l"])
add_shape(s, Inches(0.8), Inches(3.2), Inches(2), Pt(4), fill=T["p"])
add_text(s, Inches(0.8), Inches(1.8), Inches(11), Inches(1.5), title, size=36, bold=True, color="p")
return s
def content_slide(title, bullets, note=""):
s = prs.slides.add_slide(prs.slide_layouts[6])
add_shape(s, 0, 0, W, Inches(0.06), fill=T["p"])
add_text(s, Inches(0.8), Inches(0.4), Inches(11), Inches(1), title, size=28, bold=True, color="p")
add_shape(s, Inches(0.8), Inches(1.3), Inches(2), Pt(3), fill=T["a"])
add_bullets(s, Inches(0.8), Inches(1.6), Inches(11), Inches(4.8), bullets, size=18)
if note:
add_text(s, Inches(0.8), Inches(6.5), Inches(11), Inches(0.6), note, size=12, color="m")
return s
def two_col_slide(title, left_items, right_items, left_title="", right_title=""):
s = prs.slides.add_slide(prs.slide_layouts[6])
add_shape(s, 0, 0, W, Inches(0.06), fill=T["p"])
add_text(s, Inches(0.8), Inches(0.4), Inches(11), Inches(1), title, size=28, bold=True, color="p")
add_shape(s, Inches(0.8), Inches(1.3), Inches(2), Pt(3), fill=T["a"])
if left_title:
add_text(s, Inches(0.8), Inches(1.6), Inches(5.2), Inches(0.5), left_title, size=20, bold=True, color="p")
add_bullets(s, Inches(0.8), Inches(2.2), Inches(5.2), Inches(4.2), left_items, size=16)
if right_title:
add_text(s, Inches(7), Inches(1.6), Inches(5.2), Inches(0.5), right_title, size=20, bold=True, color="p")
add_bullets(s, Inches(7), Inches(2.2), Inches(5.2), Inches(4.2), right_items, size=16)
return s
def table_slide(title, headers, rows):
s = prs.slides.add_slide(prs.slide_layouts[6])
add_shape(s, 0, 0, W, Inches(0.06), fill=T["p"])
add_text(s, Inches(0.8), Inches(0.4), Inches(11), Inches(1), title, size=28, bold=True, color="p")
add_shape(s, Inches(0.8), Inches(1.3), Inches(2), Pt(3), fill=T["a"])
cols = len(headers)
tbl = s.shapes.add_table(len(rows)+1, cols, Inches(0.8), Inches(1.8), Inches(11.5), Inches(4.5)).table
for j, h in enumerate(headers):
c = tbl.cell(0, j); c.text = h
for p in c.text_frame.paragraphs:
p.font.size = Pt(14); p.font.bold = True; p.font.color.rgb = RGBColor(255,255,255)
c.fill.solid(); c.fill.fore_color.rgb = rgb("p")
for i, row in enumerate(rows):
for j, val in enumerate(row):
c = tbl.cell(i+1, j); c.text = str(val)
for p in c.text_frame.paragraphs:
p.font.size = Pt(13); p.font.color.rgb = rgb("t")
c.fill.solid(); c.fill.fore_color.rgb = RGBColor(*(T["l"] if i%2==0 else (255,255,255)))
return s
def end_slide(title, items=None):
s = prs.slides.add_slide(prs.slide_layouts[6])
add_shape(s, 0, 0, W, H, fill=T["p"])
add_text(s, Inches(1), Inches(2.5), Inches(11), Inches(2), title, size=36, bold=True, color="l", align=PP_ALIGN.CENTER)
if items:
add_bullets(s, Inches(2), Inches(4.2), Inches(9), Inches(2), items, size=18, color="l")
return s
# ============================================================
# FILL IN SLIDES BELOW — use the helpers above
# ============================================================
title_slide(
"Your Title Here",
subtitle="Subtitle line",
presenter="Author · Institution · Date",
)
content_slide("Slide Title", [
"• Bullet point one",
"• Bullet point two",
"• Bullet point three",
])
# ... add more slides using the helpers ...
end_slide("Thank You", ["[email protected]"])
# ============================================================
# SAVE
# ============================================================
prs.save(OUTPUT_PATH)
print(f"DONE: {OUTPUT_PATH} ({len(prs.slides)} slides)")
~/.scienceclaw/workspace/<descriptive-name>.pptxpython-pptx fails to install: tell the user to run pip install python-pptx on the hosttesting
Therapeutics Data Commons. AI-ready drug discovery datasets (ADME, toxicity, DTI), benchmarks, scaffold splits, molecular oracles, for therapeutic ML and pharmacological prediction.
tools
Genomic file toolkit. Read/write SAM/BAM/CRAM alignments, VCF/BCF variants, FASTA/FASTQ sequences, extract regions, calculate coverage, for NGS data processing pipelines.
development
Complete mass spectrometry analysis platform. Use for proteomics workflows feature detection, peptide identification, protein quantification, and complex LC-MS/MS pipelines. Supports extensive file formats and algorithms. Best for proteomics, comprehensive MS data processing. For simple spectral comparison and metabolite ID use matchms.
development
Multi-objective optimization framework. NSGA-II, NSGA-III, MOEA/D, Pareto fronts, constraint handling, benchmarks (ZDT, DTLZ), for engineering design and optimization problems.