Download or view lineWrapper.frink in plain text format
/** This contains routines for wrapping a string to a specified width. It
uses Frink's smart Unicode-aware routines for finding line-wrapping points
that understand punctuation, numbers, and hyphenated words
and by counting graphemes correctly.
*/
/** Wrap a string to an array of lines, removing any newline characters in the
string.
The linebreaks are found intelligently using Frink's smart lineBreakList
function which intelligently handles punctuation, numbers, and hyphenated
words. It is human-language-aware and can wrap according to a different
human language by specifying the languageSpecifier variable. If
languageSpecifier is undef (the default) this uses the language defined in
your JVM. Otherwise, the language can be specfied with one of Frink's
language specifiers which can be a string like "en", "en_US", or a
java.util.Locale. See:
https://frinklang.org/#LanguageSpecifiers
It is also smart in that it correctly counts composed Unicode characters
by counting graphemes and not just characters nor codepoints.
TODO: Attempt to hyphenate words if it gives better fill? Should these
be options?
TODO: Attempt to hyphenate words that are fully too long for the line?
THINK ABOUT: Disregard (trim) whitespace at the end of lines so centering
or right-justifying is cleaner?
THINK ABOUT: Disregard multiple sequential whitespaces?
THINK ABOUT: Allow user-defined seperator characters?
*/
wrapToArray[str, cols, languageSpecifier=undef] :=
{
length = 0
result = new array
currLine = ""
if languageSpecifier == undef
lineBreaker = lineBreakList[str]
else
lineBreaker = lineBreakList[str, languageSpecifier]
WORD:
for word = lineBreaker
{
//println[toASCII[word]]
finishLine = false
// lineBreakList returns words with the \n or \r character appended when
// that occurs in the input.
// If word ends with line terminator, remove it and finalize the line
if word =~ %r/\r\n|\r|\n|\u2028|\u2029|\u000B|\u000C|\u0085$/
{
word =~ %s/(.*)\r\n|\r|\n|\u2028|\u2029|\u000B|\u000C|\u0085$/$1/
finishLine = true
}
wordLen = graphemeLength[word]
if length + wordLen <= cols
{
// Word fits on the line
currLine = currLine + word
length = length + wordLen
} else
{
// Word doesn't fit, create new line
if length > 0 // Unless the current line is already empty
result.push[currLine] // Trim here?
currLine = word
length = wordLen
}
if (finishLine)
{
result.push[currLine] // Trim here?
currLine = ""
length = 0
}
}
// Append any remaining text
if length > 0
result.push[currLine] // Trim here?
return result
}
/** Wrap a string to the specified width, returning the result as a single
big string with embedded newlines. */
wrap[str, cols, languageSpecifier=undef] :=
{
return joinln[wrapToArray[str, cols, languageSpecifier]]
}
Download or view lineWrapper.frink in plain text format
This is a program written in the programming language Frink.
For more information, view the Frink
Documentation or see More Sample Frink Programs.
Alan Eliasen was born 20217 days, 15 hours, 36 minutes ago.