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
alignmentis returned unchanged. - A string representation of any of the eight
alignmentvalues 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
alignmentrepresentations 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
dictionarycontaining one or more of the keysxandy, and no other keys, is converted.- The value of
x, if present, must be either a horizontalalignmentor a value that would convert to one. - The value of
y, if present, must be either a verticalalignmentor 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
angleis returned unchanged. - A string representation of a number followed by the letters
degorradis 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
coloris 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-rgbfunctions.
- 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
directionis returned unchanged. - A string representation of any of the four
directionvalues 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
fractionis returned unchanged. - A string representation of a number followed by the letters
fris 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
lengthis 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
ratiois 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
relativeis returned unchanged. - A
ratiois returned as arelativewith alengthof0pt. - A
lengthis returned as arelativewith aratioof0%. - 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
ratios andlengthsjoined by plus signs or minus signs is converted to a singlerelativelength.- All
length-like substrings are added. - All
ratio-like substrings are added.
- All
- A
dictionarycontaining one or more of the keysratioandlength, and no other keys, is converted.- The value of
ratio, if present, must be either aratioor a value that would convert to one. - The value of
length, if present, must be either alengthor 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,colororlengthis 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
colors,lengths 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
dictionarythat would otherwise be accepted as a validstrokeis 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