Skip to content

Instantly share code, notes, and snippets.

@davepagurek
Created October 4, 2021 10:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davepagurek/c9cfd12f91c571e86c5c1b9ed091a2d9 to your computer and use it in GitHub Desktop.
Save davepagurek/c9cfd12f91c571e86c5c1b9ed091a2d9 to your computer and use it in GitHub Desktop.
function addExplicitNewlines(
input,
maxWidth,
textCanvas,
font,
size
): string {
const split = ['']
const currentLine = () => split[split.length - 1]
const append = (token) => (split[split.length - 1] += token)
const carriageReturn = () => {
// Remove trailing whitespace from the current line
split.push(split.pop()!.trim())
split.push('')
}
const width = (line) => {
return textCanvas.textWidth(line)
}
// Separate words and whitespace into separate tokens
const tokens = input
// Split on whitespace, without getting rid of it
.split(/(?=\s)/g)
.flatMap((s) => {
// Make the whitespace characters their own tokens
const match = s.match(/^(\s)(.+)$/)
if (match) {
return [match[1], match[2]]
} else {
return s
}
})
.reverse()
textCanvas.push()
if (font !== undefined) textCanvas.textFont(font)
if (size !== undefined) textCanvas.textSize(size)
while (tokens.length > 0) {
const token = tokens.pop() as string
if (token === '\n') {
carriageReturn()
} else if (width((currentLine() + token).trim()) <= maxWidth) {
append(token)
} else {
if (currentLine().trim()) carriageReturn()
append(token)
}
}
if (!currentLine()) {
split.pop()
}
textCanvas.pop()
return split.join('\n')
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment