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 types for internal use
|
||||||
import type { DisplayOptions } from './typstHelpers/shared/types'
|
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
|
// Re-export everything from modular structure
|
||||||
export type {
|
export type {
|
||||||
DisplayOptions,
|
|
||||||
CellDimensions,
|
CellDimensions,
|
||||||
|
DisplayOptions,
|
||||||
} from './typstHelpers/shared/types'
|
} from './typstHelpers/shared/types'
|
||||||
export { generateTypstHelpers } from './typstHelpers/shared/helpers'
|
|
||||||
export { generatePlaceValueColors } from './typstHelpers/shared/colors'
|
|
||||||
export { generateSubtractionProblemStackFunction } from './typstHelpers/subtraction/problemStack'
|
export { generateSubtractionProblemStackFunction } from './typstHelpers/subtraction/problemStack'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -103,12 +103,14 @@ export function generateProblemStackFunction(cellSize: number, maxDigits: number
|
|||||||
dir: ttb,
|
dir: ttb,
|
||||||
spacing: 0pt,
|
spacing: 0pt,
|
||||||
problem-number-display,
|
problem-number-display,
|
||||||
grid(
|
// Wrap grid in a box to enable place() overlay for operator
|
||||||
columns: column-list,
|
box[
|
||||||
gutter: 0pt,
|
#grid(
|
||||||
|
columns: column-list,
|
||||||
|
gutter: 0pt,
|
||||||
|
|
||||||
// Carry boxes row (one per place value, right to left)
|
// Carry boxes row (one per place value, right to left)
|
||||||
[], // Empty cell for + sign column
|
[], // Empty cell for + sign column
|
||||||
..for i in range(0, actual-digits).rev() {
|
..for i in range(0, actual-digits).rev() {
|
||||||
// DEBUG: Show which place values get carry boxes and why
|
// DEBUG: Show which place values get carry boxes and why
|
||||||
let show-carry = show-carries and i > 0
|
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)
|
// Second addend row (operator sign rendered separately via place() for proper layering)
|
||||||
box(width: 0.5em, height: ${cellSizeIn})[#align(center + horizon)[#text(size: ${(cellSizePt * 0.8).toFixed(1)}pt)[+]]],
|
[], // Empty cell for operator column (operator overlaid later)
|
||||||
..for i in range(0, actual-digits).rev() {
|
..for i in range(0, actual-digits).rev() {
|
||||||
let digit = b-digits.at(i)
|
let digit = b-digits.at(i)
|
||||||
let place-color = place-colors.at(i) // Dynamic color lookup by place value
|
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 { getPlaceValueColorNames } from '../shared/colors'
|
||||||
import type { CellDimensions } from '../shared/types'
|
import type { CellDimensions } from '../shared/types'
|
||||||
|
import { generateAnswerBoxesRow, generateLineRow, generateTenFramesRow } from './answerRow'
|
||||||
import { generateBorrowBoxesRow } from './borrowBoxes'
|
import { generateBorrowBoxesRow } from './borrowBoxes'
|
||||||
import { generateMinuendRow } from './minuendRow'
|
import { generateMinuendRow } from './minuendRow'
|
||||||
|
import { generateOperatorOverlay } from './operatorOverlay'
|
||||||
import { generateSubtrahendRow } from './subtrahendRow'
|
import { generateSubtrahendRow } from './subtrahendRow'
|
||||||
import { generateLineRow, generateTenFramesRow, generateAnswerBoxesRow } from './answerRow'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate the main subtraction problem stack function for Typst
|
* Generate the main subtraction problem stack function for Typst
|
||||||
@@ -115,9 +116,11 @@ export function generateSubtractionProblemStackFunction(
|
|||||||
dir: ttb,
|
dir: ttb,
|
||||||
spacing: 0pt,
|
spacing: 0pt,
|
||||||
problem-number-display,
|
problem-number-display,
|
||||||
grid(
|
// Wrap grid in a box to enable place() overlay for operator
|
||||||
columns: column-list,
|
box[
|
||||||
gutter: 0pt,
|
#grid(
|
||||||
|
columns: column-list,
|
||||||
|
gutter: 0pt,
|
||||||
|
|
||||||
${generateBorrowBoxesRow(cellDimensions)}
|
${generateBorrowBoxesRow(cellDimensions)}
|
||||||
|
|
||||||
@@ -130,7 +133,9 @@ ${generateLineRow(cellDimensions)}
|
|||||||
${generateTenFramesRow(cellDimensions)}
|
${generateTenFramesRow(cellDimensions)}
|
||||||
|
|
||||||
${generateAnswerBoxesRow(cellDimensions)}
|
${generateAnswerBoxesRow(cellDimensions)}
|
||||||
)
|
)
|
||||||
|
${generateOperatorOverlay(cellDimensions)}
|
||||||
|
]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|||||||
@@ -18,12 +18,8 @@ export function generateSubtrahendRow(cellDimensions: CellDimensions): string {
|
|||||||
const { cellSize, cellSizeIn, cellSizePt } = cellDimensions
|
const { cellSize, cellSizeIn, cellSizePt } = cellDimensions
|
||||||
|
|
||||||
return String.raw`
|
return String.raw`
|
||||||
// Subtrahend row with − sign
|
// Subtrahend row (operator sign rendered separately via place() for proper layering)
|
||||||
box(width: 0.5em, height: ${cellSizeIn})[
|
[], // Empty cell for operator column (operator overlaid later)
|
||||||
#align(center + horizon)[
|
|
||||||
#text(size: ${(cellSizePt * 0.8).toFixed(1)}pt)[−]
|
|
||||||
]
|
|
||||||
],
|
|
||||||
..for i in range(0, grid-digits).rev() {
|
..for i in range(0, grid-digits).rev() {
|
||||||
let digit = s-digits.at(i)
|
let digit = s-digits.at(i)
|
||||||
let place-color = place-colors.at(i)
|
let place-color = place-colors.at(i)
|
||||||
|
|||||||
Reference in New Issue
Block a user