Agent skill
presentations
Create slide presentations in multiple formats: Marp (Markdown, default), Beamer (LaTeX), Jupyter Notebook slides, and PowerPoint (python-pptx). Supports scientific, business, and developer content with math, code, charts, and tables. Converts existing documents into slides or creates from scratch. Auto-compiles to PDF/HTML/PPTX. Use this skill when the user requests: - Creating a presentation or slide deck - Converting a document, paper, or report into slides - Making conference talk, lecture, or meeting slides - Generating PowerPoint, PDF slides, or HTML slideshows - Beamer, Marp, reveal.js, or notebook slideshow creation
Install this agent skill to your Project
npx add-skill https://github.com/jkitchin/skillz/tree/main/skills/creative/presentations
SKILL.md
Purpose
Generate professional slide presentations from scratch or by converting existing documents. Supports four output formats covering academic, business, and developer use cases. Enforces slide layout best practices to prevent text overflow, cluttered slides, and poor readability.
When to Use
- User asks to create a presentation, slide deck, or talk
- User wants to convert a paper, report, outline, or notes into slides
- User requests a specific format: Beamer, Marp, Jupyter slides, or PowerPoint
- User asks for conference talk, lecture, or meeting slides
CRITICAL: Slide Layout Rules
These rules apply to ALL formats. Follow them by default. The user may override for specific slides (e.g., reference/appendix slides), but warn about readability.
Text Density Limits
- Max 6 bullet points per slide — if more content is needed, split across multiple slides
- Max ~40 words per slide body (excluding title) — slides are visual aids, not documents
- One core idea per slide — each slide should have a single takeaway message
- Bullet text max ~10 words each — use sentence fragments, not full sentences
Font Size Minimums
| Element | Beamer | Marp | PPTX | Jupyter |
|---|---|---|---|---|
| Title | \Large (24pt+) |
32px+ | Pt(28)+ | H1/H2 |
| Body text | \normalsize (11pt+) |
20px+ | Pt(18)+ | normal |
| Code | \small (10pt) |
16px+ | Pt(14)+ | cell default |
| Footnotes | \footnotesize (8pt) |
14px | Pt(12) | small |
Content-Specific Limits
- Code blocks: Max ~12 lines per slide. For longer code, split across slides or move to appendix
- Tables: Max ~5 data rows visible per slide. Paginate or simplify larger tables
- Images: Always specify explicit size constraints. Never let images overflow slide boundaries
- Equations: Max 2-3 display equations per slide. Use align environments for multi-line math
Whitespace and Margins
- Maintain at least 10% padding on all sides — do not fill every pixel
- Leave breathing room between elements (bullets, images, code blocks)
- Prefer visual balance over cramming content
Override Policy
If the user explicitly requests dense content (e.g., "make a reference slide with all parameters"), honor the request but:
- Reduce font sizes to the minimums above (never below)
- Add a note that the slide is intentionally dense
- Suggest splitting if it still overflows
Format Selection
Default: Marp (Markdown-based, exports to HTML/PDF/PPTX)
Use AskUserQuestion only if the user hasn't specified a format and the content strongly suggests a different one.
Format Decision:
├── Heavy LaTeX math / academic conference → Beamer
├── Live code demos / data science → Jupyter Notebook slides
├── Enterprise / editable by non-technical users → PowerPoint (python-pptx)
└── Everything else (default) → Marp
Instructions
Step 1: Gather Requirements
Before generating slides, determine:
- Topic and audience — what is the presentation about and who is it for?
- Format — use Marp unless user specifies otherwise or content suggests a better fit
- Slide count — ask if not specified; default to ~10-15 slides for a talk
- Content source — from scratch, or converting an existing document?
- Special needs — math, code, charts, animations, speaker notes?
If converting a document, read it first with the Read tool, then extract key points and organize into an outline before generating slides.
Step 2: Create Slide Outline
Before writing any slides, create a brief outline:
1. Title slide
2. Outline/Agenda
3-N. Content slides (one idea each)
N+1. Summary/Conclusions
N+2. Questions / Thank you
Present the outline to the user for approval before proceeding.
Step 3: Generate Slides
Use the appropriate format section below. Always apply the layout rules from the CRITICAL section.
Step 4: Auto-Compile
After writing the source file, compile to final output:
| Format | Command |
|---|---|
| Marp → PDF | npx @marp-team/marp-cli@latest --pdf --allow-local-files slides.md |
| Marp → HTML | npx @marp-team/marp-cli@latest --allow-local-files slides.md |
| Marp → PPTX | npx @marp-team/marp-cli@latest --pptx --allow-local-files slides.md |
| Beamer → PDF | latexmk -pdf presentation.tex |
| Beamer + minted | latexmk -pdf -shell-escape presentation.tex |
| Jupyter → HTML slides | jupyter nbconvert --to slides presentation.ipynb --post serve |
| PowerPoint | No compilation needed — python-pptx writes .pptx directly |
If a compilation tool is not installed, inform the user and provide the install command.
Format: Marp (Default)
Prerequisites
# Option 1: Use npx (no install, requires Node.js >= 18)
npx @marp-team/marp-cli@latest --version
# Option 2: Global install
npm install -g @marp-team/marp-cli
# Option 3: Homebrew
brew install marp-cli
Template
---
marp: true
theme: default
paginate: true
size: 16:9
style: |
section {
font-size: 20px;
}
h1 {
font-size: 36px;
}
h2 {
font-size: 30px;
}
code {
font-size: 16px;
}
table {
font-size: 18px;
}
---
<!-- _paginate: false -->
# Presentation Title
**Author Name**
Date | Event
---
## Outline
1. First topic
2. Second topic
3. Third topic
---
## Slide Title
- Key point one
- Key point two
- Key point three
<!-- Use fragment-style reveals sparingly -->
---
Key Features
Auto-fit headers (prevents title overflow):
<!-- fit -->
# This Long Title Will Auto-Scale to Fit
Background images:

