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?
*/
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.
// 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
if (finishLine)
{
result.push[currLine]
currLine = ""
length = 0
}
} else
{
// Word doesn't fit, create new line
if length > 0 // Unless the current line is already empty
result.push[currLine]
currLine = word
length = wordLen
if (finishLine)
{
result.push[currLine]
currLine = ""
length = 0
}
}
}
// Append any remaining text
if length > 0
result.push[currLine]
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 19305 days, 17 hours, 54 minutes ago.