Imported from sabarixr/study-skill-pack-claude (
SKILL.md). Install upstream withnpx skills add sabarixr/study-skill-pack-claude. Copyright stays with the author.
Study Content Skill β Web Client Edition
Transforms raw study material into focused, cognitively optimised outputs.
Platform notes (web client):
- No file system, bash, or npm. Everything runs in-browser via CDN.
- Outputs are HTML Artifacts rendered inline in chat.
- DOCX is generated client-side via docx.js (jsDelivr CDN) and downloaded.
- Mind maps use D3.js from cdnjs.
present_filesis never used.
Step 0 β Parse Source Material First (MANDATORY β do this before anything else)
Read the entire source. Do not skip sections. Do not summarise away detail.
Build a full content inventory before writing a single line of output:
Content types to extract (check every one)
| Type | What to look for | How to handle |
|---|---|---|
| Definitions | "X is...", "X refers to...", bold terms | Key Terms table row |
| Numbered lists | Steps, phases, principles, rules | Numbered list block β preserve order and count |
| Bullet lists | Features, properties, characteristics | Bullet block β keep every item, none dropped |
| Formulas / equations | Any mathematical expression, coverage formula, calculation | Formula box β never inline in prose |
| Worked examples | Sample calculations, case studies, code, scenarios | Example box β verbatim, never paraphrased |
| Comparisons / A vs B | Pros/cons, advantages/disadvantages, X vs Y | Two-column comparison table |
| Processes / workflows | "Steps to...", flowcharts described in text | Numbered process block |
| Diagrams described in text | "Figure shows...", "The diagram illustrates..." | Describe in a key box with a note it came from a diagram |
| Classifications / types | "Types of X are...", "Categories include..." | Card-style table or bullet block per type |
| Important notes / warnings | "Note:", "Important:", "Remember:", starred items | Key box (blue) |
| Exam hints in source | Anything the original author flagged as important | Key box with β οΈ prefix |
Zero-drop rule
Every piece of content in the source must appear somewhere in the output. If a detail doesn't fit the current section's flow, add it as a bullet under an "Additional Notes" sub-heading β but never silently drop it.
Content tree (build this mentally before generating)
Major Topic 1
βββ Definition / overview
βββ Subtopic A
β βββ Sub-definition
β βββ List of items (ALL of them)
β βββ Formula (if any)
β βββ Example (if any)
βββ Subtopic B
β βββ Comparison (if any)
β βββ Process steps (if any)
βββ Memory aid (derived)
Major Topic 2
βββ ...
Step 1 β Always Ask Mode First
NEVER start generating without knowing the mode. Ask:
"What do you need?
- π Study Notes β detailed DOCX, structured for reading and revision
- πΊοΈ Mind Map β interactive visual overview of all topics
- π Exam Prep β focused Q&A, key facts, formulas, last-minute cheat sheet
- All three"
Map responses:
| User says... | Build |
|---|---|
| "notes" / "study notes" / "revision" / "1" | Notes DOCX only |
| "mind map" / "visual" / "map" / "2" | Mind map only |
| "exam" / "exam prep" / "quiz" / "3" | Exam Prep DOCX only |
| "all" / "everything" / "4" | All three |
| Ambiguous with an exam mentioned | Exam Prep |
| Ambiguous otherwise | Ask again β never guess |
Step 2 β The One DOCX Per Output Rule
Generate exactly ONE DOCX per output type. Never split across multiple files.
Why this matters:
- Multiple files fragment attention. The brain loses context switching between docs.
- A single file = one open tab, one scroll, one flow state.
- For long content: use parts within the same document (Part 1, Part 2 headings) β not separate files.
- The document should feel like a book chapter, not a stack of handouts.
Part-splitting rules (within a single document):
- Content with 4+ major Level-1 topics β add a
PART X β [Group Name]page break heading before every 2β3 topics - Each part gets its own mini summary box at the end
- A master cheat sheet section at the very end covers everything
- Never cut content to make a doc shorter β compress the prose, not the coverage
Step 3 β Content Structuring Rules (all output types)
Hierarchy
Part I (if 4+ major topics)
Level 1 β Major Topic e.g. "Software Testing"
Level 2 β Subtopic e.g. "7 Principles of Testing"
Level 3 β Detail e.g. "Pesticide Paradox: repeated tests stop catching bugs"
Max 3 levels. Flatten anything deeper.
Compression rules
- Notes DOCX: full sentences, but every sentence earns its place. No filler.
- Exam Prep DOCX: bullet-only. One fact per bullet. No prose.
- Mind map: 2β5 word labels only. Full text lives in tooltips.
Memory aids β mandatory in every section
Pick at least ONE per Level-1 topic:
- Acronym β first letters form a word (SOLID, PEEDPCA)
- Story sentence β each word starts with the acronym's letters
- Analogy β maps the abstract to something tangible
- Formula box β for anything with numbers or steps
Output A β Study Notes DOCX
What it is
A complete structured document covering 100% of the source content β every definition, list, formula, example, comparison, and process. Built for slow careful reading. Nothing is dropped; everything is formatted for maximum retention.
Cognitive design rules
- Max 3 bullet points per block before switching to a table or a box
- No wall-of-text paragraphs β break after 4 lines with a visual element
- Alternate: paragraph β table β box β paragraph β rhythm prevents fatigue
- Formula box for every equation β formulas never buried in prose
- Mnemonic box closes every section β last thing you read = most retained
Per-content-type placement rules
| Source content | Where it goes in the document |
|---|---|
| Definition of the topic | Opening body-text paragraph |
| List of terms + meanings | Key Terms two-column table |
| Numbered steps / phases | Numbered list block under its own h3 |
| Formula / equation | box-formula β always, no exceptions |
| Worked example / calculation | box-example |
| Pros vs Cons / A vs B | Two-column comparison table |
| Important note / warning | box-key (blue) |
| Types / classifications | Bullet block or mini-table per type |
| Diagram content | box-key with note: "From figure in source" |
| Exam hints from source | box-key with β οΈ prefix |
Document structure
Cover page
[If 4+ topics: PART I β {group}]
Section 1: Topic Name
Overview paragraph (definition + scope)
Key Terms table β every term from source
[Numbered process block if source has steps]
[Formula box if source has any equation]
[Worked Example box if source has one]
[Comparison table if source has pros/cons or A vs B]
[Additional Notes β catches anything not placed above]
Mnemonic box β always last in section
Part Summary β if last section in a part
[PART II β {group}]
Section N: ...
Master Cheat Sheet (last β all topics, one-line + mnemonic each)
HTML Artifact template (renders doc + Download DOCX button)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Study Notes</title>
<script src="https://cdn.jsdelivr.net/npm/docx@8.5.0/build/index.js"></script>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: Arial, sans-serif; background: #f0f4f8; }
#toolbar {
position: sticky; top: 0; background: #1F3864; padding: 10px 24px;
display: flex; align-items: center; gap: 12px; z-index: 100;
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
}
#toolbar h1 { color: #fff; font-size: 14px; font-weight: 600; flex: 1; }
#toolbar .meta { color: #BDD7EE; font-size: 12px; }
.dl-btn {
background: #ED7D31; color: white; border: none; padding: 7px 16px;
border-radius: 5px; cursor: pointer; font-size: 13px; font-weight: 600;
}
.dl-btn:hover { background: #C8621F; }
.dl-btn:disabled { background: #888; cursor: wait; }
.doc { max-width: 820px; margin: 28px auto 60px; background: #fff;
box-shadow: 0 4px 24px rgba(0,0,0,0.12); border-radius: 8px;
overflow: hidden; }
/* Cover */
.cover { background: #1F3864; padding: 56px 48px 48px; text-align: center; }
.cover h1 { font-size: 34px; color: #fff; font-weight: 700; }
.cover .sub { font-size: 15px; color: #BDD7EE; margin-top: 10px; }
.cover .accent { width: 60px; height: 4px; background: #ED7D31; margin: 20px auto 0; border-radius: 2px; }
/* Body */
.body { padding: 40px 48px 56px; }
/* Part divider */
.part-divider { background: #EBF3FB; border-left: 5px solid #2E75B6;
padding: 12px 20px; margin: 40px 0 28px; border-radius: 0 6px 6px 0; }
.part-divider .part-label { font-size: 11px; color: #2E75B6; font-weight: 700;
text-transform: uppercase; letter-spacing: 1px; }
.part-divider h2 { font-size: 20px; color: #1F3864; font-weight: 700; margin-top: 2px; }
/* Section headings */
h2.sec { font-size: 24px; color: #1F3864; font-weight: 700;
margin: 36px 0 10px; padding-bottom: 8px; border-bottom: 2px solid #2E75B6; }
h3.sub { font-size: 18px; color: #2E75B6; font-weight: 700; margin: 22px 0 8px; }
h4.detail { font-size: 15px; color: #ED7D31; font-weight: 700; margin: 14px 0 6px; }
p.body-text { font-size: 14px; line-height: 1.75; color: #222; margin-bottom: 12px; }
ul.bl { padding-left: 22px; margin-bottom: 14px; }
ul.bl li { font-size: 14px; line-height: 1.65; margin-bottom: 5px; color: #222; }
ul.bl li strong { color: #1F3864; }
/* Tables */
table { width: 100%; border-collapse: collapse; margin: 14px 0 20px; font-size: 13px; }
th { background: #2E75B6; color: #fff; padding: 9px 14px; text-align: left; }
td { padding: 8px 14px; border-bottom: 1px solid #E0E8F0; vertical-align: top; }
tr:nth-child(even) td { background: #F6F9FC; }
/* Boxes */
.box { border-radius: 6px; padding: 14px 18px; margin: 16px 0; }
.box-label { font-size: 12px; font-weight: 700; margin-bottom: 6px; text-transform: uppercase; letter-spacing: 0.5px; }
.box-content { font-size: 13px; line-height: 1.65; }
.box-mnemonic { background: #FFF8DC; border: 1.5px solid #FFC000; }
.box-mnemonic .box-label { color: #7B5800; }
.box-mnemonic .box-content { color: #7B5800; }
.box-mnemonic .acronym { font-size: 28px; font-weight: 700; color: #ED7D31; }
.box-key { background: #EBF3FB; border: 1.5px solid #2E75B6; }
.box-key .box-label { color: #1F4E79; }
.box-example { background: #FFF8E1; border: 1.5px solid #FFC000; }
.box-example .box-label { color: #7B3F00; }
.box-formula { background: #FCE4EC; border: 1.5px solid #E91E63; text-align: center; }
.box-formula .box-label { color: #880E4F; }
.box-formula .formula-text { font-size: 20px; font-weight: 700; color: #880E4F; margin-top: 4px; font-family: 'Courier New', monospace; }
.box-formula .formula-vars { font-size: 12px; color: #880E4F; margin-top: 6px; text-align: left; }
.box-summary { background: #F0FFF0; border: 1.5px solid #70AD47; }
.box-summary .box-label { color: #2E7D32; }
/* Cheat sheet */
.cheat-header { background: #1F3864; color: #fff; padding: 10px 14px; font-weight: 700;
font-size: 15px; margin: 40px 0 0; border-radius: 6px 6px 0 0; }
</style>
</head>
<body>
<div id="toolbar">
<h1>π TOPIC_NAME β Study Notes</h1>
<span class="meta">1 document Β· all topics</span>
<button class="dl-btn" id="dlbtn" onclick="downloadDOCX()">β¬ Download DOCX</button>
</div>
<div class="doc">
<!-- COVER -->
<div class="cover">
<h1>TOPIC_NAME</h1>
<div class="sub">Study Notes Β· Unit N</div>
<div class="accent"></div>
</div>
<div class="body">
<!-- ββ PART I (use only if 4+ major topics) ββ -->
<div class="part-divider">
<div class="part-label">Part I</div>
<h2>Part Group Name</h2>
</div>
<!-- ββ Section 1 ββ -->
<h2 class="sec">1. Section Title</h2>
<p class="body-text">Overview paragraph β 2β3 sentences in plain prose. State what this section covers and why it matters.</p>
<h3 class="sub">Key Terms</h3>
<table>
<tr><th style="width:30%">Term</th><th>Explanation</th></tr>
<tr><td><strong>Term 1</strong></td><td>Explanation here</td></tr>
<tr><td><strong>Term 2</strong></td><td>Explanation here</td></tr>
</table>
<div class="box box-example">
<div class="box-label">π‘ Worked Example</div>
<div class="box-content">Example content β preserved verbatim from source. Never paraphrase examples.</div>
</div>
<!-- Formula box β use whenever source has ANY equation, formula, or calculation -->
<div class="box box-formula">
<div class="box-label">π Formula / Equation</div>
<div class="formula-text">Result = (A / B) Γ 100</div>
<div class="formula-vars">A = description of variable A Β· B = description of variable B</div>
</div>
<!-- Numbered list block β use for steps, phases, principles (in order) -->
<h3 class="sub">Process / Steps</h3>
<ol style="padding-left:22px; margin-bottom:14px; font-size:14px; line-height:1.7; color:#222;">
<li style="margin-bottom:6px"><strong>Step name:</strong> description</li>
<li style="margin-bottom:6px"><strong>Step name:</strong> description</li>
</ol>
<!-- Comparison table β use for pros/cons, A vs B, advantages/disadvantages -->
<h3 class="sub">Comparison</h3>
<table>
<tr><th style="width:50%">Advantages β
</th><th>Disadvantages β</th></tr>
<tr><td>Advantage 1</td><td>Disadvantage 1</td></tr>
<tr><td>Advantage 2</td><td>Disadvantage 2</td></tr>
</table>
<!-- Key box β for important notes, warnings, exam hints from source -->
<div class="box box-key">
<div class="box-label">β οΈ Important Note</div>
<div class="box-content">Critical information flagged in source β exam hints, "remember" callouts, warnings.</div>
</div>
<div class="box box-mnemonic">
<div class="box-label">π§ Memory Aid</div>
<div class="box-content">
<div class="acronym">ACRONYM</div>
<div style="margin-top:6px"><strong>A</strong> β First item <strong>C</strong> β Second item</div>
<div style="margin-top:8px; font-style:italic; color:#5D4037">"Story sentence where each word starts with the acronym letters"</div>
</div>
</div>
<!-- ββ Part Summary (last section of a part) ββ -->
<div class="box box-summary">
<div class="box-label">β
Part I Summary</div>
<div class="box-content">
One-line recap of each section covered in this part, in a mini bullet list.
</div>
</div>
<!-- ββ PART II ββ -->
<div class="part-divider">
<div class="part-label">Part II</div>
<h2>Next Group Name</h2>
</div>
<!-- ... repeat sections ... -->
<!-- ββ Master Cheat Sheet (always last) ββ -->
<div class="cheat-header">π Master Cheat Sheet</div>
<table>
<tr><th>Topic</th><th>One-line Summary</th><th>Mnemonic</th></tr>
<tr><td>Section 1</td><td>Summary here</td><td>ACRONYM</td></tr>
<tr><td>Section 2</td><td>Summary here</td><td>ACRONYM</td></tr>
</table>
</div><!-- /body -->
</div><!-- /doc -->
<script>
async function downloadDOCX() {
const btn = document.getElementById('dlbtn');
btn.disabled = true; btn.textContent = 'Generatingβ¦';
const { Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell,
HeadingLevel, AlignmentType, BorderStyle, WidthType, ShadingType,
LevelFormat, PageBreak } = docx;
// ββ Shared styles ββ
const border = { style: BorderStyle.SINGLE, size: 1, color: "CCCCCC" };
const borders = { top: border, bottom: border, left: border, right: border };
// ββ Helpers ββ
const sp = () => new Paragraph({ children: [new TextRun({ text: "" })] });
const h1 = t => new Paragraph({ heading: HeadingLevel.HEADING_1,
children: [new TextRun({ text: t, bold: true, size: 36, color: "1F3864", font: "Arial" })] });
const h2 = t => new Paragraph({ heading: HeadingLevel.HEADING_2,
children: [new TextRun({ text: t, bold: true, size: 28, color: "2E75B6", font: "Arial" })] });
const h3 = t => new Paragraph({ heading: HeadingLevel.HEADING_3,
children: [new TextRun({ text: t, bold: true, size: 24, color: "ED7D31", font: "Arial" })] });
const body = t => new Paragraph({ children: [new TextRun({ text: t, size: 22, font: "Arial" })] });
const bl = t => new Paragraph({ numbering: { reference: "bullets", level: 0 },
children: [new TextRun({ text: t, size: 22, font: "Arial" })] });
const partBreak = t => new Paragraph({
pageBreakBefore: true,
children: [new TextRun({ text: t, bold: true, size: 32, color: "2E75B6", font: "Arial" })] });
// ββ Box component (shaded single-cell table) ββ
const box = (label, lines, fill, textColor) => new Table({
width: { size: 9360, type: WidthType.DXA }, columnWidths: [9360],
rows: [new TableRow({ children: [new TableCell({
borders,
shading: { fill, type: ShadingType.CLEAR },
margins: { top: 120, bottom: 120, left: 200, right: 200 },
children: [
new Paragraph({ children: [new TextRun({ text: label, bold: true, size: 20, color: textColor, font: "Arial" })] }),
...lines.map(l => new Paragraph({ children: [new TextRun({ text: l, size: 20, color: textColor, font: "Arial" })] }))
]
})] })]
});
const mnemonicBox = (title, acronym, items, story) => new Table({
width: { size: 9360, type: WidthType.DXA }, columnWidths: [9360],
rows: [new TableRow({ children: [new TableCell({
borders,
shading: { fill: "FFF8DC", type: ShadingType.CLEAR },
margins: { top: 140, bottom: 140, left: 200, right: 200 },
children: [
new Paragraph({ children: [new TextRun({ text: "π§ " + title, bold: true, size: 22, color: "7B5800", font: "Arial" })] }),
new Paragraph({ children: [new TextRun({ text: acronym, bold: true, size: 40, color: "ED7D31", font: "Arial" })] }),
...items.map(i => new Paragraph({ children: [new TextRun({ text: i, size: 20, color: "7B5800", font: "Arial" })] })),
new Paragraph({ children: [new TextRun({ text: `"${story}"`, size: 20, italics: true, color: "5D4037", font: "Arial" })] })
]
})] })]
});
// ββ Formula box β use for ANY equation, formula, or calculation in source ββ
// formulaBox("Branch Coverage", "BC = (Branches Covered / Total Branches) Γ 100", ["BC = branch coverage %", "Use after every test suite run"])
const formulaBox = (label, formula, varLines = []) => new Table({
width: { size: 9360, type: WidthType.DXA }, columnWidths: [9360],
rows: [new TableRow({ children: [new TableCell({
borders,
shading: { fill: "FCE4EC", type: ShadingType.CLEAR },
margins: { top: 140, bottom: 140, left: 200, right: 200 },
children: [
new Paragraph({ alignment: AlignmentType.CENTER, children: [new TextRun({ text: "π " + label, bold: true, size: 22, color: "880E4F", font: "Arial" })] }),
new Paragraph({ alignment: AlignmentType.CENTER, children: [new TextRun({ text: formula, bold: true, size: 28, color: "880E4F", font: "Courier New" })] }),
...varLines.map(v => new Paragraph({ alignment: AlignmentType.LEFT, children: [new TextRun({ text: v, size: 18, color: "880E4F", italics: true, font: "Arial" })] }))
]
})] })]
});
// ββ Numbered list (for steps, phases, processes) β pass array of strings ββ
const numList = items => items.map(t => new Paragraph({
numbering: { reference: "numbers", level: 0 },
children: [new TextRun({ text: t, size: 22, font: "Arial" })]
}));
// ββ Two-column table ββ
const twoCol = (headers, rows, c1 = 2800, c2 = 6560) => new Table({
width: { size: 9360, type: WidthType.DXA }, columnWidths: [c1, c2],
rows: [
new TableRow({ children: headers.map((h, i) => new TableCell({
borders,
width: { size: i === 0 ? c1 : c2, type: WidthType.DXA },
shading: { fill: "2E75B6", type: ShadingType.CLEAR },
margins: { top: 80, bottom: 80, left: 120, right: 120 },
children: [new Paragraph({ children: [new TextRun({ text: h, bold: true, size: 20, color: "FFFFFF", font: "Arial" })] })]
})) }),
...rows.map(([a, b], idx) => new TableRow({ children: [
new TableCell({ borders, width: { size: c1, type: WidthType.DXA }, shading: { fill: idx % 2 === 0 ? "F2F7FF" : "FFFFFF", type: ShadingType.CLEAR }, margins: { top: 80, bottom: 80, left: 120, right: 120 }, children: [new Paragraph({ children: [new TextRun({ text: a, bold: true, size: 20, font: "Arial" })] })] }),
new TableCell({ borders, width: { size: c2, type: WidthType.DXA }, shading: { fill: idx % 2 === 0 ? "F2F7FF" : "FFFFFF", type: ShadingType.CLEAR }, margins: { top: 80, bottom: 80, left: 120, right: 120 }, children: [new Paragraph({ children: [new TextRun({ text: b, size: 20, font: "Arial" })] })] }),
] }))
]
});
// ββ BUILD DOCUMENT β mirror HTML content above exactly ββ
const doc = new Document({
numbering: { config: [
{ reference: "bullets", levels: [{ level: 0, format: LevelFormat.BULLET, text: "β’", alignment: AlignmentType.LEFT, style: { paragraph: { indent: { left: 720, hanging: 360 } } } }] },
{ reference: "numbers", levels: [{ level: 0, format: LevelFormat.DECIMAL, text: "%1.", alignment: AlignmentType.LEFT, style: { paragraph: { indent: { left: 720, hanging: 360 } } } }] },
]},
styles: {
default: { document: { run: { font: "Arial", size: 22 } } },
paragraphStyles: [
{ id: "Heading1", name: "Heading 1", basedOn: "Normal", next: "Normal", quickFormat: true,
run: { size: 36, bold: true, font: "Arial", color: "1F3864" },
paragraph: { spacing: { before: 320, after: 160 }, outlineLevel: 0 } },
{ id: "Heading2", name: "Heading 2", basedOn: "Normal", next: "Normal", quickFormat: true,
run: { size: 28, bold: true, font: "Arial", color: "2E75B6" },
paragraph: { spacing: { before: 240, after: 120 }, outlineLevel: 1 } },
{ id: "Heading3", name: "Heading 3", basedOn: "Normal", next: "Normal", quickFormat: true,
run: { size: 24, bold: true, font: "Arial", color: "ED7D31" },
paragraph: { spacing: { before: 180, after: 80 }, outlineLevel: 2 } },
]
},
sections: [{ properties: { page: {
size: { width: 12240, height: 15840 },
margin: { top: 1080, right: 1080, bottom: 1080, left: 1080 }
} }, children: [
// Cover
h1("TOPIC_NAME"),
body("Study Notes Β· Unit N"),
sp(),
// Part break (use partBreak() β triggers new page in DOCX)
partBreak("PART I β Group Name"),
sp(),
// Section
h2("1. Section Title"),
body("Overview paragraph β definition + scope of this topic. 2β3 sentences."),
sp(),
// Key Terms β every term from source goes here
h3("Key Terms"),
twoCol(["Term", "Explanation"], [
["Term 1", "Full explanation here"],
["Term 2", "Full explanation here"],
]),
sp(),
// Numbered process β use for steps/phases/principles that have an order
h3("Steps / Process"),
...numList(["Step 1: description", "Step 2: description", "Step 3: description"]),
sp(),
// Formula box β EVERY equation from source, one box per formula
formulaBox("Formula Name", "Result = (A / B) Γ 100", ["A = what A represents", "B = what B represents"]),
sp(),
// Worked example β verbatim from source
box("π‘ Worked Example", ["Example line 1", "Example line 2", "Example line 3"], "FFF8E1", "7B3F00"),
sp(),
// Comparison table β for pros/cons, A vs B, advantages/disadvantages
h3("Comparison"),
twoCol(["Advantages β
", "Disadvantages β"], [
["Advantage 1", "Disadvantage 1"],
["Advantage 2", "Disadvantage 2"],
], 4680, 4680),
sp(),
// Key/warning box β for important notes, exam hints, warnings
box("β οΈ Important Note", ["Critical info here β exam hints, warnings, 'remember' callouts"], "DEEAF1", "1F4E79"),
sp(),
// Mnemonic β always LAST in the section
mnemonicBox("Memory Aid β Topic", "ACR", ["A β First", "C β Second", "R β Third"], "A Clever Robot"),
sp(),
// Part summary β last section of a part only
box("β
Part I Summary", ["Topic 1: one line", "Topic 2: one line"], "F0FFF0", "2E7D32"),
sp(),
// Part 2 break
partBreak("PART II β Next Group"),
sp(),
// ... repeat full section pattern for every topic ...
// Cheat sheet (no page break β flows naturally at end)
sp(), h2("π Master Cheat Sheet"),
twoCol(["Topic", "Summary Β· Mnemonic"], [
["Section 1", "Summary β ACRONYM"],
["Section 2", "Summary β ACRONYM"],
], 3000, 6360),
]}]
});
const blob = await Packer.toBlob(doc);
const url = URL.createObjectURL(blob);
const a = document.createElement('a'); a.href = url;
a.download = 'StudyNotes_TOPIC.docx'; a.click();
URL.revokeObjectURL(url);
btn.disabled = false; btn.textContent = 'β¬ Download DOCX';
}
</script>
</body>
</html>
docx.js rules (critical β don't skip)
- Never use
\ninside TextRun β use separate Paragraph elements - Never use unicode bullet chars β always use
LevelFormat.BULLETwith numbering config - Numbered lists: use
LevelFormat.DECIMALwith reference"numbers"β always declare innumbering.config - All table widths in DXA;
columnWidthsarray must exactly sum to tablesize - Always use
ShadingType.CLEARβ never SOLID (causes black backgrounds) - Always set cell
marginsβ without it cells feel cramped - Formula font: use
"Courier New"for the formula string,"Arial"for labels - Part breaks: use
pageBreakBefore: trueon the Paragraph, never a standalone PageBreak element - Font:
"Arial"everywhere except formula strings ("Courier New") AlignmentTypemust be imported β required for formula box center alignment- Equal-width comparison tables:
c1 = c2 = 4680(both sum to 9360)
Output B β Interactive Mind Map (HTML Artifact)
What it is
A D3.js force-directed graph. Drag, zoom, pan, click to collapse/expand. No download β the artifact IS the output.
Cognitive design rules
- Start collapsed at Level 1 β don't dump everything at once (overwhelms)
- Max 6β8 children per node β if a topic has 10+ subtopics, group them
- Root β topic β subtopic β detail. Strict 4-level max
Full template
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mind Map</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.min.js"></script>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #0F1923; font-family: 'Segoe UI', Arial, sans-serif; overflow: hidden; }
#toolbar {
position: fixed; top: 0; left: 0; right: 0; z-index: 100;
background: #1A2A3A; padding: 10px 20px;
display: flex; align-items: center; gap: 16px; border-bottom: 2px solid #2E75B6;
}
#toolbar h1 { color: #fff; font-size: 14px; font-weight: 600; flex: 1; }
#toolbar button { background: #2E75B6; color: white; border: none; padding: 6px 14px; border-radius: 5px; cursor: pointer; font-size: 12px; }
#toolbar button:hover { background: #1F5A9B; }
.legend { display: flex; gap: 12px; align-items: center; }
.legend-item { display: flex; align-items: center; gap: 5px; color: #AAB; font-size: 11px; }
.legend-dot { width: 10px; height: 10px; border-radius: 50%; }
#svg-container { position: fixed; top: 48px; left: 0; right: 0; bottom: 0; }
svg { width: 100%; height: 100%; cursor: grab; }
svg:active { cursor: grabbing; }
.node circle { stroke-width: 2.5; cursor: pointer; transition: filter 0.2s; }
.node circle:hover { filter: brightness(1.25); }
.node.collapsed circle { opacity: 0.8; stroke-dasharray: 4 2; }
.node text { pointer-events: none; dominant-baseline: middle; text-anchor: middle; font-weight: 600; user-select: none; }
.link { fill: none; stroke-opacity: 0.45; }
#tooltip { position: fixed; background: #1A2A3A; color: #EEE; border: 1px solid #2E75B6; padding: 8px 12px; border-radius: 6px; font-size: 12px; pointer-events: none; opacity: 0; transition: opacity 0.15s; max-width: 260px; z-index: 200; }
#hint { position: fixed; bottom: 14px; right: 16px; color: #455; font-size: 11px; text-align: right; line-height: 1.7; }
</style>
</head>
<body>
<div id="toolbar">
<h1>TOPIC β Mind Map</h1>
<div class="legend">
<div class="legend-item"><div class="legend-dot" style="background:#1F3864"></div>Root</div>
<div class="legend-item"><div class="legend-dot" style="background:#2E75B6"></div>Topic</div>
<div class="legend-item"><div class="legend-dot" style="background:#ED7D31"></div>Subtopic</div>
<div class="legend-item"><div class="legend-dot" style="background:#70AD47"></div>Detail</div>
</div>
<button onclick="expandAll()">Expand All</button>
<button onclick="collapseAll()">Collapse All</button>
<button onclick="resetView()">Reset View</button>
</div>
<div id="svg-container"><svg id="map"></svg></div>
<div id="tooltip"></div>
<div id="hint">π± Drag to pan Β· Scroll to zoom Β· Click node to expand/collapse</div>
<script>
// ββ REPLACE THIS OBJECT WITH ACTUAL CONTENT ββ
const treeData = {
id: "root", label: "Subject", depth: 0,
children: [
{ id: "t1", label: "Topic 1", depth: 1, children: [
{ id: "t1a", label: "Subtopic A", depth: 2, children: [
{ id: "t1a1", label: "Detail 1", depth: 3 },
{ id: "t1a2", label: "Detail 2", depth: 3 }
]},
{ id: "t1b", label: "Subtopic B", depth: 2 }
]},
{ id: "t2", label: "Topic 2", depth: 1, children: [] }
]
};
// ββ END DATA ββ
const depthColors = { 0:"#1F3864", 1:"#2E75B6", 2:"#ED7D31", 3:"#70AD47" };
const depthRadius = { 0:52, 1:38, 2:28, 3:18 };
const depthFont = { 0:13, 1:12, 2:11, 3:9 };
const linkColors = { 0:"#2E75B6", 1:"#ED7D31", 2:"#70AD47", 3:"#888" };
const linkWidth = { 0:3, 1:2.5, 2:1.5, 3:1 };
let nodeData = [], linkData = [], svg, g, simulation, nodes, links;
const collapsed = new Set();
const tooltip = document.getElementById("tooltip");
function flattenTree(n, parent = null) {
nodeData.push({ ...n, parent: parent?.id ?? null, _children: n.children || [] });
(n.children || []).forEach(c => flattenTree(c, n));
}
function buildLinks() {
linkData = nodeData.filter(n => n.parent)
.map(n => ({ source: n.parent, target: n.id, depth: n.depth - 1 }));
}
function isAncestorCollapsed(n) {
let pid = n.parent;
while (pid) {
if (collapsed.has(pid)) return true;
pid = nodeData.find(x => x.id === pid)?.parent ?? null;
}
return false;
}
const visibleNodes = () => nodeData.filter(n => !n.parent || !isAncestorCollapsed(n));
const visibleLinks = () => { const ids = new Set(visibleNodes().map(n => n.id)); return linkData.filter(l => ids.has(l.source) && ids.has(l.target)); };
function init() {
flattenTree(treeData); buildLinks();
// Start with level-1 nodes collapsed β less overwhelming
nodeData.filter(n => n.depth === 1 && n._children?.length).forEach(n => collapsed.add(n.id));
const c = document.getElementById("svg-container");
const W = c.clientWidth, H = c.clientHeight;
svg = d3.select("#map");
const zoom = d3.zoom().scaleExtent([0.15, 3]).on("zoom", e => g.attr("transform", e.transform));
svg.call(zoom);
g = svg.append("g");
svg.call(zoom.transform, d3.zoomIdentity.translate(W/2, H/2));
simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(d => d.id).distance(d => [130,110,85,65][d.depth]||80).strength(0.85))
.force("charge", d3.forceManyBody().strength(d => [-500,-380,-280,-180][d.depth]||-250))
.force("collision", d3.forceCollide().radius(d => depthRadius[d.depth]+16))
.force("center", d3.forceCenter(0, 0))
.on("tick", ticked);
render();
}
function render() {
const vN = visibleNodes(), vL = visibleLinks();
const lSel = g.selectAll(".link").data(vL, d => d.source+"-"+d.target);
lSel.exit().remove();
links = lSel.enter().append("line").attr("class","link")
.attr("stroke", d => linkColors[d.depth]||"#888").attr("stroke-width", d => linkWidth[d.depth]||1)
.merge(lSel);
const nSel = g.selectAll(".node").data(vN, d => d.id);
nSel.exit().remove();
const nEnter = nSel.enter().append("g").attr("class","node")
.call(d3.drag()
.on("start",(e,d)=>{ if(!e.active) simulation.alphaTarget(0.3).restart(); d.fx=d.x; d.fy=d.y; })
.on("drag", (e,d)=>{ d.fx=e.x; d.fy=e.y; })
.on("end", (e,d)=>{ if(!e.active) simulation.alphaTarget(0); d.fx=d.fy=null; }))
.on("click",(e,d)=>{
e.stopPropagation();
if(d._children?.length){ collapsed.has(d.id)?collapsed.delete(d.id):collapsed.add(d.id); render(); simulation.alpha(0.3).restart(); }
})
.on("mouseover",(e,d)=>{ tooltip.style.opacity=1; tooltip.innerHTML=`<strong>${d.label}</strong>${d._children?.length?`<br><span style="color:#9AB">${d._children.length} child${d._children.length>1?'ren':''}</span>`:""}`;})
.on("mousemove",e=>{ tooltip.style.left=(e.clientX+14)+"px"; tooltip.style.top=(e.clientY-10)+"px"; })
.on("mouseout",()=>{ tooltip.style.opacity=0; });
nEnter.append("circle")
.attr("r", d=>depthRadius[d.depth]||20)
.attr("fill", d=>depthColors[d.depth]||"#888")
.attr("stroke", d=>d3.color(depthColors[d.depth]).brighter(0.6).formatHex());
nEnter.append("text").attr("fill","#fff").style("font-size",d=>depthFont[d.depth]+"px");
nodes = nEnter.merge(nSel);
nodes.select("text").text(d=>{ const m=Math.floor((depthRadius[d.depth]||20)*0.52); return d.label.length>m?d.label.slice(0,m-1)+"β¦":d.label; });
nodes.classed("collapsed",d=>collapsed.has(d.id));
simulation.nodes(vN); simulation.force("link").links(vL); simulation.alpha(0.5).restart();
}
function ticked() {
const pos = id => nodeData.find(n=>n.id===(id.id||id));
links.attr("x1",d=>pos(d.source)?.x||0).attr("y1",d=>pos(d.source)?.y||0)
.attr("x2",d=>pos(d.target)?.x||0).attr("y2",d=>pos(d.target)?.y||0);
nodes.attr("transform",d=>`translate(${d.x||0},${d.y||0})`);
}
function expandAll() { collapsed.clear(); render(); simulation.alpha(0.4).restart(); }
function collapseAll(){ nodeData.filter(n=>n._children?.length).forEach(n=>collapsed.add(n.id)); render(); simulation.alpha(0.4).restart(); }
function resetView() {
const W=document.getElementById("svg-container").clientWidth, H=document.getElementById("svg-container").clientHeight;
d3.select("#map").transition().duration(600).call(d3.zoom().transform, d3.zoomIdentity.translate(W/2,H/2).scale(1));
}
init();
</script>
</body>
</html>
How to fill the data tree
// ID rules: unique, no spaces/special chars. Scheme: t1, t1a, t1a1
// depth: root=0, topic=1, subtopic=2, detail=3
// labels: keep SHORT β auto-truncated in circle, full text in tooltip
// children: omit key entirely for leaf nodes (cleaner than empty array)
Output C β Exam Prep DOCX
What it is
A laser-focused document for the night before an exam. No prose. No intros. Just:
- Q&A pairs (fill-in-the-blank style)
- Key facts in bullet lists
- All formulas grouped
- One-line definitions
- Common traps / "examiner tricks"
- Master cheat sheet last
Cognitive design rules
- Zero prose β every line is a standalone scannable fact
- Max 5 bullets per block β then a new sub-heading
- Formula box for every equation β never buried in a sentence
- "β οΈ Common Trap" boxes β things students get wrong, call them out explicitly
- Q&A format: question first, answer hidden below or in italics β forces active recall
HTML Artifact template
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Exam Prep</title>
<script src="https://cdn.jsdelivr.net/npm/docx@8.5.0/build/index.js"></script>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: Arial, sans-serif; background: #f0f4f8; }
#toolbar {
position: sticky; top: 0; background: #1F3864; padding: 10px 24px;
display: flex; align-items: center; gap: 12px; z-index: 100;
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
}
#toolbar h1 { color: #fff; font-size: 14px; font-weight: 600; flex: 1; }
#toolbar .meta { color: #BDD7EE; font-size: 12px; }
.dl-btn { background: #ED7D31; color: white; border: none; padding: 7px 16px; border-radius: 5px; cursor: pointer; font-size: 13px; font-weight: 600; }
.dl-btn:hover { background: #C8621F; }
.dl-btn:disabled { background: #888; cursor: wait; }
.doc { max-width: 820px; margin: 28px auto 60px; background: #fff;
box-shadow: 0 4px 24px rgba(0,0,0,0.12); border-radius: 8px; overflow: hidden; }
.cover { background: #880E4F; padding: 40px 48px; text-align: center; }
.cover h1 { font-size: 30px; color: #fff; font-weight: 700; }
.cover .sub { font-size: 14px; color: #F8BBD9; margin-top: 8px; }
.cover .warn { display: inline-block; background: #ED7D31; color: #fff; padding: 4px 14px; border-radius: 20px; font-size: 12px; font-weight: 700; margin-top: 12px; }
.body { padding: 32px 48px 56px; }
h2.sec { font-size: 22px; color: #880E4F; font-weight: 700;
margin: 32px 0 10px; padding-bottom: 6px; border-bottom: 2px solid #E91E63; }
h3.sub { font-size: 16px; color: #1F3864; font-weight: 700; margin: 20px 0 8px; }
/* Q&A pairs */
.qa { margin: 10px 0; }
.qa .q { font-size: 14px; font-weight: 700; color: #1F3864; padding: 8px 12px;
background: #EBF3FB; border-left: 4px solid #2E75B6; border-radius: 0 4px 4px 0; }
.qa .a { font-size: 14px; color: #222; padding: 8px 12px 8px 16px;
border-left: 4px solid #70AD47; background: #F0FFF0; border-radius: 0 4px 4px 0; margin-top: 2px; }
/* Key facts list */
ul.facts { padding-left: 20px; margin: 10px 0 16px; }
ul.facts li { font-size: 13px; line-height: 1.65; margin-bottom: 5px; color: #222; }
ul.facts li strong { color: #1F3864; }
/* Boxes */
.box { border-radius: 6px; padding: 12px 16px; margin: 12px 0; }
.box-label { font-size: 11px; font-weight: 700; margin-bottom: 6px; text-transform: uppercase; letter-spacing: 0.5px; }
.box-content { font-size: 13px; line-height: 1.6; }
.box-formula { background: #FCE4EC; border: 1.5px solid #E91E63; text-align: center; }
.box-formula .box-label { color: #880E4F; }
.box-formula .formula-text { font-size: 20px; font-weight: 700; color: #880E4F; margin-top: 4px; }
.box-trap { background: #FFF3E0; border: 1.5px solid #FF9800; }
.box-trap .box-label { color: #E65100; }
.box-trap .box-content { color: #BF360C; }
.box-mnemonic { background: #FFF8DC; border: 1.5px solid #FFC000; }
.box-mnemonic .box-label { color: #7B5800; }
.box-mnemonic .acronym { font-size: 26px; font-weight: 700; color: #ED7D31; }
/* Cheat sheet */
table { width: 100%; border-collapse: collapse; margin: 14px 0 20px; font-size: 13px; }
th { background: #880E4F; color: #fff; padding: 9px 14px; text-align: left; }
td { padding: 7px 14px; border-bottom: 1px solid #E0E8F0; vertical-align: top; }
tr:nth-child(even) td { background: #FFF0F5; }
</style>
</head>
<body>
<div id="toolbar">
<h1>π TOPIC_NAME β Exam Prep</h1>
<span class="meta">Quick facts Β· Q&A Β· Formulas</span>
<button class="dl-btn" id="dlbtn" onclick="downloadDOCX()">β¬ Download DOCX</button>
</div>
<div class="doc">
<div class="cover">
<h1>TOPIC_NAME</h1>
<div class="sub">Exam Prep Β· Focus Pack</div>
<div class="warn">β‘ Last-Minute Ready</div>
</div>
<div class="body">
<!-- ββ Section 1 ββ -->
<h2 class="sec">1. Topic Name</h2>
<h3 class="sub">Q&A β Active Recall</h3>
<div class="qa">
<div class="q">Q: What is [concept]?</div>
<div class="a">A: [Answer β one clear sentence]</div>
</div>
<div class="qa">
<div class="q">Q: What does [acronym] stand for?</div>
<div class="a">A: [Full expansion]</div>
</div>
<h3 class="sub">Key Facts</h3>
<ul class="facts">
<li><strong>Fact name:</strong> one-line fact</li>
<li><strong>Fact name:</strong> one-line fact</li>
<li><strong>Fact name:</strong> one-line fact</li>
</ul>
<div class="box box-formula">
<div class="box-label">π Formula</div>
<div class="formula-text">Formula = Expression</div>
<div class="box-content" style="margin-top:6px">What each variable means</div>
</div>
<div class="box box-trap">
<div class="box-label">β οΈ Common Trap</div>
<div class="box-content">What students confuse or get wrong. Be explicit.</div>
</div>
<div class="box box-mnemonic">
<div class="box-label">π§ Mnemonic</div>
<div class="box-content">
<div class="acronym">ACRONYM</div>
<div style="margin-top:4px; color:#7B5800; font-size:13px">"Story sentence here"</div>
</div>
</div>
<!-- ... repeat for each topic ... -->
<!-- ββ Cheat Sheet ββ -->
<h2 class="sec">β‘ Master Cheat Sheet</h2>
<table>
<tr><th>Topic</th><th>Key Fact</th><th>Formula / Mnemonic</th></tr>
<tr><td>Topic 1</td><td>Core fact</td><td>ACRONYM</td></tr>
<tr><td>Topic 2</td><td>Core fact</td><td>Formula</td></tr>
</table>
</div>
</div>
<script>
async function downloadDOCX() {
const btn = document.getElementById('dlbtn');
btn.disabled = true; btn.textContent = 'Generatingβ¦';
const { Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell,
HeadingLevel, AlignmentType, BorderStyle, WidthType, ShadingType, LevelFormat } = docx;
const border = { style: BorderStyle.SINGLE, size: 1, color: "CCCCCC" };
const borders = { top: border, bottom: border, left: border, right: border };
const sp = () => new Paragraph({ children: [new TextRun({ text: "" })] });
const h1 = t => new Paragraph({ heading: HeadingLevel.HEADING_1, children: [new TextRun({ text: t, bold: true, size: 36, color: "880E4F", font: "Arial" })] });
const h2 = t => new Paragraph({ heading: HeadingLevel.HEADING_2, children: [new TextRun({ text: t, bold: true, size: 26, color: "1F3864", font: "Arial" })] });
const bl = t => new Paragraph({ numbering: { reference: "bullets", level: 0 }, children: [new TextRun({ text: t, size: 20, font: "Arial" })] });
const qLine = (label, text, color) => new Paragraph({
shading: { fill: color, type: ShadingType.CLEAR },
children: [new TextRun({ text: label + " ", bold: true, size: 20, color: "1F3864", font: "Arial" }), new TextRun({ text, size: 20, font: "Arial" })]
});
const box = (label, lines, fill, textColor) => new Table({
width: { size: 9360, type: WidthType.DXA }, columnWidths: [9360],
rows: [new TableRow({ children: [new TableCell({
borders,
shading: { fill, type: ShadingType.CLEAR },
margins: { top: 120, bottom: 120, left: 200, right: 200 },
children: [
new Paragraph({ children: [new TextRun({ text: label, bold: true, size: 20, color: textColor, font: "Arial" })] }),
...lines.map(l => new Paragraph({ children: [new TextRun({ text: l, size: 20, font: "Arial" })] }))
]
})] })]
});
const twoCol = (headers, rows, c1=2800, c2=6560) => new Table({
width: { size: 9360, type: WidthType.DXA }, columnWidths: [c1, c2],
rows: [
new TableRow({ children: headers.map((h,i) => new TableCell({ borders, width: { size: i===0?c1:c2, type: WidthType.DXA }, shading: { fill: "880E4F", type: ShadingType.CLEAR }, margins: { top: 80, bottom: 80, left: 120, right: 120 }, children: [new Paragraph({ children: [new TextRun({ text: h, bold: true, size: 20, color: "FFFFFF", font: "Arial" })] })] })) }),
...rows.map(([a,b],idx) => new TableRow({ children: [
new TableCell({ borders, width: { size: c1, type: WidthType.DXA }, shading: { fill: idx%2===0?"FFF0F5":"FFFFFF", type: ShadingType.CLEAR }, margins: { top: 80, bottom: 80, left: 120, right: 120 }, children: [new Paragraph({ children: [new TextRun({ text: a, bold: true, size: 20, font: "Arial" })] })] }),
new TableCell({ borders, width: { size: c2, type: WidthType.DXA }, shading: { fill: idx%2===0?"FFF0F5":"FFFFFF", type: ShadingType.CLEAR }, margins: { top: 80, bottom: 80, left: 120, right: 120 }, children: [new Paragraph({ children: [new TextRun({ text: b, size: 20, font: "Arial" })] })] }),
] }))
]
});
// ββ BUILD DOCUMENT β mirror HTML content ββ
const doc = new Document({
numbering: { config: [{ reference: "bullets", levels: [{ level: 0, format: LevelFormat.BULLET, text: "β’", alignment: AlignmentType.LEFT, style: { paragraph: { indent: { left: 720, hanging: 360 } } } }] }] },
styles: {
default: { document: { run: { font: "Arial", size: 22 } } },
paragraphStyles: [
{ id: "Heading1", name: "Heading 1", basedOn: "Normal", next: "Normal", quickFormat: true, run: { size: 36, bold: true, font: "Arial", color: "880E4F" }, paragraph: { spacing: { before: 320, after: 160 }, outlineLevel: 0 } },
{ id: "Heading2", name: "Heading 2", basedOn: "Normal", next: "Normal", quickFormat: true, run: { size: 26, bold: true, font: "Arial", color: "1F3864" }, paragraph: { spacing: { before: 200, after: 100 }, outlineLevel: 1 } },
]
},
sections: [{ properties: { page: {
size: { width: 12240, height: 15840 },
margin: { top: 1080, right: 1080, bottom: 1080, left: 1080 }
} }, children: [
h1("TOPIC_NAME β Exam Prep"),
sp(),
h2("1. Topic Name"),
h2("Q&A β Active Recall"),
// Q&A pairs
qLine("Q:", "What is [concept]?", "EBF3FB"),
qLine("A:", "Answer here.", "F0FFF0"),
sp(),
h2("Key Facts"),
bl("Fact name: one-line fact"),
bl("Fact name: one-line fact"),
sp(),
box("π Formula", ["Formula = Expression", "Variable meanings here"], "FCE4EC", "880E4F"),
sp(),
box("β οΈ Common Trap", ["What students confuse / get wrong"], "FFF3E0", "E65100"),
sp(),
box("π§ Mnemonic", ["ACRONYM", "Story sentence here"], "FFF8DC", "7B5800"),
sp(),
// ... repeat for each topic ...
h1("β‘ Master Cheat Sheet"),
twoCol(["Topic", "Key Fact Β· Mnemonic"], [
["Topic 1", "Core fact β ACRONYM"],
["Topic 2", "Core fact β Formula"],
], 3000, 6360),
]}]
});
const blob = await Packer.toBlob(doc);
const url = URL.createObjectURL(blob);
const a = document.createElement('a'); a.href = url;
a.download = 'ExamPrep_TOPIC.docx'; a.click();
URL.revokeObjectURL(url);
btn.disabled = false; btn.textContent = 'β¬ Download DOCX';
}
</script>
</body>
</html>
Quality Checklist
Before delivering any artifact:
All outputs:
- Mode was asked and confirmed before generating
- Zero-drop β every piece of source content mapped to an output element before starting
- All Level-1 topics from source are covered β nothing dropped
- Max 3-level hierarchy everywhere
- Every section has at least one memory aid
- Worked examples preserved verbatim β never paraphrased
- Every formula/equation in a dedicated box β never inline in prose or bullets
Notes DOCX:
- Zero-drop β every definition, list, formula, example, comparison from source is present
- Single file β no split across multiple artifacts
- 4+ topics β Part breaks within same document
- Every formula/equation in a
formulaBoxβ never in prose - Every worked example in an
exampleBoxβ never paraphrased - Every pros/cons or A vs B as a comparison table
- Every numbered process as a numbered list block
- Important notes / exam hints as key boxes
- Max 3 bullets per block before switching to table/box
- Mnemonic box is the last element in each section
- Master Cheat Sheet at end
Mind Map:
- Starts collapsed at Level 1
- No node has more than 8 children (group if needed)
- Zoom, pan, expand/collapse all work
- D3 loads from cdnjs CDN
Exam Prep DOCX:
- Zero prose β only Q&A, bullets, boxes
- Every formula in a formula box β never in a sentence
- Common Trap box per section (if applicable)
- Max 5 bullets per sub-heading block
- Master Cheat Sheet at end
DOCX generation (both):
- No
\ninside TextRun β separate Paragraphs - No unicode bullets β LevelFormat.BULLET only
- All table widths DXA, columnWidths sum to table size
- ShadingType.CLEAR everywhere
- Font: Arial throughout
CDN Reference
| Library | URL | Used for |
|---|---|---|
| D3.js v7 | https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.min.js |
Mind map |
| docx 8.5 | https://cdn.jsdelivr.net/npm/docx@8.5.0/build/index.js |
Notes + Exam Prep DOCX download |