Skip to content

Instantly share code, notes, and snippets.

@jsoendermann
Created October 29, 2018 22:04
Show Gist options
  • Save jsoendermann/6723a1eb952dc28b0641147a464ca004 to your computer and use it in GitHub Desktop.
Save jsoendermann/6723a1eb952dc28b0641147a464ca004 to your computer and use it in GitHub Desktop.
interface RowSegment {
width: number
canStartLine?: boolean | undefined
canEndLine?: boolean | undefined
}
// This implementation isn't fully currect since it never backtracks more than one element but it's good enough for now
export const sentenceLayoutAlgo = <T extends RowSegment>(
rowSegments: T[],
lineWidth: number,
): T[][] => {
if (rowSegments.length === 0) {
return []
}
const segments = [...rowSegments]
const rows: T[][] = []
let currentRow: T[] = [segments.shift()!]
let currentRowWidth = currentRow[0].width
while (segments.length > 0) {
const segment = segments.shift()!
if (currentRowWidth + segment.width <= lineWidth) {
currentRow.push(segment)
currentRowWidth += segment.width
} else {
const nextRow: T[] = []
const lastOfCurrentRow = currentRow[currentRow.length - 1]
if (lastOfCurrentRow.canEndLine && segment.canStartLine) {
nextRow.push(segment)
currentRowWidth = segment.width
} else {
nextRow.push(currentRow.pop()!)
nextRow.push(segment)
currentRowWidth = nextRow[0].width + nextRow[1].width
}
rows.push(currentRow)
currentRow = nextRow
}
}
rows.push(currentRow)
return rows
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment