To-Stuff is a small package of Typst functions for converting string values to native types. This is most useful when loading layout data from an external configuration source, such as a YAML file.
How To Use
Import the module into the current scope, optionally renamed using the as
keyword:
#import "@preview/to-stuff:0.1.0"
// Bindings available as to-stuff.alignment(), to-stuff.angle(), etc.
#import "@preview/to-stuff:0.1.0" as to
// Bindings available as to.alignment(), to.angle(), etc.
The module’s let
bindings have the same names as their return types, and rely on Typst’s import
syntax to scope safely. It is not recommended to load the individual bindings into the current scope, as that may cause collisions with the types themselves.
#import "@preview/to-stuff:0.1.0": *
// NOT RECOMMENDED
// Bindings will collide with built-in types: alignment, angle, etc.
Functions
alignment()
Attempts to convert a value to an alignment
.
#alignment(
str|alignment|dictionary,
quiet: bool,
) -> none|alignment
value
str
or alignment
or dictionary
(positional, required)
The value that should be converted to an alignment
.
- An
alignment
is returned unchanged. - A string representation of any of the eight
alignment
values is converted to that value.- If the string includes the
alignment.…
scoping prefix, the conversion fails.
- If the string includes the
- A string consisting of two
alignment
representations joined by a plus sign is converted to the corresponding 2D alignment, provided the two strings do not correspond to alignments on the same axis. - A
dictionary
containing one or more of the keysx
andy
, and no other keys, is converted.- The value of
x
, if present, must be either a horizontalalignment
or a value that would convert to one. - The value of
y
, if present, must be either a verticalalignment
or a value that would convert to one.
- The value of
quiet
bool
Whether to return none
if the value could not be converted. If false
, invalid values cause a panic.
Default: false
View examples
#import "@preview/to-stuff:0.1.0" as to
#let a = to.alignment("top + right")
// -> right + top
#let b = to.alignment(top + right)
// -> right + top
#let c = to.alignment((x: "right", y: "top"))
// -> right + top
#let d = to.alignment("turnwise")
// panics with: "could not convert to alignment: \"turnwise\""
#let e = to.alignment("top + bottom")
// panics with: "cannot add two vertical alignments: \"top + bottom\""
#let f = to.alignment(quiet: true, "top + bottom")
// -> none
angle()
Attempts to convert a value to an angle
.
#angle(
str|angle,
quiet: bool,
) -> none|angle
value
str
or angle
(positional, required)
The value that should be converted to an angle
.
- An
angle
is returned unchanged. - A string representation of a number followed by the letters
deg
orrad
is converted.- The number may be positive or negative, and may contain decimal places.
quiet
bool
Whether to return none
if the value could not be converted. If false
, invalid values cause a panic.
Default: false
View examples
#import "@preview/to-stuff:0.1.0" as to
#let a = to.angle("45deg")
// -> 45deg
#let b = to.angle(45deg)
// -> 45deg
#let c = to.angle("42")
// panics with: "could not convert to angle: \"42\""
#let d = to.angle(quiet: true, "42")
// -> none
color()
Attempts to convert a value to a color
.
#angle(
str|color,
quiet: bool,
) -> none|color
value
str
or color
(positional, required)
The value that should be converted to a color
.
- A
color
is returned unchanged. - A string representation of a predefined color value is converted to that built-in color.
- A string representation of a hash symbol followed by a 6- or 8-digit hexadecimal code is converted to the corresponding RGB or RGBA value.
- A string representation of a color space function followed by parentheses and arguments is converted.
- If the string includes the
color.…
scoping prefix, the conversion fails. This includes thehsl
,hsv
, andlinear-rgb
functions.
- If the string includes the
Note: Color space function arguments are not currently checked for validity before the string is passed to eval()
. Invalid function arguments causes a native Typst syntax error rather than a panic; this error cannot be suppressed by setting quiet
to true
(see below). This may change in a future version.
quiet
bool
Whether to return none
if the value could not be converted. If false
, invalid values cause a panic.
Default: false
View examples
#import "@preview/to-stuff:0.1.0" as to
#let a = to.color("red")
// -> rgb("#ff4136")
#let b = to.color(red)
// -> rgb("#ff4136")
#let c = to.color("#FF4136FF")
// -> rgb("#ff4136")
#let d = to.color("rgb(255, 65, 54)")
// -> rgb("#ff4136")
#let e = to.color("hsv(135deg,75%,127,100)")
// -> color.hsv(135deg, 75%, 49.8%, 39.22%)
#let f = to.color("indigo")
// panics with: "could not convert to color: \"indigo\""
#let g = to.color(quiet: true, "indigo")
// -> none
direction()
Attempts to convert a value to a direction
.
#direction(
str|direction,
quiet: bool,
) -> none|direction
value
str
or direction
(positional, required)
The value that should be converted to a direction
.
- A
direction
is returned unchanged. - A string representation of any of the four
direction
values is converted to that value.- If the string includes the
direction.…
scoping prefix, the conversion fails.
- If the string includes the
quiet
bool
Whether to return none
if the value could not be converted. If false
, invalid values cause a panic.
Default: false
View examples
#import "@preview/to-stuff:0.1.0" as to
#let a = to.direction("rtl")
// -> rtl
#let b = to.direction(rtl)
// -> rtl
#let c = to.direction("btf")
// panics with: "could not convert to direction: \"btf\""
#let d = to.direction(quiet: true, "btf")
// -> none
fraction()
Attempts to convert a value to a fraction
.
#fraction(
str|fraction,
quiet: bool,
) -> none|fraction
value
str
or fraction
(positional, required)
The value that should be converted to a fraction
.
- A
fraction
is returned unchanged. - A string representation of a number followed by the letters
fr
is converted.- The number may be positive or negative, and may contain decimal places.
quiet
bool
Whether to return none
if the value could not be converted. If false
, invalid values cause a panic.
Default: false
View examples
#import "@preview/to-stuff:0.1.0" as to
#let a = to.fraction("2.5fr")
// -> 2.5fr
#let b = to.fraction(2.5fr)
// -> 2.5fr
#let c = to.fraction("42")
// panics with: "could not convert to fraction: \"42\""
#let d = to.fraction(quiet: true, "42")
// -> none
length()
Attempts to convert a value to a length
.
#length(
str|length,
quiet: bool,
) -> none|length
value
str
or length
(positional, required)
The value that should be converted to a length
.
- A
length
is returned unchanged. - A string representation of a number followed by the letters
pt
,mm
,cm
,in
, orem
, is converted.- The number may be positive or negative, and may contain decimal places.
quiet
bool
Whether to return none
if the value could not be converted. If false
, invalid values cause a panic.
Default: false
View examples
#import "@preview/to-stuff:0.1.0" as to
#let a = to.length("45pt")
// -> 45pt
#let b = to.length(45pt)
// -> 45pt
#let c = to.length("42")
// panics with: "could not convert to length: \"42\""
#let d = to.length(quiet: true, "42")
// -> none
ratio()
Attempts to convert a value to a ratio
.
#ratio(
str|ratio,
quiet: bool,
) -> none|ratio
value
str
or ratio
(positional, required)
The value that should be converted to a ratio
.
- A
ratio
is returned unchanged. - A string representation of a number followed by a percent sign is converted.
- The number may be positive or negative, and may contain decimal places.
quiet
bool
Whether to return none
if the value could not be converted. If false
, invalid values cause a panic.
Default: false
View examples
#import "@preview/to-stuff:0.1.0" as to
#let a = to.ratio("45%")
// -> 45%
#let b = to.ratio(45%)
// -> 45%
#let c = to.ratio("42")
// panics with: "could not convert to ratio: \"42\""
#let d = to.ratio(quiet: true, "42")
// -> none
relative()
Attempts to convert a value to a relative
.
#relative(
str|relative|ratio|length|dictionary,
quiet: bool,
) -> none|relative
value
str
or relative
or ratio
or length
or dictionary
(positional, required)
The value that should be converted to a relative
.
- A
relative
is returned unchanged. - A
ratio
is returned as arelative
with alength
of0pt
. - A
length
is returned as arelative
with aratio
of0%
. - A string representation of a
ratio
(see above) is converted. - A string representation of a
length
(see above) is converted. - A string consisting of multiple
ratio
s andlengths
joined by plus signs or minus signs is converted to a singlerelative
length.- All
length
-like substrings are added. - All
ratio
-like substrings are added.
- All
- A
dictionary
containing one or more of the keysratio
andlength
, and no other keys, is converted.- The value of
ratio
, if present, must be either aratio
or a value that would convert to one. - The value of
length
, if present, must be either alength
or a value that would convert to one.
- The value of
quiet
bool
Whether to return none
if the value could not be converted. If false
, invalid values cause a panic.
Default: false
View examples
#import "@preview/to-stuff:0.1.0" as to
#let a = to.relative("45pt + 3%")
// -> 3% + 45pt
#let b = to.relative(45pt + 3%)
// -> 3% + 45pt
#let c = to.relative((ratio: "3%", length: "45pt"))
// -> 3% + 45pt
#let d = to.relative("42")
// panics with: "could not convert to relative: \"42\""
#let e = to.relative(quiet: true, "42")
// -> none
stroke()
Attempts to convert a value to a stroke
.
#stroke(
str|stroke|color|length|array|dictionary,
quiet: bool,
) -> none|stroke
value
str
or stroke
or color
or length
or array
or dictionary
(positional, required)
The value that should be converted to a stroke
.
- A
stroke
,color
orlength
is returned unchanged. - A string representation of a
color
(see above) is converted. - A string representation of a
length
(see above) is converted. - A valid dash pattern is converted.
- A string representation of one or more valid
color
s,length
s and/or predefined dash patterns joined by plus signs is converted.- All
color
-like substrings are combined viacolor.mix()
. - All
length
-like substrings added.
- All
- A
dictionary
that would otherwise be accepted as a validstroke
is converted.
quiet
bool
Whether to return none
if the value could not be converted. If false
, invalid values cause a panic.
Default: false
View examples
#import "@preview/to-stuff:0.1.0" as to
#let a = to.stroke("red")
// -> rgb("#ff4136")
#let b = to.stroke(45pt)
// -> 45pt
#let c = to.stroke("densely-dashed")
// -> (dash: array(3pt, 2pt), phase: 0pt)
#let d = to.stroke((3pt, 2pt))
// -> (dash: array(3pt, 2pt), phase: 0pt)
#let e = to.stroke((paint: red, thickness: 2pt, dash: "densely-dashed"))
// -> (paint: rgb("#ff4136"), thickness: 2pt, dash: (array: (3pt, 2pt), phase: 0pt))
#let f = to.stroke("2pt + red + densely-dashed + silver + 5pt")
// -> (paint: oklab(77.85%, 0.1, 0.054), thickness: 7pt, dash: (array: (3pt, 2pt), phase: 0pt))
#let g = to.stroke("deep-dish")
// panics with: "could not convert to stroke: \"deep-dish\""
#let h = to.stroke(quiet: true, "deep-dish")
// -> none