Require font to be a named argument

This commit is contained in:
Laurenz 2023-03-08 10:43:03 +01:00
parent 25b5bd1175
commit 1b2b53ecb9
59 changed files with 215 additions and 259 deletions

View File

@ -20,7 +20,7 @@ settable parameters. In the example below, we use two set rules to change the
[heading numbering]($func/heading.numbering) style. [heading numbering]($func/heading.numbering) style.
```example ```example
#set text("New Computer Modern") #set text(font: "New Computer Modern")
#set heading(numbering: "I.") #set heading(numbering: "I.")
= Introduction = Introduction
@ -85,8 +85,8 @@ fantasy encyclopedia.
#set heading(numbering: "(I)") #set heading(numbering: "(I)")
#show heading: it => block[ #show heading: it => block[
#set align(center) #set align(center)
#set text("Inria Serif")
\~ _#it.title;_ \~ _#it.title;_
#set text(font: "Inria Serif")
#it.numbers \~ #it.numbers \~
] ]

View File

@ -100,7 +100,7 @@ Let's add a few more styles to our document. We want larger margins and a serif
font. For the purposes of the example, we'll also set another page size. font. For the purposes of the example, we'll also set another page size.
```example ```example
#set text(10pt, "New Computer Modern") #set text(font: "New Computer Modern", 10pt)
#set page( #set page(
"a6", "a6",
margin: (x: 1.8cm, y: 1.5cm), margin: (x: 1.8cm, y: 1.5cm),
@ -171,7 +171,7 @@ can do this by setting the `numbering` parameter of the
[`heading`]($func/heading) function. [`heading`]($func/heading) function.
```example ```example
>>> #set text("New Computer Modern") >>> #set text(font: "New Computer Modern")
#set heading(numbering: "1.") #set heading(numbering: "1.")
= Introduction = Introduction
@ -190,7 +190,7 @@ each level. We can also use
[letters, roman numerals, and symbols]($func/numbering) for our headings: [letters, roman numerals, and symbols]($func/numbering) for our headings:
```example ```example
>>> #set text("New Computer Modern") >>> #set text(font: "New Computer Modern")
#set heading(numbering: "1.a") #set heading(numbering: "1.a")
= Introduction = Introduction

View File

@ -50,7 +50,7 @@ to learn some new tricks.
Let's start by writing some set rules for the document. Let's start by writing some set rules for the document.
```example ```example
#set text(11pt, "Linux Libertine") #set text(font: "Linux Libertine", 11pt)
#set par(justify: true) #set par(justify: true)
#set page( #set page(
@ -97,7 +97,7 @@ align it and increase its font weight by enclosing it in `[*stars*]`.
```example ```example
>>> #set page(width: 300pt, margin: 30pt) >>> #set page(width: 300pt, margin: 30pt)
>>> #set text(11pt, "Linux Libertine") >>> #set text(font: "Linux Libertine", 11pt)
#align(center, text(17pt)[ #align(center, text(17pt)[
*A fluid dynamic model *A fluid dynamic model
for glacier flow* for glacier flow*
@ -111,7 +111,7 @@ supervisor, we'll add our own and their name.
```example ```example
>>> #set page(width: 300pt, margin: 30pt) >>> #set page(width: 300pt, margin: 30pt)
>>> #set text(11pt, "Linux Libertine") >>> #set text(font: "Linux Libertine", 11pt)
>>> >>>
>>> #align(center, text(17pt)[ >>> #align(center, text(17pt)[
>>> *A fluid dynamic model >>> *A fluid dynamic model
@ -148,7 +148,7 @@ Now, let's add the abstract. Remember that the conference wants the abstract to
be set ragged and centered. be set ragged and centered.
```example:0,0,612,317.5 ```example:0,0,612,317.5
>>> #set text(11pt, "Linux Libertine") >>> #set text(font: "Linux Libertine", 11pt)
>>> #set par(justify: true) >>> #set par(justify: true)
>>> #set page( >>> #set page(
>>> "us-letter", >>> "us-letter",
@ -210,7 +210,7 @@ keyword:
<<< ... <<< ...
>>> #set text(11pt, "Linux Libertine") >>> #set text(font: "Linux Libertine", 11pt)
>>> #set par(justify: true) >>> #set par(justify: true)
#set page( #set page(
>>> "us-letter", >>> "us-letter",
@ -280,7 +280,7 @@ content. In our case, it passes it on to the `columns` function.
>>> for glacier flow >>> for glacier flow
>>> ] >>> ]
>>> >>>
>>> #set text(11pt, "Linux Libertine") >>> #set text(font: "Linux Libertine", 11pt)
>>> #set par(justify: true) >>> #set par(justify: true)
>>> #set page( >>> #set page(
>>> "us-letter", >>> "us-letter",
@ -342,7 +342,7 @@ a way to set any of that, we need to write our own heading show rule.
>>> for glacier flow >>> for glacier flow
>>> ] >>> ]
>>> >>>
>>> #set text(11pt, "Linux Libertine") >>> #set text(font: "Linux Libertine", 11pt)
>>> #set par(justify: true) >>> #set par(justify: true)
>>> #set page( >>> #set page(
>>> "us-letter", >>> "us-letter",
@ -421,7 +421,7 @@ differentiate between section and subsection headings:
>>> for glacier flow >>> for glacier flow
>>> ] >>> ]
>>> >>>
>>> #set text(11pt, "Linux Libertine") >>> #set text(font: "Linux Libertine", 11pt)
>>> #set par(justify: true) >>> #set par(justify: true)
>>> #set page( >>> #set page(
>>> "us-letter", >>> "us-letter",

View File

@ -67,7 +67,7 @@ that content block.
```example ```example
#let template(doc) = [ #let template(doc) = [
#set text("Inria Serif") #set text(font: "Inria Serif")
#show "something cool": [Typst] #show "something cool": [Typst]
#doc #doc
] ]
@ -86,7 +86,7 @@ previous chapter.
```example ```example
#let conf(title, doc) = { #let conf(title, doc) = {
set text(11pt, "Linux Libertine") set text(font: "Linux Libertine", 11pt)
set par(justify: true) set par(justify: true)
set page( set page(
paper: "us-letter", paper: "us-letter",
@ -266,7 +266,7 @@ path of the file after the `{from}` keyword.
>>> abstract: [], >>> abstract: [],
>>> doc, >>> doc,
>>> ) = { >>> ) = {
>>> set text(11pt, "Linux Libertine") >>> set text(font: "Linux Libertine", 11pt)
>>> set par(justify: true) >>> set par(justify: true)
>>> set page( >>> set page(
>>> "us-letter", >>> "us-letter",

View File

@ -57,6 +57,7 @@ pub struct AlignNode {
/// ) /// )
/// ``` /// ```
#[settable] #[settable]
#[positional]
#[fold] #[fold]
#[skip] #[skip]
#[default(Axes::new(GenAlign::Start, GenAlign::Specific(Align::Top)))] #[default(Axes::new(GenAlign::Start, GenAlign::Specific(Align::Top)))]

View File

@ -49,20 +49,6 @@ use super::GridLayouter;
/// becomes part of that item. /// becomes part of that item.
/// ///
/// ## Parameters /// ## Parameters
/// - items: `Content` (positional, variadic)
/// The enumeration's children.
///
/// When using the enum syntax, adjacent items are automatically collected
/// into enumerations, even through constructs like for loops.
///
/// ```example
/// #for phase in (
/// "Launch",
/// "Orbit",
/// "Descent",
/// ) [+ #phase]
/// ```
///
/// - start: `NonZeroUsize` (named) /// - start: `NonZeroUsize` (named)
/// Which number to start the enumeration with. /// Which number to start the enumeration with.
/// ///
@ -74,31 +60,39 @@ use super::GridLayouter;
/// ) /// )
/// ``` /// ```
/// ///
/// - tight: `bool` (named)
/// If this is `{false}`, the items are spaced apart with
/// [enum spacing]($func/enum.spacing). If it is `{true}`, they use normal
/// [leading]($func/par.leading) instead. This makes the enumeration more
/// compact, which can look better if the items are short.
///
/// ```example
/// + If an enum has a lot of text, and
/// maybe other inline content, it
/// should not be tight anymore.
///
/// + To make an enum wide, simply
/// insert a blank line between the
/// items.
/// ```
///
/// Display: Numbered List /// Display: Numbered List
/// Category: layout /// Category: layout
#[node(Construct, Layout)] #[node(Construct, Layout)]
pub struct EnumNode { pub struct EnumNode {
/// The numbered list's items. /// The numbered list's items.
///
/// When using the enum syntax, adjacent items are automatically collected
/// into enumerations, even through constructs like for loops.
///
/// ```example
/// #for phase in (
/// "Launch",
/// "Orbit",
/// "Descent",
/// ) [+ #phase]
/// ```
#[variadic] #[variadic]
pub items: Vec<EnumItem>, pub items: Vec<EnumItem>,
/// If true, the items are separated by leading instead of list spacing. /// If this is `{false}`, the items are spaced apart with
/// [enum spacing]($func/enum.spacing). If it is `{true}`, they use normal
/// [leading]($func/par.leading) instead. This makes the enumeration more
/// compact, which can look better if the items are short.
///
/// ```example
/// + If an enum has a lot of text, and
/// maybe other inline content, it
/// should not be tight anymore.
///
/// + To make an enum wide, simply
/// insert a blank line between the
/// items.
/// ```
#[named] #[named]
#[default(true)] #[default(true)]
pub tight: bool, pub tight: bool,
@ -252,6 +246,9 @@ impl Layout for EnumNode {
} }
/// An enumeration item. /// An enumeration item.
///
/// Display: Numbered List Item
/// Category: layout
#[node] #[node]
pub struct EnumItem { pub struct EnumItem {
/// The item's number. /// The item's number.

View File

@ -8,6 +8,9 @@ use crate::visualize::{CircleNode, EllipseNode, ImageNode, RectNode, SquareNode}
/// ///
/// This node is responsible for layouting both the top-level content flow and /// This node is responsible for layouting both the top-level content flow and
/// the contents of boxes. /// the contents of boxes.
///
/// Display: Flow
/// Category: layout
#[node(Layout)] #[node(Layout)]
pub struct FlowNode { pub struct FlowNode {
/// The children that will be arranges into a flow. /// The children that will be arranges into a flow.

View File

@ -167,6 +167,9 @@ impl Layout for ListNode {
} }
/// A bullet list item. /// A bullet list item.
///
/// Display: Bullet List Item
/// Category: layout
#[node] #[node]
pub struct ListItem { pub struct ListItem {
/// The item's body. /// The item's body.

View File

@ -12,11 +12,6 @@ use crate::prelude::*;
/// Pages can be set to use `{auto}` as their width or height. In this case, /// Pages can be set to use `{auto}` as their width or height. In this case,
/// the pages will grow to fit their content on the respective axis. /// the pages will grow to fit their content on the respective axis.
/// ///
/// ## Parameters
/// - paper: `Paper` (positional, settable)
/// A standard paper size to set width and height. When this is not specified,
/// Typst defaults to `{"a4"}` paper.
///
/// ## Example /// ## Example
/// ```example /// ```example
/// >>> #set page(margin: auto) /// >>> #set page(margin: auto)
@ -25,6 +20,11 @@ use crate::prelude::*;
/// There you go, US friends! /// There you go, US friends!
/// ``` /// ```
/// ///
/// ## Parameters
/// - paper: `Paper` (positional, settable)
/// A standard paper size to set width and height. When this is not specified,
/// Typst defaults to `{"a4"}` paper.
///
/// Display: Page /// Display: Page
/// Category: layout /// Category: layout
#[node] #[node]

View File

@ -45,6 +45,7 @@ use crate::text::{
pub struct ParNode { pub struct ParNode {
/// The paragraph's children. /// The paragraph's children.
#[variadic] #[variadic]
#[skip]
pub children: Vec<Content>, pub children: Vec<Content>,
/// The indent the first line of a consecutive paragraph should have. /// The indent the first line of a consecutive paragraph should have.

View File

@ -86,9 +86,6 @@ impl Behave for HNode {
/// ``` /// ```
/// ///
/// ## Parameters /// ## Parameters
/// - amount: `Spacing` (positional, required)
/// How much spacing to insert.
///
/// - weak: `bool` (named) /// - weak: `bool` (named)
/// If true, the spacing collapses at the start or end of a flow. Moreover, /// If true, the spacing collapses at the start or end of a flow. Moreover,
/// from multiple adjacent weak spacings all but the largest one collapse. /// from multiple adjacent weak spacings all but the largest one collapse.
@ -108,7 +105,7 @@ impl Behave for HNode {
/// Category: layout /// Category: layout
#[node(Construct, Behave)] #[node(Construct, Behave)]
pub struct VNode { pub struct VNode {
/// The amount of vertical spacing. /// How much spacing to insert.
#[positional] #[positional]
#[required] #[required]
pub amount: Spacing, pub amount: Spacing,

View File

@ -127,6 +127,9 @@ impl Layout for TermsNode {
} }
/// A term list item. /// A term list item.
///
/// Display: Term List Item
/// Category: layout
#[node] #[node]
pub struct TermItem { pub struct TermItem {
/// The term described by the list item. /// The term described by the list item.

View File

@ -79,12 +79,11 @@ pub struct RotateNode {
/// The amount of rotation. /// The amount of rotation.
/// ///
/// ```example /// ```example
/// #rotate(angle: -1.571rad)[Space!] /// #rotate(-1.571rad)[Space!]
/// ``` /// ```
/// ///
#[named] #[positional]
#[shorthand] #[required]
#[default]
pub angle: Angle, pub angle: Angle,
/// The content to rotate. /// The content to rotate.
@ -104,9 +103,9 @@ pub struct RotateNode {
/// #let square = square.with(width: 8pt) /// #let square = square.with(width: 8pt)
/// ///
/// #box(square()) /// #box(square())
/// #box(rotate(angle: 30deg, origin: center, square())) /// #box(rotate(30deg, origin: center, square()))
/// #box(rotate(angle: 30deg, origin: top + left, square())) /// #box(rotate(30deg, origin: top + left, square()))
/// #box(rotate(angle: 30deg, origin: bottom + right, square())) /// #box(rotate(30deg, origin: bottom + right, square()))
/// ``` /// ```
#[settable] #[settable]
#[resolve] #[resolve]

View File

@ -14,15 +14,6 @@ pub(super) const DELIM_SHORT_FALL: Em = Em::new(0.1);
/// $ lr(]sum_(x=1)^n] x, size: #50%) $ /// $ lr(]sum_(x=1)^n] x, size: #50%) $
/// ``` /// ```
/// ///
/// ## Parameters
/// - body: `Content` (positional, variadic)
/// The delimited content, including the delimiters.
///
/// - size: `Rel<Length>` (named)
/// The size of the brackets, relative to the height of the wrapped content.
///
/// Defaults to `{100%}`.
///
/// Display: Left/Right /// Display: Left/Right
/// Category: math /// Category: math
#[node(Construct, LayoutMath)] #[node(Construct, LayoutMath)]
@ -32,7 +23,9 @@ pub struct LrNode {
#[required] #[required]
pub body: Content, pub body: Content,
/// The size of the brackets. /// The size of the brackets, relative to the height of the wrapped content.
///
/// Defaults to `{100%}`.
#[named] #[named]
#[default] #[default]
pub size: Smart<Rel<Length>>, pub size: Smart<Rel<Length>>,

View File

@ -41,8 +41,7 @@ use self::spacing::*;
use crate::layout::{HNode, ParNode, Spacing}; use crate::layout::{HNode, ParNode, Spacing};
use crate::prelude::*; use crate::prelude::*;
use crate::text::{ use crate::text::{
families, variant, FallbackList, FontFamily, LinebreakNode, SpaceNode, TextNode, families, variant, FontFamily, FontList, LinebreakNode, SpaceNode, TextNode, TextSize,
TextSize,
}; };
/// Create a module with all math definitions. /// Create a module with all math definitions.
@ -113,7 +112,7 @@ pub fn module() -> Module {
/// ///
/// ## Example /// ## Example
/// ```example /// ```example
/// #set text("New Computer Modern") /// #set text(font: "New Computer Modern")
/// ///
/// Let $a$, $b$, and $c$ be the side /// Let $a$, $b$, and $c$ be the side
/// lengths of right-angled triangle. /// lengths of right-angled triangle.
@ -161,8 +160,8 @@ impl Finalize for FormulaNode {
realized realized
.styled(TextNode::WEIGHT, FontWeight::from_number(450)) .styled(TextNode::WEIGHT, FontWeight::from_number(450))
.styled( .styled(
TextNode::FAMILY, TextNode::FONT,
FallbackList(vec![FontFamily::new("New Computer Modern Math")]), FontList(vec![FontFamily::new("New Computer Modern Math")]),
) )
} }
} }
@ -233,7 +232,7 @@ impl LayoutMath for Content {
if let Some(styled) = self.to::<StyledNode>() { if let Some(styled) = self.to::<StyledNode>() {
let map = styled.map(); let map = styled.map();
if map.contains(TextNode::FAMILY) { if map.contains(TextNode::FONT) {
let frame = ctx.layout_content(self)?; let frame = ctx.layout_content(self)?;
ctx.push(FrameFragment::new(ctx, frame).with_spaced(true)); ctx.push(FrameFragment::new(ctx, frame).with_spaced(true));
return Ok(()); return Ok(());

View File

@ -183,7 +183,7 @@ impl LayoutMath for FrakNode {
/// $ mono(x + y = z) $ /// $ mono(x + y = z) $
/// ``` /// ```
/// ///
/// Display: Monospace /// Display: Monospace
/// Category: math /// Category: math
#[node(LayoutMath)] #[node(LayoutMath)]
pub struct MonoNode { pub struct MonoNode {

View File

@ -23,42 +23,38 @@ use crate::text::{Hyphenate, TextNode};
/// This function also has dedicated syntax: Text that starts with `http://` or /// This function also has dedicated syntax: Text that starts with `http://` or
/// `https://` is automatically turned into a link. /// `https://` is automatically turned into a link.
/// ///
/// ## Parameters
/// - dest: `Destination` (positional, required)
/// The destination the link points to.
///
/// - To link to web pages, `dest` should be a valid URL string. If the URL is
/// in the `mailto:` or `tel:` scheme and the `body` parameter is omitted,
/// the email address or phone number will be the link's body, without the
/// scheme.
///
/// - To link to another part of the document, `dest` must contain a
/// dictionary with a `page` key of type `integer` and `x` and `y`
/// coordinates of type `length`. Pages are counted from one, and the
/// coordinates are relative to the page's top left corner.
///
/// ```example
/// #link("mailto:hello@typst.app") \
/// #link((page: 1, x: 0pt, y: 0pt))[
/// Go to top
/// ]
/// ```
///
/// - body: `Content` (positional)
///
/// The content that should become a link. If `dest` is an URL string, the
/// parameter can be omitted. In this case, the URL will be shown as the link.
///
/// Display: Link /// Display: Link
/// Category: meta /// Category: meta
#[node(Construct, Show, Finalize)] #[node(Construct, Show, Finalize)]
pub struct LinkNode { pub struct LinkNode {
/// The destination the link points to. /// The destination the link points to.
///
/// - To link to web pages, `dest` should be a valid URL string. If the URL is
/// in the `mailto:` or `tel:` scheme and the `body` parameter is omitted,
/// the email address or phone number will be the link's body, without the
/// scheme.
///
/// - To link to another part of the document, `dest` must contain a
/// dictionary with a `page` key of type `integer` and `x` and `y`
/// coordinates of type `length`. Pages are counted from one, and the
/// coordinates are relative to the page's top left corner.
///
/// ```example
/// #link("mailto:hello@typst.app") \
/// #link((page: 1, x: 0pt, y: 0pt))[
/// Go to top
/// ]
/// ```
///
#[positional] #[positional]
#[required] #[required]
pub dest: Destination, pub dest: Destination,
/// How the link is represented. /// How the link is represented.
///
/// The content that should become a link. If `dest` is an URL string, the
/// parameter can be omitted. In this case, the URL will be shown as the
/// link.
#[positional] #[positional]
#[default] #[default]
pub body: Content, pub body: Content,

View File

@ -74,10 +74,10 @@ pub trait StyleMapExt {
impl StyleMapExt for StyleMap { impl StyleMapExt for StyleMap {
fn set_family(&mut self, preferred: crate::text::FontFamily, existing: StyleChain) { fn set_family(&mut self, preferred: crate::text::FontFamily, existing: StyleChain) {
self.set( self.set(
crate::text::TextNode::FAMILY, crate::text::TextNode::FONT,
crate::text::FallbackList( crate::text::FontList(
std::iter::once(preferred) std::iter::once(preferred)
.chain(existing.get(crate::text::TextNode::FAMILY).0.iter().cloned()) .chain(existing.get(crate::text::TextNode::FONT).0.iter().cloned())
.collect(), .collect(),
), ),
); );

View File

@ -31,7 +31,6 @@ pub struct UnderlineNode {
/// ) /// )
/// ``` /// ```
#[settable] #[settable]
#[shorthand]
#[resolve] #[resolve]
#[fold] #[fold]
#[default] #[default]
@ -117,7 +116,6 @@ pub struct OverlineNode {
/// ) /// )
/// ``` /// ```
#[settable] #[settable]
#[shorthand]
#[resolve] #[resolve]
#[fold] #[fold]
#[default] #[default]
@ -207,7 +205,6 @@ pub struct StrikeNode {
/// This is #strike(stroke: 10pt)[redacted]. /// This is #strike(stroke: 10pt)[redacted].
/// ``` /// ```
#[settable] #[settable]
#[shorthand]
#[resolve] #[resolve]
#[fold] #[fold]
#[default] #[default]
@ -219,7 +216,7 @@ pub struct StrikeNode {
/// This is useful if you are unhappy with the offset your font provides. /// This is useful if you are unhappy with the offset your font provides.
/// ///
/// ```example /// ```example
/// #set text(family: "Inria Serif") /// #set text(font: "Inria Serif")
/// This is #strike(offset: auto)[low-ish]. \ /// This is #strike(offset: auto)[low-ish]. \
/// This is #strike(offset: -3.5pt)[on-top]. /// This is #strike(offset: -3.5pt)[on-top].
/// ``` /// ```

View File

@ -39,60 +39,12 @@ use crate::prelude::*;
/// ``` /// ```
/// ///
/// ## Parameters /// ## Parameters
/// - family: `FallbackList` (positional, named, variadic, settable)
/// A prioritized sequence of font families.
///
/// When processing text, Typst tries all specified font families in order
/// until it finds a font that has the necessary glyphs. In the example below,
/// the font `Inria Serif` is preferred, but since it does not contain Arabic
/// glyphs, the arabic text uses `Noto Sans Arabic` instead.
///
/// ```example
/// #set text(
/// "Inria Serif",
/// "Noto Sans Arabic",
/// )
///
/// This is Latin. \
/// هذا عربي.
///
/// ```
///
/// - body: `Content` (positional, required) /// - body: `Content` (positional, required)
/// Content in which all text is styled according to the other arguments. /// Content in which all text is styled according to the other arguments.
/// ///
/// Display: Text /// Display: Text
/// Category: text /// Category: text
#[node(Construct)] #[node(Construct)]
#[set({
if let Some(family) = args.named("family")? {
styles.set(Self::FAMILY, family);
} else {
let mut count = 0;
let mut content = false;
for item in args.items.iter().filter(|item| item.name.is_none()) {
if EcoString::is(&item.value) {
count += 1;
} else if <Content as Cast<Spanned<Value>>>::is(&item.value) {
content = true;
}
}
// Skip the final string if it's needed as the body.
if constructor && !content && count > 0 {
count -= 1;
}
if count > 0 {
let mut list = Vec::with_capacity(count);
for _ in 0..count {
list.push(args.find()?.unwrap());
}
styles.set(Self::FAMILY, FallbackList(list));
}
}
})]
pub struct TextNode { pub struct TextNode {
/// The text. /// The text.
#[positional] #[positional]
@ -101,10 +53,25 @@ pub struct TextNode {
pub text: EcoString, pub text: EcoString,
/// A prioritized sequence of font families. /// A prioritized sequence of font families.
///
/// When processing text, Typst tries all specified font families in order
/// until it finds a font that has the necessary glyphs. In the example
/// below, the font `Inria Serif` is preferred, but since it does not
/// contain Arabic glyphs, the arabic text uses `Noto Sans Arabic` instead.
///
/// ```example
/// #set text(font: (
/// "Inria Serif",
/// "Noto Sans Arabic",
/// ))
///
/// This is Latin. \
/// هذا عربي.
///
/// ```
#[settable] #[settable]
#[skip] #[default(FontList(vec![FontFamily::new("Linux Libertine")]))]
#[default(FallbackList(vec![FontFamily::new("Linux Libertine")]))] pub font: FontList,
pub family: FallbackList,
/// Whether to allow last resort font fallback when the primary font list /// Whether to allow last resort font fallback when the primary font list
/// contains no match. This lets Typst search through all available fonts /// contains no match. This lets Typst search through all available fonts
@ -117,7 +84,7 @@ pub struct TextNode {
/// something is up. /// something is up.
/// ///
/// ```example /// ```example
/// #set text(family: "Inria Serif") /// #set text(font: "Inria Serif")
/// هذا عربي /// هذا عربي
/// ///
/// #set text(fallback: false) /// #set text(fallback: false)
@ -141,8 +108,8 @@ pub struct TextNode {
/// style later if you change your mind about how to signify the emphasis. /// style later if you change your mind about how to signify the emphasis.
/// ///
/// ```example /// ```example
/// #text("Linux Libertine", style: "italic")[Italic] /// #text(font: "Linux Libertine", style: "italic")[Italic]
/// #text("DejaVu Sans", style: "oblique")[Oblique] /// #text(font: "DejaVu Sans", style: "oblique")[Oblique]
/// ``` /// ```
#[settable] #[settable]
#[default(FontStyle::Normal)] #[default(FontStyle::Normal)]
@ -460,7 +427,7 @@ pub struct TextNode {
/// default numbers for the font are used. /// default numbers for the font are used.
/// ///
/// ```example /// ```example
/// #set text(20pt, "Noto Sans") /// #set text(font: "Noto Sans", 20pt)
/// #set text(number-type: "lining") /// #set text(number-type: "lining")
/// Number 9. /// Number 9.
/// ///
@ -475,7 +442,7 @@ pub struct TextNode {
/// numbers for the font are used. /// numbers for the font are used.
/// ///
/// ```example /// ```example
/// #set text(20pt, "Noto Sans") /// #set text(font: "Noto Sans", 20pt)
/// #set text(number-width: "proportional") /// #set text(number-width: "proportional")
/// A 12 B 34. \ /// A 12 B 34. \
/// A 56 B 78. /// A 56 B 78.
@ -609,16 +576,16 @@ cast_to_value! {
/// Font family fallback list. /// Font family fallback list.
#[derive(Debug, Default, Clone, Eq, PartialEq, Hash)] #[derive(Debug, Default, Clone, Eq, PartialEq, Hash)]
pub struct FallbackList(pub Vec<FontFamily>); pub struct FontList(pub Vec<FontFamily>);
cast_from_value! { cast_from_value! {
FallbackList, FontList,
family: FontFamily => Self(vec![family]), family: FontFamily => Self(vec![family]),
values: Array => Self(values.into_iter().map(|v| v.cast()).collect::<StrResult<_>>()?), values: Array => Self(values.into_iter().map(|v| v.cast()).collect::<StrResult<_>>()?),
} }
cast_to_value! { cast_to_value! {
v: FallbackList => v.0.into() v: FontList => v.0.into()
} }
/// The size of text. /// The size of text.

View File

@ -3,8 +3,7 @@ use syntect::highlighting as synt;
use typst::syntax::{self, LinkedNode}; use typst::syntax::{self, LinkedNode};
use super::{ use super::{
FallbackList, FontFamily, Hyphenate, LinebreakNode, SmartQuoteNode, TextNode, FontFamily, FontList, Hyphenate, LinebreakNode, SmartQuoteNode, TextNode, TextSize,
TextSize,
}; };
use crate::layout::BlockNode; use crate::layout::BlockNode;
use crate::prelude::*; use crate::prelude::*;
@ -185,10 +184,7 @@ impl Finalize for RawNode {
map.set(TextNode::OVERHANG, false); map.set(TextNode::OVERHANG, false);
map.set(TextNode::HYPHENATE, Hyphenate(Smart::Custom(false))); map.set(TextNode::HYPHENATE, Hyphenate(Smart::Custom(false)));
map.set(TextNode::SIZE, TextSize(Em::new(0.8).into())); map.set(TextNode::SIZE, TextSize(Em::new(0.8).into()));
map.set( map.set(TextNode::FONT, FontList(vec![FontFamily::new("DejaVu Sans Mono")]));
TextNode::FAMILY,
FallbackList(vec![FontFamily::new("DejaVu Sans Mono")]),
);
map.set(SmartQuoteNode::ENABLED, false); map.set(SmartQuoteNode::ENABLED, false);
realized.styled_with_map(map) realized.styled_with_map(map)
} }

View File

@ -560,7 +560,7 @@ pub fn families(styles: StyleChain) -> impl Iterator<Item = FontFamily> + Clone
let tail = if styles.get(TextNode::FALLBACK) { FALLBACKS } else { &[] }; let tail = if styles.get(TextNode::FALLBACK) { FALLBACKS } else { &[] };
styles styles
.get(TextNode::FAMILY) .get(TextNode::FONT)
.0 .0
.into_iter() .into_iter()
.chain(tail.iter().copied().map(FontFamily::new)) .chain(tail.iter().copied().map(FontFamily::new))

View File

@ -174,7 +174,7 @@ fn search_text(content: &Content, sub: bool) -> Option<EcoString> {
/// given string. /// given string.
fn is_shapable(vt: &Vt, text: &str, styles: StyleChain) -> bool { fn is_shapable(vt: &Vt, text: &str, styles: StyleChain) -> bool {
let world = vt.world(); let world = vt.world();
for family in styles.get(TextNode::FAMILY).0.iter() { for family in styles.get(TextNode::FONT).0.iter() {
if let Some(font) = world if let Some(font) = world
.book() .book()
.select(family.as_str(), variant(styles)) .select(family.as_str(), variant(styles))

View File

@ -10,10 +10,6 @@ use crate::prelude::*;
/// ``` /// ```
/// ///
/// ## Parameters /// ## Parameters
/// - start: `Axes<Rel<Length>>` (named)
/// The start point of the line.
/// Must be an array of exactly two relative lengths.
///
/// - end: `Axes<Rel<Length>>` (named) /// - end: `Axes<Rel<Length>>` (named)
/// The end point of the line. /// The end point of the line.
/// Must be an array of exactly two relative lengths. /// Must be an array of exactly two relative lengths.
@ -29,7 +25,9 @@ use crate::prelude::*;
/// Category: visualize /// Category: visualize
#[node(Construct, Layout)] #[node(Construct, Layout)]
pub struct LineNode { pub struct LineNode {
/// Where the line starts. /// The start point of the line.
///
/// Must be an array of exactly two relative lengths.
#[named] #[named]
#[default] #[default]
pub start: Axes<Rel<Length>>, pub start: Axes<Rel<Length>>,
@ -37,6 +35,7 @@ pub struct LineNode {
/// The offset from `start` where the line ends. /// The offset from `start` where the line ends.
#[named] #[named]
#[default] #[default]
#[skip]
pub delta: Axes<Rel<Length>>, pub delta: Axes<Rel<Length>>,
/// How to stroke the line. This can be: /// How to stroke the line. This can be:

View File

@ -190,6 +190,11 @@ impl Layout for RectNode {
/// ] /// ]
/// ``` /// ```
/// ///
/// ## Parameters
/// - size: `Smart<Length>` (named)
/// The square's side length. This is mutually exclusive with `width` and
/// `height`.
///
/// Display: Square /// Display: Square
/// Category: visualize /// Category: visualize
#[node(Construct, Layout)] #[node(Construct, Layout)]
@ -414,26 +419,10 @@ impl Layout for EllipseNode {
/// ``` /// ```
/// ///
/// ## Parameters /// ## Parameters
/// - body: `Content` (positional)
/// The content to place into the circle. The circle expands to fit this
/// content, keeping the 1-1 aspect ratio.
///
/// - radius: `Length` (named) /// - radius: `Length` (named)
/// The circle's radius. This is mutually exclusive with `width` and /// The circle's radius. This is mutually exclusive with `width` and
/// `height`. /// `height`.
/// ///
/// - width: `Rel<Length>` (named)
/// The circle's width. This is mutually exclusive with `radius` and `height`.
///
/// In contrast to `size`, this can be relative to the parent container's
/// width.
///
/// - height: `Rel<Length>` (named)
/// The circle's height.This is mutually exclusive with `radius` and `width`.
///
/// In contrast to `size`, this can be relative to the parent container's
/// height.
///
/// Display: Circle /// Display: Circle
/// Category: visualize /// Category: visualize
#[node(Construct, Layout)] #[node(Construct, Layout)]

View File

@ -1,22 +1,34 @@
use super::*; use super::*;
/// Expand the `#[func]` macro. /// Expand the `#[func]` macro.
pub fn func(item: syn::Item) -> Result<TokenStream> { pub fn func(mut item: syn::Item) -> Result<TokenStream> {
let mut docs = match &item { let attrs = match &mut item {
syn::Item::Struct(item) => documentation(&item.attrs), syn::Item::Struct(item) => &mut item.attrs,
syn::Item::Enum(item) => documentation(&item.attrs), syn::Item::Fn(item) => &mut item.attrs,
syn::Item::Fn(item) => documentation(&item.attrs), _ => bail!(item, "expected struct or fn"),
_ => String::new(),
}; };
let docs = documentation(&attrs);
let mut lines: Vec<_> = docs.lines().collect();
let Some(category) = lines.pop().and_then(|s| s.strip_prefix("Category: ")) else {
bail!(item, "expected category");
};
let Some(display) = lines.pop().and_then(|s| s.strip_prefix("Display: ")) else {
bail!(item, "expected display name");
};
let mut docs = lines.join("\n");
let (params, returns) = params(&mut docs)?; let (params, returns) = params(&mut docs)?;
let docs = docs.trim(); let docs = docs.trim();
attrs.retain(|attr| !attr.path.is_ident("doc"));
attrs.push(parse_quote! { #[doc = #docs] });
let info = quote! { let info = quote! {
::typst::eval::FuncInfo { ::typst::eval::FuncInfo {
name, name,
display: "TODO", display: #display,
category: "TODO", category: #category,
docs: #docs, docs: #docs,
params: ::std::vec![#(#params),*], params: ::std::vec![#(#params),*],
returns: ::std::vec![#(#returns),*] returns: ::std::vec![#(#returns),*]

View File

@ -598,13 +598,15 @@ pub enum Meta {
} }
/// Host for metadata. /// Host for metadata.
///
/// Display: Meta
/// Category: special
#[node] #[node]
pub struct MetaNode { pub struct MetaNode {
/// Metadata that should be attached to all elements affected by this style /// Metadata that should be attached to all elements affected by this style
/// property. /// property.
#[settable] #[settable]
#[fold] #[fold]
#[skip]
#[default] #[default]
pub data: Vec<Meta>, pub data: Vec<Meta>,
} }

View File

@ -326,6 +326,9 @@ impl Sum for Content {
} }
/// A node with applied styles. /// A node with applied styles.
///
/// Display: Styled
/// Category: special
#[node] #[node]
pub struct StyledNode { pub struct StyledNode {
/// The styled content. /// The styled content.
@ -347,6 +350,9 @@ cast_from_value! {
/// ///
/// Combines other arbitrary content. So, when you write `[Hi] + [you]` in /// Combines other arbitrary content. So, when you write `[Hi] + [you]` in
/// Typst, the two text nodes are combined into a single sequence node. /// Typst, the two text nodes are combined into a single sequence node.
///
/// Display: Sequence
/// Category: special
#[node] #[node]
pub struct SequenceNode { pub struct SequenceNode {
#[variadic] #[variadic]

View File

@ -146,8 +146,8 @@ impl Args {
} }
fn library() -> Library { fn library() -> Library {
/// Category: test
/// Display: Test /// Display: Test
/// Category: test
#[func] #[func]
fn test(args: &mut typst::eval::Args) -> SourceResult<Value> { fn test(args: &mut typst::eval::Args) -> SourceResult<Value> {
let lhs = args.expect::<Value>("left-hand side")?; let lhs = args.expect::<Value>("left-hand side")?;
@ -158,8 +158,8 @@ fn library() -> Library {
Ok(Value::None) Ok(Value::None)
} }
/// Category: test
/// Display: Print /// Display: Print
/// Category: test
#[func] #[func]
fn print(args: &mut typst::eval::Args) -> SourceResult<Value> { fn print(args: &mut typst::eval::Args) -> SourceResult<Value> {
print!("> "); print!("> ");

View File

@ -115,7 +115,7 @@
// Should output `Some` in red, `Some` in blue and `Last` in green. // Should output `Some` in red, `Some` in blue and `Last` in green.
// Everything should be in smallcaps. // Everything should be in smallcaps.
#for color in (red, blue, green, yellow) [ #for color in (red, blue, green, yellow) [
#set text("Roboto") #set text(font: "Roboto")
#show: it => text(fill: color, it) #show: it => text(fill: color, it)
#smallcaps(if color != green [ #smallcaps(if color != green [
Some Some

View File

@ -44,8 +44,8 @@
} }
--- ---
// Error: 28-34 duplicate argument // Error: 26-30 duplicate argument
#set text(family: "Arial", family: "Helvetica") #set text(font: "Arial", font: "Helvetica")
--- ---
// Error: 2-6 expected function, found boolean // Error: 2-6 expected function, found boolean

View File

@ -7,7 +7,7 @@ The non-breaking~space does work.
// Make sure non-breaking and normal space always // Make sure non-breaking and normal space always
// have the same width. Even if the font decided // have the same width. Even if the font decided
// differently. // differently.
#set text("New Computer Modern") #set text(font: "New Computer Modern")
a b \ a b \
a~b a~b
@ -16,5 +16,5 @@ a~b
- Em dash: --- - Em dash: ---
--- ---
#set text("Roboto") #set text(font: "Roboto")
A... vs #"A..." A... vs #"A..."

View File

@ -2,14 +2,14 @@
--- ---
// Test classic example. // Test classic example.
#set text("Roboto") #set text(font: "Roboto")
#show "Der Spiegel": smallcaps #show "Der Spiegel": smallcaps
Die Zeitung Der Spiegel existiert. Die Zeitung Der Spiegel existiert.
--- ---
// Another classic example. // Another classic example.
#show "TeX": [T#h(-0.145em)#box(move(dy: 0.233em)[E])#h(-0.135em)X] #show "TeX": [T#h(-0.145em)#box(move(dy: 0.233em)[E])#h(-0.135em)X]
#show regex("(Lua)?(La)?TeX"): name => box(text("New Computer Modern")[#name]) #show regex("(Lua)?(La)?TeX"): name => box(text(font: "New Computer Modern")[#name])
TeX, LaTeX, LuaTeX and LuaLaTeX! TeX, LaTeX, LuaTeX and LuaLaTeX!

View File

@ -54,7 +54,7 @@
#eval("let") #eval("let")
--- ---
#show raw: it => text("PT Sans", eval("[" + it.text + "]")) #show raw: it => text(font: "PT Sans", eval("[" + it.text + "]"))
Interacting Interacting
``` ```

View File

@ -3,7 +3,7 @@
--- ---
// Test normal operation and RTL directions. // Test normal operation and RTL directions.
#set page(height: 3.25cm, width: 7.05cm, columns: 2) #set page(height: 3.25cm, width: 7.05cm, columns: 2)
#set text(lang: "ar", "Noto Sans Arabic", "Linux Libertine") #set text(lang: "ar", font: ("Noto Sans Arabic", "Linux Libertine"))
#set columns(gutter: 30pt) #set columns(gutter: 30pt)
#box(fill: conifer, height: 8pt, width: 6pt) وتحفيز #box(fill: conifer, height: 8pt, width: 6pt) وتحفيز

View File

@ -37,7 +37,7 @@
--- ---
// Test numbering with closure and nested lists. // Test numbering with closure and nested lists.
#set text("New Computer Modern") #set text(font: "New Computer Modern")
#set enum(numbering: (..args) => math.mat(args.pos()), full: true) #set enum(numbering: (..args) => math.mat(args.pos()), full: true)
+ A + A
+ B + B

View File

@ -24,5 +24,5 @@
#set page("a4") #set page("a4")
#set page("a5") #set page("a5")
#set page("a11", flipped: true, fill: eastern) #set page("a11", flipped: true, fill: eastern)
#set text("Roboto", white) #set text(font: "Roboto", white)
#smallcaps[Typst] #smallcaps[Typst]

View File

@ -23,7 +23,7 @@
--- ---
// Test page fill. // Test page fill.
#set page(width: 80pt, height: 40pt, fill: eastern) #set page(width: 80pt, height: 40pt, fill: eastern)
#text(15pt, "Roboto", fill: white, smallcaps[Typst]) #text(15pt, font: "Roboto", fill: white, smallcaps[Typst])
#page(width: 40pt, fill: none, margin: (top: 10pt, rest: auto))[Hi] #page(width: 40pt, fill: none, margin: (top: 10pt, rest: auto))[Hi]
--- ---

View File

@ -10,7 +10,7 @@
// Test that consecutive, embedded LTR runs stay LTR. // Test that consecutive, embedded LTR runs stay LTR.
// Here, we have two runs: "A" and italic "B". // Here, we have two runs: "A" and italic "B".
#let content = par[أنت A#emph[B]مطرC] #let content = par[أنت A#emph[B]مطرC]
#set text("PT Sans", "Noto Sans Arabic") #set text(font: ("PT Sans", "Noto Sans Arabic"))
#text(lang: "ar", content) #text(lang: "ar", content)
#text(lang: "de", content) #text(lang: "de", content)
@ -18,7 +18,7 @@
// Test that consecutive, embedded RTL runs stay RTL. // Test that consecutive, embedded RTL runs stay RTL.
// Here, we have three runs: "גֶ", bold "שֶׁ", and "ם". // Here, we have three runs: "גֶ", bold "שֶׁ", and "ם".
#let content = par[Aגֶ#strong[שֶׁ]םB] #let content = par[Aגֶ#strong[שֶׁ]םB]
#set text("Linux Libertine", "Noto Serif Hebrew") #set text(font: ("Linux Libertine", "Noto Serif Hebrew"))
#text(lang: "he", content) #text(lang: "he", content)
#text(lang: "de", content) #text(lang: "de", content)
@ -29,7 +29,7 @@
--- ---
// Test hard line break (leads to two paragraphs in unicode-bidi). // Test hard line break (leads to two paragraphs in unicode-bidi).
#set text(lang: "ar", "Noto Sans Arabic", "PT Sans") #set text(lang: "ar", font: ("Noto Sans Arabic", "PT Sans"))
Life المطر هو الحياة \ Life المطر هو الحياة \
الحياة تمطر is rain. الحياة تمطر is rain.

View File

@ -20,7 +20,7 @@ starts a paragraph without indent.
Except if you have another paragraph in them. Except if you have another paragraph in them.
#set text(8pt, lang: "ar", "Noto Sans Arabic", "Linux Libertine") #set text(8pt, lang: "ar", font: ("Noto Sans Arabic", "Linux Libertine"))
#set par(leading: 8pt) #set par(leading: 8pt)
= Arabic = Arabic

View File

@ -1,6 +1,6 @@
#set page(width: auto, height: auto) #set page(width: auto, height: auto)
#set par(leading: 4pt, justify: true) #set par(leading: 4pt, justify: true)
#set text(family: "New Computer Modern") #set text(font: "New Computer Modern")
#let story = [ #let story = [
In olden times when wishing still helped one, there lived a king whose In olden times when wishing still helped one, there lived a king whose

View File

@ -23,7 +23,7 @@
[X] [X]
} }
#set text("New Computer Modern", size) #set text(font: "New Computer Modern", size)
Neither #tex, \ Neither #tex, \
nor #xetex! nor #xetex!

View File

@ -15,5 +15,5 @@ $ x := #table(columns: 2)[x][y]/mat(1, 2, 3)
--- ---
// Test font switch. // Test font switch.
#let here = text.with("Noto Sans") #let here = text.with(font: "Noto Sans")
$#here[f] := #here[Hi there]$. $#here[f] := #here[Hi there]$.

View File

@ -11,7 +11,7 @@ $ &sin x + log_2 x \
--- ---
// Test scripts vs limits. // Test scripts vs limits.
#set text("New Computer Modern") #set text(font: "New Computer Modern")
Discuss $lim_(n->oo) 1/n$ now. Discuss $lim_(n->oo) 1/n$ now.
$ lim_(n->infinity) 1/n = 0 $ $ lim_(n->infinity) 1/n = 0 $

View File

@ -26,5 +26,5 @@ $text(#red, "time"^2) + sqrt("place")$
--- ---
// Test different font. // Test different font.
#show math.formula: set text(family: "Fira Math") #show math.formula: set text(font: "Fira Math")
$ v := vec(1 + 2, 2 - 4, sqrt(3), arrow(x)) + 1 $ $ v := vec(1 + 2, 2 - 4, sqrt(3), arrow(x)) + 1 $

View File

@ -38,7 +38,7 @@ multiline.
--- ---
// Test styling. // Test styling.
#show heading.where(level: 5): it => block( #show heading.where(level: 5): it => block(
text(family: "Roboto", fill: eastern, it.title + [!]) text(font: "Roboto", fill: eastern, it.title + [!])
) )
= Heading = Heading

View File

@ -1,7 +1,7 @@
// Test chinese text from Wikipedia. // Test chinese text from Wikipedia.
--- ---
#set text("Noto Serif CJK SC") #set text(font: "Noto Serif CJK SC")
是美国广播公司电视剧《迷失》第3季的第22和23集也是全剧的第71集和72集 是美国广播公司电视剧《迷失》第3季的第22和23集也是全剧的第71集和72集
由执行制作人戴蒙·林道夫和卡尔顿·库斯编剧,导演则是另一名执行制作人杰克·本德 由执行制作人戴蒙·林道夫和卡尔顿·库斯编剧,导演则是另一名执行制作人杰克·本德

View File

@ -10,7 +10,7 @@
#underline(offset: 5pt)[Further below.] #underline(offset: 5pt)[Further below.]
// Different color. // Different color.
#underline(red, evade: false)[Critical information is conveyed here.] #underline(stroke: red, evade: false)[Critical information is conveyed here.]
// Inherits font color. // Inherits font color.
#text(fill: red, underline[Change with the wind.]) #text(fill: red, underline[Change with the wind.])
@ -19,7 +19,7 @@
#overline(underline[Running amongst the wolves.]) #overline(underline[Running amongst the wolves.])
--- ---
#let redact = strike.with(10pt, extent: 0.05em) #let redact = strike.with(stroke: 10pt, extent: 0.05em)
#let highlight = strike.with(stroke: 10pt + rgb("abcdef88"), extent: 0.05em) #let highlight = strike.with(stroke: 10pt + rgb("abcdef88"), extent: 0.05em)
// Abuse thickness and transparency for redacting and highlighting stuff. // Abuse thickness and transparency for redacting and highlighting stuff.

View File

@ -5,7 +5,7 @@
#set text(size: 8pt) #set text(size: 8pt)
#let try(top, bottom) = rect(inset: 0pt, fill: conifer)[ #let try(top, bottom) = rect(inset: 0pt, fill: conifer)[
#set text("IBM Plex Mono", top-edge: top, bottom-edge: bottom) #set text(font: "IBM Plex Mono", top-edge: top, bottom-edge: bottom)
From #top to #bottom From #top to #bottom
] ]

View File

@ -11,7 +11,7 @@
--- ---
// Test alternates and stylistic sets. // Test alternates and stylistic sets.
#set text("IBM Plex Serif") #set text(font: "IBM Plex Serif")
a vs #text(alternates: true)[a] \ a vs #text(alternates: true)[a] \
ß vs #text(stylistic-set: 5)[ß] ß vs #text(stylistic-set: 5)[ß]
@ -33,7 +33,7 @@ fi vs. #text(ligatures: false)[No fi]
--- ---
// Test extra number stuff. // Test extra number stuff.
#set text("IBM Plex Serif") #set text(font: "IBM Plex Serif")
0 vs. #text(slashed-zero: true)[0] \ 0 vs. #text(slashed-zero: true)[0] \
1/2 vs. #text(fractions: true)[1/2] 1/2 vs. #text(fractions: true)[1/2]

View File

@ -18,8 +18,8 @@
// Set stretch (not available, matching closest). // Set stretch (not available, matching closest).
#text(stretch: 50%)[Condensed] #text(stretch: 50%)[Condensed]
// Set family. // Set font family.
#text(family: "IBM Plex Serif")[Serif] #text(font: "IBM Plex Serif")[Serif]
// Emoji. // Emoji.
Emoji: 🐪, 🌋, 🏞 Emoji: 🐪, 🌋, 🏞
@ -32,16 +32,16 @@ Emoji: 🐪, 🌋, 🏞
// Disable font fallback beyond the user-specified list. // Disable font fallback beyond the user-specified list.
// Without disabling, New Computer Modern Math would come to the rescue. // Without disabling, New Computer Modern Math would come to the rescue.
#set text("PT Sans", "Twitter Color Emoji", fallback: false) #set text(font: ("PT Sans", "Twitter Color Emoji"), fallback: false)
= 𝛼 + 𝛽. = 𝛼 + 𝛽.
--- ---
// Test string body. // Test string body.
#text("Text") \ #text("Text") \
#text(red, "Text") \ #text(red, "Text") \
#text("Ubuntu", blue, "Text") \ #text(font: "Ubuntu", blue, "Text") \
#text([Text], teal, "IBM Plex Serif") \ #text([Text], teal, font: "IBM Plex Serif") \
#text(forest, "New Computer Modern", [Text]) \ #text(forest, font: "New Computer Modern", [Text]) \
--- ---
// Error: 11-16 unexpected argument // Error: 11-16 unexpected argument
@ -55,10 +55,6 @@ Emoji: 🐪, 🌋, 🏞
// Error: 23-27 unexpected argument // Error: 23-27 unexpected argument
#set text(size: 10pt, 12pt) #set text(size: 10pt, 12pt)
---
// Error: 32-39 unexpected argument
#set text(family: "Helvetica", "Arial")
--- ---
// Error: 11-31 unexpected argument // Error: 11-31 unexpected argument
#set text(something: "invalid") #set text(something: "invalid")

View File

@ -12,7 +12,7 @@
--- ---
// Test that the language passed to the shaper has an effect. // Test that the language passed to the shaper has an effect.
#set text("Ubuntu") #set text(font: "Ubuntu")
// Some lowercase letters are different in Serbian Cyrillic compared to other // Some lowercase letters are different in Serbian Cyrillic compared to other
// Cyrillic languages. Since there is only one set of Unicode codepoints for // Cyrillic languages. Since there is only one set of Unicode codepoints for

View File

@ -12,7 +12,7 @@
] ]
// Test hanging punctuation with RTL. // Test hanging punctuation with RTL.
#set text(lang: "he", "PT Sans", "Noto Serif Hebrew") #set text(lang: "he", font: ("PT Sans", "Noto Serif Hebrew"))
בנייה נכונה של משפטים ארוכים דורשת ידע בשפה. אז בואו נדבר על מזג האוויר. בנייה נכונה של משפטים ארוכים דורשת ידע בשפה. אז בואו נדבר על מזג האוויר.
--- ---

View File

@ -46,7 +46,7 @@ The keyword ```rust let```.
--- ---
// Text show rule // Text show rule
#show raw: set text("Roboto") #show raw: set text(font: "Roboto")
`Roboto` `Roboto`
--- ---

View File

@ -14,5 +14,5 @@ ABCअपार्टमेंट
--- ---
// Test that RTL safe-to-break doesn't panic even though newline // Test that RTL safe-to-break doesn't panic even though newline
// doesn't exist in shaping output. // doesn't exist in shaping output.
#set text(dir: rtl, "Noto Serif Hebrew") #set text(dir: rtl, font: "Noto Serif Hebrew")
\ ט \ ט

View File

@ -23,11 +23,11 @@ A /**/B/**/ C
--- ---
// Test that a run consisting only of whitespace isn't trimmed. // Test that a run consisting only of whitespace isn't trimmed.
A#text("IBM Plex Serif")[ ]B A#text(font: "IBM Plex Serif")[ ]B
--- ---
// Test font change after space. // Test font change after space.
Left #text("IBM Plex Serif")[Right]. Left #text(font: "IBM Plex Serif")[Right].
--- ---
// Test that linebreak consumed surrounding spaces. // Test that linebreak consumed surrounding spaces.

View File

@ -5,7 +5,7 @@
#emoji.woman.old #emoji.woman.old
#emoji.turtle #emoji.turtle
#set text("New Computer Modern Math") #set text(font: "New Computer Modern Math")
#sym.arrow #sym.arrow
#sym.arrow.l #sym.arrow.l
#sym.arrow.r.squiggly #sym.arrow.r.squiggly

View File

@ -11,7 +11,7 @@ I'm in#text(tracking: 0.15em + 1.5pt)[ spaace]!
--- ---
// Test that tracking doesn't disrupt mark placement. // Test that tracking doesn't disrupt mark placement.
#set text("PT Sans", "Noto Serif Hebrew") #set text(font: ("PT Sans", "Noto Serif Hebrew"))
#set text(tracking: 0.3em) #set text(tracking: 0.3em)
טֶקסט טֶקסט

View File

@ -42,7 +42,7 @@
--- ---
// Test stroke composition. // Test stroke composition.
#set square(stroke: 4pt) #set square(stroke: 4pt)
#set text("Roboto") #set text(font: "Roboto")
#square( #square(
stroke: (left: red, top: yellow, right: green, bottom: blue), stroke: (left: red, top: yellow, right: green, bottom: blue),
radius: 100%, align(center+horizon)[*G*], radius: 100%, align(center+horizon)[*G*],