# Split Layout
Content on the left, image on the right.
Image sizing (always constrain):



Math (KaTeX):
Inline: $E = mc^2$
$$
\nabla \cdot \mathbf{E} = \frac{\rho}{\epsilon_0}
$$
Code blocks (syntax highlighted automatically):
```python
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)
```
Two-column layout:
<div style="display: flex; gap: 40px;">
<div style="flex: 1;">
### Left Column
- Point A
- Point B
</div>
<div style="flex: 1;">
### Right Column
- Point C
- Point D
</div>
</div>
Speaker notes (only when requested):
<!--
Speaker notes go here.
These are not visible in the presentation.
-->
Overflow Prevention
- Use
<!-- fit -->before headings that might be too long - Set global
font-sizein the style block to control base size - Use
![width:Npx]or![height:Npx]for all images — never use unsized images - For dense tables, reduce font size locally:
<div style="font-size: 14px;">...</div> - Split content across slides rather than shrinking fonts below minimums
Compilation
# PDF output (most common)
npx @marp-team/marp-cli@latest --pdf --allow-local-files slides.md
# HTML output (interactive, good for sharing)
npx @marp-team/marp-cli@latest --allow-local-files slides.md -o slides.html
# PPTX output (note: slides are rasterized images, not editable)
npx @marp-team/marp-cli@latest --pptx --allow-local-files slides.md
Format: Beamer (LaTeX)
Prerequisites
# macOS
brew install --cask mactex
# Ubuntu/Debian
sudo apt install texlive-latex-extra latexmk
# For code highlighting with minted
pip install Pygments
Template
\documentclass[aspectratio=169]{beamer}
\usetheme{Madrid}
\usecolortheme{default}
% Prevent text overflow
\setbeamertemplate{frametitle}{\vspace{0.2cm}\insertframetitle}
% Code listings
\usepackage{listings}
\usepackage{xcolor}
\lstset{
basicstyle=\ttfamily\small,
keywordstyle=\color{blue},
commentstyle=\color{green!60!black},
stringstyle=\color{red},
frame=single,
breaklines=true,
breakatwhitespace=true,
postbreak=\mbox{\textcolor{red}{$\hookrightarrow$}\space},
numbers=left,
numberstyle=\tiny\color{gray}
}
% Graphics
\usepackage{graphicx}
% Math
\usepackage{amsmath,amssymb}
\title[Short Title]{Full Presentation Title}
\author{Author Name}
\institute{Institution}
\date{\today}
\begin{document}
\begin{frame}
\titlepage
\end{frame}
\begin{frame}{Outline}
\tableofcontents
\end{frame}
\section{Introduction}
\begin{frame}{Slide Title}
\begin{itemize}
\item First key point
\item Second key point
\item Third key point
\end{itemize}
\end{frame}
\end{document}
Key Features
Overlay animations:
\begin{frame}{Incremental Reveal}
\begin{itemize}
\item<1-> Always visible
\item<2-> Appears second
\item<3-> Appears third
\end{itemize}
\end{frame}
Two-column layout:
\begin{frame}{Side by Side}
\begin{columns}
\column{0.48\textwidth}
Left content here.
\column{0.48\textwidth}
\includegraphics[width=\textwidth]{figure.png}
\end{columns}
\end{frame}
Code blocks (use [fragile] on the frame):
\begin{frame}[fragile]{Code Example}
\begin{lstlisting}[language=Python]
def greet(name):
return f"Hello, {name}!"
\end{lstlisting}
\end{frame}
Math:
\begin{frame}{Equations}
The Schrödinger equation:
\begin{equation}
i\hbar\frac{\partial}{\partial t}\Psi = \hat{H}\Psi
\end{equation}
\end{frame}
Figures with size control:
\begin{frame}{Results}
\begin{figure}
\centering
\includegraphics[width=0.7\textwidth,height=0.5\textheight,keepaspectratio]{plot.png}
\caption{Always constrain both width and height.}
\end{figure}
\end{frame}
Blocks:
\begin{block}{Definition}
A concise definition here.
\end{block}
\begin{alertblock}{Warning}
Important caveat.
\end{alertblock}
\begin{exampleblock}{Example}
Illustrative example.
\end{exampleblock}
Speaker notes (only when requested):
\usepackage{pgfpages}
\setbeameroption{show notes on second screen=right}
\begin{frame}{Title}
Content here.
\note{Talking points for this slide.}
\end{frame}
Popular Themes
| Theme | Style | Best for |
|---|---|---|
| Madrid | Classic with navigation | General academic |
| Metropolis | Clean, modern, minimal | Modern talks |
| Berlin | Header navigation bar | Long talks |
| CambridgeUS | Red/blue accent | Formal conferences |
| default | Minimal, no decoration | When you want plain |
Overflow Prevention
- Use
[shrink]frame option as a last resort:\begin{frame}[shrink]{Title} - Constrain images:
\includegraphics[width=0.7\textwidth,height=0.5\textheight,keepaspectratio]{img} - Use
breaklines=truein lstset for code that might wrap - For dense slides, use
\smallor\footnotesizebut never below\scriptsize - Use
\resizebox{\textwidth}{!}{...}to scale a table to fit width
Compilation
# Standard
latexmk -pdf presentation.tex
# With minted code highlighting
latexmk -pdf -shell-escape presentation.tex
# Clean auxiliary files
latexmk -c
Format: Jupyter Notebook Slides
Prerequisites
pip install notebook nbconvert
# For live presentation mode (classic notebook only)
pip install RISE # notebook <= 6
pip install jupyterlab-rise # JupyterLab / notebook 7+
Creating Slides Programmatically
Use this approach to generate a notebook with slide metadata from Python:
import nbformat
nb = nbformat.v4.new_notebook()
# Title slide
title_cell = nbformat.v4.new_markdown_cell("# Presentation Title\n\n**Author** | Date")
title_cell.metadata["slideshow"] = {"slide_type": "slide"}
nb.cells.append(title_cell)
# Content slide with markdown
content_cell = nbformat.v4.new_markdown_cell(
"## Key Findings\n\n"
"- Finding one\n"
"- Finding two\n"
"- Finding three"
)
content_cell.metadata["slideshow"] = {"slide_type": "slide"}
nb.cells.append(content_cell)
# Code slide
code_cell = nbformat.v4.new_code_cell(
"import matplotlib.pyplot as plt\n"
"import numpy as np\n\n"
"x = np.linspace(0, 10, 100)\n"
"plt.plot(x, np.sin(x))\n"
"plt.title('Sine Wave')\n"
"plt.show()"
)
code_cell.metadata["slideshow"] = {"slide_type": "slide"}
nb.cells.append(code_cell)
# Save
nbformat.write(nb, "presentation.ipynb")
Cell Slide Types
| Type | Behavior | Use for |
|---|---|---|
slide |
New horizontal slide | Main content slides |
subslide |
Vertical sub-slide | Detail under a main slide |
fragment |
Appears incrementally | Reveals within a slide |
skip |
Hidden from presentation | Setup code, scratch work |
notes |
Speaker notes | Talking points (only when requested) |
- |
Continues previous slide | Output cells below code |
Key Features
- Live code execution during presentation (RISE only)
- Interactive widgets and plots remain functional
- Mix markdown, code, and output on the same slide
- Native syntax highlighting for code cells
Overflow Prevention
- Keep code cells to max ~10 lines — move setup code to
skipcells - Use
plt.figure(figsize=(8, 4))to control plot sizes explicitly - For markdown cells, follow the same bullet/word count limits
- Hide verbose output with
;at end of cell orskiptype for output-heavy cells - Use
--no-inputflag with nbconvert to hide code cells if showing only results
Compilation
# Static HTML slides
jupyter nbconvert --to slides presentation.ipynb
# Serve in browser immediately
jupyter nbconvert --to slides presentation.ipynb --post serve
# Hide code cells (output only)
jupyter nbconvert --to slides presentation.ipynb --no-input
Format: PowerPoint (python-pptx)
Prerequisites
pip install python-pptx
Template
from pptx import Presentation
from pptx.util import Inches, Pt, Emu
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN
# Load custom template if provided, otherwise use default
# prs = Presentation("template.pptx") # with template
prs = Presentation() # default
# --- Inspect available layouts (do this first with custom templates) ---
for i, layout in enumerate(prs.slide_layouts):
print(f"{i}: {layout.name}")
# --- Title Slide ---
slide = prs.slides.add_slide(prs.slide_layouts[0])
slide.shapes.title.text = "Presentation Title"
slide.placeholders[1].text = "Author | Date"
# --- Content Slide with Bullets ---
slide = prs.slides.add_slide(prs.slide_layouts[1])
slide.shapes.title.text = "Key Points"
tf = slide.placeholders[1].text_frame
tf.word_wrap = True
tf.text = "First bullet point"
for text, level in [("Second point", 0), ("Sub-point", 1), ("Third point", 0)]:
p = tf.add_paragraph()
p.text = text
p.level = level
p.font.size = Pt(18) if level == 0 else Pt(16)
prs.save("presentation.pptx")
Adding Images
slide = prs.slides.add_slide(prs.slide_layouts[5]) # Title Only
slide.shapes.title.text = "Results"
# Always specify position and size to prevent overflow
slide_width = prs.slide_width
slide_height = prs.slide_height
img_width = Inches(6)
img_height = Inches(4)
left = (slide_width - img_width) // 2 # center horizontally
top = Inches(1.5)
slide.shapes.add_picture("figure.png", left, top, img_width, img_height)
Adding Tables
slide = prs.slides.add_slide(prs.slide_layouts[5])
slide.shapes.title.text = "Data Summary"
rows, cols = 4, 3 # max ~5 data rows per slide
table_shape = slide.shapes.add_table(
rows, cols,
left=Inches(1), top=Inches(1.8),
width=Inches(8), height=Inches(3)
)
table = table_shape.table
# Header row
for col_idx, text in enumerate(["Metric", "Value", "Change"]):
cell = table.cell(0, col_idx)
cell.text = text
for paragraph in cell.text_frame.paragraphs:
paragraph.font.bold = True
paragraph.font.size = Pt(16)
# Data rows
data = [("Revenue", "$1.2M", "+15%"), ("Users", "50K", "+22%"), ("NPS", "72", "+5")]
for row_idx, row_data in enumerate(data, start=1):
for col_idx, text in enumerate(row_data):
cell = table.cell(row_idx, col_idx)
cell.text = text
for paragraph in cell.text_frame.paragraphs:
paragraph.font.size = Pt(14)
Adding Charts
from pptx.chart.data import CategoryChartData
from pptx.enum.chart import XL_CHART_TYPE
slide = prs.slides.add_slide(prs.slide_layouts[5])
slide.shapes.title.text = "Performance"
chart_data = CategoryChartData()
chart_data.categories = ["Q1", "Q2", "Q3", "Q4"]
chart_data.add_series("Revenue", (120, 150, 130, 175))
chart_frame = slide.shapes.add_chart(
XL_CHART_TYPE.COLUMN_CLUSTERED,
Inches(1), Inches(1.8), Inches(8), Inches(4.5),
chart_data
)
chart = chart_frame.chart
chart.has_legend = True
chart.has_title = True
chart.chart_title.text_frame.text = "Quarterly Revenue"
Custom Template Support
# Load a branded template
prs = Presentation("company_template.pptx")
# Inspect layouts to find the right ones
for i, layout in enumerate(prs.slide_layouts):
print(f"{i}: {layout.name}")
for ph in layout.placeholders:
print(f" Placeholder {ph.placeholder_format.idx}: {ph.name}")
# Use template layouts by index (indices depend on the template)
slide = prs.slides.add_slide(prs.slide_layouts[1])
Speaker Notes (only when requested)
from pptx.util import Pt
slide = prs.slides.add_slide(prs.slide_layouts[1])
notes_slide = slide.notes_slide
notes_tf = notes_slide.notes_text_frame
notes_tf.text = "Key talking points for this slide."
Overflow Prevention
- Always use
Inches()orPt()for positioning — never raw integers - Center images:
left = (prs.slide_width - img_width) // 2 - Set
text_frame.word_wrap = Trueon all text boxes - Cap font sizes: title
Pt(28), bodyPt(18), minimumPt(12) - For tables with many rows, paginate across slides automatically
- Validate positions: ensure
left + width <= prs.slide_widthandtop + height <= prs.slide_height
Document Conversion Workflow
When converting an existing document into slides:
Step 1: Read the Source
Use the Read tool to read the document. Supported inputs:
- Markdown (.md)
- LaTeX (.tex)
- Org-mode (.org)
- Plain text (.txt)
- PDF (extract key sections)
Step 2: Extract Key Points
Identify:
- Main thesis/argument
- Section headings → slide titles
- Key findings/results → bullet points (max 6 per slide)
- Figures/tables → dedicated slides
- Equations → math slides (max 2-3 per slide)
Step 3: Create Outline
Map document sections to slides. Apply the density rules — a paper section with 5 paragraphs may need 3-4 slides, not one.
Step 4: Generate and Compile
Follow the format-specific instructions above.
Figure Generation
For slides that need charts or figures:
Basic inline generation (matplotlib):
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots(figsize=(8, 4)) # explicit size for slides
x = np.linspace(0, 10, 100)
ax.plot(x, np.sin(x), linewidth=2)
ax.set_xlabel("x", fontsize=14)
ax.set_ylabel("sin(x)", fontsize=14)
ax.tick_params(labelsize=12)
fig.savefig("sine_plot.png", dpi=150, bbox_inches="tight")
plt.close()
For complex visualizations, use the python-plotting skill. For AI-generated images or diagrams, use the image-generation skill.
Requirements
Marp
- Node.js >= 18 (for npx/npm)
- Chrome, Edge, or Firefox (for PDF/PPTX export — used headlessly)
Beamer
- TeX Live, MiKTeX, or MacTeX (full LaTeX distribution)
latexmk(included with TeX Live)- Pygments (
pip install Pygments) for minted code highlighting
Jupyter Notebook Slides
notebookandnbconvert(pip install notebook nbconvert)- Optional:
RISEorjupyterlab-risefor live presentations
PowerPoint
python-pptx(pip install python-pptx)- No system dependencies
Examples
Example 1: Conference Talk (Marp)
User request: "Make a 10-slide presentation about machine learning in materials science"
Expected behavior:
- Use AskUserQuestion to confirm audience and any specific topics to cover
- Create outline with 10 slides: title, outline, 6 content, summary, questions
- Write Marp markdown with
theme: default,size: 16:9, proper font sizes - Include math for key equations, code for example workflows
- Apply layout rules: max 6 bullets, ~40 words per slide
- Compile to PDF:
npx @marp-team/marp-cli@latest --pdf --allow-local-files slides.md
Example 2: Paper Conversion (Beamer)
User request: "Convert my paper draft.tex into a 20-minute conference talk"
Expected behavior:
- Read draft.tex with Read tool
- Extract key contributions, figures, and equations
- Create outline: ~15 slides for 20 minutes (1-1.5 min per slide)
- Generate Beamer .tex file reusing figures from the paper directory
- Apply layout rules: one idea per slide, max 2-3 equations per slide
- Compile:
latexmk -pdf presentation.tex
Example 3: Business Report (PowerPoint)
User request: "Create a PowerPoint for my quarterly review with sales data"
Expected behavior:
- Ask about data source and key metrics
- Generate python-pptx script with title slide, data slides, chart slides, summary
- Create charts using CategoryChartData for sales figures
- Use proper font sizes (Pt(28) titles, Pt(18) body)
- Save directly as .pptx — no compilation needed
Example 4: Interactive Demo (Jupyter)
User request: "Make a notebook slideshow demonstrating pandas data analysis"
Expected behavior:
- Create notebook with nbformat, setting slide_type metadata
- Include code cells with live-executable pandas examples
- Add markdown cells for explanations (following density limits)
- Mark setup/import cells as
skiptype - Export:
jupyter nbconvert --to slides presentation.ipynb
Limitations
- Marp PPTX export produces rasterized slides — text is not editable in PowerPoint
- python-pptx cannot render slides — visual verification requires opening in PowerPoint or LibreOffice
- Beamer compilation requires a full LaTeX distribution (several GB)
- Jupyter RISE only works with classic notebook (<= v6); JupyterLab needs jupyterlab-rise
- Speaker notes are only generated when explicitly requested
Related Skills
- python-plotting — for complex chart and visualization generation
- image-generation — for AI-generated images and diagrams
- scientific-writing — for academic content structuring and LaTeX guidance
Didn't find tool you were looking for?