fix(worksheets): render operators last for proper layering
Use Typst's place() function to overlay + and − operators on top of all other problem elements. This ensures operators are always visible and properly layered over carry/borrow boxes, scratch work, and other decorations. Changes: - Addition: wrap grid in box, use place() for + sign overlay - Subtraction: extract operator to operatorOverlay.ts, use place() - Both operators positioned at correct row using dy offset 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -7,13 +7,13 @@
|
||||
// Import types for internal use
|
||||
import type { DisplayOptions } from './typstHelpers/shared/types'
|
||||
|
||||
export { generatePlaceValueColors } from './typstHelpers/shared/colors'
|
||||
export { generateTypstHelpers } from './typstHelpers/shared/helpers'
|
||||
// Re-export everything from modular structure
|
||||
export type {
|
||||
DisplayOptions,
|
||||
CellDimensions,
|
||||
DisplayOptions,
|
||||
} from './typstHelpers/shared/types'
|
||||
export { generateTypstHelpers } from './typstHelpers/shared/helpers'
|
||||
export { generatePlaceValueColors } from './typstHelpers/shared/colors'
|
||||
export { generateSubtractionProblemStackFunction } from './typstHelpers/subtraction/problemStack'
|
||||
|
||||
/**
|
||||
@@ -103,12 +103,14 @@ export function generateProblemStackFunction(cellSize: number, maxDigits: number
|
||||
dir: ttb,
|
||||
spacing: 0pt,
|
||||
problem-number-display,
|
||||
grid(
|
||||
columns: column-list,
|
||||
gutter: 0pt,
|
||||
// Wrap grid in a box to enable place() overlay for operator
|
||||
box[
|
||||
#grid(
|
||||
columns: column-list,
|
||||
gutter: 0pt,
|
||||
|
||||
// Carry boxes row (one per place value, right to left)
|
||||
[], // Empty cell for + sign column
|
||||
// Carry boxes row (one per place value, right to left)
|
||||
[], // Empty cell for + sign column
|
||||
..for i in range(0, actual-digits).rev() {
|
||||
// DEBUG: Show which place values get carry boxes and why
|
||||
let show-carry = show-carries and i > 0
|
||||
@@ -152,8 +154,8 @@ export function generateProblemStackFunction(cellSize: number, maxDigits: number
|
||||
],)
|
||||
},
|
||||
|
||||
// Second addend row with + sign (right to left)
|
||||
box(width: 0.5em, height: ${cellSizeIn})[#align(center + horizon)[#text(size: ${(cellSizePt * 0.8).toFixed(1)}pt)[+]]],
|
||||
// Second addend row (operator sign rendered separately via place() for proper layering)
|
||||
[], // Empty cell for operator column (operator overlaid later)
|
||||
..for i in range(0, actual-digits).rev() {
|
||||
let digit = b-digits.at(i)
|
||||
let place-color = place-colors.at(i) // Dynamic color lookup by place value
|
||||
@@ -240,7 +242,20 @@ export function generateProblemStackFunction(cellSize: number, maxDigits: number
|
||||
],)
|
||||
}
|
||||
},
|
||||
)
|
||||
)
|
||||
// Operator overlay - rendered last for proper layering
|
||||
// Position: left edge, at second addend row vertical position
|
||||
#place(
|
||||
left + top,
|
||||
dx: 0pt,
|
||||
dy: ${cellSizeIn} * 2, // Skip carry boxes row + first addend row
|
||||
box(width: 0.5em, height: ${cellSizeIn})[
|
||||
#align(center + horizon)[
|
||||
#text(size: ${(cellSizePt * 0.8).toFixed(1)}pt)[+]
|
||||
]
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
}
|
||||
`
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
// Operator overlay for subtraction problems
|
||||
// Rendered last to ensure proper layering over all other elements
|
||||
|
||||
import type { CellDimensions } from '../shared/types'
|
||||
|
||||
/**
|
||||
* Generate Typst code for the operator overlay
|
||||
*
|
||||
* The operator (− sign) is rendered using place() to overlay it on top of
|
||||
* all other problem elements, ensuring proper layering regardless of
|
||||
* borrow boxes, scratch work, or other decorations.
|
||||
*
|
||||
* @param cellDimensions - Cell sizing information
|
||||
* @returns Typst code for operator overlay using place()
|
||||
*/
|
||||
export function generateOperatorOverlay(cellDimensions: CellDimensions): string {
|
||||
const { cellSizeIn, cellSizePt } = cellDimensions
|
||||
|
||||
// The operator should be positioned at the subtrahend row level
|
||||
// Borrow boxes row height + minuend row height = 2 * cellSize from top
|
||||
// We position relative to the grid, so we need to account for:
|
||||
// - Row 0: borrow boxes (height: cellSize)
|
||||
// - Row 1: minuend row (height: cellSize)
|
||||
// - Row 2: subtrahend row (where operator should appear)
|
||||
|
||||
return String.raw`
|
||||
// Operator overlay - rendered last for proper layering
|
||||
// Position: left edge, at subtrahend row vertical position
|
||||
#place(
|
||||
left + top,
|
||||
dx: 0pt,
|
||||
dy: ${cellSizeIn} * 2, // Skip borrow boxes row + minuend row
|
||||
box(width: 0.5em, height: ${cellSizeIn})[
|
||||
#align(center + horizon)[
|
||||
#text(size: ${(cellSizePt * 0.8).toFixed(1)}pt)[−]
|
||||
]
|
||||
]
|
||||
)`
|
||||
}
|
||||
@@ -3,10 +3,11 @@
|
||||
|
||||
import { getPlaceValueColorNames } from '../shared/colors'
|
||||
import type { CellDimensions } from '../shared/types'
|
||||
import { generateAnswerBoxesRow, generateLineRow, generateTenFramesRow } from './answerRow'
|
||||
import { generateBorrowBoxesRow } from './borrowBoxes'
|
||||
import { generateMinuendRow } from './minuendRow'
|
||||
import { generateOperatorOverlay } from './operatorOverlay'
|
||||
import { generateSubtrahendRow } from './subtrahendRow'
|
||||
import { generateLineRow, generateTenFramesRow, generateAnswerBoxesRow } from './answerRow'
|
||||
|
||||
/**
|
||||
* Generate the main subtraction problem stack function for Typst
|
||||
@@ -115,9 +116,11 @@ export function generateSubtractionProblemStackFunction(
|
||||
dir: ttb,
|
||||
spacing: 0pt,
|
||||
problem-number-display,
|
||||
grid(
|
||||
columns: column-list,
|
||||
gutter: 0pt,
|
||||
// Wrap grid in a box to enable place() overlay for operator
|
||||
box[
|
||||
#grid(
|
||||
columns: column-list,
|
||||
gutter: 0pt,
|
||||
|
||||
${generateBorrowBoxesRow(cellDimensions)}
|
||||
|
||||
@@ -130,7 +133,9 @@ ${generateLineRow(cellDimensions)}
|
||||
${generateTenFramesRow(cellDimensions)}
|
||||
|
||||
${generateAnswerBoxesRow(cellDimensions)}
|
||||
)
|
||||
)
|
||||
${generateOperatorOverlay(cellDimensions)}
|
||||
]
|
||||
)
|
||||
}
|
||||
`
|
||||
|
||||
@@ -18,12 +18,8 @@ export function generateSubtrahendRow(cellDimensions: CellDimensions): string {
|
||||
const { cellSize, cellSizeIn, cellSizePt } = cellDimensions
|
||||
|
||||
return String.raw`
|
||||
// Subtrahend row with − sign
|
||||
box(width: 0.5em, height: ${cellSizeIn})[
|
||||
#align(center + horizon)[
|
||||
#text(size: ${(cellSizePt * 0.8).toFixed(1)}pt)[−]
|
||||
]
|
||||
],
|
||||
// Subtrahend row (operator sign rendered separately via place() for proper layering)
|
||||
[], // Empty cell for operator column (operator overlaid later)
|
||||
..for i in range(0, grid-digits).rev() {
|
||||
let digit = s-digits.at(i)
|
||||
let place-color = place-colors.at(i)
|
||||
|
||||
Reference in New Issue
Block a user