summaryrefslogtreecommitdiff
path: root/library/src
diff options
context:
space:
mode:
Diffstat (limited to 'library/src')
-rw-r--r--library/src/compute/calc.rs22
-rw-r--r--library/src/compute/data.rs47
-rw-r--r--library/src/compute/foundations.rs3
-rw-r--r--library/src/layout/measure.rs3
-rw-r--r--library/src/layout/terms.rs8
-rw-r--r--library/src/lib.rs26
-rw-r--r--library/src/math/attach.rs44
-rw-r--r--library/src/math/cancel.rs34
-rw-r--r--library/src/meta/reference.rs82
-rw-r--r--library/src/text/raw.rs18
-rw-r--r--library/src/visualize/line.rs54
-rw-r--r--library/src/visualize/shape.rs4
12 files changed, 198 insertions, 147 deletions
diff --git a/library/src/compute/calc.rs b/library/src/compute/calc.rs
index b6b2442f..708d795d 100644
--- a/library/src/compute/calc.rs
+++ b/library/src/compute/calc.rs
@@ -41,6 +41,7 @@ pub fn module() -> Module {
scope.define("even", even);
scope.define("odd", odd);
scope.define("rem", rem);
+ scope.define("mod", mod_);
scope.define("quo", quo);
scope.define("inf", Value::Float(f64::INFINITY));
scope.define("nan", Value::Float(f64::NAN));
@@ -912,6 +913,27 @@ pub fn rem(
dividend.apply2(divisor.v, Rem::rem, Rem::rem).value()
}
+/// Calculate the modulus of two numbers. (Deprecated)
+///
+/// **This function is deprecated in favor of `rem`. It will be removed in
+/// a future update.**
+///
+/// Display: Modulus
+/// Category: calculate
+/// Returns: integer or float
+#[func]
+pub fn mod_(
+ /// The dividend of the remainder.
+ dividend: Num,
+ /// The divisor of the remainder.
+ divisor: Spanned<Num>,
+) -> Value {
+ if divisor.v.float() == 0.0 {
+ bail!(divisor.span, "divisor must not be zero");
+ }
+ dividend.apply2(divisor.v, Rem::rem, Rem::rem).value()
+}
+
/// Calculate the quotient of two numbers.
///
/// ## Example
diff --git a/library/src/compute/data.rs b/library/src/compute/data.rs
index 02586ddc..14ae304b 100644
--- a/library/src/compute/data.rs
+++ b/library/src/compute/data.rs
@@ -201,7 +201,6 @@ fn convert_json(value: serde_json::Value) -> Value {
}
/// Format the user-facing JSON error message.
-#[track_caller]
fn format_json_error(error: serde_json::Error) -> EcoString {
assert!(error.is_syntax() || error.is_eof());
eco_format!("failed to parse json file: syntax error in line {}", error.line())
@@ -209,30 +208,24 @@ fn format_json_error(error: serde_json::Error) -> EcoString {
/// Read structured data from a TOML file.
///
-/// The file must contain a valid TOML table. Tables will be
+/// The file must contain a valid TOML table. TOML tables will be
/// converted into Typst dictionaries, and TOML arrays will be converted into
/// Typst arrays. Strings and booleans will be converted into the Typst
-/// equivalents, numbers will be converted to floats or integers depending on
-/// whether they are whole numbers. TOML DateTim will be converted to strings.
+/// equivalents and numbers will be converted to floats or integers depending on
+/// whether they are whole numbers. For the time being, datetimes will be
+/// converted to strings as Typst does not have a built-in datetime yet.
///
-/// The function returns a dictionary.
-///
-/// The JSON files in the example contain objects with the keys `temperature`,
-/// `unit`, and `weather`.
+/// The TOML file in the example consists of a table with the keys `title`,
+/// `version`, and `authors`.
///
/// ## Example
/// ```example
-/// #let informations(content) = {
-/// [This work is made by #content.authors.join(", ", last: " and "). We are currently at version #content.version.
-/// The favorites series of the audience are ]
-/// for serie in content.series [
-/// - #serie.name with #serie.fans fans.
-/// ]
-/// [We need to submit our work in #content.informations.location, we currently have #content.informations.pages pages.]
-/// }
-///
+/// #let details = toml("details.toml")
///
-/// #informations(toml("informations.toml"))
+/// Title: #details.title \
+/// Version: #details.version \
+/// Authors: #(details.authors
+/// .join(", ", last: " and "))
/// ```
///
/// Display: TOML
@@ -268,23 +261,22 @@ fn convert_toml(value: toml::Value) -> Value {
.map(|(key, value)| (key.into(), convert_toml(value)))
.collect(),
),
- // Todo: make it use native date/time object(s) once it is implemented.
+ // TODO: Make it use native date/time object(s) once it is implemented.
toml::Value::Datetime(v) => Value::Str(v.to_string().into()),
}
}
/// Format the user-facing TOML error message.
-#[track_caller]
-fn format_toml_error(error: toml::de::Error) -> String {
+fn format_toml_error(error: toml::de::Error) -> EcoString {
if let Some(range) = error.span() {
- format!(
- "failed to parse toml file: {message}, index {start}-{end}",
- message = error.message(),
- start = range.start,
- end = range.end
+ eco_format!(
+ "failed to parse toml file: {}, index {}-{}",
+ error.message(),
+ range.start,
+ range.end
)
} else {
- format!("failed to parse toml file: {message}", message = error.message())
+ eco_format!("failed to parse toml file: {}", error.message())
}
}
@@ -373,7 +365,6 @@ fn convert_yaml_key(key: serde_yaml::Value) -> Option<Str> {
}
/// Format the user-facing YAML error message.
-#[track_caller]
fn format_yaml_error(error: serde_yaml::Error) -> EcoString {
eco_format!("failed to parse yaml file: {}", error.to_string().trim())
}
diff --git a/library/src/compute/foundations.rs b/library/src/compute/foundations.rs
index d5397e60..bad9f8ab 100644
--- a/library/src/compute/foundations.rs
+++ b/library/src/compute/foundations.rs
@@ -31,6 +31,9 @@ pub fn type_(
/// in monospace with syntax-highlighting. The exceptions are `{none}`,
/// integers, floats, strings, content, and functions.
///
+/// **Note:** This function is for debugging purposes. Its output should not be
+/// considered stable and may change at any time!
+///
/// ## Example
/// ```example
/// #none vs #repr(none) \
diff --git a/library/src/layout/measure.rs b/library/src/layout/measure.rs
index 0b7b9ee7..473bf5c6 100644
--- a/library/src/layout/measure.rs
+++ b/library/src/layout/measure.rs
@@ -5,6 +5,9 @@ use crate::prelude::*;
/// The `measure` function lets you determine the layouted size of content.
/// Note that an infinite space is assumed, therefore the measured height/width
/// may not necessarily match the final height/width of the measured content.
+/// If you want to measure in the current layout dimensions, you can combined
+/// `measure` and [`layout`]($func/layout).
+///
/// The same content can have a different size depending on the styles that
/// are active when it is layouted. For example, in the example below
/// `[#content]` is of course bigger when we increase the font size.
diff --git a/library/src/layout/terms.rs b/library/src/layout/terms.rs
index ecda7668..b6919eec 100644
--- a/library/src/layout/terms.rs
+++ b/library/src/layout/terms.rs
@@ -8,10 +8,6 @@ use crate::prelude::*;
/// descriptions span over multiple lines, they use hanging indent to
/// communicate the visual hierarchy.
///
-/// ## Syntax
-/// This function also has dedicated syntax: Starting a line with a slash,
-/// followed by a term, a colon and a description creates a term list item.
-///
/// ## Example
/// ```example
/// / Ligature: A merged glyph.
@@ -19,6 +15,10 @@ use crate::prelude::*;
/// between two adjacent letters.
/// ```
///
+/// ## Syntax
+/// This function also has dedicated syntax: Starting a line with a slash,
+/// followed by a term, a colon and a description creates a term list item.
+///
/// Display: Term List
/// Category: layout
#[element(Layout)]
diff --git a/library/src/lib.rs b/library/src/lib.rs
index 0350746d..3701894d 100644
--- a/library/src/lib.rs
+++ b/library/src/lib.rs
@@ -228,25 +228,25 @@ fn items() -> LangItems {
equation: |body, block| math::EquationElem::new(body).with_block(block).pack(),
math_align_point: || math::AlignPointElem::new().pack(),
math_delimited: |open, body, close| math::LrElem::new(open + body + close).pack(),
- math_attach: |base, top, bottom, topleft, bottomleft, topright, bottomright| {
+ math_attach: |base, t, b, tl, bl, tr, br| {
let mut elem = math::AttachElem::new(base);
- if let Some(top) = top {
- elem.push_t(Some(top));
+ if let Some(t) = t {
+ elem.push_t(Some(t));
}
- if let Some(bottom) = bottom {
- elem.push_b(Some(bottom));
+ if let Some(b) = b {
+ elem.push_b(Some(b));
}
- if let Some(topleft) = topleft {
- elem.push_tl(Some(topleft));
+ if let Some(tl) = tl {
+ elem.push_tl(Some(tl));
}
- if let Some(bottomleft) = bottomleft {
- elem.push_bl(Some(bottomleft));
+ if let Some(bl) = bl {
+ elem.push_bl(Some(bl));
}
- if let Some(topright) = topright {
- elem.push_tr(Some(topright));
+ if let Some(tr) = tr {
+ elem.push_tr(Some(tr));
}
- if let Some(bottomright) = bottomright {
- elem.push_br(Some(bottomright));
+ if let Some(br) = br {
+ elem.push_br(Some(br));
}
elem.pack()
},
diff --git a/library/src/math/attach.rs b/library/src/math/attach.rs
index 34c24e17..e7cffdd3 100644
--- a/library/src/math/attach.rs
+++ b/library/src/math/attach.rs
@@ -2,16 +2,23 @@ use super::*;
/// A base with optional attachments.
///
-/// ## Syntax
-/// This function also has dedicated syntax for attachments after the base: Use the
-/// underscore (`_`) to indicate a subscript i.e. bottom attachment and the hat (`^`)
-/// to indicate a superscript i.e. top attachment.
-///
/// ## Example
/// ```example
+/// // With syntax.
/// $ sum_(i=0)^n a_i = 2^(1+i) $
+///
+/// // With function call.
+/// $ attach(
+/// Pi, t: alpha, b: beta,
+/// tl: 1, tr: 2, bl: 3, br: 4,
+/// ) $
/// ```
///
+/// ## Syntax
+/// This function also has dedicated syntax for attachments after the base: Use
+/// the underscore (`_`) to indicate a subscript i.e. bottom attachment and the
+/// hat (`^`) to indicate a superscript i.e. top attachment.
+///
/// Display: Attachment
/// Category: math
#[element(LayoutMath)]
@@ -21,41 +28,42 @@ pub struct AttachElem {
pub base: Content,
/// The top attachment, smartly positioned at top-right or above the base.
- /// Use limits() or scripts() on the base to override the smart positioning.
+ ///
+ /// You can wrap the base in `{limits()}` or `{scripts()}` to override the
+ /// smart positioning.
pub t: Option<Content>,
- /// The bottom attachment, smartly positioned at the bottom-right or below the base.
- /// Use limits() or scripts() on the base to override the smart positioning.
+ /// The bottom attachment, smartly positioned at the bottom-right or below
+ /// the base. You can wrap the base in `{limits()}` or `{scripts()}` to
+ /// override the smart positioning.
pub b: Option<Content>,
- /// The top-left attachment before the base.
+ /// The top-left attachment (before the base).
pub tl: Option<Content>,
- /// The bottom-left attachment before base.
+ /// The bottom-left attachment (before base).
pub bl: Option<Content>,
- /// The top-right attachment after the base.
+ /// The top-right attachment (after the base).
pub tr: Option<Content>,
- /// The bottom-right attachment after the base.
+ /// The bottom-right attachment (after the base).
pub br: Option<Content>,
}
-type GetAttachmentContent =
- fn(&AttachElem, styles: ::typst::model::StyleChain) -> Option<Content>;
-
impl LayoutMath for AttachElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
- let base = ctx.layout_fragment(&self.base())?;
-
- let getarg = |ctx: &mut MathContext, getter: GetAttachmentContent| {
+ type GetAttachment = fn(&AttachElem, styles: StyleChain) -> Option<Content>;
+ let getarg = |ctx: &mut MathContext, getter: GetAttachment| {
getter(self, ctx.styles())
.map(|elem| ctx.layout_fragment(&elem))
.transpose()
.unwrap()
};
+ let base = ctx.layout_fragment(&self.base())?;
+
ctx.style(ctx.style.for_superscript());
let arg_tl = getarg(ctx, Self::tl);
let arg_tr = getarg(ctx, Self::tr);
diff --git a/library/src/math/cancel.rs b/library/src/math/cancel.rs
index 0ea7b1d2..edc2ba1e 100644
--- a/library/src/math/cancel.rs
+++ b/library/src/math/cancel.rs
@@ -2,10 +2,14 @@ use super::*;
/// Displays a diagonal line over a part of an equation.
///
+/// This is commonly used to show the eliminiation of a term.
+///
/// ## Example
/// ```example
+/// >>> #set page(width: 140pt)
/// Here, we can simplify:
-/// $ (a dot.c b dot.c cancel(x)) / cancel(x) $
+/// $ (a dot b dot cancel(x)) /
+/// cancel(x) $
/// ```
///
/// Display: Cancel
@@ -23,18 +27,22 @@ pub struct CancelElem {
/// Defaults to `{100% + 3pt}`.
///
/// ```example
- /// $ a + cancel(x, length: #200%) - b - cancel(x, length: #200%) $
+ /// >>> #set page(width: 140pt)
+ /// $ a + cancel(x, length: #200%)
+ /// - cancel(x, length: #200%) $
/// ```
#[default(Rel::new(Ratio::one(), Abs::pt(3.0).into()))]
pub length: Rel<Length>,
- /// If the cancel line should be inverted (heading northwest instead of
- /// northeast).
+ /// If the cancel line should be inverted (pointing to the top left instead
+ /// of top right).
///
/// Defaults to `{false}`.
///
/// ```example
- /// $ (a cancel((b + c), inverted: #true)) / cancel(b + c, inverted: #true) $
+ /// >>> #set page(width: 140pt)
+ /// $ (a cancel((b + c), inverted: #true)) /
+ /// cancel(b + c, inverted: #true) $
/// ```
#[default(false)]
pub inverted: bool,
@@ -45,7 +53,8 @@ pub struct CancelElem {
/// Defaults to `{false}`.
///
/// ```example
- /// $ cancel(x, cross: #true) $
+ /// >>> #set page(width: 140pt)
+ /// $ cancel(Pi, cross: #true) $
/// ```
#[default(false)]
pub cross: bool,
@@ -54,7 +63,8 @@ pub struct CancelElem {
/// [line's documentation]($func/line.angle) for more details.
///
/// ```example
- /// $ cancel(x, rotation: #30deg) $
+ /// >>> #set page(width: 140pt)
+ /// $ cancel(Pi, rotation: #30deg) $
/// ```
#[default(Angle::zero())]
pub rotation: Angle,
@@ -63,7 +73,15 @@ pub struct CancelElem {
/// [line's documentation]($func/line.stroke) for more details.
///
/// ```example
- /// $ cancel(x, stroke: #{red + 1.5pt}) $
+ /// >>> #set page(width: 140pt)
+ /// $ cancel(
+ /// sum x,
+ /// stroke: #(
+ /// paint: red,
+ /// thickness: 1.5pt,
+ /// dash: "dashed",
+ /// ),
+ /// ) $
/// ```
#[resolve]
#[fold]
diff --git a/library/src/meta/reference.rs b/library/src/meta/reference.rs
index 29b28828..68837b89 100644
--- a/library/src/meta/reference.rs
+++ b/library/src/meta/reference.rs
@@ -19,7 +19,7 @@ use crate::text::TextElem;
/// If you just want to link to a labelled element and not get an automatic
/// textual reference, consider using the [`link`]($func/link) function instead.
///
-/// # Example
+/// ## Example
/// ```example
/// #set heading(numbering: "1.")
/// #set math.equation(numbering: "(1)")
@@ -51,6 +51,36 @@ use crate::text::TextElem;
/// To customize the supplement, add content in square brackets after the
/// reference: `[@intro[Chapter]]`.
///
+/// ## Customization
+/// If you write a show rule for references, you can access the referenced
+/// element through the `element` field of the reference. The `element` may
+/// be `{none}` even if it exists if Typst hasn't discovered it yet, so you
+/// always need to handle that case in your code.
+///
+/// ```example
+/// #set heading(numbering: "1.")
+/// #set math.equation(numbering: "(1)")
+///
+/// #show ref: it => {
+/// let eq = math.equation
+/// let el = it.element
+/// if el != none and el.func() == eq {
+/// // Override equation references.
+/// numbering(
+/// el.numbering,
+/// ..counter(eq).at(el.location())
+/// )
+/// } else {
+/// // Other references as usual.
+/// it
+/// }
+/// }
+///
+/// = Beginnings <beginning>
+/// In @beginning we prove @pythagoras.
+/// $ a^2 + b^2 = c^2 $ <pythagoras>
+/// ```
+///
/// Display: Reference
/// Category: meta
#[element(Synthesize, Locatable, Show)]
@@ -86,35 +116,7 @@ pub struct RefElem {
#[synthesized]
pub citation: Option<CiteElem>,
- /// Content of the element, it should be referable.
- ///
- /// ```example
- /// #set heading(numbering: (..nums) => {
- /// nums.pos().map(str).join(".")
- /// }, supplement: [Chapt])
- ///
- /// #show ref: it => {
- /// if it.has("element") and it.element.func() == heading {
- /// let element = it.element
- /// "["
- /// element.supplement
- /// "-"
- /// numbering(element.numbering, ..counter(heading).at(element.location()))
- /// "]"
- /// } else {
- /// it
- /// }
- /// }
- ///
- /// = Introduction <intro>
- /// = Summary <sum>
- /// == Subsection <sub>
- /// @intro
- ///
- /// @sum
- ///
- /// @sub
- /// ```
+ /// The referenced element.
#[synthesized]
pub element: Option<Content>,
}
@@ -123,22 +125,14 @@ impl Synthesize for RefElem {
fn synthesize(&mut self, vt: &mut Vt, styles: StyleChain) -> SourceResult<()> {
let citation = self.to_citation(vt, styles)?;
self.push_citation(Some(citation));
+ self.push_element(None);
- if !vt.introspector.init() {
- self.push_element(None);
- return Ok(());
- }
-
- // find the element content
let target = self.target();
- let elem = vt.introspector.query_label(&self.target());
- // not in bibliography, but in document, then push the element
- if let (false, Ok(elem)) =
- (BibliographyElem::has(vt, &target.0), elem.at(self.span()))
- {
- self.push_element(Some(elem));
- } else {
- self.push_element(None);
+ if vt.introspector.init() && !BibliographyElem::has(vt, &target.0) {
+ if let Ok(elem) = vt.introspector.query_label(&target) {
+ self.push_element(Some(elem));
+ return Ok(());
+ }
}
Ok(())
diff --git a/library/src/text/raw.rs b/library/src/text/raw.rs
index 1c216483..091026b1 100644
--- a/library/src/text/raw.rs
+++ b/library/src/text/raw.rs
@@ -9,19 +9,11 @@ use crate::layout::BlockElem;
use crate::meta::{Figurable, LocalName};
use crate::prelude::*;
-/// Raw text with optional syntax highlighting.
+/// Raw text with optionalw syntax highlighting.
///
/// Displays the text verbatim and in a monospace font. This is typically used
/// to embed computer code into your document.
///
-/// ## Syntax
-/// This function also has dedicated syntax. You can enclose text in 1 or 3+
-/// backticks (`` ` ``) to make it raw. Two backticks produce empty raw text.
-/// When you use three or more backticks, you can additionally specify a
-/// language tag for syntax highlighting directly after the opening backticks.
-/// Within raw blocks, everything is rendered as is, in particular, there are no
-/// escape sequences.
-///
/// ## Example
/// ````example
/// Adding `rbx` to `rcx` gives
@@ -34,6 +26,14 @@ use crate::prelude::*;
/// ```
/// ````
///
+/// ## Syntax
+/// This function also has dedicated syntax. You can enclose text in 1 or 3+
+/// backticks (`` ` ``) to make it raw. Two backticks produce empty raw text.
+/// When you use three or more backticks, you can additionally specify a
+/// language tag for syntax highlighting directly after the opening backticks.
+/// Within raw blocks, everything is rendered as is, in particular, there are no
+/// escape sequences.
+///
/// Display: Raw Text / Code
/// Category: text
#[element(Synthesize, Show, Finalize, LocalName, Figurable)]
diff --git a/library/src/visualize/line.rs b/library/src/visualize/line.rs
index 0555ddec..4a1cb87c 100644
--- a/library/src/visualize/line.rs
+++ b/library/src/visualize/line.rs
@@ -5,8 +5,13 @@ use crate::prelude::*;
/// ## Example
/// ```example
/// #set page(height: 100pt)
+///
/// #line(length: 100%)
/// #line(end: (50%, 50%))
+/// #line(
+/// length: 4cm,
+/// stroke: 2pt + maroon,
+/// )
/// ```
///
/// Display: Line
@@ -41,30 +46,37 @@ pub struct LineElem {
/// - A stroke combined from color and thickness using the `+` operator as
/// in `{2pt + red}`.
/// - A stroke described by a dictionary with any of the following keys:
- /// - `color`: the color to use for the stroke
- /// - `thickness`: the stroke's thickness
- /// - `cap`: one of `"butt"`, `"round"` or `"square"`, the line cap of the stroke
- /// - `join`: one of `"miter"`, `"round"` or `"bevel"`, the line join of the stroke
- /// - `miter-limit`: the miter limit to use if `join` is `"miter"`, defaults to 4.0
- /// - `dash`: the dash pattern to use. Can be any of the following:
- /// - One of the strings `"solid"`, `"dotted"`, `"densely-dotted"`, `"loosely-dotted"`,
- /// `"dashed"`, `"densely-dashed"`, `"loosely-dashed"`, `"dashdotted"`,
- /// `"densely-dashdotted"` or `"loosely-dashdotted"`
- /// - An array with elements that specify the lengths of dashes and gaps, alternating.
- /// Elements can also be the string `"dot"` for a length equal to the line thickness.
- /// - A dict with the keys `array`, same as the array above, and `phase`, the offset to
- /// the start of the first dash.
- ///
+ /// - `paint`: The [color]($type/color) to use for the stroke.
+ /// - `thickness`: The stroke's thickness as a [length]($type/length).
+ /// - `cap`: How the line terminates. One of `{"butt"}`, `{"round"}`, or
+ /// `{"square"}`.
+ /// - `join`: How sharp turns of a contour are rendered. One of
+ /// `{"miter"}`, `{"round"}`, or `{"bevel"}`. Not applicable to lines
+ /// but to [polygons]($func/polygon) or [paths]($func/path).
+ /// - `miter-limit`: Number at which protruding sharp angles are rendered
+ /// with a bevel instead. The higher the number, the sharper an angle
+ /// can be before it is bevelled. Only applicable if `join` is
+ /// `{"miter"}`. Defaults to `{4.0}`.
+ /// - `dash`: The dash pattern to use. Can be any of the following:
+ /// - One of the predefined patterns `{"solid"}`, `{"dotted"}`,
+ /// `{"densely-dotted"}`, `{"loosely-dotted"}`, `{"dashed"}`,
+ /// `{"densely-dashed"}`, `{"loosely-dashed"}`, `{"dash-dotted"}`,
+ /// `{"densely-dash-dotted"}` or `{"loosely-dash-dotted"}`
+ /// - An [array]($type/array) with alternating lengths for dashes and
+ /// gaps. You can also use the string `{"dot"}` for a length equal to
+ /// the line thickness.
+ /// - A [dictionary]($type/dictionary) with the keys `array` (same as
+ /// the array above), and `phase` (of type [length]($type/length)),
+ /// which defines where in the pattern to start drawing.
///
/// ```example
+ /// #set line(length: 100%)
/// #stack(
- /// line(length: 100%, stroke: 2pt + red),
- /// v(1em),
- /// line(length: 100%, stroke: (color: blue, thickness: 4pt, cap: "round")),
- /// v(1em),
- /// line(length: 100%, stroke: (color: blue, thickness: 1pt, dash: "dashed")),
- /// v(1em),
- /// line(length: 100%, stroke: (color: blue, thickness: 1pt, dash: ("dot", 2pt, 4pt, 2pt))),
+ /// spacing: 1em,
+ /// line(stroke: 2pt + red),
+ /// line(stroke: (paint: blue, thickness: 4pt, cap: "round")),
+ /// line(stroke: (paint: blue, thickness: 1pt, dash: "dashed")),
+ /// line(stroke: (paint: blue, thickness: 1pt, dash: ("dot", 2pt, 4pt, 2pt))),
/// )
/// ```
#[resolve]
diff --git a/library/src/visualize/shape.rs b/library/src/visualize/shape.rs
index 27ef0e3f..75f03f67 100644
--- a/library/src/visualize/shape.rs
+++ b/library/src/visualize/shape.rs
@@ -55,8 +55,8 @@ pub struct RectElem {
/// - `miter-limit`: the miter limit to use if `join` is `"miter"`, defaults to 4.0
/// - `dash`: the dash pattern to use. Can be any of the following:
/// - One of the strings `"solid"`, `"dotted"`, `"densely-dotted"`, `"loosely-dotted"`,
- /// `"dashed"`, `"densely-dashed"`, `"loosely-dashed"`, `"dashdotted"`,
- /// `"densely-dashdotted"` or `"loosely-dashdotted"`
+ /// `"dashed"`, `"densely-dashed"`, `"loosely-dashed"`, `"dash-dotted"`,
+ /// `"densely-dash-dotted"` or `"loosely-dash-dotted"`
/// - An array with elements that specify the lengths of dashes and gaps, alternating.
/// Elements can also be the string `"dot"` for a length equal to the line thickness.
/// - A dict with the keys `array`, same as the array above, and `phase`, the offset to