fix(worksheets): correct Typst array membership syntax for ten-frames rendering
Fix ten-frames not rendering on worksheets when scaffolding rules called for them. The issue was in the Typst template code using incorrect syntax for checking array membership. Typst requires `.contains(item)` method, not `(item in array)`. Changes: - typstHelpers.ts:203: Change `(i in regrouping-places)` to `regrouping-places.contains(i)` - answerRow.ts:52: Change `(i in borrow-places)` to `borrow-places.contains(i)` This was causing `shows-frame` to evaluate incorrectly, preventing ten-frames from rendering even when displayRules.tenFrames was set to 'whenRegrouping' and the problem had actual regrouping. Affects both addition and subtraction worksheets. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
26a08859d7
commit
14b359462f
|
|
@ -5,16 +5,16 @@
|
||||||
// for backward compatibility. New code should import from typstHelpers/ directly.
|
// for backward compatibility. New code should import from typstHelpers/ directly.
|
||||||
|
|
||||||
// Import types for internal use
|
// Import types for internal use
|
||||||
import type { DisplayOptions } from "./typstHelpers/shared/types";
|
import type { DisplayOptions } from './typstHelpers/shared/types'
|
||||||
|
|
||||||
// Re-export everything from modular structure
|
// Re-export everything from modular structure
|
||||||
export type {
|
export type {
|
||||||
DisplayOptions,
|
DisplayOptions,
|
||||||
CellDimensions,
|
CellDimensions,
|
||||||
} from "./typstHelpers/shared/types";
|
} from './typstHelpers/shared/types'
|
||||||
export { generateTypstHelpers } from "./typstHelpers/shared/helpers";
|
export { generateTypstHelpers } from './typstHelpers/shared/helpers'
|
||||||
export { generatePlaceValueColors } from "./typstHelpers/shared/colors";
|
export { generatePlaceValueColors } from './typstHelpers/shared/colors'
|
||||||
export { generateSubtractionProblemStackFunction } from "./typstHelpers/subtraction/problemStack";
|
export { generateSubtractionProblemStackFunction } from './typstHelpers/subtraction/problemStack'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate Typst function for rendering problem stack/grid
|
* Generate Typst function for rendering problem stack/grid
|
||||||
|
|
@ -24,23 +24,20 @@ export { generateSubtractionProblemStackFunction } from "./typstHelpers/subtract
|
||||||
* @param cellSize Size of each digit cell in inches
|
* @param cellSize Size of each digit cell in inches
|
||||||
* @param maxDigits Maximum number of digits in any problem on this page (1-6)
|
* @param maxDigits Maximum number of digits in any problem on this page (1-6)
|
||||||
*/
|
*/
|
||||||
export function generateProblemStackFunction(
|
export function generateProblemStackFunction(cellSize: number, maxDigits: number = 3): string {
|
||||||
cellSize: number,
|
const cellSizeIn = `${cellSize}in`
|
||||||
maxDigits: number = 3,
|
const cellSizePt = cellSize * 72
|
||||||
): string {
|
|
||||||
const cellSizeIn = `${cellSize}in`;
|
|
||||||
const cellSizePt = cellSize * 72;
|
|
||||||
|
|
||||||
// Generate place value color assignments (unique color per place value)
|
// Generate place value color assignments (unique color per place value)
|
||||||
// Index 0 = ones, 1 = tens, 2 = hundreds, 3 = thousands, 4 = ten-thousands, 5 = hundred-thousands
|
// Index 0 = ones, 1 = tens, 2 = hundreds, 3 = thousands, 4 = ten-thousands, 5 = hundred-thousands
|
||||||
const placeColors = [
|
const placeColors = [
|
||||||
"color-ones", // 0: ones (light blue)
|
'color-ones', // 0: ones (light blue)
|
||||||
"color-tens", // 1: tens (light green)
|
'color-tens', // 1: tens (light green)
|
||||||
"color-hundreds", // 2: hundreds (light yellow)
|
'color-hundreds', // 2: hundreds (light yellow)
|
||||||
"color-thousands", // 3: thousands (light pink/rose)
|
'color-thousands', // 3: thousands (light pink/rose)
|
||||||
"color-ten-thousands", // 4: ten-thousands (light purple/lavender)
|
'color-ten-thousands', // 4: ten-thousands (light purple/lavender)
|
||||||
"color-hundred-thousands", // 5: hundred-thousands (light peach/orange)
|
'color-hundred-thousands', // 5: hundred-thousands (light peach/orange)
|
||||||
];
|
]
|
||||||
|
|
||||||
return String.raw`
|
return String.raw`
|
||||||
// Problem rendering function for addition worksheets (supports 1-${maxDigits} digit problems)
|
// Problem rendering function for addition worksheets (supports 1-${maxDigits} digit problems)
|
||||||
|
|
@ -48,7 +45,7 @@ export function generateProblemStackFunction(
|
||||||
// Per-problem display flags: show-carries, show-answers, show-colors, show-ten-frames, show-numbers
|
// Per-problem display flags: show-carries, show-answers, show-colors, show-ten-frames, show-numbers
|
||||||
#let problem-stack(a, b, index-or-none, show-carries, show-answers, show-colors, show-ten-frames, show-numbers) = {
|
#let problem-stack(a, b, index-or-none, show-carries, show-answers, show-colors, show-ten-frames, show-numbers) = {
|
||||||
// Place value colors array for dynamic lookup (index 0 = ones, 1 = tens, ...)
|
// Place value colors array for dynamic lookup (index 0 = ones, 1 = tens, ...)
|
||||||
let place-colors = (${placeColors.join(", ")})
|
let place-colors = (${placeColors.join(', ')})
|
||||||
|
|
||||||
// Extract digits dynamically based on problem size
|
// Extract digits dynamically based on problem size
|
||||||
let max-digits = ${maxDigits}
|
let max-digits = ${maxDigits}
|
||||||
|
|
@ -203,7 +200,7 @@ export function generateProblemStackFunction(
|
||||||
[], // Empty cell for + sign column
|
[], // Empty cell for + sign column
|
||||||
// Show ten-frames for any place value that needs regrouping
|
// Show ten-frames for any place value that needs regrouping
|
||||||
..for i in range(0, actual-digits).rev() {
|
..for i in range(0, actual-digits).rev() {
|
||||||
let shows-frame = show-ten-frames-for-all or (i in regrouping-places)
|
let shows-frame = show-ten-frames-for-all or regrouping-places.contains(i)
|
||||||
if shows-frame {
|
if shows-frame {
|
||||||
// Show ten-frame for this place value
|
// Show ten-frame for this place value
|
||||||
// Top frame: carry destination (next higher place value)
|
// Top frame: carry destination (next higher place value)
|
||||||
|
|
@ -246,7 +243,7 @@ export function generateProblemStackFunction(
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
`;
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -274,10 +271,10 @@ export function generateProblemTypst(
|
||||||
addend2: number,
|
addend2: number,
|
||||||
cellSize: number,
|
cellSize: number,
|
||||||
options: DisplayOptions,
|
options: DisplayOptions,
|
||||||
problemNumber?: number,
|
problemNumber?: number
|
||||||
): string {
|
): string {
|
||||||
const cellSizeIn = `${cellSize}in`;
|
const cellSizeIn = `${cellSize}in`
|
||||||
const cellSizePt = cellSize * 72;
|
const cellSizePt = cellSize * 72
|
||||||
|
|
||||||
return String.raw`
|
return String.raw`
|
||||||
#let a = ${addend1}
|
#let a = ${addend1}
|
||||||
|
|
@ -299,7 +296,7 @@ export function generateProblemTypst(
|
||||||
#text(size: ${(cellSizePt * 0.6).toFixed(1)}pt, weight: "bold", font: "New Computer Modern Math")[\\#${problemNumber}.]
|
#text(size: ${(cellSizePt * 0.6).toFixed(1)}pt, weight: "bold", font: "New Computer Modern Math")[\\#${problemNumber}.]
|
||||||
]
|
]
|
||||||
],`
|
],`
|
||||||
: ""
|
: ''
|
||||||
}
|
}
|
||||||
grid(
|
grid(
|
||||||
columns: (0.5em, ${cellSizeIn}, ${cellSizeIn}, ${cellSizeIn}),
|
columns: (0.5em, ${cellSizeIn}, ${cellSizeIn}, ${cellSizeIn}),
|
||||||
|
|
@ -310,41 +307,31 @@ export function generateProblemTypst(
|
||||||
${
|
${
|
||||||
options.showCarryBoxes
|
options.showCarryBoxes
|
||||||
? options.showPlaceValueColors
|
? options.showPlaceValueColors
|
||||||
? "diagonal-split-box(" +
|
? 'diagonal-split-box(' + cellSizeIn + ', color-tens, color-hundreds),'
|
||||||
cellSizeIn +
|
: 'box(width: ' + cellSizeIn + ', height: ' + cellSizeIn + ', stroke: 0.5pt)[],'
|
||||||
", color-tens, color-hundreds),"
|
: 'v(' + cellSizeIn + '),'
|
||||||
: "box(width: " +
|
|
||||||
cellSizeIn +
|
|
||||||
", height: " +
|
|
||||||
cellSizeIn +
|
|
||||||
", stroke: 0.5pt)[],"
|
|
||||||
: "v(" + cellSizeIn + "),"
|
|
||||||
}
|
}
|
||||||
// Tens carry box: shows carry FROM ones (blue) TO tens (green)
|
// Tens carry box: shows carry FROM ones (blue) TO tens (green)
|
||||||
${
|
${
|
||||||
options.showCarryBoxes
|
options.showCarryBoxes
|
||||||
? options.showPlaceValueColors
|
? options.showPlaceValueColors
|
||||||
? "diagonal-split-box(" + cellSizeIn + ", color-ones, color-tens),"
|
? 'diagonal-split-box(' + cellSizeIn + ', color-ones, color-tens),'
|
||||||
: "box(width: " +
|
: 'box(width: ' + cellSizeIn + ', height: ' + cellSizeIn + ', stroke: 0.5pt)[],'
|
||||||
cellSizeIn +
|
: 'v(' + cellSizeIn + '),'
|
||||||
", height: " +
|
|
||||||
cellSizeIn +
|
|
||||||
", stroke: 0.5pt)[],"
|
|
||||||
: "v(" + cellSizeIn + "),"
|
|
||||||
}
|
}
|
||||||
[],
|
[],
|
||||||
|
|
||||||
// First addend
|
// First addend
|
||||||
[],
|
[],
|
||||||
box(width: ${cellSizeIn}, height: ${cellSizeIn}, fill: ${options.showPlaceValueColors ? "color-hundreds" : "color-none"})[#align(center + horizon)[#if aH > 0 [#aH] else [#h(0pt)]]],
|
box(width: ${cellSizeIn}, height: ${cellSizeIn}, fill: ${options.showPlaceValueColors ? 'color-hundreds' : 'color-none'})[#align(center + horizon)[#if aH > 0 [#aH] else [#h(0pt)]]],
|
||||||
box(width: ${cellSizeIn}, height: ${cellSizeIn}, fill: ${options.showPlaceValueColors ? "color-tens" : "color-none"})[#align(center + horizon)[#aT]],
|
box(width: ${cellSizeIn}, height: ${cellSizeIn}, fill: ${options.showPlaceValueColors ? 'color-tens' : 'color-none'})[#align(center + horizon)[#aT]],
|
||||||
box(width: ${cellSizeIn}, height: ${cellSizeIn}, fill: ${options.showPlaceValueColors ? "color-ones" : "color-none"})[#align(center + horizon)[#aO]],
|
box(width: ${cellSizeIn}, height: ${cellSizeIn}, fill: ${options.showPlaceValueColors ? 'color-ones' : 'color-none'})[#align(center + horizon)[#aO]],
|
||||||
|
|
||||||
// Second addend with + sign
|
// Second addend with + sign
|
||||||
[+],
|
[+],
|
||||||
box(width: ${cellSizeIn}, height: ${cellSizeIn}, fill: ${options.showPlaceValueColors ? "color-hundreds" : "color-none"})[#align(center + horizon)[#if bH > 0 [#bH] else [#h(0pt)]]],
|
box(width: ${cellSizeIn}, height: ${cellSizeIn}, fill: ${options.showPlaceValueColors ? 'color-hundreds' : 'color-none'})[#align(center + horizon)[#if bH > 0 [#bH] else [#h(0pt)]]],
|
||||||
box(width: ${cellSizeIn}, height: ${cellSizeIn}, fill: ${options.showPlaceValueColors ? "color-tens" : "color-none"})[#align(center + horizon)[#bT]],
|
box(width: ${cellSizeIn}, height: ${cellSizeIn}, fill: ${options.showPlaceValueColors ? 'color-tens' : 'color-none'})[#align(center + horizon)[#bT]],
|
||||||
box(width: ${cellSizeIn}, height: ${cellSizeIn}, fill: ${options.showPlaceValueColors ? "color-ones" : "color-none"})[#align(center + horizon)[#bO]],
|
box(width: ${cellSizeIn}, height: ${cellSizeIn}, fill: ${options.showPlaceValueColors ? 'color-ones' : 'color-none'})[#align(center + horizon)[#bO]],
|
||||||
|
|
||||||
// Horizontal line
|
// Horizontal line
|
||||||
[],
|
[],
|
||||||
|
|
@ -359,7 +346,7 @@ export function generateProblemTypst(
|
||||||
box(width: ${cellSizeIn}, height: ${cellSizeIn}, fill: color-none, stroke: grid-stroke, inset: 0pt)[],
|
box(width: ${cellSizeIn}, height: ${cellSizeIn}, fill: color-none, stroke: grid-stroke, inset: 0pt)[],
|
||||||
box(width: ${cellSizeIn}, height: ${cellSizeIn}, fill: color-none, stroke: grid-stroke, inset: 0pt)[],
|
box(width: ${cellSizeIn}, height: ${cellSizeIn}, fill: color-none, stroke: grid-stroke, inset: 0pt)[],
|
||||||
box(width: ${cellSizeIn}, height: ${cellSizeIn}, fill: color-none, stroke: grid-stroke, inset: 0pt)[],`
|
box(width: ${cellSizeIn}, height: ${cellSizeIn}, fill: color-none, stroke: grid-stroke, inset: 0pt)[],`
|
||||||
: ""
|
: ''
|
||||||
}
|
}
|
||||||
)${
|
)${
|
||||||
options.showTenFrames || options.showTenFramesForAll
|
options.showTenFrames || options.showTenFramesForAll
|
||||||
|
|
@ -368,8 +355,8 @@ export function generateProblemTypst(
|
||||||
box(inset: 2pt)[
|
box(inset: 2pt)[
|
||||||
#ten-frames-stacked(${cellSizeIn}, color-ones, color-tens)
|
#ten-frames-stacked(${cellSizeIn}, color-ones, color-tens)
|
||||||
]`
|
]`
|
||||||
: ""
|
: ''
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
`;
|
`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
// Answer row and ten-frames rendering for subtraction problems
|
// Answer row and ten-frames rendering for subtraction problems
|
||||||
// Shows answer boxes and optional borrowing visualization
|
// Shows answer boxes and optional borrowing visualization
|
||||||
|
|
||||||
import type { CellDimensions } from "../shared/types";
|
import type { CellDimensions } from '../shared/types'
|
||||||
import { TYPST_CONSTANTS } from "../shared/types";
|
import { TYPST_CONSTANTS } from '../shared/types'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate Typst code for the line row (separates problem from answer)
|
* Generate Typst code for the line row (separates problem from answer)
|
||||||
|
|
@ -11,7 +11,7 @@ import { TYPST_CONSTANTS } from "../shared/types";
|
||||||
* @returns Typst code for line row
|
* @returns Typst code for line row
|
||||||
*/
|
*/
|
||||||
export function generateLineRow(cellDimensions: CellDimensions): string {
|
export function generateLineRow(cellDimensions: CellDimensions): string {
|
||||||
const { cellSizeIn } = cellDimensions;
|
const { cellSizeIn } = cellDimensions
|
||||||
|
|
||||||
return String.raw`
|
return String.raw`
|
||||||
// Line row
|
// Line row
|
||||||
|
|
@ -19,7 +19,7 @@ export function generateLineRow(cellDimensions: CellDimensions): string {
|
||||||
..for i in range(0, grid-digits) {
|
..for i in range(0, grid-digits) {
|
||||||
(line(length: ${cellSizeIn}, stroke: heavy-stroke),)
|
(line(length: ${cellSizeIn}, stroke: heavy-stroke),)
|
||||||
},
|
},
|
||||||
`;
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -32,7 +32,7 @@ export function generateLineRow(cellDimensions: CellDimensions): string {
|
||||||
* @returns Typst code for ten-frames row
|
* @returns Typst code for ten-frames row
|
||||||
*/
|
*/
|
||||||
export function generateTenFramesRow(cellDimensions: CellDimensions): string {
|
export function generateTenFramesRow(cellDimensions: CellDimensions): string {
|
||||||
const { cellSizeIn } = cellDimensions;
|
const { cellSizeIn } = cellDimensions
|
||||||
|
|
||||||
return String.raw`
|
return String.raw`
|
||||||
// Ten-frames row (show borrowing visualization)
|
// Ten-frames row (show borrowing visualization)
|
||||||
|
|
@ -49,7 +49,7 @@ export function generateTenFramesRow(cellDimensions: CellDimensions): string {
|
||||||
(
|
(
|
||||||
[], // Empty cell for operator column
|
[], // Empty cell for operator column
|
||||||
..for i in range(0, grid-digits).rev() {
|
..for i in range(0, grid-digits).rev() {
|
||||||
let shows-frame = show-ten-frames-for-all or (i in borrow-places)
|
let shows-frame = show-ten-frames-for-all or borrow-places.contains(i)
|
||||||
|
|
||||||
if shows-frame {
|
if shows-frame {
|
||||||
// Show borrowed amount visualization
|
// Show borrowed amount visualization
|
||||||
|
|
@ -77,7 +77,7 @@ export function generateTenFramesRow(cellDimensions: CellDimensions): string {
|
||||||
} else {
|
} else {
|
||||||
()
|
()
|
||||||
},
|
},
|
||||||
`;
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -90,7 +90,7 @@ export function generateTenFramesRow(cellDimensions: CellDimensions): string {
|
||||||
* @returns Typst code for answer boxes row
|
* @returns Typst code for answer boxes row
|
||||||
*/
|
*/
|
||||||
export function generateAnswerBoxesRow(cellDimensions: CellDimensions): string {
|
export function generateAnswerBoxesRow(cellDimensions: CellDimensions): string {
|
||||||
const { cellSizeIn } = cellDimensions;
|
const { cellSizeIn } = cellDimensions
|
||||||
|
|
||||||
return String.raw`
|
return String.raw`
|
||||||
// Answer boxes (only for actual difference digits, hiding leading zeros)
|
// Answer boxes (only for actual difference digits, hiding leading zeros)
|
||||||
|
|
@ -111,5 +111,5 @@ export function generateAnswerBoxesRow(cellDimensions: CellDimensions): string {
|
||||||
],)
|
],)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
`;
|
`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue