From 3680c854a21db665d64cdb8f31aa0f9a1af16ceb Mon Sep 17 00:00:00 2001 From: Laurenz Date: Wed, 26 Apr 2023 13:46:42 +0200 Subject: [PATCH] Touch up docs --- Cargo.toml | 4 +- assets/files/details.toml | 3 + assets/files/informations.toml | 11 --- .../{toml_types.toml => toml-types.toml} | 2 +- .../files/{yamltypes.yaml => yaml-types.yaml} | 0 cli/Cargo.toml | 16 ++-- docs/Cargo.toml | 12 +-- docs/src/lib.rs | 4 +- docs/src/reference/scripting.md | 38 ++++++++- docs/src/reference/styling.md | 20 +++-- docs/src/reference/types.md | 64 +++++++++------ library/Cargo.toml | 6 +- library/src/compute/calc.rs | 22 +++++ library/src/compute/data.rs | 47 +++++------ library/src/compute/foundations.rs | 3 + library/src/layout/measure.rs | 3 + library/src/layout/terms.rs | 8 +- library/src/lib.rs | 26 +++--- library/src/math/attach.rs | 44 ++++++---- library/src/math/cancel.rs | 34 ++++++-- library/src/meta/reference.rs | 82 +++++++++---------- library/src/text/raw.rs | 18 ++-- library/src/visualize/line.rs | 54 +++++++----- library/src/visualize/shape.rs | 4 +- macros/Cargo.toml | 2 +- src/eval/library.rs | 12 +-- src/eval/mod.rs | 8 +- src/geom/stroke.rs | 10 +-- src/model/content.rs | 1 - src/model/styles.rs | 56 ++++++++++++- src/syntax/parser.rs | 15 +++- tests/typ/bugs/args-underscore.typ | 5 ++ tests/typ/compiler/show-node.typ | 2 +- tests/typ/compiler/show-selector.typ | 4 + tests/typ/compute/data.typ | 4 +- tests/typ/math/matrix.typ | 8 +- tests/typ/meta/query-before-after.typ | 24 +++--- tests/typ/visualize/stroke.typ | 78 +++++++++--------- 38 files changed, 451 insertions(+), 303 deletions(-) create mode 100644 assets/files/details.toml delete mode 100644 assets/files/informations.toml rename assets/files/{toml_types.toml => toml-types.toml} (87%) rename assets/files/{yamltypes.yaml => yaml-types.yaml} (100%) create mode 100644 tests/typ/bugs/args-underscore.typ diff --git a/Cargo.toml b/Cargo.toml index cab4f3a5b..dbd25c338 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,7 @@ flate2 = "1" fontdb = "0.9" if_chain = "1" image = { version = "0.24", default-features = false, features = ["png", "jpeg", "gif"] } +indexmap = "1.9.3" log = "0.4" miniz_oxide = "0.7" once_cell = "1" @@ -43,6 +44,7 @@ siphasher = "0.3" subsetter = "0.1.1" svg2pdf = "0.4" tiny-skia = "0.6.6" +tracing = "0.1.37" ttf-parser = "0.18.1" unicode-math-class = "0.1" unicode-segmentation = "1" @@ -50,8 +52,6 @@ unicode-xid = "0.2" unscanny = "0.1" usvg = { version = "0.22", default-features = false, features = ["text"] } xmp-writer = "0.1" -tracing = "0.1.37" -indexmap = "1.9.3" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] stacker = "0.1.15" diff --git a/assets/files/details.toml b/assets/files/details.toml new file mode 100644 index 000000000..56cf166d8 --- /dev/null +++ b/assets/files/details.toml @@ -0,0 +1,3 @@ +title = "Secret project" +version = 2 +authors = ["Mr Robert", "Miss Enola"] diff --git a/assets/files/informations.toml b/assets/files/informations.toml deleted file mode 100644 index f6e3b5fb0..000000000 --- a/assets/files/informations.toml +++ /dev/null @@ -1,11 +0,0 @@ -authors = ["Mr Robert", "Miss Enola", "Mr Jonathan"] -version = "1.0.3" - -series = [ - { name = "attack on titan", fans = 500}, - { name = "demon slayer", fans = 10} -] - -[informations] -location = "room A204" -pages = 47 \ No newline at end of file diff --git a/assets/files/toml_types.toml b/assets/files/toml-types.toml similarity index 87% rename from assets/files/toml_types.toml rename to assets/files/toml-types.toml index 08f1118d5..93feead8b 100644 --- a/assets/files/toml_types.toml +++ b/assets/files/toml-types.toml @@ -8,4 +8,4 @@ inline_table = { first = "amazing", second = "greater" } [table] element = 5 -others = [false, "indeed", 7] \ No newline at end of file +others = [false, "indeed", 7] diff --git a/assets/files/yamltypes.yaml b/assets/files/yaml-types.yaml similarity index 100% rename from assets/files/yamltypes.yaml rename to assets/files/yaml-types.yaml diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 8557281f7..528ce614c 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -22,24 +22,24 @@ doc = false typst = { path = ".." } typst-library = { path = "../library" } chrono = { version = "0.4", default-features = false, features = ["clock", "std"] } +clap = { version = "4.2.4", features = ["derive", "env"] } codespan-reporting = "0.11" comemo = "0.2.2" dirs = "5" elsa = "1.8" +inferno = "0.11.15" memmap2 = "0.5" notify = "5" once_cell = "1" +open = "4.0.2" same-file = "1" siphasher = "0.3" -walkdir = "2" -clap = { version = "4.2.4", features = ["derive", "env"] } -open = "4.0.2" -tracing = "0.1.37" -tracing-subscriber = "0.3.17" -tracing-flame = "0.2.0" -tracing-error = "0.2" -inferno = "0.11.15" tempfile = "3.5.0" +tracing = "0.1.37" +tracing-error = "0.2" +tracing-flame = "0.2.0" +tracing-subscriber = "0.3.17" +walkdir = "2" [build-dependencies] clap = { version = "4.2.4", features = ["derive", "string"] } diff --git a/docs/Cargo.toml b/docs/Cargo.toml index 77d0b375c..e2f06e04c 100644 --- a/docs/Cargo.toml +++ b/docs/Cargo.toml @@ -12,14 +12,14 @@ bench = false [dependencies] typst = { path = ".." } typst-library = { path = "../library" } -unscanny = "0.1" -include_dir = "0.7" -pulldown-cmark = "0.9" comemo = "0.2.2" +heck = "0.4" +include_dir = "0.7" +once_cell = "1" +pulldown-cmark = "0.9" serde = { version = "1", features = ["derive"] } serde_yaml = "0.8" -heck = "0.4" -yaml-front-matter = "0.1" unicode_names2 = "0.6.0" -once_cell = "1" +unscanny = "0.1" ureq = { version = "2.6", features = ["json"] } +yaml-front-matter = "0.1" diff --git a/docs/src/lib.rs b/docs/src/lib.rs index 7333090d1..bc4456247 100644 --- a/docs/src/lib.rs +++ b/docs/src/lib.rs @@ -300,7 +300,7 @@ pub struct FuncModel { pub name: &'static str, pub display: &'static str, pub oneliner: &'static str, - pub showable: bool, + pub element: bool, pub details: Html, pub params: Vec, pub returns: Vec<&'static str>, @@ -340,7 +340,7 @@ fn func_model(resolver: &dyn Resolver, func: &Func, info: &FuncInfo) -> FuncMode name: info.name, display: info.display, oneliner: oneliner(docs), - showable: func.element().is_some(), + element: func.element().is_some(), details: Html::markdown(resolver, docs), params: info.params.iter().map(|param| param_model(resolver, param)).collect(), returns: info.returns.clone(), diff --git a/docs/src/reference/scripting.md b/docs/src/reference/scripting.md index d125bf5b5..6af17cc78 100644 --- a/docs/src/reference/scripting.md +++ b/docs/src/reference/scripting.md @@ -64,7 +64,7 @@ Content and code blocks can be nested arbitrarily. In the example below, } ``` -## Let bindings { #bindings } +## Bindings and Destructuring { #bindings } As already demonstrated above, variables can be defined with `{let}` bindings. The variable is assigned the value of the expression that follows the `=` sign. The assignment of a value is optional, if no value is assigned, the variable @@ -82,7 +82,10 @@ Sum is #add(2, 3). ``` Let bindings can also be used to destructure [arrays]($type/array) and -[dictionaries]($type/dictionary). +[dictionaries]($type/dictionary). In this case, the left-hand side of the +assignment should mirror an array or dictionary. The `..` operator can be used +once in the pattern to collect the remainder of the array's or dictionary's +items. ```example #let (x, y) = (1, 2) @@ -117,6 +120,28 @@ You can use the underscore to discard elements in a destructuring pattern: The y coordinate is #y. ``` +Destructuring also work in argument lists of functions ... + +```example +#let left = (2, 4, 5) +#let right = (3, 2, 6) +#left.zip(right).map( + ((a,b)) => a + b +) +``` + +... and on the left-hand side of normal assignments. This can be useful to +swap variables among other things. + +```example +#{ + let a = 1 + let b = 2 + (a, b) = (b, a) + [a = #a, b = #b] +} +``` + ## Conditionals { #conditionals } With a conditional, you can display or compute different things depending on whether some condition is fulfilled. Typst supports `{if}`, `{else if}` and @@ -206,12 +231,19 @@ can be either: - a [dictionary]($type/dictionary) that has the specified key, - a [symbol]($type/symbol) that has the specified modifier, - a [module]($type/module) containing the specified definition, -- [content]($type/content) that has the specified field. +- [content]($type/content) consisting of an element that has the specified + field. The available fields match the arguments of the + [element function]($type/function/#element-functions) that were given when + the element was constructed. ```example #let dict = (greet: "Hello") #dict.greet \ #emoji.face + +#let it = [= Heading] +#it.body \ +#it.level ``` ## Methods { #methods } diff --git a/docs/src/reference/styling.md b/docs/src/reference/styling.md index a3cc3c2eb..d088d61dc 100644 --- a/docs/src/reference/styling.md +++ b/docs/src/reference/styling.md @@ -12,11 +12,12 @@ of elements. ## Set rules { #set-rules } With set rules, you can customize the appearance of elements. They are written -as a [function call]($type/function) to the respective function preceded by the -`{set}` keyword (or `[#set]` in markup). Only optional parameters of that -function can be provided to the set rule. Refer to each function's documentation -to see which parameters are optional. In the example below, we use two set rules -to change the [font family]($func/text.family) and +as a [function call]($type/function) to an +[element function]($type/function/#element-functions) preceded by the `{set}` +keyword (or `[#set]` in markup). Only optional parameters of that function can +be provided to the set rule. Refer to each function's documentation to see which +parameters are optional. In the example below, we use two set rules to change +the [font family]($func/text.family) and [heading numbering]($func/heading.numbering). ```example @@ -62,9 +63,10 @@ a _set-if_ rule. ## Show rules { #show-rules } With show rules, you can deeply customize the look of a type of element. The most basic form of show rule is a _show-set rule._ Such a rule is written as the -`{show}` keyword followed by a function name, a colon and then a set rule. This -lets the set rule only apply to the selected element. In the example below, -headings become dark blue while all other text stays black. +`{show}` keyword followed by a [selector]($type/selector), a colon and then a set rule. The most basic form of selector is an +[element function]($type/function/#element-functions). This lets the set rule +only apply to the selected element. In the example below, headings become dark +blue while all other text stays black. ```example #show heading: set text(navy) @@ -78,7 +80,7 @@ achieve many different effects. But they still limit you to what is predefined in Typst. For maximum flexibility, you can instead write a show rule that defines how to format an element from scratch. To write such a show rule, replace the set rule behind the colon with an arbitrary -[function]($type/function). This functions receives the element in question and +[function]($type/function). This function receives the element in question and can return arbitrary content. Different [fields]($scripting/#fields) are available on the element passed to the function. Below, we define a show rule that formats headings for a diff --git a/docs/src/reference/types.md b/docs/src/reference/types.md index 1bae6b752..0714d1f7f 100644 --- a/docs/src/reference/types.md +++ b/docs/src/reference/types.md @@ -644,14 +644,14 @@ Folds all items into a single value using an accumulator function. Sums all items (works for any types that can be added). - default: any (named) - If set and the array is empty, sum will return this. + What to return if the array is empty. Must be set if the array can be empty. - returns: any ### product() Calculates the product all items (works for any types that can be multiplied) - default: any (named) - If set and the array is empty, sum will return this. + What to return if the array is empty. Must be set if the array can be empty. - returns: any ### any() @@ -814,6 +814,13 @@ documentation about [set]($styling/#set-rules) and [show]($styling/#show-rules) rules to learn about additional ways you can work with functions in Typst. +### Element functions { #element-functions } +Some functions are associated with _elements_ like [headings]($func/heading) or +[tables]($func/table). When called, these create an element of their respective +kind. In contrast to normal functions, they can further be used in +[set rules]($styling/#set-rules), [show rules]($styling/#show-rules), and +[selectors]($type/selector). + ### Defining functions { #definitions } You can define your own function with a [let binding]($scripting/#bindings) that has a parameter list after @@ -916,30 +923,11 @@ Returns the captured named arguments as a dictionary. - returns: dictionary -# Module -An evaluated module, either built-in or resulting from a file. - -You can access definitions from the module using -[field access notation]($scripting/#fields) and interact with it using the -[import and include syntaxes]($scripting/#modules). - -## Example -```example -<<< #import "utils.typ" -<<< #utils.add(2, 5) - -<<< #import utils: sub -<<< #sub(1, 4) ->>> #7 ->>> ->>> #(-3) -``` - # Selector A filter for selecting elements within the document. You can construct a selector in the following ways: -- you can use an element function +- you can use an element [function]($type/function) - you can filter for an element function with [specific fields]($type/function.where) - you can use a [string]($type/string) or [regular expression]($func/regex) @@ -948,13 +936,16 @@ You can construct a selector in the following ways: - call the [`selector`]($func/selector) function to convert any of the above types into a selector value and use the methods below to refine it -A selector is what you can use to query the document for certain types -of elements. It can also be used to apply styling rules to element. You can -combine multiple selectors using the methods shown below. +Selectors are used to [apply styling rules]($styling/#show-rules) to elements. +You can also use selectors to [query]($func/query) the document for certain +types of elements. -Selectors can also be passed to several of Typst's built-in functions to +Furthermore, you can pass a selector to several of Typst's built-in functions to configure their behaviour. One such example is the [outline]($func/outline) -where it can be use to change which elements are listed within the outline. +where it can be used to change which elements are listed within the outline. + +Multiple selectors can be combined using the methods shown below. However, not +all kinds of selectors are supported in all places, at the moment. ## Example ```example @@ -1004,3 +995,22 @@ first match of the selector argument. - inclusive: boolean (named) Whether `start` itself should match or not. This is only relevant if both selectors match the same type of element. Defaults to `{true}`. + +# Module +An evaluated module, either built-in or resulting from a file. + +You can access definitions from the module using +[field access notation]($scripting/#fields) and interact with it using the +[import and include syntaxes]($scripting/#modules). + +## Example +```example +<<< #import "utils.typ" +<<< #utils.add(2, 5) + +<<< #import utils: sub +<<< #sub(1, 4) +>>> #7 +>>> +>>> #(-3) +``` diff --git a/library/Cargo.toml b/library/Cargo.toml index c0c20c411..bc68b5649 100644 --- a/library/Cargo.toml +++ b/library/Cargo.toml @@ -16,6 +16,7 @@ bench = false [dependencies] typst = { path = ".." } +chinese-number = { version = "0.7.2", default-features = false, features = ["number-to-chinese"] } comemo = "0.2.2" csv = "1" ecow = "0.1" @@ -31,6 +32,8 @@ serde_json = "1" serde_yaml = "0.8" smallvec = "1.10" syntect = { version = "5", default-features = false, features = ["default-syntaxes", "regex-fancy"] } +toml = { version = "0.7.3", default-features = false, features = ["parse"] } +tracing = "0.1.37" ttf-parser = "0.18.1" typed-arena = "2" unicode-bidi = "0.3.13" @@ -38,6 +41,3 @@ unicode-math-class = "0.1" unicode-script = "0.5" unicode-segmentation = "1" xi-unicode = "0.3" -chinese-number = { version = "0.7.2", default-features = false, features = ["number-to-chinese"] } -tracing = "0.1.37" -toml = { version = "0.7.3", default-features = false, features = ["parse"]} diff --git a/library/src/compute/calc.rs b/library/src/compute/calc.rs index b6b2442f6..708d795d9 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, +) -> 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 02586ddc4..14ae304bf 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 { } /// 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 d5397e601..bad9f8ab1 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 0b7b9ee71..473bf5c64 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 ecda76687..b6919eec0 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 0350746dc..3701894d5 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 34c24e17f..e7cffdd32 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, - /// 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, - /// The top-left attachment before the base. + /// The top-left attachment (before the base). pub tl: Option, - /// The bottom-left attachment before base. + /// The bottom-left attachment (before base). pub bl: Option, - /// The top-right attachment after the base. + /// The top-right attachment (after the base). pub tr: Option, - /// The bottom-right attachment after the base. + /// The bottom-right attachment (after the base). pub br: Option, } -type GetAttachmentContent = - fn(&AttachElem, styles: ::typst::model::StyleChain) -> Option; - 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; + 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 0ea7b1d29..edc2ba1ea 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, - /// 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 29b28828e..68837b895 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 +/// In @beginning we prove @pythagoras. +/// $ a^2 + b^2 = c^2 $ +/// ``` +/// /// Display: Reference /// Category: meta #[element(Synthesize, Locatable, Show)] @@ -86,35 +116,7 @@ pub struct RefElem { #[synthesized] pub citation: Option, - /// 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 - /// = Summary - /// == Subsection - /// @intro - /// - /// @sum - /// - /// @sub - /// ``` + /// The referenced element. #[synthesized] pub element: Option, } @@ -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 1c2164832..091026b19 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 0555ddec6..4a1cb87cb 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 27ef0e3f1..75f03f67b 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 diff --git a/macros/Cargo.toml b/macros/Cargo.toml index 337c03a6b..a1cd0c277 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -16,7 +16,7 @@ doctest = false bench = false [dependencies] +heck = "0.4" proc-macro2 = "1" quote = "1" syn = { version = "1", features = ["full", "extra-traits"] } -heck = "0.4" diff --git a/src/eval/library.rs b/src/eval/library.rs index a92d8bd19..13825d7ee 100644 --- a/src/eval/library.rs +++ b/src/eval/library.rs @@ -91,13 +91,13 @@ pub struct LangItems { pub math_attach: fn( base: Content, // Positioned smartly. - top: Option, - bottom: Option, + t: Option, + b: Option, // Fixed positions. - topleft: Option, - bottomleft: Option, - topright: Option, - bottomright: Option, + tl: Option, + bl: Option, + tr: Option, + br: Option, ) -> Content, /// A base with an accent: `arrow(x)`. pub math_accent: fn(base: Content, accent: char) -> Content, diff --git a/src/eval/mod.rs b/src/eval/mod.rs index e8e1af51b..68163bf6a 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -48,8 +48,9 @@ use unicode_segmentation::UnicodeSegmentation; use crate::diag::{ bail, error, At, SourceError, SourceResult, StrResult, Trace, Tracepoint, }; +use crate::model::ShowableSelector; use crate::model::{ - Content, Introspector, Label, Recipe, Selector, StabilityProvider, Styles, Transform, + Content, Introspector, Label, Recipe, StabilityProvider, Styles, Transform, Unlabellable, Vt, }; use crate::syntax::ast::AstNode; @@ -1428,8 +1429,9 @@ impl Eval for ast::ShowRule { fn eval(&self, vm: &mut Vm) -> SourceResult { let selector = self .selector() - .map(|sel| sel.eval(vm)?.cast::().at(sel.span())) - .transpose()?; + .map(|sel| sel.eval(vm)?.cast::().at(sel.span())) + .transpose()? + .map(|selector| selector.0); let transform = self.transform(); let span = transform.span(); diff --git a/src/geom/stroke.rs b/src/geom/stroke.rs index 344da3c53..ead30cbb9 100644 --- a/src/geom/stroke.rs +++ b/src/geom/stroke.rs @@ -256,9 +256,9 @@ cast_from_value! { "dashed" => vec![Abs::pt(3.0).into(), Abs::pt(3.0).into()].into(), "densely-dashed" => vec![Abs::pt(3.0).into(), Abs::pt(2.0).into()].into(), "loosely-dashed" => vec![Abs::pt(3.0).into(), Abs::pt(6.0).into()].into(), - "dashdotted" => vec![Abs::pt(3.0).into(), Abs::pt(2.0).into(), DashLength::LineWidth, Abs::pt(2.0).into()].into(), - "densely-dashdotted" => vec![Abs::pt(3.0).into(), Abs::pt(1.0).into(), DashLength::LineWidth, Abs::pt(1.0).into()].into(), - "loosely-dashdotted" => vec![Abs::pt(3.0).into(), Abs::pt(4.0).into(), DashLength::LineWidth, Abs::pt(4.0).into()].into(), + "dash-dotted" => vec![Abs::pt(3.0).into(), Abs::pt(2.0).into(), DashLength::LineWidth, Abs::pt(2.0).into()].into(), + "densely-dash-dotted" => vec![Abs::pt(3.0).into(), Abs::pt(1.0).into(), DashLength::LineWidth, Abs::pt(1.0).into()].into(), + "loosely-dash-dotted" => vec![Abs::pt(3.0).into(), Abs::pt(4.0).into(), DashLength::LineWidth, Abs::pt(4.0).into()].into(), array: Vec => { Self { array, @@ -314,14 +314,14 @@ cast_from_value! { .transpose()?.map(Smart::Custom).unwrap_or(Smart::Auto)) } - let paint = take::(&mut dict, "color")?; + let paint = take::(&mut dict, "paint")?; let thickness = take::(&mut dict, "thickness")?; let line_cap = take::(&mut dict, "cap")?; let line_join = take::(&mut dict, "join")?; let dash_pattern = take::>(&mut dict, "dash")?; let miter_limit = take::(&mut dict, "miter-limit")?; - dict.finish(&["color", "thickness", "cap", "join", "dash", "miter-limit"])?; + dict.finish(&["paint", "thickness", "cap", "join", "dash", "miter-limit"])?; Self { paint, diff --git a/src/model/content.rs b/src/model/content.rs index c2c70f9de..4af4e6550 100644 --- a/src/model/content.rs +++ b/src/model/content.rs @@ -584,7 +584,6 @@ impl Fold for Vec { /// The missing key access error message. #[cold] -#[track_caller] fn missing_field(key: &str) -> EcoString { eco_format!("content does not contain field {:?}", Str::from(key)) } diff --git a/src/model/styles.rs b/src/model/styles.rs index 9ef742769..6757ed5df 100644 --- a/src/model/styles.rs +++ b/src/model/styles.rs @@ -412,9 +412,7 @@ impl Selector { Self::Or(selectors) => selectors.iter().any(move |sel| sel.matches(target)), Self::And(selectors) => selectors.iter().all(move |sel| sel.matches(target)), Self::Location(location) => target.location() == Some(*location), - Self::Before { .. } | Self::After { .. } => { - panic!("Cannot match a `Selector::Before` or `Selector::After` selector") - } + Self::Before { .. } | Self::After { .. } => false, } } } @@ -491,7 +489,7 @@ impl Cast for LocatableSelector { fn cast(value: Value) -> StrResult { fn validate(selector: &Selector) -> StrResult<()> { - match &selector { + match selector { Selector::Elem(elem, _) => { if !elem.can::() { Err(eco_format!("{} is not locatable", elem.name()))? @@ -533,6 +531,56 @@ impl Cast for LocatableSelector { ]) } } + +/// A selector that can be used with show rules. +#[derive(Clone, PartialEq, Hash)] +pub struct ShowableSelector(pub Selector); + +impl Cast for ShowableSelector { + fn is(value: &Value) -> bool { + matches!(value, Value::Str(_) | Value::Label(_) | Value::Func(_)) + || value.type_name() == "regular expression" + || value.type_name() == "selector" + } + + fn cast(value: Value) -> StrResult { + fn validate(selector: &Selector) -> StrResult<()> { + match selector { + Selector::Elem(_, _) => {} + Selector::Label(_) => {} + Selector::Regex(_) => {} + Selector::Or(_) + | Selector::And(_) + | Selector::Location(_) + | Selector::Can(_) + | Selector::Before { .. } + | Selector::After { .. } => { + Err("this selector cannot be used with show")? + } + } + Ok(()) + } + + if !Self::is(&value) { + return ::error(value); + } + + let selector = Selector::cast(value)?; + validate(&selector)?; + Ok(Self(selector)) + } + + fn describe() -> CastInfo { + CastInfo::Union(vec![ + CastInfo::Type("function"), + CastInfo::Type("label"), + CastInfo::Type("string"), + CastInfo::Type("regular expression"), + CastInfo::Type("selector"), + ]) + } +} + /// A show rule transformation that can be applied to a match. #[derive(Clone, PartialEq, Hash)] pub enum Transform { diff --git a/src/syntax/parser.rs b/src/syntax/parser.rs index ab73479e9..1198774b6 100644 --- a/src/syntax/parser.rs +++ b/src/syntax/parser.rs @@ -850,12 +850,19 @@ fn item(p: &mut Parser, keyed: bool) -> SyntaxKind { return SyntaxKind::Spread; } - if !p.eat_if(SyntaxKind::Underscore) { - code_expr_or_pattern(p); - } else { - return SyntaxKind::Underscore; + if p.at(SyntaxKind::Underscore) { + // This is a temporary workaround to fix `v.map(_ => {})`. + let mut lexer = p.lexer.clone(); + let next = + std::iter::from_fn(|| Some(lexer.next())).find(|kind| !kind.is_trivia()); + if next != Some(SyntaxKind::Arrow) { + p.eat(); + return SyntaxKind::Underscore; + } } + code_expr_or_pattern(p); + if !p.eat_if(SyntaxKind::Colon) { return SyntaxKind::Int; } diff --git a/tests/typ/bugs/args-underscore.typ b/tests/typ/bugs/args-underscore.typ new file mode 100644 index 000000000..ca3c0ff89 --- /dev/null +++ b/tests/typ/bugs/args-underscore.typ @@ -0,0 +1,5 @@ +// Test that lone underscore works. +// Ref: false + +--- +#test((1, 2, 3).map(_ => {}).len(), 3) diff --git a/tests/typ/compiler/show-node.typ b/tests/typ/compiler/show-node.typ index 42aee5069..99a4364eb 100644 --- a/tests/typ/compiler/show-node.typ +++ b/tests/typ/compiler/show-node.typ @@ -96,7 +96,7 @@ Hey = Heading --- -// Error: 7-10 expected function, label, string, regular expression, location, or selector, found color +// Error: 7-10 expected function, label, string, regular expression, or selector, found color #show red: [] --- diff --git a/tests/typ/compiler/show-selector.typ b/tests/typ/compiler/show-selector.typ index d1229eee4..19f43feec 100644 --- a/tests/typ/compiler/show-selector.typ +++ b/tests/typ/compiler/show-selector.typ @@ -37,3 +37,7 @@ the ```rs &mut T``` reference. = Red == Blue === Green + +--- +// Error: 7-35 this selector cannot be used with show +#show selector(heading).or(strong): none diff --git a/tests/typ/compute/data.typ b/tests/typ/compute/data.typ index 8b50f7c46..96b655c04 100644 --- a/tests/typ/compute/data.typ +++ b/tests/typ/compute/data.typ @@ -43,7 +43,7 @@ --- // Test reading TOML data. -#let data = toml("/toml_types.toml") +#let data = toml("/toml-types.toml") #test(data.string, "wonderful") #test(data.integer, 42) #test(data.float, 3.14) @@ -60,7 +60,7 @@ --- // Test reading YAML data -#let data = yaml("/yamltypes.yaml") +#let data = yaml("/yaml-types.yaml") #test(data.len(), 7) #test(data.null_key, (none, none)) #test(data.string, "text") diff --git a/tests/typ/math/matrix.typ b/tests/typ/math/matrix.typ index c1fba6277..514827c3c 100644 --- a/tests/typ/math/matrix.typ +++ b/tests/typ/math/matrix.typ @@ -23,10 +23,10 @@ $ mat( --- // Test baseline alignment. $ mat( - a, b^2; - sum_(x \ y) x, a^(1/2); - zeta, alpha; - ) $ + a, b^2; + sum_(x \ y) x, a^(1/2); + zeta, alpha; +) $ --- // Test alternative delimiter with set rule. diff --git a/tests/typ/meta/query-before-after.typ b/tests/typ/meta/query-before-after.typ index 734e84b49..7488a2d56 100644 --- a/tests/typ/meta/query-before-after.typ +++ b/tests/typ/meta/query-before-after.typ @@ -11,18 +11,18 @@ #set text(size: 12pt, weight: "regular") #outline( - title: "Chapter outline", - indent: true, - target: heading - .where(level: 1) - .or(heading.where(level: 2)) - .after(it.location(), inclusive: true) - .before( - heading - .where(level: 1, outlined: true) - .after(it.location(), inclusive: false), - inclusive: false, - ) + title: "Chapter outline", + indent: true, + target: heading + .where(level: 1) + .or(heading.where(level: 2)) + .after(it.location(), inclusive: true) + .before( + heading + .where(level: 1, outlined: true) + .after(it.location(), inclusive: false), + inclusive: false, + ) ) ] diff --git a/tests/typ/visualize/stroke.typ b/tests/typ/visualize/stroke.typ index 60733d783..844cd8c25 100644 --- a/tests/typ/visualize/stroke.typ +++ b/tests/typ/visualize/stroke.typ @@ -2,22 +2,19 @@ --- // Some simple test lines - #line(length: 60pt, stroke: red) #v(3pt) #line(length: 60pt, stroke: 2pt) #v(3pt) #line(length: 60pt, stroke: blue + 1.5pt) #v(3pt) -#line(length: 60pt, stroke: (color: red, thickness: 1pt, dash: "dashed")) +#line(length: 60pt, stroke: (paint: red, thickness: 1pt, dash: "dashed")) #v(3pt) -#line(length: 60pt, stroke: (color: red, thickness: 4pt, cap: "round")) +#line(length: 60pt, stroke: (paint: red, thickness: 4pt, cap: "round")) --- // Set rules with stroke - -#set line(stroke: (color: red, thickness: 1pt, cap: "butt", dash: "dashdotted")) - +#set line(stroke: (paint: red, thickness: 1pt, cap: "butt", dash: "dash-dotted")) #line(length: 60pt) #v(3pt) #line(length: 60pt, stroke: blue) @@ -26,79 +23,78 @@ --- // Rectangle strokes - #rect(width: 20pt, height: 20pt, stroke: red) #v(3pt) -#rect(width: 20pt, height: 20pt, stroke: (rest: red, top: (color: blue, dash: "dashed"))) +#rect(width: 20pt, height: 20pt, stroke: (rest: red, top: (paint: blue, dash: "dashed"))) #v(3pt) #rect(width: 20pt, height: 20pt, stroke: (thickness: 5pt, join: "round")) --- // Dashing -#line(length: 60pt, stroke: (color: red, thickness: 1pt, dash: ("dot", 1pt))) +#line(length: 60pt, stroke: (paint: red, thickness: 1pt, dash: ("dot", 1pt))) #v(3pt) -#line(length: 60pt, stroke: (color: red, thickness: 1pt, dash: ("dot", 1pt, 4pt, 2pt))) +#line(length: 60pt, stroke: (paint: red, thickness: 1pt, dash: ("dot", 1pt, 4pt, 2pt))) #v(3pt) -#line(length: 60pt, stroke: (color: red, thickness: 1pt, dash: (array: ("dot", 1pt, 4pt, 2pt), phase: 5pt))) +#line(length: 60pt, stroke: (paint: red, thickness: 1pt, dash: (array: ("dot", 1pt, 4pt, 2pt), phase: 5pt))) #v(3pt) -#line(length: 60pt, stroke: (color: red, thickness: 1pt, dash: ())) +#line(length: 60pt, stroke: (paint: red, thickness: 1pt, dash: ())) #v(3pt) -#line(length: 60pt, stroke: (color: red, thickness: 1pt, dash: (1pt, 3pt, 9pt))) +#line(length: 60pt, stroke: (paint: red, thickness: 1pt, dash: (1pt, 3pt, 9pt))) --- // Line joins -#stack(dir: ltr, - polygon(stroke: (thickness: 4pt, color: blue, join: "round"), +#stack( + dir: ltr, + spacing: 1em, + polygon(stroke: (thickness: 4pt, paint: blue, join: "round"), (0pt, 20pt), (15pt, 0pt), (0pt, 40pt), (15pt, 45pt)), - h(1em), - polygon(stroke: (thickness: 4pt, color: blue, join: "bevel"), + polygon(stroke: (thickness: 4pt, paint: blue, join: "bevel"), (0pt, 20pt), (15pt, 0pt), (0pt, 40pt), (15pt, 45pt)), - h(1em), - polygon(stroke: (thickness: 4pt, color: blue, join: "miter"), + polygon(stroke: (thickness: 4pt, paint: blue, join: "miter"), (0pt, 20pt), (15pt, 0pt), (0pt, 40pt), (15pt, 45pt)), - h(1em), - polygon(stroke: (thickness: 4pt, color: blue, join: "miter", miter-limit: 20.0), + polygon(stroke: (thickness: 4pt, paint: blue, join: "miter", miter-limit: 20.0), (0pt, 20pt), (15pt, 0pt), (0pt, 40pt), (15pt, 45pt)), ) --- -// Error: 29-56 unexpected key "thicknes", valid keys are "color", "thickness", "cap", "join", "dash", and "miter-limit" -#line(length: 60pt, stroke: (color: red, thicknes: 1pt)) +// Error: 29-56 unexpected key "thicknes", valid keys are "paint", "thickness", "cap", "join", "dash", and "miter-limit" +#line(length: 60pt, stroke: (paint: red, thicknes: 1pt)) --- -// Error: 29-55 expected "solid", "dotted", "densely-dotted", "loosely-dotted", "dashed", "densely-dashed", "loosely-dashed", "dashdotted", "densely-dashdotted", "loosely-dashdotted", array, dictionary, dash pattern, or none -#line(length: 60pt, stroke: (color: red, dash: "dash")) +// Error: 29-55 expected "solid", "dotted", "densely-dotted", "loosely-dotted", "dashed", "densely-dashed", "loosely-dashed", "dash-dotted", "densely-dash-dotted", "loosely-dash-dotted", array, dictionary, dash pattern, or none +#line(length: 60pt, stroke: (paint: red, dash: "dash")) --- // 0pt strokes must function exactly like 'none' strokes and not draw anything + #rect(width: 10pt, height: 10pt, stroke: none) #rect(width: 10pt, height: 10pt, stroke: 0pt) - #rect(width: 10pt, height: 10pt, stroke: none, fill: blue) #rect(width: 10pt, height: 10pt, stroke: 0pt + red, fill: blue) #line(length: 30pt, stroke: 0pt) -#line(length: 30pt, stroke: (color: red, thickness: 0pt, dash: ("dot", 1pt))) +#line(length: 30pt, stroke: (paint: red, thickness: 0pt, dash: ("dot", 1pt))) #table(columns: 2, stroke: none)[A][B] #table(columns: 2, stroke: 0pt)[A][B] #path( - fill: red, - stroke: none, - closed: true, - ((0%, 0%), (4%, -4%)), - ((50%, 50%), (4%, -4%)), - ((0%, 50%), (4%, 4%)), - ((50%, 0%), (4%, 4%)), + fill: red, + stroke: none, + closed: true, + ((0%, 0%), (4%, -4%)), + ((50%, 50%), (4%, -4%)), + ((0%, 50%), (4%, 4%)), + ((50%, 0%), (4%, 4%)), ) + #path( - fill: red, - stroke: 0pt, - closed: true, - ((0%, 0%), (4%, -4%)), - ((50%, 50%), (4%, -4%)), - ((0%, 50%), (4%, 4%)), - ((50%, 0%), (4%, 4%)), + fill: red, + stroke: 0pt, + closed: true, + ((0%, 0%), (4%, -4%)), + ((50%, 50%), (4%, -4%)), + ((0%, 50%), (4%, 4%)), + ((50%, 0%), (4%, 4%)), )