Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | // API route for generating compact addition problem examples for display option previews // // REUSABLE FOR BLOG POSTS: The generateExampleTypst function below is also used // to generate static single-problem examples for blog posts. See: // - scripts/generateTenFrameExamples.ts for the blog post example generator // - scripts/generateBlogExamples.ts for difficulty progression examples // // This ensures blog post examples use the EXACT same rendering as the live UI preview, // maintaining consistency between what users see in documentation vs. the actual tool. import { execSync } from 'child_process' import { NextResponse } from 'next/server' import type { WorksheetOperator } from '@/app/create/worksheets/types' import { generatePlaceValueColors, generateProblemStackFunction, generateSubtractionProblemStackFunction, generateTypstHelpers, } from '@/app/create/worksheets/typstHelpers' import { withAuth } from '@/lib/auth/withAuth' export const dynamic = 'force-dynamic' interface ExampleRequest { showCarryBoxes?: boolean showAnswerBoxes?: boolean showPlaceValueColors?: boolean showProblemNumbers?: boolean showCellBorder?: boolean showTenFrames?: boolean showTenFramesForAll?: boolean showBorrowNotation?: boolean showBorrowingHints?: boolean fontSize?: number operator?: WorksheetOperator // For addition addend1?: number addend2?: number // For subtraction minuend?: number subtrahend?: number } /** * Generate a single compact problem example showing the combined display options * Uses the EXACT same Typst structure as the full worksheet generator */ function generateExampleTypst(config: ExampleRequest): string { const operator = config.operator ?? 'addition' const fontSize = config.fontSize || 14 const cellSize = 0.35 // Compact cell size for examples // Boolean flags matching worksheet generator const showCarries = config.showCarryBoxes ?? false const showAnswers = config.showAnswerBoxes ?? false const showColors = config.showPlaceValueColors ?? false const showNumbers = config.showProblemNumbers ?? false const showTenFrames = config.showTenFrames ?? false const showTenFramesForAll = config.showTenFramesForAll ?? false const showBorrowNotation = config.showBorrowNotation ?? true const showBorrowingHints = config.showBorrowingHints ?? false if (operator === 'addition') { // Use custom addends if provided, otherwise use a 3-digit problem with multiple regroups let a: number let b: number if (config.addend1 !== undefined && config.addend2 !== undefined) { a = config.addend1 b = config.addend2 } else { // Use a 3-digit problem with multiple regroups to demonstrate all scaffolding features // 456 + 789 = 1245 (3 digits, 3 regroups: ones, tens, hundreds) a = 456 b = 789 } return String.raw` #set page(width: auto, height: auto, margin: 8pt, fill: white) #set text(size: ${fontSize}pt, font: "New Computer Modern Math") #let heavy-stroke = 0.8pt #let show-carries = ${showCarries ? 'true' : 'false'} #let show-answers = ${showAnswers ? 'true' : 'false'} #let show-colors = ${showColors ? 'true' : 'false'} #let show-numbers = ${showNumbers ? 'true' : 'false'} #let show-ten-frames = ${showTenFrames ? 'true' : 'false'} #let show-ten-frames-for-all = ${showTenFramesForAll ? 'true' : 'false'} ${generatePlaceValueColors()} ${generateTypstHelpers(cellSize)} ${generateProblemStackFunction(cellSize, 3)} #let a = ${a} #let b = ${b} #align(center + horizon)[ #problem-stack(a, b, if show-numbers { 0 } else { none }, show-carries, show-answers, show-colors, show-ten-frames, show-numbers) ] ` } else { // Subtraction let minuend: number let subtrahend: number if (config.minuend !== undefined && config.subtrahend !== undefined) { minuend = config.minuend subtrahend = config.subtrahend } else { // Use a 3-digit problem with multiple borrows to demonstrate all scaffolding features // 832 - 456 = 376 (3 digits, 2 borrows: ones and tens) minuend = 832 subtrahend = 456 } return String.raw` #set page(width: auto, height: auto, margin: 8pt, fill: white) #set text(size: ${fontSize}pt, font: "New Computer Modern Math") #let heavy-stroke = 0.8pt #let show-borrows = ${showCarries ? 'true' : 'false'} #let show-answers = ${showAnswers ? 'true' : 'false'} #let show-colors = ${showColors ? 'true' : 'false'} #let show-numbers = ${showNumbers ? 'true' : 'false'} #let show-ten-frames = ${showTenFrames ? 'true' : 'false'} #let show-ten-frames-for-all = ${showTenFramesForAll ? 'true' : 'false'} #let show-borrow-notation = ${showBorrowNotation ? 'true' : 'false'} #let show-borrowing-hints = ${showBorrowingHints ? 'true' : 'false'} ${generatePlaceValueColors()} ${generateTypstHelpers(cellSize)} ${generateSubtractionProblemStackFunction(cellSize, 3)} #let minuend = ${minuend} #let subtrahend = ${subtrahend} #align(center + horizon)[ #subtraction-problem-stack(minuend, subtrahend, if show-numbers { 0 } else { none }, show-borrows, show-answers, show-colors, show-ten-frames, show-numbers, show-borrow-notation, show-borrowing-hints) ] ` } } export const POST = withAuth(async (request) => { try { const body: ExampleRequest = await request.json() // Generate Typst source with all display options const typstSource = generateExampleTypst(body) // Compile to SVG const svg = execSync('typst compile --format svg - -', { input: typstSource, encoding: 'utf8', maxBuffer: 2 * 1024 * 1024, }) return NextResponse.json({ svg }) } catch (error) { console.error('Error generating example:', error) const errorMessage = error instanceof Error ? error.message : String(error) return NextResponse.json( { error: 'Failed to generate example', message: errorMessage, }, { status: 500 } ) } }) |