knit
Start knitting with the new
/from
functions!
For complexity reasons, formatters are not aware of linebreaks! See
split
for an example on how to handle multilineString
s.
Except where otherwise noted; for formatters that take a
width
, the total length of the resultingString
will never exceedwidth
.
Types
Values
pub fn crop_centre(this: Yarn, to width: Int) -> Yarn
Drop characters equally from both sides of a String
if it exceeds width
.
- If
width
is less than 0, it will be clamped to 0.
Examples:
knit.new(knit.crop_centre(_, 5))("hello world") // "lo wo"
pub fn crop_left(this: Yarn, to width: Int) -> Yarn
Drop characters from the left side of a String
if it exceeds width
.
- If
width
is less than 0, it will be clamped to 0.
Examples:
knit.new(knit.crop_left(_, 5))("hello world") // "hello"
pub fn crop_right(this: Yarn, to width: Int) -> Yarn
Drop characters from the right side of a String
if it exceeds width
.
- If
width
is less than 0, it will be clamped to 0.
Examples:
knit.new(knit.crop_right(_, 5))("hello world") // "world"
pub fn digit_separator(
this: Yarn,
every interval: Int,
with separator: String,
) -> Yarn
Add a separator
every interval
integer digits in a String
representing a number.
- If
interval
is less than 1, it will default to 3. separator
is truncated to the first character.- If
separator
is""
, it will default to","
. - This function does not check that what it’s processing actually represents a number; this may lead to amusing behavior if used on other
String
s.
Examples:
knit.from(int.to_string, knit.digit_separator(_, 3, ","))(1_000_000) // "1,000,000"
knit.from(float.to_string, knit.digit_separator(_, 3, "_"))(1_000.0001) // "1_000.0001"
knit.from(int.to_string, knit.digit_separator(_, 3, "."))(-100_001) // "-100.001"
pub fn ellipsize(
this: Yarn,
to width: Int,
with ellipses: String,
) -> Yarn
Ellipsize the right side of a String
with ellipses
if the total length exceeds width
.
- If
width
is less than 0, it will be clamped to 0. - If
ellipses
is""
, it will default to"..."
. ellipses
is truncated towidth
.
Examples:
knit.new(knit.ellipsize(_, 10, "..."))("hello world") // "hello w..."
knit.new(knit.ellipsize(_, 11, "..."))("hello world") // "hello world"
pub fn from(
from: fn(a) -> String,
formatter: fn(Yarn) -> Yarn,
) -> fn(a) -> String
Create a new formatter that accepts any type you can convert to a String
.
Examples:
let fmt = knit.from(int.to_string, knit.digit_separator(_, 3, " "))
fmt(3_141_592) // "3 141 592"
let normalise = {
use yarn <- knit.from(fn(a) { a |> float.to_precision(2) |> float.to_string })
yarn |> knit.pad_right(8, "0")
}
normalise(3.1415926) // "3.140000"
normalise(1000.1) // "1000.100"
pub fn from_string(this: String) -> Yarn
Convert a String
into a Yarn
.
- This requires a call to
string.length
.
pub fn join(this: List(Yarn), with separator: String) -> Yarn
Join String
s by separator
.
separator
is truncated to the first character.- If
separator
is""
, it will default to"\n"
.
Examples:
- See
split
pub fn length(this: Yarn) -> Int
Get the length of a Yarn
.
- This is a “free” operation, as the length is already tracked.
pub fn margin_centre(
this: Yarn,
by amount: Int,
with fill: String,
) -> Yarn
Pad both sides of a String
with fill
, adding amount
characters total.
- If
amount
is less than 0, it will be clamped to 0. fill
is truncated to the first character.- If
fill
is""
, it will default to" "
.
Examples:
knit.new(knit.margin_centre(_, 4, " "))("hello world") // " hello world "
pub fn margin_left(
this: Yarn,
by amount: Int,
with fill: String,
) -> Yarn
Pad the left side of a String
with fill
, amount
times.
- If
amount
is less than 0, it will be clamped to 0. fill
is truncated to the first character.- If
fill
is""
, it will default to" "
.
Examples:
knit.new(knit.margin_left(_, 4, " "))("hello world") // " hello world"
pub fn margin_right(
this: Yarn,
by amount: Int,
with fill: String,
) -> Yarn
Pad the right side of a String
with fill
, amount
times.
- If
amount
is less than 0, it will be clamped to 0. fill
is truncated to the first character.- If
fill
is""
, it will default to" "
.
Examples:
knit.new(knit.margin_right(_, 4, " "))("hello world") // "hello world "
pub fn new(formatter: fn(Yarn) -> Yarn) -> fn(String) -> String
Create a new formatter that accepts String
s.
Examples:
let pad = knit.new(knit.pad_centre(_, 15, " "))
pad("hello world") // " hello world "
let fmt = {
use yarn <- knit.new
yarn |> knit.crop_centre(9) |> knit.pad_centre(9, " ")
}
fmt("hello world") // "ello worl"
fmt("hello") // " hello "
pub fn pad_centre(
this: Yarn,
to width: Int,
with fill: String,
) -> Yarn
Pad both sides of a String
with fill
if it is less than width
.
- The resulting
String
will be allowed to exceedwidth
. - If
width
is less than 0, it will be clamped to 0. fill
is truncated to the first character.- If
fill
is""
, it will default to" "
.
Examples:
knit.new(knit.pad_centre(_, 15, " "))("hello world") // " hello world "
pub fn pad_left(
this: Yarn,
to width: Int,
with fill: String,
) -> Yarn
Pad the left side of a String
with fill
if it is less than width
.
- The resulting
String
will be allowed to exceedwidth
. - If
width
is less than 0, it will be clamped to 0. fill
is truncated to the first character.- If
fill
is""
, it will default to" "
.
Examples:
knit.new(knit.pad_left(_, 15, " "))("hello world") // " hello world"
pub fn pad_right(
this: Yarn,
to width: Int,
with fill: String,
) -> Yarn
Pad the right side of a String
with fill
if it is less than width
.
- The resulting
String
will be allowed to exceedwidth
. - If
width
is less than 0, it will be clamped to 0. fill
is truncated to the first character.- If
fill
is""
, it will default to" "
.
Examples:
knit.new(knit.pad_right(_, 15, " "))("hello world") // "hello world "
pub fn simple_wrap(this: Yarn, to width: Int) -> List(Yarn)
Simply wrap a String
onto multiple lines at width
.
- This function is very simplistic and does not wrap at word boundaries or hyphenate. If you’re looking for something fancier, consider the
string_width
package!
Examples:
knit.new(fn(yarn) { knit.simple_wrap(yarn, 16) |> knit.from_lines })(
"this is a long sentence that maybe doesn't look so great",
)
this is a long s
entence that may
be doesn't look
so great
pub fn split(this: Yarn, by separator: String) -> List(Yarn)
Split a String
by separator
.
This function is useful for formatting multiline String
s correctly!
separator
is truncated to the first character.- If
separator
is""
, it will default to"\n"
.
Examples:
let fmt = {
use yarn <- knit.new
yarn
|> knit.split("\n")
|> list.map(fn(yarn) {
knit.pad_centre(yarn, 14, " ") |> knit.margin_centre(2, "|")
})
|> knit.join("\n")
}
fmt("line 1\nline 2\nline 3")
| line 1 |
| line 2 |
| line 3 |
pub fn with(this: fn(String) -> String) -> fn(Yarn) -> Yarn
Convert any fn(String) -> String
into a composable formatter.
- The formatter returned by this function will always call
string.length
, take care when calling repeatedly on large inputs.
Examples:
let header = {
use yarn <- knit.new
yarn |> knit.with(string.uppercase) |> knit.pad_centre(32, "-")
}
echo header("section header") // "---------SECTION HEADER---------"
let header = {
let title_case = {
use string <- knit.with
string.split(string, " ") |> list.map(string.capitalise) |> string.join(" ")
}
use yarn <- knit.new
title_case(yarn) |> knit.pad_centre(32, " ")
}
echo header("section 2: electric boogaloo") // " Section 2: Electric Boogaloo "
pub fn with_arg(
this: fn(String, a) -> String,
) -> fn(Yarn, a) -> Yarn
Convert any fn(String, a) -> String
into a composable formatter.
- The formatter returned by this function will always call
string.length
, take care when calling repeatedly on large inputs. - If you need to pass more than one argument, try using a tuple!
Examples:
// todo