A teaching deck workflow based on Professor Li Junyi's SOIL teaching principles. Six engines, one clear path: first think clearly about what to teach, then arrange how to teach it, and only finally handle how to present it.
Theory summary: The six SOIL engines are, in order, concept positioning(what to teach, what the core concept is) → context positioning(where students are, why they need to learn it) → page architecture(what role each page plays) → cognitive editing(reduce cognitive load, one message per page) → style construction(font sizes, color scheme, visual consistency) → output(generate the .pptx and do QA). Each chapter of this document unfolds according to these six engines; no external theory files need to be read separately.
Step 1: Determine the work mode
After receiving the user's request, do not start working directly. First determine the work mode through one question.
Ask the user (ask only this one question):
What is your current situation?
- I have materials (text, teaching materials, documents) and want to turn them into a teaching deck
- I have an existing presentation (.pptx) and want to improve it
- I only have a topic and want to start from scratch
- I want to define a presentation style (YAML) for repeated use later
Based on the answer, enter the corresponding path:
| Answer | Work mode | Which engines to run |
|---|---|---|
| 1 | Full workflow mode | Engines 1→2→3→4→5→6 |
| 2 | Diagnose and revise mode | Engine 4 (+3 to fill in page roles) → revise the .pptx |
| 3 | Full workflow mode | First help gather materials → Engines 1→2→3→4→5→6 |
| 4 | Style definition mode | Engine 5 |
If the user's request is already very clear (for example, they directly paste a large chunk of teaching material and say "turn it into a presentation"), you may skip this question and go directly into full workflow mode, but before entering Engine 1, first ask the details needed for Engine 1.
Step 2: Before entering each engine, ask the key details
Do not ask all the questions at once. Before entering the corresponding engine, ask only the minimum information that engine needs.
Before entering Engine 1, ask:
Regarding this teaching deck, I need to confirm two things:
- Who is the teaching audience?(for example: junior high students, senior high students, university students, teacher workshop, general adults)
- About how long is the class?(for example: one 45-minute class period, two class periods, half-day workshop)
These two pieces of information affect the depth of concept compression and the page count planning.
Before entering Engine 5, ask:
Do you have a preferred presentation style?
- Do you have a reference presentation or image you can give me?
- Or should I configure it automatically based on the teaching content?
If the user has no preference, the system decides automatically; no further follow-up is needed.
Engine One: SOIL Concept Positioner
Goal: Extract the teaching main axis from the material and answer "what exactly should students take away from this lesson"
Input
The teaching materials, text, documents, or topic description provided by the user.
What to do
Analyze the material and produce a "Concept Positioning Draft" containing the following six items:
- Core concept: The single most central concept of this content (one sentence)
- Sub-concepts: The 3 sub-concepts that support the core concept
- Common misconceptions: The 3 misconceptions students are most likely to have
- One takeaway sentence: If students could remember only one sentence in the end, what would that sentence be
- Minimum fact pack: The minimum facts needed to support understanding
- Slides vs. script: Which content is suitable for slides, and which is suitable for verbal supplementation
Output format
## 概念定位稿
### 總概念
[一句話]
### 三個子概念
1. [子概念 A]
2. [子概念 B]
3. [子概念 C]
### 三個常見誤解
1. [誤解 A] → 正確理解:[...]
2. [誤解 B] → 正確理解:[...]
3. [誤解 C] → 正確理解:[...]
### 帶走一句話
[那句話]
### 最小事實包
- [事實 1]
- [事實 2]
- ...
### 投影片 vs 講稿分配
| 內容 | 建議位置 | 原因 |
|-----|---------|------|
| ... | 投影片 | ... |
| ... | 講稿/口頭 | ... |
After completion, present the Concept Positioning Draft to the user for confirmation, then proceed to the next step.
Engine Two: SOIL Context Positioner
Goal: Arrange the rhythm of understanding, not the chapter order
Input
Engine One's Concept Positioning Draft + target audience + time length.
What to do
Plan the entire presentation into a three-stage rhythm of understanding:
| Rhythm | Function | Suggested proportion |
|---|---|---|
| Arouse motivation | Let students know this matter is relevant to them | 15-20% |
| Maintain attention | Help students organize the material into relationships | 60-70% |
| Evoke action | Turn understanding into results that can be spoken, judged, and applied | 15-20% |
For each stage, explain
- The teaching purpose of this stage
- Which content is suitable to include in this stage (selected from the Concept Positioning Draft)
- The understanding task students should complete in this stage
- The suggested number of pages for this stage
- The entry point of this stage (how to begin) and the exit point (how to close)
- The design error most likely to occur in this stage
Output format
## 脈絡定位稿
### 第一段:引起動機(第 1-N 頁)
- 教學目的:...
- 放入內容:...
- 學生理解任務:...
- 建議頁數:N 頁
- 入口:...
- 出口:...
- 常見錯誤:...
### 第二段:維持注意(第 N-M 頁)
[同上格式]
### 第三段:喚起行動(第 M-末 頁)
[同上格式]
After completion, present it to the user, and proceed to the next step after confirming the rhythm arrangement.
Engine Three: SOIL Page Architect
Goal: Give each page a task, not list an outline
Input
Engine Two's Context Positioning Draft.
What to do
Break the three-stage context into concrete pages. Each page is a "teaching unit," not just a "content container."
Available page roles
| Role | Purpose |
|---|---|
| Cover page | Title, subtitle, instructor information |
| Question introduction page | Use questions to spark students' curiosity |
| Myth clarification page | Present common misconceptions, then flip them into correct understanding |
| Comparison page | Place two concepts side by side for comparison |
| Process page | Steps, sequence, timeline |
| Classification page | Grouping and organizing multiple items |
| Case page | Concrete examples to explain abstract concepts |
| Data page | Big numbers, statistics, key data display |
| Summary page | Gather the key points, leave with one sentence |
| Action page | What students should do (practice, discussion, reflection) |
| Transition page | Connection between chapters (minimal, only one sentence) |
Each page must specify
- Page number
- Page title
- Page role
- The single main point of this page (only one allowed)
- Suggested page type (full-page image, two-column, icon row, big numbers, timeline, etc.)
- The comprehension task this page should help students complete
- Connection with the previous page
- Connection with the next page
- Whether it is a key slide (★ mark)
- Geometric shape requirements(see "Geometric Shape Marking Rules" below)
- AI illustration requirements(see "AI Illustration Marking Rules" below)
▶ AI visual asset marking rules (visuals field)
When the page needsnon-geometricvisual assets, use the visuals field (multiple allowed). Engine Six will automatically call the draw skill (gpt-image-2) to generate and embed them into the slide.
Visuals are not the same as "small illustrations"—this skill supports six types of role, each with a different visual weight and layout function, used to make pages richer:
| role | Purpose | Visual weight | Suggested size | Typical position |
|---|---|---|---|---|
illustration |
Traditional small illustration, paired with text | Medium | 1024x1024 |
Right column x=5.1 w=4.5 |
background |
Full-page background image, with text overlaid on top | Highest | 1536x1024 |
Full page 0,0,13.333,7.5 |
hero |
Half-page main visual, split left-right or top-bottom | High | 1536x1024 |
Right half-page x=6.7 w=6.7 |
side_panel |
Slender side strip(decoration, atmosphere) | Medium | 1024x1536(vertical) |
Left side x=0 w=3 |
section_divider |
Chapter transition, full-page visual separation | High | 1536x1024 |
Full page |
accent |
Small decorative icon(corner, next to key points) | Low | 1024x1024 |
Custom small block |
When to use which one:
- Cover page →
hero(half-page main visual) orbackground(full page, text overlaid) - Problem introduction page →
background(full-page situational atmosphere) orhero(clear characters) - Case page →
illustration(small scene) orhero(when the situation is more important) - Myth clarification page → two
accent(wrong on left, right on right) - Comparison page → two
illustration(two columns) - Chapter transition / section separation →
section_divider - Edge decoration for information-dense pages →
side_panel(slender vertical version, so it won't be empty) - Action / conclusion page →
background+ large text overlay
visuals field format (new version, multiple allowed):
第 N 頁:[頁面標題]
- 頁面角色:問題引入頁
- visuals:
- id: slide_N_bg
role: background
prompt: "一個國中生在黑板前看著數學題目困惑思考的扁平插畫,左側 40% 為純深藍色塊留白(供文字疊加)"
size: 1536x1024
quality: low
# background 自動 full-bleed,不需 insert_at / width_in
opacity: 1.0 # 可選:0-1,若要半透明讓文字更清楚
- id: slide_N_accent
role: accent
prompt: "一個紅色大問號圖示,扁平向量"
size: 1024x1024
quality: low
x: 8.5 # 自訂位置
y: 4.5
w: 2.0
h: 2.0
Backward compatibility: old version illustration: field is still supported, automatically converted to visuals: [{role: illustration, ...}]。
A single page can have both
geometryandvisuals(e.g., geometry on the left and scenario image on the right), or multiplevisuals(e.g., background + accent). Style consistency is uniformly controlled by Engine 5'simage_policy.
Typical page × visual combinations (Layout Recipes)
| Page role | Suggested combination | Example |
|---|---|---|
| Cover page | background or hero + large title overlay |
Refer to EP15 plate cover |
| Problem introduction | background + large question text |
Atmosphere-focused |
| Myth clarification | Two accent(left ❌ right ✅) + explanatory text |
Visual contrast |
| Two-column comparison | Two illustration + two-column text |
Left-right comparison |
| Process page | side_panel + central flowchart |
Side decoration not empty |
| Data page | hero + large data |
Visual impact |
| Case page | illustration + body text |
Traditional layout |
| Summary page | background(semi-transparent) + bullet points |
Atmospheric ending |
| Action page | background + large slogan |
Same as cover |
| Chapter transition | section_divider + chapter title |
Full-page visual |
▶ Geometric figure marking rules (for mathematics teaching content only)
When page content involves geometric figures, add the geometry field to the page role table. This marking will automatically trigger figure rendering in Engine 6 and insert it into the slide.
When to mark geometry:
- Need diagrams to explain geometric concepts (triangles, quadrilaterals, circles, solid figures, etc.)
- Case page: "As shown in the figure, △ABC..."
- Process page: need multiple step diagrams (one diagram per step)
- Comparison page: two figures side by side for comparison (triangles with different subtypes, different arc relationships, etc.)
geometry field format (marked in the page role table):
第 N 頁:[頁面標題]
- 頁面角色:案例頁
- geometry:
mode: single # single(單圖)/ side_by_side(並排最多3圖)
figures:
- id: slide_N_fig1
type: triangle
config:
subtype: right
vertex_labels: ["A", "B", "C"]
right_angle_at: "C"
side_labels: {AB: "5", BC: "3", CA: "4"}
canvas: {width: 360, height: 280}
caption: "直角三角形 ABC"
insert_at: right # right(右欄)/ center(置中)/ left(左欄)
width_cm: 10.0 # 插入投影片時的圖片寬度(cm),預設 12
Complete figure types and config parameters: see the "Geometric figure parameter quick reference (inline)" section at the end of this SKILL.md
Self-check
After outputting the page role table, self-check:
- Do more than half of the pages have the same role? → Page types are too monotonous, needs adjustment
- Does any page's "sole main focus" actually contain more than one concept? → It should be split into two pages
- Does every page have a clear comprehension task? → If not, this page may be redundant
- Is there a geometric concept but you forgot to mark geometry? → Add the marking
- Are the cover page / problem introduction page / case page / action page missing a main visual? → Consider adding
illustration
After completion, present to the user for confirmation.
Engine 4: SOIL Cognitive Editor
Goal: Use six cognitive words to turn each page into a true teaching page
Six cognitive words
These are not decorative terms, but the processing language of teaching slides:
| Cognitive word | What it does | How to judge |
|---|---|---|
| Reduce noise | Remove elements that do not help understanding | If you remove this element, will students' understanding get worse? If not, remove it |
| Chunking | Group similar information together | Can students see at a glance how many groups this page has? |
| Add information | Add bridges for understanding | Are the relationship markers between the two concepts clear enough? |
| Structure | Make the main-subordinate relationship visible | Can students tell which is the main concept and which is the sub-concept? |
| Follow the thread | Arrange a reasonable reading order | Will students' eyes naturally follow the order you want? |
| Step-by-step | Make understanding followable step by step | If presented dynamically, how many steps should it appear in? |
For the full-process mode
After Engine 3 completes the page role table, use the six cognitive words page by page to plan in advance how each page's content is presented, as guidance for Engine 6 when generating the slides.
For the diagnostic revision mode
When the user uploads an existing .pptx:
- First use
python -m markitdownto extract the text content - Use the pptx skill's
thumbnail.pyor convert to images to view the visual layout - Diagnose problems page by page using the six cognitive words
- Output a "Cognitive Editing Report"
Cognitive Editing Report format
## 認知編修報告
### 第 N 頁:[頁面標題]
- 降雜訊:[具體建議,不要只說「字太多」]
- 區塊化:[具體建議]
- 增資訊:[具體建議]
- 結構化:[具體建議]
- 順脈絡:[具體建議]
- 步驟化:[具體建議]
- 修改優先級:高 / 中 / 低
Engine 5: SOIL Style Architect
Goal: Fix the style into rules so the entire deck is consistent
Style should not be handled too early. Only after the teaching skeleton (Engines 1-4) is confirmed do you enter the style layer.
If the user has reference slides or images
Perform style reverse engineering and analyze:
- Overall style temperament (formal/lively/minimal/warm)
- Title position and hierarchy rules
- Color system (primary color, secondary color, accent color)
- Whitespace arrangement
- Emphasis methods (color blocks, background color, bold, enlargement)
- Page type preferences
- Image style
If the user has no preference
Automatically configure based on the teaching audience and content topic:
| Teaching scenario | Suggested color scheme | Style temperament |
|---|---|---|
| Junior high/elementary school | Teal Trust or Coral Energy | Lively, high contrast |
| High school | Forest & Moss or Ocean Gradient | Clear, steady |
| University/graduate school | Midnight Executive or Charcoal Minimal | Formal, intellectual |
| Teacher workshop | Sage Calm or Warm Terracotta | Warm, professional |
| General education/interdisciplinary | Berry & Cream or Cherry Bold | Distinctive, attention-grabbing |
Style Rules (common to all teaching slides)
- Consistent title position (all left-aligned or all centered, no mixing)
- Consistent section colors (the same section uses the same color tone)
- Consistent structure for the same page types (all comparison pages look the same, all process pages look the same)
- Prioritize supporting comparison pages, process pages, and summary pages
- Style serves understanding of core concepts, not pursuing a commercial feel or showing off
- Every page must have visual elements (color blocks, shapes, icons); no text-only pages
- Do not add decorative underlines below titles
Output
Produce a style settings summary to be applied directly when Engine Six generates the slides. Includes:
- Visual foundation: color scheme (primary, secondary, accent HEX), font pairing, title font size, body font size, layout preference
- image_policy(If Engine Three has any page marked with
illustration, required):style_tokens: unified image style descriptors (e.g., "flat illustration, dark blue background, bright cyan lines, classroom scene, 16:9")negative: elements to avoid (e.g., "no photorealistic photos, no English text, no cluttered backgrounds")default_size: default size (1024x1024/1536x1024/1024x1536)default_quality: default quality (normallylow; cover or key pages can be upgraded tomedium)palette_hint: image color hints (consistent with the slide's primary color tone)
Example:
image_policy:
style_tokens: "扁平向量插畫、深夜藍#0D1B2A背景、亮青藍#00C6FF線條、金黃#FFD700點綴、教室或數位科技情境"
negative: "不要逼真照片、不要文字、不要雜亂背景"
default_size: 1536x1024
default_quality: low
palette_hint: "主色深藍、強調亮青藍、重點金黃"
image_policy will be applied in Engine Six's I-1 batch image generation sub-process, ensuring all AI illustrations have a unified style.
Engine Six: SOIL Presentation Director
Goal: Integrate the results of the first five engines and generate a .pptx
Generation process (three rounds)
Round one: Generate the skeleton
Integrate the following materials:
- Concept positioning draft (Engine One)
- Context positioning draft (Engine Two)
- Page role table (Engine Three)
- Cognitive editing guidelines (Engine Four)
- Style settings (Engine Five)
⚠️ If the page role table has any
geometryfield, you must first fully run the "▶ Geometric Shape Integration Sub-process (G-1 to G-4)" below, confirm that the base64 data for all geometric figures is ready, and then write the PptxGenJS script.⚠️ If the page role table has any
illustrationfield, you must first fully run the "▶ AI Illustration Integration Sub-process (I-1 to I-3)" below, confirm that all AI illustration PNGs have been generated and converted to base64, and then write the PptxGenJS script.The two sub-processes are independent of each other and can be executed in parallel. The final PptxGenJS script will load both
geo_b64.jsonandillus_b64.json。
Use PptxGenJS to generate the complete .pptx.
Technical execution: PptxGenJS reference source
If the current environment has pptx skill installed (under the skill directory there is pptx/pptxgenjs.md), first read that file to obtain the complete API; if not, just write it directly according to the following minimal quick reference:
const pptxgen = require("pptxgenjs");
const pptx = new pptxgen();
pptx.layout = "LAYOUT_WIDE"; // 16:9,13.333" × 7.5"
const slide = pptx.addSlide();
slide.background = { color: "0D1B2A" }; // 頁面底色(hex 不加 #)
slide.addText("標題", { x: 0.6, y: 0.5, w: 12, h: 1.2, fontSize: 48, bold: true, color: "FFFFFF", fontFace: "Microsoft JhengHei" });
slide.addText([{ text: "重點一", options: { bullet: true } }, { text: "重點二", options: { bullet: true } }],
{ x: 0.6, y: 2, w: 6, h: 3, fontSize: 20, color: "FFFFFF", lineSpacingMultiple: 1.2 });
slide.addShape(pptx.ShapeType.rect, { x: 7, y: 2, w: 5.5, h: 3, fill: { color: "00C6FF" }, line: { color: "FFD700", width: 1 } });
slide.addTable([["術語", "定義"], ["SOIL", "六引擎工作流"]],
{ x: 0.6, y: 5.2, w: 12, colW: [3, 9], fontSize: 16, border: { type: "solid", color: "FFFFFF", pt: 1 }, fill: { color: "1B263B" } });
slide.addImage({ data: "image/png;base64,....", x: 0.4, y: 1.5, w: 4.2, h: 3.2, sizing: { type: "contain", w: 4.2, h: 3.2 } });
pptx.writeFile({ fileName: "output.pptx" }); // 寫到當前工作目錄
Apply Lin Chang-Yang #1 text ratio (55/34/21/13), upgraded to poster-level font weight:
Font size standards (Lin Chang-Yang #1 correspondence)
| Element | Font size | Usage |
|---|---|---|
| Cover main title | 72–84pt bold | Cover page, key action page |
| General title | 44–56pt bold | Main message of each page |
| Subtitle | 28–34pt bold | Supplementary text below the main title |
| Body text (body) | 18–21pt | Bullet points, descriptions |
| Annotation (muted) | 14–16pt | Footer attribution, notes |
| Badge | 18–22pt bold | Page role label |
| Highlight | 24–28pt bold | Golden/emphasis-colored sentence |
Font selection (Lin Chang-Yang #7)
| Purpose | Recommended font |
|---|---|
| Title/Subtitle/Badge/Highlight | GenSekiGothic2 TW H(GenSekiGothic Heavy, poster feel) |
| Body/Annotation | Microsoft JhengHei(Microsoft JhengHei, preserves readability) |
Other guidelines
- Use
LAYOUT_WIDE(16:9,13.333" × 7.5") - Line spacing
line_spacing=1.2(Lin Chang-Yang #5) - 0.5" minimum margin
- Dark cover + conclusion, light content pages (sandwich structure)
- Every page must have a visual element (
visualsorgeometry) - Fixed x grid (Lin Chang-Yang #14): left
0.6/0.7, two-column5.1/7.2, three-column0.6/4.85/9.1
Choose layout based on page role:
| Page role | Recommended layout |
|---|---|
| Cover page | Dark full-page background + large centered title |
| Problem introduction page | Large question text + whitespace |
| Myth clarification page | Two-column (❌ misconception vs ✅ correct) |
| Comparison page | Two-column or top-bottom comparison |
| Process page | Horizontal arrow steps or timeline |
| Category page | 2x2 or 2x3 grid |
| Case page | Image/scenario + description |
| Data page | Large numbers 60-72pt + small labels |
| Summary page | Bullet points consolidated + one takeaway sentence |
| Action page | Dark background + action guidance |
| Transition page | Full-page color block + one sentence |
▶ Geometric shape integration sub-process (Before writing the PptxGenJS scriptexecute)
If any page in Engine 3's page role table is marked with the
geometryfield, you must generate all geometric shapes first before starting to write the PptxGenJS script, then embed them as base64 into the JS script.Order: generate geometric shapes → convert to base64 → write PptxGenJS (including addImage) → execute to generate .pptx
Do not generate the skeleton first and then post-process to insert illustrations. The base64 embedding method allows more precise position control and does not require python-pptx post-processing.
G-1: Determine geometric shape source (skill priority, native shapes as fallback)
- If
jh-math-geometryskill is installed(found in the skill directoryjh-math-geometry/scripts/geometry_renderer.py) → use that renderer to generate PNG per G-2 to G-4, then embed into PptxGenJS. - If not installed → skip G-2 to G-4, directly draw with PptxGenJS native shapes (
addShape'sline/rect/ellipse/triangle, labels useaddText), see the fallback example at the end of G-5.
All intermediate artifacts (spec, PNG, base64) must be placed in thecurrent working directoryunder geo_out/, and must not be written to the home directory or the system temp area.
pip install cairosvg Pillow -q
# 依環境常見的技能根目錄尋找渲染器(找不到就走原生形狀備援)
GEOM_RENDERER="$(find ~/.claude/skills ~/.codex/skills ~/.agents/skills \
-path '*/jh-math-geometry/scripts/geometry_renderer.py' 2>/dev/null | head -1)"
if [ -n "$GEOM_RENDERER" ]; then
echo "幾何渲染器:$GEOM_RENDERER"; export GEOM_RENDERER
else
echo "未安裝 jh-math-geometry,改用 PptxGenJS 原生形狀(跳到 G-5 備援)"
fi
G-2: Generate standard geometric figures (using geometry_renderer.py)
For each geometry field marked by Engine 3, create a corresponding figure spec JSON, then batch render:
mkdir -p geo_out
cat > geo_spec.json << 'SPEC'
{
"figures": [
{
"id": "slide_N_figX",
"type": "triangle",
"config": {
"subtype": "general",
"vertex_labels": ["A", "B", "C"],
"angle_arcs": {"A": 1, "B": 1, "C": 1}
},
"canvas": {"width": 360, "height": 280}
}
],
"options": {"format": "png", "dpi": 150}
}
SPEC
python3 "$GEOM_RENDERER" geo_spec.json geo_out/
ls geo_out/*.png
Visual confirmation: Review the generated
.pngone by one, and confirm that the figure labels, angle arcs, and equal-side marks are all correct. If there are issues, adjust the spec and regenerate;do not proceed to the next step。
G-3: Generate custom geometric figures (figures not supported by geometry_renderer.py)
When figures such as "two intersecting lines," "exterior angle diagram with extended lines," or "multi-angle color marking" that the renderer does not directly support are needed, use Python to directly call SVGCanvas to draw by hand:
# geo_custom.py(存於當前工作目錄)
import math, os, sys
sys.path.insert(0, os.path.dirname(os.environ["GEOM_RENDERER"])) # G-1 找到的渲染器所在目錄
from geometry_renderer import SVGCanvas
import cairosvg
from pathlib import Path
OUT = Path("geo_out")
OUT.mkdir(exist_ok=True)
def save(c, name):
svg = c.render()
(OUT / f"{name}.svg").write_text(svg, encoding="utf-8")
cairosvg.svg2png(bytestring=svg.encode(),
write_to=str(OUT / f"{name}.png"), dpi=150)
print(f"✅ {name}")
# 範例:兩直線相交(對頂角)
def make_vertical_angles():
c = SVGCanvas(360, 280, 'white')
W, H = 360, 280
cx, cy = W/2, H/2
angle1 = math.radians(35)
angle2 = math.radians(110)
r = 130
# 直線 L
c.line(cx + r*math.cos(angle1), cy - r*math.sin(angle1),
cx - r*math.cos(angle1), cy + r*math.sin(angle1))
# 直線 M
c.line(cx + r*math.cos(angle2), cy - r*math.sin(angle2),
cx - r*math.cos(angle2), cy + r*math.sin(angle2))
c.dot(cx, cy, r=3.5)
c.text(cx+8, cy+14, 'O', size=12, bold=True)
# 角標籤與弧(可依需求調整位置)
c.text(cx+28, cy-32, '∠1', size=13, color='#028090')
c.text(cx-52, cy-28, '∠2', size=13, color='#028090')
c.text(cx-52, cy+18, '∠3', size=13, color='#E36414')
c.text(cx+22, cy+18, '∠4', size=13, color='#E36414')
save(c, 'vertical_angles')
make_vertical_angles()
python3 geo_custom.py
Common custom figure templates (copy and modify directly):
| Figure scenario | Custom key points |
|---|---|
| Two intersecting lines (vertical angles) | Use c.line() to draw two lines, and manually calculate the angle arc positions |
| Triangle exterior angle sum (with extended dashed lines) | c.polygon() to draw the triangle,c.line(..., dash='5,4') to draw the extension lines |
| Triangle exterior angle theorem (∠CBD) | Extend one side, and use c.arc_path() to mark the exterior angle arc |
| Parallel lines cut by a transversal (multiple angles color-marked) | The renderer already supports the parallel_lines type, so generally just use the renderer |
G-4: Convert to base64 for use by PptxGenJS
# geo_to_b64.py(存於當前工作目錄)
import base64, json
from pathlib import Path
geo_dir = Path("geo_out")
# 列出所有需要嵌入的圖形 id(對應引擎三 geometry 標記的 id)
figure_ids = [
"slide_N_figX", # 替換為實際的 figure id
"vertical_angles", # 自訂圖形
]
result = {}
for fid in figure_ids:
png = geo_dir / f"{fid}.png"
if png.exists():
result[fid] = "image/png;base64," + base64.b64encode(png.read_bytes()).decode()
print(f"✅ {fid} → {len(result[fid])} chars")
else:
print(f"⚠️ 找不到 {png}")
with open('geo_b64.json', 'w', encoding='utf-8') as f:
json.dump(result, f)
print("完成:geo_b64.json(當前工作目錄)")
python3 geo_to_b64.py
G-5: Embed geometric figures in the PptxGenJS script
When writing the PptxGenJS script, read the base64 data at the very beginning, then embed it on the corresponding page using addImage :
const pptxgen = require("pptxgenjs");
const fs = require("fs");
// ── 讀取所有幾何圖形 ─────────────────────────────────────
const geo = JSON.parse(fs.readFileSync('geo_b64.json', 'utf8')); // 當前工作目錄
// ...(其他設定)
// ── 在對應投影片嵌入幾何圖 ──────────────────────────────
// 位置單位為英吋;sizing.type = "contain" 保持比例
slide.addImage({
data: geo["slide_N_figX"], // 對應 figure id
x: 0.4, // 距左邊距(英吋)
y: 1.5, // 距頂部(英吋)
w: 4.2, // 圖片顯示寬度(英吋)
h: 3.2, // 圖片顯示高度(英吋)
sizing: { type: "contain", w: 4.2, h: 3.2 }
});
Fallback: When jh-math-geometry is not installed, use PptxGenJS native shapes to draw figures
// 範例:直角三角形 ABC(原生形狀,不需任何外部渲染器)
const L = { color: "FFFFFF", width: 2 };
slide.addShape(pptx.ShapeType.rtTriangle, { x: 0.8, y: 1.8, w: 3.6, h: 2.7, line: L, fill: { color: "1B263B" } });
slide.addText("A", { x: 0.5, y: 4.4, w: 0.4, h: 0.4, fontSize: 18, color: "FFD700", bold: true });
slide.addText("B", { x: 4.4, y: 4.4, w: 0.4, h: 0.4, fontSize: 18, color: "FFD700", bold: true });
slide.addText("C", { x: 0.5, y: 1.5, w: 0.4, h: 0.4, fontSize: 18, color: "FFD700", bold: true });
// 圓、線段、矩形:pptx.ShapeType.ellipse / line / rect;虛線:line: { dashType: "dash" }
Position reference (LAYOUT_16x9, 10" × 5.625"):
| Figure position | x | w | Description |
|---|---|---|---|
| Left column (two-column layout) | 0.3 | 4.2 | About 4.5" on each side |
| Right column (two-column layout) | 5.1 | 4.5 | |
| Centered (full-page figure) | 1.5 | 7.0 | |
| Small figure on the right (text-focused) | 6.5 | 3.0 |
▶ AI visual asset integration subprocess (before writing the PptxGenJS scriptexecute)
If any page in Engine 3 is marked with
visualsor the olderillustrationfield, all visual assets must be batch-generated before starting to write the PptxGenJS script, and then embedded in the script.Order: batch image generation → visual confirmation → embed into pptx
Image generation tool depends on the execution environmentthree-stageselection; do not get stuck on one option:
- ChatGPT App/Codex → directly use the built-in imagegen(no API Key required), generate according to the size/quality in the table below, and save as
slides/images/<name>_<時間戳>.png。- Claude Code → if
~/.claude/skills/draw/draw.pyexists (gpt-image-2, requiresOPENAI_API_KEY), then use it; see I-1 for the command.- If neither is available → do not generate images, and instead use PptxGenJS native color blocks/shapes/emoji placeholders (see the fallback at the end of I-1); the rest of the process proceeds as usual.
Image generation and embedding rules corresponding to role
| role | Image generation parameters (common to imagegen/draw.py) | pptx embedding |
|---|---|---|
illustration |
size=1024x1024, quality=low |
x=5.1, y=1.5, w=4.5, h=4.0 |
background |
size=1536x1024, quality=low or medium |
Full-page (0,0,13.333,7.5) |
hero |
size=1536x1024, quality=low |
x=6.7, y=0, w=6.7, h=7.5 (right half-page) |
side_panel |
size=1024x1536(portrait), quality=low |
x=0, y=0, w=3.0, h=7.5 (left thin strip) |
section_divider |
size=1536x1024, quality=medium |
Full-page |
accent |
size=1024x1024, quality=low |
Customize per block's x/y/w/h |
Prompt requirements for background / section_divider: Must enforce the negative "no text whatsoever", and specify a blank area (e.g., "the left 40% is a solid dark color block for text overlay"), otherwise text will be overlaid on the main illustration subject and readability will be poor.
I-1: Batch-generate AI visual assets
For each visuals entry marked by the engine (or the legacy illustration),merge image_policy.style_tokens with that visual's prompt, determine size/quality according to the role mapping table, and generate them one by one (Codex uses the built-in imagegen; Claude Code uses draw.py).
Merge rules:
最終 prompt = "{page_prompt},{style_tokens},{negative}"
Example batch command (Claude Code environment, when draw.py is available; for Codex/ChatGPT App, use the built-in imagegen to generate one by one and save with the same filenames):
mkdir -p slides/images
[ -f ~/.claude/skills/draw/draw.py ] || echo "沒有 draw.py:改用內建 imagegen,或走原生色塊備援"
# 以引擎五的 image_policy 為基底
STYLE="扁平向量插畫、深夜藍#0D1B2A背景、亮青藍#00C6FF線條、金黃#FFD700點綴、教室或數位科技情境"
NEG="不要逼真照片、不要雜亂背景"
DRAW="python ~/.claude/skills/draw/draw.py"
# 逐張生成(每張取一個對應 illustration id 的檔名前綴)
$DRAW "國中生在黑板前看著數學題目困惑思考,${STYLE},${NEG}" \
--size 1024x1024 --quality low --name slide_3_illus1 --outdir slides/images/
$DRAW "一張發光的火箭向上飛,象徵學習突破,${STYLE},${NEG}" \
--size 1536x1024 --quality low --name slide_10_illus1 --outdir slides/images/
ls slides/images/*.png
Cost estimate(draw.py path): low quality is about NT$0.3 per image; for a 10-page deck, if 4 pages have illustrations, it's about NT$1.2. Codex's built-in imagegen does not incur additional API costs. Parallel acceleration: If there are many images (>5), you can run multiple
$DRAW ... &with&in the background, thenwait, which can save half the time.
Fallback: When no image generation tool is available—do not generate images, do not interrupt. Replace that visual's position with native PptxGenJS elements:background/section_divider use a full-page addShape(rect) color block + a second semi-transparent rectangle for layering;illustration/hero/accent use a rounded rectangle (roundRect) + a large emoji (addText("📐", { fontSize: 96 })) as the visual anchor. Skip I-2 and I-3, andillus_b64.json leave the object empty {} .
I-2: Visual confirmation (mandatory)
Use the view tool or open the files directly to inspect the generated PNGs one by one. Check:
- Is the style consistent with
image_policy.style_tokens? - Does it match the page's instructional purpose?
- Is there any text/garbled text that shouldn't be there?
- Do the colors harmonize with the deck's primary colors?
If a certain image fails: adjust the prompt or upgrade quality to medium, and rerun that image in I-1.Do not proceed to I-3 with failed images。
I-3: Convert to base64 for PptxGenJS use
# illus_to_b64.py
import base64, json
from pathlib import Path
import glob
img_dir = Path("slides/images")
result = {}
# 對每個 illustration id(對應引擎三標記),找最新生成的 PNG
# 檔名格式:<name>_<YYYYMMDD_HHMMSS>.png(draw.py 預設;內建 imagegen 存檔時請沿用同樣命名)
illus_ids = [
"slide_3_illus1",
"slide_10_illus1",
# ... 依引擎三標記補齊
]
for iid in illus_ids:
candidates = sorted(glob.glob(str(img_dir / f"{iid}_*.png")))
if not candidates:
print(f"⚠️ 找不到 {iid}")
continue
latest = Path(candidates[-1]) # 取時間戳最新的
result[iid] = "image/png;base64," + base64.b64encode(latest.read_bytes()).decode()
print(f"✅ {iid} → {latest.name}")
with open('illus_b64.json', 'w', encoding='utf-8') as f:
json.dump(result, f)
print("完成:illus_b64.json")
python illus_to_b64.py
I-4: Embed AI visual assets in the PptxGenJS script
Get positions according to the role mapping table:
const pptxgen = require("pptxgenjs");
const fs = require("fs");
// ── 讀取幾何圖與 AI 插畫 ───────────────────────────────
const geo = fs.existsSync('geo_b64.json')
? JSON.parse(fs.readFileSync('geo_b64.json', 'utf8')) : {};
const illus = fs.existsSync('illus_b64.json')
? JSON.parse(fs.readFileSync('illus_b64.json', 'utf8')) : {};
// ── 在對應投影片嵌入 AI 插畫 ──────────────────────────
// 位置單位為英吋;可依 illustration.insert_at / width_in 調整
slide.addImage({
data: illus["slide_3_illus1"],
x: 5.1, // 右欄起始
y: 1.5,
w: 4.5,
h: 3.0,
sizing: { type: "contain", w: 4.5, h: 3.0 }
});
background / section_divider (full-page background image):
slide.addImage({
data: illus["slide_1_bg"],
x: 0, y: 0, w: 13.333, h: 7.5,
sizing: { type: "cover", w: 13.333, h: 7.5 }
});
// 若需要暗化讓文字更清楚,疊半透明深色矩形
slide.addShape(pptx.shapes.RECTANGLE, {
x: 0, y: 0, w: 6.5, h: 7.5, // 左半版暗化
fill: { type: "solid", color: "0D1B2A", transparency: 30 },
line: { color: "0D1B2A", transparency: 100 }
});
// 再放標題文字(用亮色字在暗化區上)
hero (half-page main visual):
slide.addImage({
data: illus["slide_1_hero"],
x: 6.7, y: 0, w: 6.63, h: 7.5,
sizing: { type: "cover", w: 6.63, h: 7.5 }
});
// 左側 6.7" 放文字
side_panel (side thin strip):
slide.addImage({
data: illus["slide_3_panel"],
x: 0, y: 0, w: 3.0, h: 7.5,
sizing: { type: "cover", w: 3.0, h: 7.5 }
});
// 右側 10.3" 放主內容
accent (small decoration, with x/y/w/h specified per block):
slide.addImage({
data: illus["slide_2_q"],
x: 8.5, y: 4.5, w: 2.0, h: 2.0,
sizing: { type: "contain", w: 2.0, h: 2.0 }
});
Second round: Fix pages
After generation is complete, run visual QA:
# 文字內容檢查
python -m markitdown output.pptx
# 轉成圖片逐頁檢查(需本機有 LibreOffice;若環境有 pptx 技能,也可改用其 scripts/office/soffice.py)
soffice --headless --convert-to pdf output.pptx
rm -f slide-*.jpg
pdftoppm -jpeg -r 150 output.pdf slide
ls -1 "$PWD"/slide-*.jpg
Use a subagent to inspect each slide with fresh eyes:
- Whether elements overlap
- Whether text overflows
- Whether spacing is consistent
- Whether contrast is sufficient
- Is the page role clear (can you tell what this page is doing?)
- Are geometric shapes correctly aligned and appropriately proportioned
- Is the AI illustration style consistent (does the whole thing look like the same set of assets), does it not overlap with text, is the main visual clear
Regenerate after fixing the issues.
Third round: Final check
Confirm each item using the following checklist:
- Each page has only one main point
- The three-part teaching flow is complete (motivation → attention → action)
- Page roles are diverse (not all are bullet-point summary pages)
- Key slides are highlighted
- The takeaway sentence appears on the summary page
- Common misconceptions are addressed
- Style is consistent (color scheme, fonts, title position)
- No text-only pages (every page has visual elements)
- Content is complete with nothing missing
- For pages marked with geometry, all geometric shapes have been previewed as PNG using the view tool and confirmed correct before being embedded
- Geometric shapes are correctly aligned within the slides, appropriately proportioned, and do not overlap with text
- For pages marked with illustration, all AI illustrations have passed the I-2 visual confirmation
- All AI illustrations have a consistent style (consistent color scheme, art style, and brushwork), complying with image_policy
- Contextual pages such as the cover, problem introduction, case studies, and action pages have a main visual and are not text-only
Output
Save the final .pptx to the user's working folder and provide a download link. Briefly explain the slide structure (how many pages, how many pages in each of the three parts, and which key pages there are).
Diagnostic revision mode (user brings in an existing .pptx)
When the user brings in an existing presentation, do not run the full workflow; instead:
Step 1: Read the existing presentation
python -m markitdown input.pptx
At the same time, convert it into images to inspect the visual layout.
Step 2: Use Engine 4 to perform a cognitive editing diagnosis
Check each page using the six cognitive terms (reduce noise, chunking, add information, structuring, follow the flow, step-by-step).
Step 3: Additionally perform Engine 3's page role analysis
Check whether each page has a clear role and whether the page types are too monotonous.
Step 4: Output the cognitive editing report
Present the diagnostic results to the user and indicate revision priority (high/medium/low).
Step 5: Execute revisions after confirmation
Only after the user confirms which items to revise, carry out the actual revisions. After revision, perform QA verification again.
Style definition mode (user wants to produce YAML)
When the user only wants to define style rules:
- Ask the user to provide a reference presentation or images
- Execute Engine 5's style reverse engineering
- Produce a style settings summary and save it as a standalone file
- Explain that this style setting can be directly applied when creating teaching presentations in the future
Integration of Lin Chang-Yang's 30 presentation principles
This skill integrates Lin Chang-Yang's "30 Presentation Secrets AI Still Can't Do" as the quality check rules for Engine 5 and Engine 6. See the complete entries in [Knowledge Base/AI Workflow/Presentation Design 30 Principles — Human Judgment AI Can't Do].
Hard rules (automatically applied by Engine 5 Style Architect)
| # | Principle | Implementation method |
|---|---|---|
| 1 | Text ratio 55/34/21/13 | Title 36–44pt, subtitle 24–28pt, body text 14–16pt, annotations 10–12pt (adjust according to pptx slide proportions) |
| 5 | Line spacing 50–75% | python-pptx setting paragraph.line_spacing=1.2 |
| 7 | Bold sans-serif | Use heavy-weight fonts for titles (e.g., GenSekiGothic2 TW H), Bold for subtitles |
| 14 | Element alignment | Fixed grid x: left 0.5/0.7, two-column 5.1/7.2, three-column 0.6/4.85/9.1 |
| 17 | The fewer table borders, the better | Default tables have no outer border, separated only by whitespace |
| 21, 25 | Fixed brand colors, 1–2 accent colors | Engine Five style settings use only primary + accent |
| 24 | Light gray + accent color focus | Use muted gray for secondary information, accent color for key points |
| 27 | Full-bleed images for cover/ending | Cover pages and action pages are recommended to use a full-page dark background |
Soft rules (Engine Three page structure self-check)
- #3 Title ≤ 10 characters: Check the title character count on each page (split if exceeded)
- #4 One point per page: Engine Three checks whether the "single main point" contains only one concept
- #6 Content hierarchy: Each page contains at least two levels: main title + body text
- #13 Z-pattern layout: The layout within the page role guides the eye from top-left to bottom-right
- #18 Multi-image alignment: Unify x/y/w/h for multiple images
- #23 Progress bar reduces pressure: Add a progress bar at the bottom of long presentations (>15 pages)
Pure human judgment (Engine One/Two strategy)
- #2 Talk about what the audience cares about first → Engine Two "arouse motivation" paragraph key point
- #19 Three options → Engine Three "comparison page" or "classification page"
- #20 Use questions to promote thinking → Engine Three "question introduction page"
- #22 Pain first, benefits later → Engine Two three-part rhythm arrangement
- #28 Use comparison to help judgment → Use "comparison page" as the main page type
- #29 Real experience brings uniqueness → Engine One "minimum fact package" can add the teacher's personal cases
- #30 Drive the next action → Engine Two "call to action" section exit
Final checklist expansion
In addition to the original checklist items, add Lin Chang-Yang's key items:
- #1 Clear hierarchy of title/subtitle/body text sizes
- #3 Each page title ≤ 10 characters
- #14 Consistent x-coordinates for similar elements
- #25 No more than 2 accent colors
- #2 The motivation section first talks about what the audience cares about
- #30 The action page has a clear next step
Core principles (run through all modes)
These principles come from the SOIL teaching method and are the underlying logic of all judgments:
- Teaching presentations ≠ business presentations: The focus is on reducing cognitive load and promoting understanding, not on persuading or selling
- Teacher's perspective vs student's perspective: The teacher's design order is "core concept→key layout→single-page layout", but the student's understanding order is the reverse. Design starting from the student's order of reception
- One point per page: Each slide carries only one main concept
- Pages are teaching units: Each page has a role and a task, not just a content container
- Style serves understanding: Every visual decision must be able to answer "Will this make it easier for students to understand?"
- Teaching judgment first, tool operation second: Concept → context → page → cognition → style → generation; the order cannot be reversed
Dependencies
Required:Node.js + pptxgenjs(the only hard dependency). All outputs (.pptx, intermediate JSON, images) are written to thecurrent working directory。
Optional: pptx skill(read it if available; if not, use the minimal PptxGenJS quick reference embedded in Engine 6):
pptx/pptxgenjs.md— Complete PptxGenJS APIpptx/editing.md— Workflow for editing an existing .pptxpptx/scripts/— Conversion and inspection tools
Optional: jh-math-geometry skill(for geometric figures; if not installed, use PptxGenJS native shapes instead, see G-1/G-5):
jh-math-geometry/scripts/geometry_renderer.py— SVG rendering engine- Shape parameter quick reference → see the "Geometric Shape Parameter Quick Reference (Embedded)" section below; no need to read external files
Optional: image generation tools(three-stage, see the AI visual asset sub-workflow):
- ChatGPT App/Codex → built-in imagegen, no API Key required
- Claude Code →
~/.claude/skills/draw/draw.py(gpt-image-2; requiresOPENAI_API_KEY; cost approximately NT$0.3/image at low, NT$1.3/image at medium, NT$5.5/image at high; default is low) - If none are available → do not generate images; use PptxGenJS native color blocks as placeholders
# 需要的套件
pip install "markitdown[pptx]" Pillow cairosvg python-pptx # 依環境需要時加 --break-system-packages
npm install -g pptxgenjs
Geometric Shape Parameter Quick Reference (Embedded)
This section fully covers all supported shape types and parameters. When writing Engine 3's
geometrymarkup, consult it directly; no need to read external files.
Common Structure
{
"id": "fig1",
"type": "<圖形類型>",
"config": { ... },
"canvas": { "width": 360, "height": 280 }
}
Batch specification (provided to geometry_renderer.py):
{
"figures": [ {...}, {...} ],
"options": { "format": "png", "dpi": 150 }
}
For presentation images, recommended canvas:
360×280; for side-by-side comparison images, use240×200
1. triangle
| Parameter | Description | Allowed Values |
|---|---|---|
subtype |
Type | general(default),right、isosceles、equilateral |
vertex_labels |
Vertex labels | String array, default ["A","B","C"] |
right_angle_at |
Vertex with right-angle symbol | Vertex label string |
angle_arcs |
Number of angle arcs at each vertex | {"A":1, "B":2} |
side_labels |
Text label for each side | {"AB":"5", "BC":"3"} |
equal_marks |
Number of equal-length tick marks | {"AB":1, "CD":2} |
altitude_from |
Vertex from which to draw the altitude | Vertex label string |
median_from |
Vertex from which to draw the median | Vertex label string |
dashed_sides |
Sides drawn as dashed lines | ["AB"] |
show_dots |
Vertex black dots | true(default) |
Common Examples:
Right triangle (right angle at C):
{"type":"triangle","config":{"subtype":"right","vertex_labels":["A","B","C"],"right_angle_at":"C","side_labels":{"AB":"5","BC":"3","CA":"4"}}}
Isosceles triangle (mark equal sides + base angles):
{"type":"triangle","config":{"subtype":"isosceles","equal_marks":{"AB":1,"AC":1},"angle_arcs":{"B":1,"C":1}}}
2. quadrilateral
| Parameter | Description |
|---|---|
subtype |
parallelogram / rectangle / rhombus / square / trapezoid / right_trapezoid / general |
vertex_labels |
Vertex label array, default ["A","B","C","D"] |
side_labels |
Text label for each side |
equal_marks |
Equal-length tick marks |
right_angles |
Array of vertices marked with right angles |
diagonals |
Whether to draw diagonals,true/false |
diagonal_labels |
Diagonal labels {"AC":"m","BD":"n"} |
Common Examples:
Parallelogram (with diagonals):
{"type":"quadrilateral","config":{"subtype":"parallelogram","vertex_labels":["A","B","C","D"],"diagonals":true,"equal_marks":{"AB":1,"CD":1,"BC":2,"AD":2}}}
Isosceles trapezoid:
{"type":"quadrilateral","config":{"subtype":"trapezoid","vertex_labels":["A","B","C","D"],"equal_marks":{"AB":1,"CD":1}}}
3. circle
| Parameter | Description |
|---|---|
center_label |
Center label, default "O" |
show_center |
Whether to show the center point |
points |
Points on the circumference:{"A": 60, "B": 160}(angle, 0=right, 90=up, counterclockwise) |
radius_lines |
Array of points for drawing radius lines |
radius_label |
Radius label |
chords |
Chord:[["A","B"],["C","D"]] |
diameter |
Diameter endpoints ["A","C"] |
tangent_at |
Tangent point |
central_angle |
Endpoints of the filled sector (central angle) |
inscribed_angle |
Inscribed angle:{"vertex":"C","arc":["A","B"]} |
Common examples:
Central angle and inscribed angle:
{"type":"circle","config":{"center_label":"O","points":{"A":30,"B":150,"C":270},"radius_lines":["A","B"],"central_angle":["A","B"],"inscribed_angle":{"vertex":"C","arc":["A","B"]}}}
4. coordinate_plane
| Parameter | Description |
|---|---|
x_range |
x-axis range, e.g. [-5, 5] |
y_range |
y-axis range |
show_grid |
Whether to show grid lines |
tick_interval |
Tick interval |
points |
Point array:[{"x":1,"y":2,"label":"A","color":"#cc0000"}] |
lines |
Line:[{"slope":2,"intercept":-1,"label":"y=2x-1"}] |
parabolas |
Parabola:[{"a":1,"b":0,"c":-2,"label":"y=x²-2"}] |
segments |
Line segment:[{"x1":0,"y1":0,"x2":3,"y2":4}] |
Common examples:
Linear function y=2x-1:
{"type":"coordinate_plane","config":{"x_range":[-3,5],"y_range":[-4,8],"lines":[{"slope":2,"intercept":-1,"label":"y=2x-1"}],"points":[{"x":0,"y":-1,"label":"(0,-1)"}]}}
Parabola y=x²-2x-3:
{"type":"coordinate_plane","config":{"x_range":[-2,5],"y_range":[-5,6],"parabolas":[{"a":1,"b":-2,"c":-3,"label":"y=x²-2x-3"}]}}
5. solid_3d
| subtype | Description | Vertex order |
|---|---|---|
rectangular_prism |
Quadrilateral prism (rectangular cuboid) | ABCD (top) EFGH (bottom) |
cylinder |
Cylinder | labels: radius, height |
cone |
Cone | labels: apex, base, radius, slant, height |
triangular_prism |
Triangular prism | ABC (back) DEF (front) |
square_pyramid |
Quadrilateral pyramid | ABCD (base) P (apex) |
triangular_pyramid |
Triangular pyramid | ABCD |
Shared parameters:show_hidden(dashed edges),vertex_labels、labels(label radius/height/slant height)
Quadrilateral prism (labeled vertices + dashed lines):
{"type":"solid_3d","config":{"subtype":"rectangular_prism","vertex_labels":["A","B","C","D","E","F","G","H"],"show_hidden":true}}
6. parallel_lines
| Parameter | Description |
|---|---|
n_parallel |
Number of parallel lines (usually 2) |
line_labels |
Parallel line labels ["l","m"] |
transversal_angle |
Transversal angle (degrees) |
transversal_labels |
Transversal label ["t"] |
angle_marks |
Angle markers:[{"line":0,"position":"upper_left","label":"A"}]; position is upper_left/upper_right/lower_left/lower_right |
Two parallel lines cut by a transversal, marking corresponding angles:
{"type":"parallel_lines","config":{"n_parallel":2,"line_labels":["l","m"],"transversal_angle":55,"angle_marks":[{"line":0,"position":"upper_left","label":"A"},{"line":1,"position":"upper_left","label":"E"}]}}
7. triangle_center
center_type |
Description | Default label |
|---|---|---|
centroid |
Centroid (three medians) | G |
circumcenter |
Circumcenter (circumcircle) | O |
incenter |
Incenter (incircle) | I |
{"type":"triangle_center","config":{"center_type":"centroid","center_label":"G","triangle":{"subtype":"general","vertex_labels":["A","B","C"]}}}
8. similar_triangles
Two triangles are configured separately and displayed side by side; identical angle arcs indicate equal angles:
{"type":"similar_triangles","config":{"triangle1":{"vertex_labels":["A","B","C"],"angle_arcs":{"A":1,"B":2},"side_labels":{"AB":"3","BC":"4","CA":"5"}},"triangle2":{"vertex_labels":["D","E","F"],"angle_arcs":{"D":1,"E":2},"side_labels":{"DE":"6","EF":"8","FD":"10"}}}}
Quick copy section (most commonly used in presentations)
| Page scenario | Spec to copy directly |
|---|---|
| Pythagorean theorem illustration | {"type":"triangle","config":{"subtype":"right","vertex_labels":["A","B","C"],"right_angle_at":"C","side_labels":{"AB":"c","BC":"a","CA":"b"}}} |
| Congruent triangles | {"type":"triangle","config":{"subtype":"general","vertex_labels":["A","B","C"],"equal_marks":{"AB":1,"BC":2,"CA":3}}} |
| Central angle + inscribed angle | {"type":"circle","config":{"center_label":"O","points":{"A":30,"B":150,"C":270},"radius_lines":["A","B"],"central_angle":["A","B"],"inscribed_angle":{"vertex":"C","arc":["A","B"]}}} |
| Parallelogram diagonals | {"type":"quadrilateral","config":{"subtype":"parallelogram","vertex_labels":["A","B","C","D"],"diagonals":true,"equal_marks":{"AB":1,"CD":1,"BC":2,"AD":2}}} |
| Isosceles trapezoid | {"type":"quadrilateral","config":{"subtype":"trapezoid","vertex_labels":["A","B","C","D"],"equal_marks":{"AB":1,"CD":1}}} |
| Quadrilateral prism | {"type":"solid_3d","config":{"subtype":"rectangular_prism","vertex_labels":["A","B","C","D","E","F","G","H"],"show_hidden":true}} |
| Centroid illustration | {"type":"triangle_center","config":{"center_type":"centroid","center_label":"G","triangle":{"subtype":"general","vertex_labels":["A","B","C"]}}} |
| Similar triangles | {"type":"similar_triangles","config":{"triangle1":{"vertex_labels":["A","B","C"],"angle_arcs":{"A":1,"B":2}},"triangle2":{"vertex_labels":["D","E","F"],"angle_arcs":{"D":1,"E":2}}}} |
| Linear function | {"type":"coordinate_plane","config":{"x_range":[-3,5],"y_range":[-4,8],"lines":[{"slope":2,"intercept":-1,"label":"y=2x-1"}]}} |
| Parabola | {"type":"coordinate_plane","config":{"x_range":[-2,5],"y_range":[-5,6],"parabolas":[{"a":1,"b":-2,"c":-3,"label":"y=x²-2x-3"}]}} |