8.8 KiB
Math Tasks Generator
Printable math worksheet generator (A4 PDF) for children aged 7–9. Claude Code-driven workflow: user describes a task idea → Claude generates JSON config → creates HTML pages with Tailwind CSS → converts to PDF via Puppeteer.
No template engine. Claude Code generates fresh HTML pages directly from JSON task configs each time.
Commands
npm run build:css # Build Tailwind CSS (minified)
npm run build:css:watch # Watch mode for CSS
npm run preview # Serve HTML at localhost:3000
npm run dev # CSS watch + preview server (concurrent)
npm run pdf -- <file> # Convert HTML file to PDF
npm run remove-bg -- <file|dir> # Remove white background from PNG icons
Generate images via Banatie API:
node src/scripts/banatie.mjs --type background --prompt "forest theme" --output assets/backgrounds/forest.png
node src/scripts/banatie.mjs --type icon --prompt "golden star" --output assets/icons/stars/star1.png
Directory Structure
src/
styles/main.css — Tailwind source with A4/print styles
templates/space-base.html — Base template (layout/styling reference)
examples/space-worksheet2.html — Finished 3-page example (output reference)
scripts/
generate-pdf.mjs — HTML → PDF via Puppeteer
banatie.mjs — Banatie API client for image generation
remove-bg.mjs — Remove white background from PNGs (flood fill)
tasks/ — JSON task definition files
assets/
hero-images/ — spaceship1-6.jpeg (header hero images)
footers/ — planet1-6.jpeg (footer panorama images)
icons/pack1/ — minerals1-6 + plants1-6, 16 variants each ({name}-{row}-{col}.png)
backgrounds/ — large background images per theme (~1200x1700px)
output/
html/ — generated HTML (gitignored)
pdf/ — generated PDFs (gitignored)
css/ — built Tailwind CSS (gitignored)
JSON Task Format
Each task is a JSON file in tasks/ defining a multi-page document. See tasks/space-exploration-1.json for a real example.
{
"id": "space-exploration-1",
"title": "Исследуй Планету",
"description": "3-page space worksheet: addition ±, multiply by 5 ±, multiplication table ±",
"labels": {
"title": "Исследуй Планету",
"subtitle": "Собери ресурсы, решая примеры!",
"footerBubble": "Итого собрано на планете:"
},
"theme": {
"style": "space",
"template": "space-base",
"icons": "assets/icons/pack1/"
},
"layout": {
"columns": 2,
"problemsPerPage": 20
},
"pages": [
{
"task": "A + B ± C, где A от 8 до 16, B от 4 до 8, C от 1 до 3. Знак ± выбирается случайно",
"problemCount": 20,
"heroImage": "assets/hero-images/spaceship2.jpeg",
"footerImage": "assets/footers/planet3.jpeg",
"heroDirection": "row-reverse"
}
]
}
Fields
- pages[] — array of pages, each with its own task and images
- pages[].task — free-text description of problems to generate (Claude reads this and creates concrete expressions)
- pages[].problemCount — how many problems on this page
- pages[].heroImage — path to hero image for this page
- pages[].footerImage — path to footer panorama for this page
- pages[].heroDirection —
row(hero left) orrow-reverse(hero right) - layout.columns — 1 or 2 column layout
- layout.problemsPerPage — max problems per A4 page
- labels — all visible text (no hardcoded language)
- theme.style — visual theme name (e.g. "space")
- theme.template — which base template to use (e.g. "space-base")
- theme.icons — path to icon directory for problem cards
Space Base Template
Base template: src/templates/space-base.html
Finished example: src/examples/space-worksheet2.html (3-page output matching tasks/space-worksheet2.json)
The base template defines the visual design for all space-themed worksheets. The example shows a complete generated document. When generating a new worksheet, read both files first, then produce a new HTML with these variations:
What to vary per worksheet
- Hero image — pick one from
assets/hero-images/spaceship{1-6}.jpeg - Footer image — pick one from
assets/footers/planet{1-6}.jpeg - Hero position — use
flex-row-reverseclass (hero right) or default flex direction (hero left) on the header div - Problem icons — pick from
assets/icons/pack1/(minerals and plants, any variant{name}-{row}-{col}.png). Every icon must be unique across the entire document (no repeats across pages). Shuffle minerals and plants together randomly — do not sort by type - Problem alignment — for each problem card, randomly assign
justify-start,justify-center, orjustify-endwithin its grid column. No repeating patterns — should look chaotic/scattered - Title, subtitle, footer text — set from the task description
- Problems — generate directly from the
tasktext in JSON config. Claude reads the free-text description and creates concrete math expressions
Layout structure (do not change)
- Page:
w-[210mm] h-[297mm]white container - Footer: absolute bottom,
h-[80mm], with white-to-transparent fade on top. Nooverflow-hiddenon footer container (causes 1px hairline artifact in PDF) - Footer bubble: absolute
bottom-[12mm], pill-shaped with semi-transparent white bg - Content area:
px-[12mm] pt-[4mm] pb-[65mm]flex column - Header: hero image
w-[48%]+ title block centered, useflex-row-reversefor hero-right - Footer gradient:
linear-gradient(to bottom, white 0%, rgba(255,255,255,0.6) 25%, transparent 50%)withh-full - Problems:
grid grid-cols-2 gap-x-3 gap-y-[3px]— 20 problems total - Each problem: 58px icon outside pill +
text-[1.2rem]expression +w-16answer underline inside pill - Font: Nunito via Google Fonts
- Uses Tailwind CDN (
<script src="https://cdn.tailwindcss.com">)
Color palette (do not change)
| Element | Hex |
|---|---|
| Title text | text-indigo-950 (#1e1b4b) |
| Subtitle | text-indigo-400 (#6366f1) |
| Card border | border-indigo-100 (#e0e7ff) |
| Answer underline | border-indigo-300 (#a5b4fc) |
| Card bg gradient | from-white to-indigo-50/40 |
| Footer bubble border | border-indigo-200 |
HTML Generation Guidelines
When generating HTML worksheets:
- Always read
src/templates/space-base.html(structure) andsrc/examples/space-worksheet.html(finished output) before generating - Page size: A4 = 210mm × 297mm
- CSS: Uses Tailwind CDN in the HTML
<script>tag (not the compiled CSS file) - Page breaks: Use
break-after: pagebetween pages - Icons: 58×58px inline images from
assets/icons/next to each problem (outside the pill card) - Fonts: Nunito from Google Fonts via
<link> - Images in PDF: Use local file paths (not URLs). Puppeteer resolves
file://protocol - Embed images as base64 data URIs when possible for reliable PDF rendering
Banatie API
REST API for generating images.
- Backgrounds: ~1200×1700px, themed illustrations (forest, space, ocean, etc.)
- Icons: 128×128px, transparent PNG, simple collectible items (stars, gems, animals)
Configuration is in src/scripts/banatie.mjs. Set the BANATIE_API_KEY environment variable for authentication.
Background Removal
Script src/scripts/remove-bg.mjs removes white backgrounds from PNG icons using flood-fill from edges (like magic wand in Photoshop). Uses sharp. White areas inside objects are preserved.
node src/scripts/remove-bg.mjs <file|dir> [--threshold N] [--fuzz N]
--threshold— whiteness threshold for R,G,B (default: 230, lower = more aggressive)--fuzz— anti-alias radius in pixels at the boundary (default: 0)- Default input:
assets/icons/pack2/
This is optional — not all icons need it. After generating/splitting new icons, ask the user if they want background removal on specific files.
PDF Generation
Puppeteer settings for A4 worksheets:
- Format: A4
printBackground: true(required for background images)- Margins: zero (CSS handles margins)
preferCSSPageSize: true
Workflow
- User describes the math task idea (or runs
/new-doc) - Claude creates/updates a JSON config in
tasks/withpages[].taskdescriptions - Claude reads
src/templates/space-base.html+src/examples/space-worksheet.htmlas references - Claude generates HTML file in
output/html/— creates concrete problems fromtasktext, assigns unique shuffled icons, builds all pages - Run
npm run pdf -- output/html/<file>.htmlto create PDF - Preview with
npm run previewat localhost:3000