docs/changelog/0.1.0.md
# 0.1.0
## Breaking changes
- When using the CLI, you now have to use subcommands:
- `typst compile file.typ` or `typst c file.typ` to create a PDF
- `typst watch file.typ` or `typst w file.typ` to compile and watch
- `typst fonts` to list all fonts
- Manual counters now start at zero. Read the "How to step" section [here](/docs/reference/introspection/counter/) for more details
- The [bibliography styles](/docs/reference/model/bibliography/#parameters-style) `"author-date"` and `"author-title"` were renamed to `"chicago-author-date"` and `"chicago-author-title"`
## Figure improvements
- Figures now automatically detect their content and adapt their behavior. Figures containing tables, for instance, are automatically prefixed with "Table X" and have a separate counter
- The figure's supplement (e.g. "Figure" or "Table") can now be customized
- In addition, figures can now be completely customized because the show rule gives access to the automatically resolved kind, supplement, and counter
## Bibliography improvements
- The [`bibliography`](/docs/reference/model/bibliography/) now also accepts multiple bibliography paths (as an array)
- Parsing of BibLaTeX files is now more permissive (accepts non-numeric edition, pages, volumes, dates, and Jabref-style comments; fixed abbreviation parsing)
- Labels and references can now include `:` and `.` except at the end
- Fixed APA bibliography ordering
## Drawing additions
- Added [`polygon`](/docs/reference/visualize/polygon/) function for drawing polygons
- Added support for clipping in [boxes](/docs/reference/layout/box/#parameters-clip) and [blocks](/docs/reference/layout/block/#parameters-clip)
## Command line interface
- Now returns with non-zero status code if there is an error
- Now watches the root directory instead of the current one
- Now puts the PDF file next to input file by default
- Now accepts more kinds of input files (e.g. `/dev/stdin`)
- Added `--open` flag to directly open the PDF
## Miscellaneous improvements
- Added [`yaml`](/docs/reference/data-loading/yaml/) function to load data from YAML files
- Added basic i18n for a few more languages (IT, RU, ZH, FR, PT)
- Added numbering support for Hebrew
- Added support for [integers](/docs/reference/foundations/int/) with base 2, 8, and 16
- Added symbols for double bracket and laplace operator
- The [`link`](/docs/reference/model/link/) function now accepts [labels](/docs/reference/foundations/label/)
- The link syntax now allows more characters
- Improved justification of Japanese and Chinese text
- Calculation functions behave more consistently w.r.t to non-real results
- Replaced deprecated angle brackets
- Reduced maximum function call depth from 256 to 64
- Fixed [`first-line-indent`](/docs/reference/model/par/#parameters-first-line-indent) being not applied when a paragraph starts with styled text
- Fixed extraneous spacing in unary operators in equations
- Fixed block spacing, e.g. in `block(above: 1cm, below: 1cm, ..)`
- Fixed styling of text operators in math
- Fixed invalid parsing of language tag in raw block with a single backtick
- Fixed bugs with displaying counters and state
- Fixed crash related to page counter
- Fixed crash when [`symbol`](/docs/reference/foundations/symbol/) function was called without arguments
- Fixed crash in bibliography generation
- Fixed access to label of certain content elements
- Fixed line number in error message for CSV parsing
- Fixed invalid autocompletion after certain markup elements
## Contributors
docs/changelog/0.10.0.md
# 0.10.0
## Bibliography management
- Added support for citation collapsing (e.g. `[1]-[3]` instead of `[1], [2], [3]`) if requested by a CSL style
- Fixed bug where an additional space would appear after a group of citations
- Fixed link show rules for links in the bibliography
- Fixed show-set rules on citations
- Fixed bibliography-related crashes that happened on some systems
- Corrected name of the GB/T 7714 family of styles from 7114 to 7714
- Fixed missing title in some bibliography styles
- Fixed printing of volumes in some styles
- Fixed delimiter order for contributors in some styles (e.g. APA)
- Fixed behavior of alphanumeric style
- Fixed multiple bugs with GB/T 7714 style
- Fixed escaping in Hayagriva values
- Fixed crashes with empty dates in Hayagriva files
- Fixed bug with spacing around math blocks
- Fixed title case formatting after verbatim text and apostrophes
- Page ranges in `.bib` files can now be arbitrary strings
- Multi-line values in `.bib` files are now parsed correctly
- Entry keys in `.bib` files now allow more characters
- Fixed error message for empty dates in `.bib` files
- Added support for years of lengths other than 4 without leading zeros in `.bib` files
- More LaTeX commands (e.g. for quotes) are now respected in `.bib` files
## Visualization
- Added support for [patterns](/docs/reference/visualize/tiling/) as fills and strokes
- The `alpha` parameter of the [`components`](/docs/reference/visualize/color/#definitions-components) function on colors is now a named parameter **(Breaking change)**
- Added support for the [Oklch](/docs/reference/visualize/color/#definitions-oklch) color space
- Improved conversions between colors in different color spaces
- Removed restrictions on [Oklab](/docs/reference/visualize/color/#definitions-oklab) chroma component
- Fixed [clipping](/docs/reference/layout/block/#parameters-clip) on blocks and boxes without a stroke
- Fixed bug with [gradients](/docs/reference/visualize/gradient/) on math
- Fixed bug with gradient rotation on text
- Fixed bug with gradient colors in PDF
- Fixed relative base of Oklab chroma ratios
- Fixed Oklab color negation
## Text and Layout
- CJK text can now be emphasized with the `*` and `_` syntax even when there are no spaces
- Added basic i18n for Greek and Estonian
- Improved default [figure caption separator](/docs/reference/model/figure/#definitions-caption-separator) for Chinese, French, and Russian
- Changed default [figure supplement](/docs/reference/model/figure/#parameters-supplement) for Russian to short form
- Fixed [CJK-Latin-spacing](/docs/reference/text/text/#parameters-cjk-latin-spacing) before line breaks and in [`locate`](/docs/reference/introspection/locate/) calls
- Fixed line breaking at the end of links
## Math
- Added [`mid`](/docs/reference/math/lr/#functions-mid) function for scaling a delimiter up to the height of the surrounding [`lr`](/docs/reference/math/lr/#functions-lr) group
- The [`op`](/docs/reference/math/op/) function can now take any content, not just strings
- Improved documentation for [math alignment](/docs/reference/math/#alignment)
- Fixed swallowing of trailing comma when a symbol is used in a function-like way (e.g. `pi(a,b,)`)
## Scripting
- Any non-identifier dictionary key is now interpreted as an expression: For instance, `((key): value)` will create a dictionary with a dynamic key
- The [`stroke`](/docs/reference/visualize/stroke/) type now has a constructor that converts a value to a stroke or creates one from its parts
- Added constructor for [`arguments`](/docs/reference/foundations/arguments/) type
- Added [`calc.div-euclid`](/docs/reference/foundations/calc/#functions-div-euclid) and [`calc.rem-euclid`](/docs/reference/foundations/calc/#functions-rem-euclid) functions
- Fixed equality of [`arguments`](/docs/reference/foundations/arguments/)
- Fixed [`repr`](/docs/reference/foundations/repr/)of [`cmyk`](/docs/reference/visualize/color/#definitions-cmyk) colors
- Fixed crashes with provided elements like figure captions, outline entries, and footnote entries
## Tooling and Diagnostics
- Show rules that match on their own output now produce an appropriate error message instead of a crash (this is a first step, in the future they will just work)
- Too highly or infinitely nested layouts now produce error messages instead of crashes
- Added hints for invalid identifiers
- Added hint when trying to use a manually constructed footnote or outline entry
- Added missing details to autocompletions for types
- Improved error message when passing a named argument where a positional one is expected
- Jump from click now works on raw blocks
## Export
- PDF compilation output is now again fully byte-by-byte reproducible if the document's [`date`](/docs/reference/model/document/#parameters-date) is set manually
- Fixed color export in SVG
- Fixed PDF metadata encoding of multiple [authors](/docs/reference/model/document/#parameters-author)
## Command line interface
- Fixed a major bug where `typst watch` would confuse files and fail to pick up updates
- Fetching of the release metadata in `typst update` now respects proxies
- Fixed bug with `--open` flag on Windows when the path contains a space
- The `TYPST_FONT_PATHS` environment variable can now contain multiple paths (separated by `;` on Windows and `:` elsewhere)
- Updated embedded New Computer Modern fonts to version 4.7
- The watching process doesn't stop anymore when the main file contains invalid UTF-8
## Miscellaneous Improvements
- Parallelized image encoding in PDF export
- Improved the internal representation of content for improved performance
- Optimized introspection (query, counter, etc.) performance
- The [document title](/docs/reference/model/document/#parameters-title) can now be arbitrary content instead of just a string
- The [`number-align`](/docs/reference/model/enum/#parameters-number-align) parameter on numbered lists now also accepts vertical alignments
- Fixed selectors on [quote](/docs/reference/model/quote/) elements
- Fixed parsing of `#return` expression in markup
- Fixed bug where inline equations were displayed in equation outlines
- Fixed potential CRLF issue in [`raw`](/docs/reference/text/raw/) blocks
- Fixed a bug where Chinese numbering couldn't exceed the number 255
## Development
- Merged `typst` and `typst-library` and extracted `typst-pdf`, `typst-svg`, and `typst-render` into separate crates
- The Nix flake now includes the git revision when running `typst --version`
## Contributors
docs/changelog/0.11.0.md
# 0.11.0
## Tables
- Tables are now _much_ more flexible, read the new [Table Guide](/docs/guides/tables/) to get started
- Added [`table.cell`](/docs/reference/model/table/#definitions-cell) element for per-cell configuration
- Cells can now span multiple [columns](/docs/reference/model/table/#definitions-cell-colspan) or [rows](/docs/reference/model/table/#definitions-cell-rowspan)
- The [stroke](/docs/reference/model/table/#definitions-cell-stroke) of individual cells can now be customized
- The [`align`](/docs/reference/model/table/#parameters-align) and [`inset`](/docs/reference/model/table/#parameters-inset) arguments of the table function now also take `(x, y) => ..` functions
- Added [`table.hline`](/docs/reference/model/table/#definitions-hline) and [`table.vline`](/docs/reference/model/table/#definitions-vline) for convenient line customization
- Added [`table.header`](/docs/reference/model/table/#definitions-header) element for table headers that repeat on every page
- Added [`table.footer`](/docs/reference/model/table/#definitions-footer) element for table footers that repeat on every page
- All the new table functionality is also available for [grids](/docs/reference/layout/grid/)
- Fixed gutter-related bugs
_Thanks to @PgBiel for his work on tables!_
## Templates
- You can now use template packages to get started with new projects. Click _Start from template_ on the web app's dashboard and choose your preferred template or run the `typst init <template>` command in the CLI. You can [browse the available templates here](https://typst.app/universe/search/?kind=templates).
- Switching templates after the fact has become easier. You can just import a styling function from a different template package.
- Package authors can now submit their own templates to the [package repository](https://github.com/typst/packages). Share a template for a paper, your institution, or an original work to help the community get a head start on their projects.
- Templates and packages are now organized by category and discipline. Filter packages by either taxonomy in the _Start from template_ wizard. If you are a package author, take a look at the new documentation for [categories](https://github.com/typst/packages/blob/main/docs/CATEGORIES.md) and [disciplines](https://github.com/typst/packages/blob/main/docs/DISCIPLINES.md).
## Context
- Added _context expressions:_ Read the chapter on [context](/docs/reference/context/) to get started
- With context, you can access settable properties, e.g. `context text.lang` to access the language set via `set text(lang: "..")`
- The following existing functions have been made contextual: [`query`](/docs/reference/introspection/query/), [`locate`](/docs/reference/introspection/locate/), [`measure`](/docs/reference/layout/measure/), [`counter.display`](/docs/reference/introspection/counter/#definitions-display), [`counter.at`](/docs/reference/introspection/counter/#definitions-at), [`counter.final`](/docs/reference/introspection/counter/#definitions-final), [`state.at`](/docs/reference/introspection/state/#definitions-at), and [`state.final`](/docs/reference/introspection/state/#definitions-final)
- Added contextual methods [`counter.get`](/docs/reference/introspection/counter/#definitions-get) and [`state.get`](/docs/reference/introspection/state/#definitions-get) to retrieve the value of a counter or state in the current context
- Added contextual function [`here`](/docs/reference/introspection/here/) to retrieve the [location](/docs/reference/introspection/location/) of the current context
- The [`locate`](/docs/reference/introspection/locate/) function now returns the location of a selector's unique match. Its old behavior has been replaced by context expressions and only remains temporarily available for compatibility.
- The [`counter.at`](/docs/reference/introspection/counter/#definitions-at) and [`state.at`](/docs/reference/introspection/state/#definitions-at) methods are now more flexible: They directly accept any kind of [locatable](/docs/reference/introspection/location/#locatable) selector with a unique match (e.g. a label) instead of just locations
- When context is available, [`counter.display`](/docs/reference/introspection/counter/#definitions-display) now directly returns the result of applying the numbering instead of yielding opaque content. It should not be used anymore without context. (Deprecation planned)
- The `state.display` function should not be used anymore, use [`state.get`](/docs/reference/introspection/state/#definitions-get) instead (Deprecation planned)
- The `location` argument of [`query`](/docs/reference/introspection/query/), [`counter.final`](/docs/reference/introspection/counter/#definitions-final), and [`state.final`](/docs/reference/introspection/state/#definitions-final) should not be used anymore (Deprecation planned)
- The `styles` argument of the `measure` function should not be used anymore (Deprecation planned)
- The `style` function should not be used anymore, use context instead (Deprecation planned)
- The correct context is now also provided in various other places where it is available, e.g. in show rules, layout callbacks, and numbering functions in the outline
## Styling
- Fixed priority of multiple [show-set rules](/docs/reference/styling/#show-rules): They now apply in the same order as normal set rules would
- Show-set rules on the same element (e.g. `show heading.where(level: 1): set heading(numbering: "1.")`) now work properly
- Setting properties on an element within a transformational show rule (e.g. `show heading: it => \{ set heading(..); it \}`) is **not** supported anymore (previously it also only worked sometimes); use show-set rules instead **(Breaking change)**
- Text show rules that match their own output now work properly (e.g. `show "cmd": `cmd``)
- The elements passed to show rules and returned by queries now contain all fields of their respective element functions rather than just specific ones
- All settable properties can now be used in [where](/docs/reference/foundations/function/#definitions-where) selectors
- [And](/docs/reference/foundations/selector/#definitions-and) and [or](/docs/reference/foundations/selector/#definitions-or) selectors can now be used with show rules
- Errors within show rules and context expressions are now ignored in all but the last introspection iteration, in line with the behavior of the old [`locate`](/docs/reference/introspection/locate/)
- Fixed a bug where document set rules were allowed after content
## Layout
- Added `reflow` argument to [`rotate`](/docs/reference/layout/rotate/) and [`scale`](/docs/reference/layout/scale/) which lets them affect the layout
- Fixed a bug where [floating placement](/docs/reference/layout/place/#parameters-float) or [floating figures](/docs/reference/model/figure/#parameters-placement) could end up out of order
- Fixed overlap of text and figure for full-page floating figures
- Fixed various cases where the [`hide`](/docs/reference/layout/hide/) function didn't hide its contents properly
- Fixed usage of [`h`](/docs/reference/layout/h/) and [`v`](/docs/reference/layout/v/) in [stacks](/docs/reference/layout/stack/)
- Invisible content like a counter update will no longer force a visible block for just itself
- Fixed a bug with horizontal spacing followed by invisible content (like a counter update) directly at the start of a paragraph
## Text
- Added [`stroke`](/docs/reference/text/text/#parameters-stroke) property for text
- Added basic i18n for Serbian and Catalan
- Added support for contemporary Japanese [numbering](/docs/reference/model/numbering/) method
- Added patches for various wrong metadata in specific fonts
- The [text direction](/docs/reference/text/text/#parameters-dir) can now be overridden within a paragraph
- Fixed Danish [smart quotes](/docs/reference/text/smartquote/)
- Fixed font fallback next to a line break
- Fixed width adjustment of JIS-style Japanese punctuation
- Fixed Finnish translation of "Listing"
- Fixed Z-ordering of multiple text decorations (underlines, etc.)
- Fixed a bug due to which text [features](/docs/reference/text/text/#parameters-features) could not be overridden in consecutive set rules
## Model
- Added [`depth`](/docs/reference/model/heading/#parameters-depth) and [`offset`](/docs/reference/model/heading/#parameters-offset) arguments to heading to increase or decrease the heading level for a bunch of content; the heading syntax now sets `depth` rather than `level` **(Breaking change)**
- List [markers](/docs/reference/model/list/#parameters-marker) now cycle by default
- The [`quote`](/docs/reference/model/quote/) function now more robustly selects the correct quotes based on language and nesting
- Fixed indent bugs related to the default show rule of [terms](/docs/reference/model/terms/)
## Math
- Inline equations now automatically linebreak at appropriate places
- Added [`number-align`](/docs/reference/math/equation/#parameters-number-align) argument to equations
- Added support for adjusting the [`size`](/docs/reference/math/accent/#parameters-size) of accents relative to their base
- Improved positioning of accents
- [Primes](/docs/reference/math/primes/) are now always attached as [scripts](/docs/reference/math/attach/#functions-scripts) by default
- Exposed [`math.primes`](/docs/reference/math/primes/) element which backs the `$f'$` syntax in math
- Math mode is not affected by [`strong`](/docs/reference/model/strong/) and [`emph`](/docs/reference/model/emph/) anymore
- Fixed [`attach`](/docs/reference/math/attach/#functions-attach) under [fractions](/docs/reference/math/frac/)
- Fixed that [`math.class`](/docs/reference/math/class/) did not affect smart limit placement
- Fixed weak spacing in [`lr`](/docs/reference/math/lr/#functions-lr) groups
- Fixed layout of large operators for Cambria Math font
- Fixed math styling of Hebrew symbol codepoints
## Symbols
- Added `gradient` as an alias for `nabla`
- Added `partial` as an alias for `diff`, `diff` will be deprecated in the future
- Added `colon.double`, `gt.approx`, `gt.napprox`, `lt.approx`, and `lt.napprox`
- Added `arrow.r.tilde` and `arrow.l.tilde`
- Added `tilde.dot`
- Added `forces` and `forces.not`
- Added `space.nobreak.narrow`
- Added `lrm` (Left-to-Right Mark) and `rlm` (Right-to-Left Mark)
- Fixed `star.stroked` symbol (which previously had the wrong codepoint)
## Scripting
- Arrays can now be compared lexicographically
- Added contextual method [`to-absolute`](/docs/reference/layout/length/#definitions-to-absolute) to lengths
- Added [`calc.root`](/docs/reference/foundations/calc/#functions-root)
- Added [`int.signum`](/docs/reference/foundations/int/#definitions-signum) and [`float.signum`](/docs/reference/foundations/float/#definitions-signum) methods
- Added [`float.is-nan`](/docs/reference/foundations/float/#definitions-is-nan) and [`float.is-infinite`](/docs/reference/foundations/float/#definitions-is-infinite) methods
- Added [`int.bit-not`](/docs/reference/foundations/int/#definitions-bit-not), [`int.bit-and`](/docs/reference/foundations/int/#definitions-bit-and), [`int.bit-or`](/docs/reference/foundations/int/#definitions-bit-or), [`int.bit-xor`](/docs/reference/foundations/int/#definitions-bit-xor), [`int.bit-lshift`](/docs/reference/foundations/int/#definitions-bit-lshift), and [`int.bit-rshift`](/docs/reference/foundations/int/#definitions-bit-rshift) methods
- Added [`array.chunks`](/docs/reference/foundations/array/#definitions-chunks) method
- A module can now be converted to a dictionary with the [dictionary constructor](/docs/reference/foundations/dictionary/#constructor) to access its contents dynamically
- Added [`row-type`](/docs/reference/data-loading/csv/#parameters-row-type) argument to `csv` function to configure how rows will be represented
- [XML parsing](/docs/reference/data-loading/xml/) now allows DTDs (document type definitions)
- Improved formatting of negative numbers with [`str`](/docs/reference/foundations/str/) and [`repr`](/docs/reference/foundations/repr/)
- For loops can now iterate over [bytes](/docs/reference/foundations/bytes/)
- Fixed a bug with pattern matching in for loops
- Fixed a bug with labels not being part of [`.fields()`](/docs/reference/foundations/content/#definitions-fields) dictionaries
- Fixed a bug where unnamed argument sinks wouldn't capture excess arguments
- Fixed typo in `repr` output of strokes
## Syntax
- Added support for nested [destructuring patterns](/docs/reference/scripting/#bindings)
- Special spaces (like thin or non-breaking spaces) are now parsed literally instead of being collapsed into normal spaces **(Breaking change)**
- Korean text can now use emphasis syntax without adding spaces **(Breaking change)**
- The token [`context`](/docs/reference/context/) is now a keyword and cannot be used as an identifier anymore **(Breaking change)**
- Nested line comments aren't allowed anymore in block comments **(Breaking change)**
- Fixed a bug where `x.)` would be treated as a field access
- Text elements can now span across curly braces in markup
- Fixed silently wrong parsing when function name is parenthesized
- Fixed various bugs with parsing of destructuring patterns, arrays, and dictionaries
## Tooling & Diagnostics
- Click-to-jump now works properly within [`raw`](/docs/reference/text/raw/) text
- Added suggestion for accessing a field if a method doesn't exist
- Improved hint for calling a function stored in a dictionary
- Improved errors for mutable accessor functions on arrays and dictionaries
- Fixed error message when calling constructor of type that doesn't have one
- Fixed confusing error message with nested dictionaries for strokes on different sides
- Fixed autocompletion for multiple packages with the same name from different namespaces
## Visualization
- The [`image`](/docs/reference/visualize/image/) function doesn't upscale images beyond their natural size anymore
- The [`image`](/docs/reference/visualize/image/) function now respects rotation stored in EXIF metadata
- Added support for SVG filters
- Added alpha component to [`luma`](/docs/reference/visualize/color/#definitions-luma) colors
- Added [`color.transparentize`](/docs/reference/visualize/color/#definitions-transparentize) and [`color.opacify`](/docs/reference/visualize/color/#definitions-opacify) methods
- Improved [`color.negate`](/docs/reference/visualize/color/#definitions-negate) function
- Added [`stroke`](/docs/reference/text/highlight/#parameters-stroke) and [`radius`](/docs/reference/text/highlight/#parameters-radius) arguments to `highlight` function
- Changed default [`highlight`](/docs/reference/text/highlight/) color to be transparent
- CMYK to RGB conversion is now color-managed
- Fixed crash with gradients in Oklch color space
- Fixed color-mixing for hue-based spaces
- Fixed bugs with color conversion
- SVG sizes are not rounded anymore, preventing slightly wrong aspect ratios
- Fixed a few other SVG-related bugs
- [`color.components`](/docs/reference/visualize/color/#definitions-components) doesn't round anything anymore
## Export
- PDFs now contain named destinations for headings derived from their labels
- The internal PDF structure was changed to make it easier for external tools to extract or modify individual pages, avoiding a bug with Typst PDFs in Apple Preview
- PDFs produced by Typst should now be byte-by-byte reproducible when `set document(date: none)` is set
- Added missing flag to PDF annotation
- Fixed multiple bugs with gradients in PDF export
- Fixed a bug with patterns in PDF export
- Fixed a bug with embedding of grayscale images in PDF export
- Fixed a bug with To-Unicode mapping of CFF fonts in PDF export
- Fixed a bug with the generation of the PDF outline
- Fixed a sorting bug in PDF export leading to non-reproducible output
- Fixed a bug with transparent text in PNG export
- Exported SVG files now include units in their top-level `width` and `height`
## Command line interface
- Added support for passing [inputs](/docs/reference/foundations/sys/) via a CLI flag
- When passing the filename `-`, Typst will now read input from stdin
- Now uses the system-native TLS implementation for network fetching which should be generally more robust
- Watch mode will now properly detect when a previously missing file is created
- Added `--color` flag to configure whether to print colored output
- Fixed user agent with which packages are downloaded
- Updated bundled fonts to the newest versions
## Development
- Added `--vendor-openssl` to CLI to configure whether to link OpenSSL statically instead of dynamically (not applicable to Windows and Apple platforms)
- Removed old tracing (and its verbosity) flag from the CLI
- Added new `--timings` flag which supersedes the old flamegraph profiling in the CLI
- Added minimal CLI to `typst-docs` crate for extracting the language and standard library documentation as JSON
- The `typst_pdf::export` function's `ident` argument switched from `Option` to `Smart`. It should only be set to `Smart::Custom` if you can provide a stable identifier (like the web app can). The CLI sets `Smart::Auto`.
## Contributors
docs/changelog/0.11.1.md
# 0.11.1
## Security
- Fixed a vulnerability where image files at known paths could be embedded into the PDF even if they were outside of the project directory
## Bibliography
- Fixed et-al handling in subsequent citations
- Fixed suppression of title for citations and bibliography references with no author
- Fixed handling of initials in citation styles without a delimiter
- Fixed bug with citations in footnotes
## Text and Layout
- Fixed interaction of [`first-line-indent`](/docs/reference/model/par/#parameters-first-line-indent) and [`outline`](/docs/reference/model/outline/)
- Fixed compression of CJK punctuation marks at line start and end
- Fixed handling of [rectangles](/docs/reference/visualize/rect/) with negative dimensions
- Fixed layout of [`path`](/docs/reference/visualize/path/) in explicitly sized container
- Fixed broken [`raw`](/docs/reference/text/raw/) text in right-to-left paragraphs
- Fixed tab rendering in `raw` text with language `typ` or `typc`
- Fixed highlighting of multi-line `raw` text enclosed by single backticks
- Fixed indentation of overflowing lines in `raw` blocks
- Fixed extra space when `raw` text ends with a backtick
## Math
- Fixed broken [equations](/docs/reference/math/equation/) in right-to-left paragraphs
- Fixed missing [blackboard bold](/docs/reference/math/variants/#functions-bb) letters
- Fixed error on empty arguments in 2D math argument list
- Fixed stretching via [`mid`](/docs/reference/math/lr/#functions-mid) for various characters
- Fixed that alignment points in equations were affected by `set align(..)`
## Export
- Fixed [smart quotes](/docs/reference/text/smartquote/) in PDF outline
- Fixed [patterns](/docs/reference/visualize/tiling/) with spacing in PDF
- Fixed wrong PDF page labels when [page numbering](/docs/reference/layout/page/#parameters-numbering) was disabled after being previously enabled
## Scripting
- Fixed overflow for large numbers in external data files (by converting to floats instead)
- Fixed [`str.trim(regex, at: end)`](/docs/reference/foundations/str/#definitions-trim) when the whole string is matched
## Miscellaneous
- Fixed deformed strokes for specific shapes and thicknesses
- Fixed newline handling in code mode: There can now be comments within chained method calls and between an `if` branch and the `else` keyword
- Fixed inefficiency with incremental reparsing
- Fixed autocompletions for relative file imports
- Fixed crash in autocompletion handler
- Fixed a bug where the path and entrypoint printed by `typst init` were not properly escaped
- Fixed various documentation errors
## Contributors
docs/changelog/0.12.0.md
# 0.12.0
## Highlights
- Added support for multi-column floating [placement](/docs/reference/layout/place/#parameters-scope) and [figures](/docs/reference/model/figure/#parameters-scope)
- Added support for automatic [line numbering](/docs/reference/model/par/#definitions-line) (often used in academic papers)
- Typst's layout engine is now multithreaded. Typical speedups are 2-3x for larger documents. The multithreading operates on page break boundaries, so explicit page breaks are necessary for it to kick in.
- Paragraph justification was optimized with a new two-pass algorithm. Speedups are larger for shorter paragraphs and go up to 6x.
- Highly reduced PDF file sizes due to better font subsetting (thanks to [@LaurenzV](https://github.com/LaurenzV))
- Emoji are now exported properly in PDF
- Added initial support for PDF/A. For now, only the PDF/A-2b profile is supported, but more is planned for the future.
- Added various options for configuring the CLI's environment (fonts, package paths, etc.)
- Text show rules now match across multiple text elements
- Block-level equations can now optionally break over multiple pages
- Fixed a bug where some fonts would not print correctly on professional printers
- Fixed a long-standing bug which could cause headings to be orphaned at the bottom of the page
## Layout
- Added support for multi-column floating placement and figures via [`place.scope`](/docs/reference/layout/place/#parameters-scope) and [`figure.scope`](/docs/reference/model/figure/#parameters-scope). Two-column documents should now prefer `set page(columns: 2)` over `show: column.with(2)` (see the [Page Setup Guide](/docs/guides/page-setup/#columns)).
- Added support for automatic [line numbering](/docs/reference/model/par/#definitions-line) (often used in academic papers)
- Added [`par.spacing`](/docs/reference/model/par/#parameters-spacing) property for configuring paragraph spacing. This should now be used instead of `show par: set block(spacing: ..)` **(Breaking change)**
- Block-level elements like lists, grids, and stacks now show themselves as blocks and are thus affected by all block properties (e.g. `stroke`) rather than just `spacing` **(Breaking change)**
- Added [`block.sticky`](/docs/reference/layout/block/#parameters-sticky) property which prevents a page break after a block
- Added [`place.flush`](/docs/reference/layout/place/#definitions-flush) function which forces all floating figures to be placed before any further content
- Added [`skew`](/docs/reference/layout/skew/) function
- Added `auto` option for [`page.header`](/docs/reference/layout/page/#parameters-header) and [`page.footer`](/docs/reference/layout/page/#parameters-footer) which results in an automatic header/footer based on the numbering (which was previously inaccessible after a change)
- Added `gap` and `justify` parameters to [`repeat`](/docs/reference/layout/repeat/) function
- Added `width` and `height` parameters to the [`measure`](/docs/reference/layout/measure/) function to define the space in which the content should be measured. Especially useful in combination with [`layout`](/docs/reference/layout/layout/).
- The height of a `block`, `image`, `rect`, `square`, `ellipse`, or `circle` can now be specified in [fractional units](/docs/reference/layout/fraction/)
- The [`scale`](/docs/reference/layout/scale/) function now supports absolute lengths for `x`, `y`, `factor`. This way an element of unknown size can be scaled to a fixed size.
- The values of `block.above` and `block.below` can now be retrieved in context expressions.
- Increased accuracy of conversions between absolute units (pt, mm, cm, in)
- Fixed a bug which could cause headings to be orphaned at the bottom of the page
- Fixed footnotes within breakable blocks appearing on the page where the breakable block ends instead of at the page where the footnote marker is
- Fixed numbering of nested footnotes and footnotes in floats
- Fixed empty pages appearing when a [context](/docs/reference/context/) expression wraps whole pages
- Fixed `set block(spacing: x)` behaving differently from `set block(above: x, below: x)`
- Fixed behavior of [`rotate`](/docs/reference/layout/rotate/) and [`scale`](/docs/reference/layout/scale/) with `reflow: true`
- Fixed interaction of `align(horizon)` and `v(1fr)`
- Fixed various bugs where floating placement would yield overlapping results
- Fixed a bug where widow/orphan prevention would unnecessarily move text into the next column
- Fixed [weak spacing](/docs/reference/layout/h/#parameters-weak) not being trimmed at the start and end of lines in a paragraph (only at the start and end of paragraphs)
- Fixed interaction of weak page break and [`pagebreak.to`](/docs/reference/layout/pagebreak/#parameters-to)
- Fixed compilation output of a single weak page break
- Fixed crash when [padding](/docs/reference/layout/pad/) by `100%`
## Text
- Tuned hyphenation: It is less eager by default and hyphenations close to the edges of words are now discouraged more strongly **(May lead to larger layout reflows)**
- New default font: Libertinus Serif. This is the maintained successor to the old default font Linux Libertine. **(May lead to smaller reflows)**
- Setting the font to an unavailable family will now result in a warning
- Implemented a new smart quote algorithm, fixing various bugs where smart quotes weren't all that smart
- Added [`text.costs`](/docs/reference/text/text/#parameters-costs) parameter for tweaking various parameters that affect the choices of the layout engine during text layout
- Added `typm` highlighting mode for math in [raw blocks](/docs/reference/text/raw/#parameters-lang)
- Added basic i18n for Galician, Catalan, Latin, Icelandic, Hebrew
- Implemented hyphenation duplication for Czech, Croatian, Lower Sorbian, Polish, Portuguese, Slovak, and Spanish.
- The [`smallcaps`](/docs/reference/text/smallcaps/) function is now an element function and can thereby be used in show(-set) rules.
- The [`raw.theme`](/docs/reference/text/raw/#parameters-theme) parameter can now be set to `none` to disable highlighting even in the presence of a language tag, and to `auto` to reset to the default
- Multiple [stylistic sets](/docs/reference/text/text/#parameters-stylistic-set) can now be enabled at once
- Fixed the Chinese translation for "Equation"
- Fixed that hyphenation could occur outside of words
- Fixed incorrect layout of bidirectional text in edge cases
- Fixed layout of paragraphs with explicit trailing whitespace
- Fixed bugs related to empty paragraphs created via `#""`
- Fixed accidental trailing spaces for line breaks immediately preceding an inline equation
- Fixed [`text.historical-ligatures`](/docs/reference/text/text/#parameters-historical-ligatures) not working correctly
- Fixed accidental repetition of Thai characters around line breaks in some circumstances
- Fixed [smart quotes](/docs/reference/text/smartquote/) for Swiss French
- New font metadata exceptions for Archivo, Kaiti SC, and Kaiti TC
- Updated bundled New Computer Modern fonts to version 6.0
## Math
- Block-level equations can now break over multiple pages if enabled via `show math.equation: set block(breakable: true)`.
- Matrix and vector sizing is now more consistent across different cell contents
- Added [`stretch`](/docs/reference/math/stretch/) function for manually or automatically stretching characters like arrows or parentheses horizontally or vertically
- Improved layout of attachments on parenthesized as well as under- or overlined expressions
- Improved layout of nested attachments resulting from code like `#let a0 = $a_0$; $a0^1$`
- Improved layout of primes close to superscripts
- Improved layout of fractions
- Typst now makes use of math-specific height-dependent kerning information in some fonts for better attachment layout
- The `floor` and `ceil` functions in math are now callable symbols, such that `$ floor(x) = lr(floor.l x floor.r) $`
- The [`mat.delim`](/docs/reference/math/mat/#parameters-delim), [`vec.delim`](/docs/reference/math/vec/#parameters-delim), and [`cases.delim`](/docs/reference/math/cases/#parameters-delim) parameters now allow any character that is considered a delimiter or "fence" (e.g. |) by Unicode. The `delim: "||"` notation is _not_ supported anymore and should be replaced by `delim: bar.double` **(Minor breaking change)**
- Added [`vec.align`](/docs/reference/math/vec/#parameters-align) and [`mat.align`](/docs/reference/math/mat/#parameters-align) parameters
- Added [`underparen`](/docs/reference/math/underover/#functions-underparen), [`overparen`](/docs/reference/math/underover/#functions-overparen), [`undershell`](/docs/reference/math/underover/#functions-undershell), and [`overshell`](/docs/reference/math/underover/#functions-overshell)
- Added `~` shorthand for `tilde.op` in math mode **(Minor breaking change)**
- Fixed baseline alignment of equation numbers
- Fixed positioning of corner brackets (⌜, ⌝, ⌞, ⌟)
- Fixed baseline of large roots
- Fixed multiple minor layout bugs with attachments
- Fixed that alignment points could affect line height in math
- Fixed that spaces could show up between text and invisible elements like [`metadata`](/docs/reference/introspection/metadata/) in math
- Fixed a crash with recursive show rules in math
- Fixed [`lr.size`](/docs/reference/math/lr/#functions-lr-size) not affecting characters enclosed in [`mid`](/docs/reference/math/lr/#functions-mid) in some cases
- Fixed resolving of em units in sub- and superscripts
- Fixed bounding box of inline equations when a [text edge](/docs/reference/text/text/#parameters-top-edge) is set to `"bounds"`
## Introspection
- Implemented a new system by which Typst tracks where elements end up on the pages. This may lead to subtly different behavior in introspections. **(Breaking change)**
- Fixed various bugs with wrong counter behavior in complex layout situations, through a new, more principled implementation
- Counter updates can now be before the first, in between, and after the last page when isolated by weak page breaks. This allows, for instance, updating a counter before the first page header and background.
- Fixed logical ordering of introspections within footnotes and figures
- Fixed incorrect [`here().position()`](/docs/reference/introspection/here/) when [`place`](/docs/reference/layout/place/) was used in a context expression
- Fixed resolved positions of elements (in particular, headings) whose show rule emits an invisible element (like a state update) before a page break
- Fixed behavior of stepping a counter at a deeper level than its current state has
- Fixed citation formatting not working in table headers and a few other places
- Displaying the footnote counter will now respect the footnote numbering style
## Model
- Document set rules do not need to be at the very start of the document anymore. The only restriction is that they must not occur inside of layout containers.
- The `spacing` property of [lists](/docs/reference/model/list/#parameters-spacing), [enumerations](/docs/reference/model/enum/#parameters-spacing), and [term lists](/docs/reference/model/terms/#parameters-spacing) is now also respected for tight lists
- Tight lists now only attach (with tighter spacing) to preceding paragraphs, not arbitrary blocks
- The [`quote`](/docs/reference/model/quote/) element is now locatable (can be used in queries)
- The bibliography heading now uses `depth` instead of `level` so that its level can still be configured via a show-set rule
- Added support for more [numbering](/docs/reference/model/numbering/) formats: Devanagari, Eastern Arabic, Bengali, and circled numbers
- Added [`hanging-indent`](/docs/reference/model/heading/#parameters-hanging-indent) parameter to heading function to tweak the appearance of multi-line headings and improved default appearance of multi-line headings
- Improved handling of bidirectional text in outline entry
- Fixed document set rules being ignored in an otherwise empty document
- Fixed document set rules not being usable in context expressions
- Fixed bad interaction between `set document` and `set page`
- Fixed `show figure: set align(..)`. Since the default figure alignment is now a show-set rule, it is not revoked by `show figure: it => it.body` anymore. **(Minor breaking change)**
- Fixed numbering of footnote references
- Fixed spacing after bibliography heading
## Bibliography
- The Hayagriva YAML `publisher` field can now accept a dictionary with a `location` key. The top-level `location` key is now primarily intended for event and item locations.
- Multiple page ranges with prefixes and suffixes are now allowed
- Added `director` and catch-all editor types to BibLaTeX parsing
- Added support for disambiguation to alphanumeric citation style
- The year 0 will now render as 1BC
- Fixes for sorting of bibliography entries
- Fixed pluralization of page range labels
- Fixed sorting of citations by their number
- Fixed how citation number ranges collapse
- Fixed when the short form of a title is used
- Fixed parsing of unbalanced dollars in BibLaTeX `url` field
- Updated built-in citation styles
## Visualization
- Added `fill-rule` parameter to [`path`](/docs/reference/visualize/path/#parameters-fill-rule) and [`polygon`](/docs/reference/visualize/polygon/#parameters-fill-rule) functions
- Fixed color mixing and gradients for [Luma colors](/docs/reference/visualize/color/#definitions-luma)
- Fixed conversion from Luma to CMYK colors
- Fixed offset gradient strokes in PNG export
- Fixed unintended cropping of some SVGs
- SVGs with foreign objects now produce a warning as they will likely not render correctly in Typst
## Syntax
- Added support for nested imports like `import "file.typ": module.item`
- Added support for parenthesized imports like `import "file.typ": (a, b, c)`. With those, the import list can break over multiple lines.
- Fixed edge case in parsing of reference syntax
- Fixed edge case in parsing of heading, list, enum, and term markers immediately followed by comments
- Fixed rare crash in parsing of parenthesized expressions
## Scripting
- Added new fixed-point [`decimal`](/docs/reference/foundations/decimal/) number type for highly precise arithmetic on numbers in base 10, as needed for finance
- Added `std` module for accessing standard library definitions even when a variable with the same name shadows/overwrites it
- Added [`array.to-dict`](/docs/reference/foundations/array/#definitions-to-dict), [`array.reduce`](/docs/reference/foundations/array/#definitions-reduce), [`array.windows`](/docs/reference/foundations/array/#definitions-windows) methods
- Added `exact` argument to [`array.zip`](/docs/reference/foundations/array/#definitions-zip)
- Added [`arguments.at`](/docs/reference/foundations/arguments/#definitions-at) method
- Added [`int.from-bytes`](/docs/reference/foundations/int/#definitions-from-bytes), [`int.to-bytes`](/docs/reference/foundations/int/#definitions-to-bytes), [`float.from-bytes`](/docs/reference/foundations/float/#definitions-from-bytes), and [`float.to-bytes`](/docs/reference/foundations/float/#definitions-to-bytes)
- Added proper support for negative values of the `digits` parameter of [`calc.round`](/docs/reference/foundations/calc/#functions-round) (the behaviour existed before but was subtly broken)
- Conversions from [`int`](/docs/reference/foundations/int/) to [`float`](/docs/reference/foundations/float/) will now error instead of saturating if the float is too large **(Minor breaking change)**
- Added `float.nan` and `float.inf`, removed `calc.nan` **(Minor breaking change)**
- Certain symbols are now generally callable like functions and not only specifically in math. Examples are accents or [`floor`](/docs/reference/math/lr/#functions-floor) and [`ceil`](/docs/reference/math/lr/#functions-ceil).
- Improved [`repr`](/docs/reference/foundations/repr/) of relative values, sequences, infinities, NaN, `type(none)` and `type(auto)`
- Fixed crash on whole packages (rather than just files) cyclically importing each other
- Fixed return type of [`calc.round`](/docs/reference/foundations/calc/#functions-round) on integers when a non-zero value is provided for `digits`
## Styling
- Text show rules now match across multiple text elements
- The string `"` in a text show rule now matches smart quotes
- Fixed a long-standing styling bug where the header and footer would incorrectly inherit styles from a lone element on the page (e.g. a heading)
- Fixed `set page` not working directly after a counter/state update
- Page fields configured via an explicit `page(..)[..]` call can now be properly retrieved in context expressions
## Export
- Highly reduced PDF file sizes due to better font subsetting
- Emoji are now exported properly in PDF
- Added initial support for PDF/A. For now, only the standard PDF/A-2b is supported, but more is planned for the future. Enabled via `--pdf-standard a-2b` in the CLI and via the UI in File \> Export as \> PDF in the web app.
- Setting [`page.fill`](/docs/reference/layout/page/#parameters-fill) to `none` will now lead to transparent pages instead of white ones in PNG and SVG. The new default of `auto` means transparent for PDF and white for PNG and SVG.
- Improved text copy-paste from PDF in complex scenarios
- Exported SVGs now contain the `data-typst-label` attribute on groups resulting from labelled [boxes](/docs/reference/layout/box/) and [blocks](/docs/reference/layout/block/)
- Fixed a bug where some fonts would not print correctly on professional printers
- Fixed a bug where transparency could leak from one PDF object to another
- Fixed a bug with CMYK gradients in PDF
- Fixed various bugs with export of Oklab gradients in PDF
- Fixed crashes related to rendering of non-outline glyphs
- Two small fixes for PDF standard conformance
## Performance
- Typst's layout engine is now multithreaded. Typical speedups are 2-3x for larger documents. The multithreading operates on page break boundaries, so explicit page breaks are necessary for it to kick in.
- Paragraph justification was optimized with a new two-pass algorithm. Speedups are larger for shorter paragraphs and range from 1-6x.
## Command Line Interface
- Added `--pages` option to select specific page ranges to export
- Added `--package-path` and `--package-cache-path` as well as `TYPST_PACKAGE_PATH` and `TYPST_PACKAGE_CACHE_PATH` environment variables for configuring where packages are loaded from and cached in, respectively
- Added `--ignore-system-fonts` flag to disable system fonts fully for better reproducibility
- Added `--make-deps` argument for outputting the dependencies of the current compilation as a Makefile
- Added `--pretty` option to `typst query`, with the default now being to minify (only applies to JSON format)
- Added `--backup-path` to `typst update` to configure where the previous version is backed up
- Added useful links to help output
- The CLI will now greet users who invoke just `typst` for the first time
- The document can now be written to stdout by passing `-` as the output filename (for PDF or single-page image export)
- Typst will now emit a proper error message instead of failing silently when the certificate specified by `--cert` or `TYPST_CERT` could not be loaded
- The CLI now respects the `SOURCE_DATE_EPOCH` environment variable for better reproducibility
- When exporting multiple images, you can now use `t` (total pages), `p` (current page), and `0p` (zero-padded current page, same as current `n`) in the output path
- The input and output paths now allow non-UTF-8 values
- Times are now formatted more consistently across the CLI
- Fixed a bug related to the `--open` flag
- Fixed path completions for `typst` not working in zsh
## Tooling and Diagnostics
- The "compiler" field for specifying the minimum Typst version required by a package now supports imprecise bounds like 0.11 instead of 0.11.0
- Added warning when a label is ignored by Typst because no preceding labellable element exists
- Added hint when trying to apply labels in code mode
- Added hint when trying to call a standard library function that has been shadowed/overwritten by a local definition
- Added hint when trying to set both the language and the region in the `lang` parameter
- Added hints when trying to compile non-Typst files (e.g. after having typed `typst c file.pdf` by accident)
- Added hint when a string is used where a label is expected
- Added hint when a stray end of a block comment (`*/`) is encountered
- Added hints when destructuring arrays with the wrong number of elements
- Improved error message when trying to use a keyword as an identifier in a let binding
- Improved error messages when accessing nonexistent fields
- Improved error message when a package exists, but not the specified version
- Improved hints for unknown variables
- Improved hint when trying to convert a length with non-zero em component to an absolute unit
- Fixed a crash that could be triggered by certain hover tooltips
- Fixed an off-by-one error in to-source jumps when first-line-indent is enabled
- Fixed suggestions for `.` after the end of an inline code expressions
- Fixed autocompletions being duplicated in a specific case
## Symbols
- New: `parallelogram`, `original`, `image`, `crossmark`, `rest`, `natural`, `flat`, `sharp`, `tiny`, `miny`, `copyleft`, `trademark`, `emoji.beet`, `emoji.fingerprint`, `emoji.harp`, `emoji.shovel`, `emoji.splatter`, `emoji.tree.leafless`,
- New variants: `club.stroked`, `diamond.stroked`, `heart.stroked`, `spade.stroked`, `gt.neq`, `lt.neq`, `checkmark.heavy`, `paren.double`, `brace.double`, `shell.double`, `arrow.turn`, `plus.double`, `plus.triple`, `infinity.bar`, `infinity.incomplete`, `infinity.tie`, `multimap.double`, `ballot.check`, `ballot.check.heavy`, `emptyset.bar`, `emptyset.circle`, `emptyset.arrow.l`, `emptyset.arrow.r`, `parallel.struck`, `parallel.eq`, `parallel.equiv`, `parallel.slanted`, `parallel.tilde`, `angle.l.curly`, `angle.l.dot`, `angle.r.curly`, `angle.r.dot`, `angle.oblique`, `angle.s`, `em.two`, `em.three`
- Renamed: `turtle` to `shell`, `notes` to `note`, `ballot.x` to `ballot.cross`, `succ.eq` to `succ.curly.eq`, `prec.eq` to `prec.curly.eq`, `servicemark` to `trademark.service`, `emoji.face.tired` to `emoji.face.distress` **(Breaking change)**
- Changed codepoint: `prec.eq`, `prec.neq`, `succ.eq`, `succ.neq`, `triangle` from ▷ to △, `emoji.face.tired` **(Breaking change)**
- Removed: `lt.curly` in favor of `prec`, `gt.curly` in favor of `succ` **(Breaking change)**
## Deprecations
- [`counter.display`](/docs/reference/introspection/counter/#definitions-display) without an established context
- [`counter.final`](/docs/reference/introspection/counter/#definitions-final) with a location
- [`state.final`](/docs/reference/introspection/state/#definitions-final) with a location
- `state.display`
- [`query`](/docs/reference/introspection/query/) with a location as the second argument
- [`locate`](/docs/reference/introspection/locate/) with a callback function
- [`measure`](/docs/reference/layout/measure/) with styles
- `style`
## Development
- Added `typst-kit` crate which provides useful APIs for `World` implementors
- Added go-to-definition API in `typst-ide`
- Added package manifest parsing APIs to `typst-syntax`
- As the compiler is now capable of multithreading, `World` implementations must satisfy `Send` and `Sync`
- Changed signature of `World::main` to allow for the scenario where the main file could not be loaded
- Removed `Tracer` in favor of `Warned<T>` and `typst::trace` function
- The `xz2` dependency used by the self-updater is now statically linked
- The Dockerfile now has an `ENTRYPOINT` directive
## Contributors
docs/changelog/0.13.0.md
# 0.13.0
## Highlights
- There is now a distinction between [proper paragraphs](/docs/reference/model/par/) and just inline-level content. This is important for future work on accessibility and means that [first line indent](/docs/reference/model/par/#parameters-first-line-indent) can now be enabled for all paragraphs instead of just consecutive ones.
- The [`outline`](/docs/reference/model/outline/) has a better out-of-the-box look and is more customizable
- The new [`curve`](/docs/reference/visualize/curve/) function (that supersedes the `path` function) provides a simpler and more flexible interface for creating Bézier curves
- The `image` function now supports raw [pixel raster formats](/docs/reference/visualize/image/#parameters-format) for generating images from within Typst
- Functions that accept [file paths](/docs/reference/syntax/#paths) now also accept raw [bytes](/docs/reference/foundations/bytes/), for full flexibility
- WebAssembly [plugins](/docs/reference/foundations/plugin/) are more flexible and automatically run multi-threaded
- Fixed a long-standing bug where single-letter strings in math (`$"a"$`) would be displayed in italics
- You can now specify which charset should be [covered](/docs/reference/text/text/#parameters-font) by which font family
- The [`pdf.embed`](/docs/reference/pdf/attach/) function lets you embed arbitrary files in the exported PDF
- HTML export is currently under active development. The feature is still _very_ incomplete, but already available for experimentation behind a feature flag.
## Model
- There is now a distinction between [proper paragraphs](/docs/reference/model/par/) and just inline-level content **(Breaking change)**
- All text at the root of a document is wrapped in paragraphs. Meanwhile, text in a container (like a block) is only wrapped in a paragraph if the container holds any block-level content. If all of the content is inline-level, no paragraph is created.
- In the laid-out document, it's not immediately visible whether text became part of a paragraph. However, it is still important for accessibility, HTML export, and for properties like `first-line-indent`.
- Show rules on `par` now only affect proper paragraphs
- The `first-line-indent` and `hanging-indent` properties also only affect proper paragraphs
- Creating a `par[..]` with body content that is not fully inline-level will result in a warning
- The default show rules of various built-in elements like lists, quotes, etc. were adjusted to ensure they produce/don't produce paragraphs as appropriate
- Removed support for booleans and content in [`outline.indent`](/docs/reference/model/outline/#parameters-indent)
- The [`outline`](/docs/reference/model/outline/) function was fully reworked to improve its out-of-the-box behavior **(Breaking change)**
- [Outline entries](/docs/reference/model/outline/#definitions-entry) are now [blocks](/docs/reference/layout/block/) and are thus affected by block spacing
- The `auto` indentation mode now aligns numberings and titles outline-wide for a grid-like look
- Automatic indentation now also indents entries without a numbering
- Titles wrapping over multiple lines now have hanging indent
- The page number won't appear alone on its own line anymore
- The link now spans the full entry instead of just the title and page number
- The default spacing between outline leader dots was increased
- The [`fill`](/docs/reference/model/outline/#definitions-entry-fill) parameter was moved from `outline` to `outline.entry` and can thus be configured through show-set rules
- Removed `body` and `page` fields from outline entry
- Added `indented`, `prefix`, `inner`, `body`, and `page` methods on outline entries to simplify writing of show rules
- Added configuration to [`par.first-line-indent`](/docs/reference/model/par/#parameters-first-line-indent) for indenting all paragraphs instead of just consecutive ones
- Added [`form`](/docs/reference/model/ref/#parameters-form) parameter to `ref` function. Setting the form to `"page"` will produce a page reference instead of a textual one.
- Added [`document.description`](/docs/reference/model/document/#parameters-description) field, which results in corresponding PDF and HTML metadata
- Added [`enum.reversed`](/docs/reference/model/enum/#parameters-reversed) parameter
- Added support for Greek [numbering](/docs/reference/model/numbering/)
- When the [`link`](/docs/reference/model/link/) function wraps around a container like a [block](/docs/reference/layout/block/), it will now generate only one link for the whole block instead of individual links for all the visible leaf elements. This significantly reduces PDF file sizes when combining `link` and [`repeat`](/docs/reference/layout/repeat/).
- The [`link`](/docs/reference/model/link/) function will now only strip one prefix (like `mailto:` or `tel:`) instead of multiple
- The link function now suppresses hyphenation via a built-in show-set rule rather than through its default show rule
- Displaying the page counter without a specified numbering will now take the page numbering into account
## Visualization
- Added new [`curve`](/docs/reference/visualize/curve/) function that supersedes the [`path`](/docs/reference/visualize/path/) function and provides a simpler and more flexible interface. The `path` function is now deprecated.
- The `image` function now supports raw [pixel raster formats](/docs/reference/visualize/image/#parameters-format). This can be used to generate images from within Typst without the need for encoding in an image exchange format.
- Added [`image.scaling`](/docs/reference/visualize/image/#parameters-scaling) parameter for configuring how an image is scaled by PNG export and PDF viewers (smooth or pixelated)
- Added [`image.icc`](/docs/reference/visualize/image/#parameters-icc) parameter for providing or overriding the ICC profile of an image
- Renamed `pattern` to [`tiling`](/docs/reference/visualize/tiling/). The name `pattern` remains as a deprecated alias.
- Added [`gradient.center`](/docs/reference/visualize/gradient/#definitions-center), [`gradient.radius`](/docs/reference/visualize/gradient/#definitions-radius), [`gradient.focal-center`](/docs/reference/visualize/gradient/#definitions-focal-center), and [`gradient.focal-radius`](/docs/reference/visualize/gradient/#definitions-focal-radius) methods
- Fixed interaction of clipping and outset on [`box`](/docs/reference/layout/box/) and [`block`](/docs/reference/layout/block/)
- Fixed panic with [`path`](/docs/reference/visualize/path/) of infinite length
- Fixed non-solid (e.g. tiling) text fills in clipped blocks
- Fixed a crash for images with a DPI value of zero
- Fixed floating-point error in [`gradient.repeat`](/docs/reference/visualize/gradient/#definitions-repeat)
- Auto-detection of image formats from a raw buffer now has support for SVGs
## Scripting
- Functions that accept [file paths](/docs/reference/syntax/#paths) now also accept raw [bytes](/docs/reference/foundations/bytes/)
- [`image`](/docs/reference/visualize/image/), [`cbor`](/docs/reference/data-loading/cbor/), [`csv`](/docs/reference/data-loading/csv/), [`json`](/docs/reference/data-loading/json/), [`toml`](/docs/reference/data-loading/toml/), [`xml`](/docs/reference/data-loading/xml/), and [`yaml`](/docs/reference/data-loading/yaml/) now support a path string or bytes and their `.decode` variants are deprecated
- [`plugin`](/docs/reference/foundations/plugin/), [`bibliography`](/docs/reference/model/bibliography/), [`bibliography.style`](/docs/reference/model/bibliography/#parameters-style), [`cite.style`](/docs/reference/model/cite/#parameters-style), [`raw.theme`](/docs/reference/text/raw/#parameters-theme), and [`raw.syntaxes`](/docs/reference/text/raw/#parameters-syntaxes) now accept bytes in addition to path strings. These did not have `.decode` variants, so this adds new flexibility.
- The `path` argument/field of [`image`](/docs/reference/visualize/image/) and [`bibliography`](/docs/reference/model/bibliography/) was renamed to `source` and `sources`, respectively **(Minor breaking change)**
- Improved WebAssembly [plugins](/docs/reference/foundations/plugin/)
- The `plugin` type is replaced by a [`plugin` function](/docs/reference/foundations/plugin/) that returns a [module](/docs/reference/foundations/module/) containing normal Typst functions. This module can be used with import syntax. **(Breaking change)**
- Plugins now automatically run in multiple threads without any changes by plugin authors
- A new [`plugin.transition`](/docs/reference/foundations/plugin/#definitions-transition) API is introduced which allows plugins to run impure initialization in a way that doesn't break Typst's purity guarantees
- The variable name bound by a bare import (no renaming, no import list) is now determined statically and dynamic imports without `as` renaming (e.g. `import "ot" + "her.typ"`) are a hard error **(Breaking change)**
- Values of the [`arguments`](/docs/reference/foundations/arguments/) type can now be added with `+` and [joined](/docs/reference/scripting/#blocks) in curly-braced code blocks
- Functions in an element function's scope can now be called with method syntax, bringing elements and types closer (in anticipation of a future full unification of the two). Currently, this is only useful for [`outline.entry`](/docs/reference/model/outline/#definitions-entry) as no other element function defines methods.
- Added [`calc.norm`](/docs/reference/foundations/calc/#functions-norm) function
- Added support for 32-bit floats in [`float.from-bytes`](/docs/reference/foundations/float/#definitions-from-bytes) and [`float.to-bytes`](/docs/reference/foundations/float/#definitions-to-bytes)
- The [`decimal`](/docs/reference/foundations/decimal/) constructor now also accepts decimal values
- Improved `repr` of [symbols](/docs/reference/foundations/symbol/), [arguments](/docs/reference/foundations/arguments/), and [types](/docs/reference/foundations/type/)
- Duplicate [symbol](/docs/reference/foundations/symbol/) variants and modifiers are now a hard error **(Breaking change)**
## Math
- Fixed a bug where single letter strings in math (`$"a"$`) would be displayed in italics
- Math function calls can now have hyphenated named arguments and support [argument spreading](/docs/reference/foundations/arguments/#spreading)
- Better looking accents thanks to support for the `flac` (Flattened Accent Forms) and `dtls` (Dotless Forms) OpenType features
- Added `lcm` [text operator](/docs/reference/math/op/)
- The [`bold`](/docs/reference/math/styles/#functions-bold) function now works with ϝ and Ϝ
- The [`italic`](/docs/reference/math/styles/#functions-italic) function now works with ħ
- Fixed a bug where the extent of a math equation was wrongly affected by internal metadata
- Fixed interaction of [`lr`](/docs/reference/math/lr/#functions-lr) and [context](/docs/reference/context/) expressions
- Fixed weak spacing being unconditionally ignored in [`lr`](/docs/reference/math/lr/#functions-lr)
- Fixed sub/superscripts sometimes being in the wrong position with [`lr`](/docs/reference/math/lr/#functions-lr)
- Fixed multi-line annotations (e.g. overbrace) changing the math baseline
- Fixed merging of attachments when the base is a nested equation
- Fixed resolving of contextual (em-based) text sizes within math
- Fixed spacing around up tacks (⊥)
## Bibliography
- Prose and author-only citations now use editor names if the author names are unavailable
- Some non-standard but widely used BibLaTeX `editortype`s like `producer`, `writer`, `scriptwriter`, and `none` (defined by widespread style `biblatex-chicago` to mean performers within `music` and `video` entries) are now recognized
- CSL styles can now render affixes around the bibliography
- For BibTeX entries with `eprinttype = \{pubmed\}`, the PubMed ID will now be correctly processed
- Whitespace handling for strings delimiting initialized names has been improved
- Uppercase spelling after apostrophes used as quotation marks is now possible
- Fixed bugs around the handling of CSL delimiting characters
- Fixed a problem with parsing multibyte characters in page ranges that could prevent Hayagriva from parsing some BibTeX page ranges
- Updated CSL APA style
- Updated CSL locales for Finnish, Swiss German, Austrian German, German, and Arabic
## Text
- Added support for specifying which charset should be [covered](/docs/reference/text/text/#parameters-font) by which font family
- Added [`all`](/docs/reference/text/smallcaps/#parameters-all) parameter to `smallcaps` function that also enables small capitals on uppercase letters
- Added basic i18n for Basque and Bulgarian
- [Justification](/docs/reference/model/par/#parameters-justify) does not affect [raw](/docs/reference/text/raw/) blocks anymore
- [CJK-Latin-spacing](/docs/reference/text/text/#parameters-cjk-latin-spacing) does not affect [raw](/docs/reference/text/raw/) text anymore
- Fixed wrong language codes being used for Greek and Ukrainian
- Fixed default quotes for Croatian and Bulgarian
- Fixed crash in RTL text handling
- Added support for [`raw`](/docs/reference/text/raw/) syntax highlighting for a few new languages: CFML, NSIS, and WGSL
- New font metadata exception for New Computer Modern Sans Math
- Updated bundled New Computer Modern fonts to version 7.0.1
## Layout
- Fixed various bugs with footnotes
- Fixed footnotes getting lost when multiple footnotes were nested within another footnote
- Fixed endless loops with empty and overlarge footnotes
- Fixed crash with overlarge footnotes within a floating placement
- Fixed sizing of quadratic shapes ([`square`](/docs/reference/visualize/square/) and [`circle`](/docs/reference/visualize/circle/))
- Fixed [`block.sticky`](/docs/reference/layout/block/#parameters-sticky) not working properly at the top of a container
- Fixed crash due to consecutive weak spacing
- Fixed crash when a [block](/docs/reference/layout/block/) or text have negative sizes
- Fixed unnecessary hyphenations occurring in rare scenarios due to a bad interaction between padding and paragraph optimization
- Fixed lone [citations](/docs/reference/model/cite/) in [`align`](/docs/reference/layout/align/) not becoming their own paragraph
## Syntax
- Top-level closing square brackets that do not have a matching opening square bracket are now a hard error **(Minor breaking change)**
- Adding a space between the identifier and the parentheses in a set rule is not allowed anymore **(Minor breaking change)**
- Numbers with a unit cannot have a base prefix anymore, e.g. `0b100000pt` is not allowed anymore. Previously, it was syntactically allowed but always resolved to a value of zero. **(Minor breaking change)**
- Using `is` as an identifier will now warn as it might become a keyword in the future
- Fixed minor whitespace handling bugs
- in math mode argument lists
- at the end of headings
- between a term list's term and description
- Fixed parsing of empty single line raw blocks with 3+ backticks and a language tag
- Fixed minor bug with parentheses parsing in math
- Markup that can only appear at the start of the line (headings, lists) can now also appear at the start of a list item
- A shebang `#!` at the very start of a file is now ignored
## PDF export
- Added [`pdf.embed`](/docs/reference/pdf/attach/) function for embedding arbitrary files in the exported PDF
- Added support for PDF/A-3b export
- The PDF timestamp will now contain the timezone by default
## HTML export
**Note:** HTML export is currently under active development. The feature is still _very_ incomplete, but already available for experimentation behind a feature flag.
- Added HTML output support for some (but not all) of the built-in elements
- Added [`html.elem`](/docs/reference/html/elem/) function for outputting an arbitrary HTML element
- Added [`html.frame`](/docs/reference/html/frame/) function for integrating content that requires layout into HTML (by embedding an SVG)
- Added [`target`](/docs/reference/foundations/target/) function which returns either `"paged"` or `"html"` depending on the export target
## Tooling and Diagnostics
- Autocompletion improvements
- Added autocompletion for file paths
- Smarter autocompletion of variables: Completing `rect(fill: |)` will now only show variables which contain a valid fill (either directly or nested, e.g. a dictionary containing a valid fill)
- Different functions will now autocomplete with different brackets (round vs square) depending on which kind is more useful
- Positional parameters which are already provided aren't autocompleted again anymore
- Fixed variable autocompletion not considering parameters
- Added autocompletion snippets for common figure usages
- Fixed autocompletion after half-completed import item
- Fixed autocompletion for `cite` function
- Added warning when an unconditional return in a code block discards joined content
- Fixed error message when accessing non-existent label
- Fixed handling of nested imports in IDE functionality
## Command Line Interface
- Added `--features` argument and `TYPST_FEATURES` environment variable for opting into experimental features. The only feature so far is `html`.
- Added a live reloading HTTP server to `typst watch` when targeting HTML
- Fixed self-update not being aware about certain target architectures
- Fixed crash when piping `typst fonts` output to another command
- Fixed handling of relative paths in `--make-deps` output
- Fixed handling of multipage SVG and PNG export in `--make-deps` output
- Colons in filenames are now correctly escaped in `--make-deps` output
## Symbols
- New
- `inter`, `inter.and`, `inter.big`, `inter.dot`, `inter.double`, `inter.sq`, `inter.sq.big`, `inter.sq.double`, `integral.inter`
- `asymp`, `asymp.not`
- `mapsto`, `mapsto.long`
- `divides.not.rev`, `divides.struck`
- `interleave`, `interleave.big`, `interleave.struck`
- `eq.triple.not`, `eq.dots`, `eq.dots.down`, `eq.dots.up`
- `smt`, `smt.eq`, `lat`, `lat.eq`
- `colon.tri`, `colon.tri.op`
- `dagger.triple`, `dagger.l`, `dagger.r`, `dagger.inv`
- `hourglass.stroked`, `hourglass.filled`
- `die.six`, `die.five`, `die.four`, `die.three`, `die.two`, `die.one`
- `errorbar.square.stroked`, `errorbar.square.filled`, `errorbar.diamond.stroked`, `errorbar.diamond.filled`, `errorbar.circle.stroked`, `errorbar.circle.filled`
- `numero`
- Renamed **(Breaking change)**
- `ohm.inv` to `Omega.inv`
- Changed codepoint **(Breaking change)**
- `angle.l.double` from `《` to `⟪`
- `angle.r.double` from `》` to `⟫`
- `angstrom` from U+212B (`Å`) to U+00C5 (`Å`)
- Deprecated
- `sect` and all its variants in favor of `inter`
- `integral.sect` in favor of `integral.inter`
- Removed **(Breaking change)**
- `degree.c` in favor of `°C` (`$upright(°C)$` or `$upright(degree C)$` in math)
- `degree.f` in favor of `°F` (`$upright(°F)$` or `$upright(degree F)$` in math)
- `kelvin` in favor of just K (`$upright(K)$` in math)
- `ohm` in favor of `Omega`
## Deprecations
- The [`path`](/docs/reference/visualize/path/) function in favor of the [`curve`](/docs/reference/visualize/curve/) function
- The name `pattern` for tiling patterns in favor of the new name [`tiling`](/docs/reference/visualize/tiling/)
- [`image.decode`](/docs/reference/visualize/image/#definitions-decode), [`cbor.decode`](/docs/reference/data-loading/cbor/#definitions-decode), [`csv.decode`](/docs/reference/data-loading/csv/#definitions-decode), [`json.decode`](/docs/reference/data-loading/json/#definitions-decode), [`toml.decode`](/docs/reference/data-loading/toml/#definitions-decode), [`xml.decode`](/docs/reference/data-loading/xml/#definitions-decode), [`yaml.decode`](/docs/reference/data-loading/yaml/#definitions-decode) in favor of the top-level functions directly accepting both paths and bytes
- The `sect` and its variants in favor of `inter`, and `integral.sect` in favor of `integral.inter`
- The compatibility behavior of type/str comparisons (e.g. `int == "integer"`) which was temporarily introduced in Typst 0.8 now emits warnings. It will be removed in Typst 0.14.
## Removals
- Removed `style` function and `styles` argument of [`measure`](/docs/reference/layout/measure/), use a [context](/docs/reference/context/) expression instead **(Breaking change)**
- Removed `state.display` function, use [`state.get`](/docs/reference/introspection/state/#definitions-get) instead **(Breaking change)**
- Removed `location` argument of [`state.at`](/docs/reference/introspection/state/#definitions-at), [`counter.at`](/docs/reference/introspection/counter/#definitions-at), and [`query`](/docs/reference/introspection/query/) **(Breaking change)**
- Removed compatibility behavior where [`counter.display`](/docs/reference/introspection/counter/#definitions-display) worked without [context](/docs/reference/context/) **(Breaking change)**
- Removed compatibility behavior of [`locate`](/docs/reference/introspection/locate/) **(Breaking change)**
## Development
- The `typst::compile` function is now generic and can return either a `PagedDocument` or an `HtmlDocument`
- `typst-timing` now supports WebAssembly targets via `web-sys` when the `wasm` feature is enabled
- Increased minimum supported Rust version to 1.80
- Fixed linux/arm64 Docker image
## Contributors
docs/changelog/0.13.1.md
# 0.13.1
## Command Line Interface
- Fixed high CPU usage for `typst watch` on Linux. Depending on the project size, CPU usage would spike for varying amounts of time. This bug appeared with 0.13.0 due to a behavioral change in the inotify file watching backend.
## HTML export
- Fixed export of tables with [gutters](/docs/reference/model/table/#parameters-gutter)
- Fixed usage of `<html>` and `<body>` element within [context](/docs/reference/context/)
- Fixed querying of [metadata](/docs/reference/introspection/metadata/) next to `<html>` and `<body>` element
## Visualization
- Fixed [curves](/docs/reference/visualize/curve/) with multiple non-closed components
## Introspection
- Fixed a regression where labelled [symbols](/docs/reference/foundations/symbol/) could not be [queried](/docs/reference/introspection/query/) by label
## Deprecations
- Fixed false positives in deprecation warnings for type/str comparisons
## Contributors
docs/changelog/0.14.0.md
# 0.14.0
## Highlights
- Typst now produces [_accessible_ PDFs](/docs/guides/accessibility/) out of the box, with opt-in support for stricter checks and conformance to PDF/UA-1
- Typst now supports all [PDF/A standards](/docs/reference/pdf/#pdf-a)
- PDFs can now be used as [images](/docs/reference/visualize/image/#parameters-format) (thanks to [@LaurenzV](https://github.com/LaurenzV))
- Added support for [character-level justification](/docs/reference/model/par/#parameters-justification-limits) (can significantly improve the appearance of justified text)
- Added support for many more built-in elements in HTML export
- Added typed HTML API (e.g. [`html.div`](/docs/reference/html/typed/#functions-div)) with individually typed attributes
- Added support for multiple [headers](/docs/reference/model/table/#definitions-header) and subheaders in tables
- Added [`title`](/docs/reference/model/title/) element for displaying the document title
- Added [`frac.style`](/docs/reference/math/frac/#parameters-style) property for producing skewed and inline fractions
## PDF export
PDF export was fully rewritten to use the new [`krilla`](https://github.com/LaurenzV/krilla) library, fixing various bugs and enabling many improvements. Known fixes are listed below, but there will likely be other changes in how the output behaves. If you spot any regressions, please [report them on GitHub](https://github.com/typst/typst/issues). _(Thanks to @LaurenzV for creating krilla!)_ [#5420](https://github.com/typst/typst/issues/5420)
- Typst now produces _accessible_ PDFs out of the box. Such documents are suitable for consumption in a wide range of circumstances. That not only includes consumption by people with permanent or temporary disabilities, but also by those with different devices or preferences.
- Typst PDFs are now _tagged_ by default. _Tags_ are rich metadata that PDF viewers can use to make the document consumable in other ways than visually (e.g., through a screen reader).
- In addition, Typst can now emit documents conforming to the PDF/UA-1 standard. (PDF/UA-2 is not yet supported, but planned.)
- There is an increasing amount of existing and upcoming legislation requiring documents to be accessible, for instance, the European Accessibility Act and the Americans with Disabilities Act.
- For more details on all of this, read the new [Accessibility Guide](/docs/guides/accessibility/).
- Typst now supports all PDF/A standards: PDF/A-1b, PDF/A-1a, PDF/A-2b, PDF/A-2u, PDF/A-2a, PDF/A-3b, PDF/A-3u, PDF/A-3a, PDF/A-4, PDF/A-4f, and PDF/A-4e. See the [expanded PDF/A documentation](/docs/reference/pdf/#pdf-a) for guidance on how to select a suitable standard. [#5420](https://github.com/typst/typst/issues/5420) [#7038](https://github.com/typst/typst/issues/7038)
- Typst now supports the PDF versions 1.4, 1.5, 1.6, and 2.0 in addition to PDF 1.7. See the [relevant section of the PDF documentation](/docs/reference/pdf/#pdf-versions) for details. [#5420](https://github.com/typst/typst/issues/5420)
- Added [`pdf.artifact`](/docs/reference/pdf/artifact/) function for marking content as not semantically meaningful [#6619](https://github.com/typst/typst/issues/6619)
- Added experimental [`pdf.header-cell`](/docs/reference/pdf/header-cell/), [`pdf.data-cell`](/docs/reference/pdf/data-cell/), and [`pdf.table-summary`](/docs/reference/pdf/table-summary/) functions for enhancing accessibility of documents with complex tables. These functions are guarded by the `a11y-extras` feature. They do not have a final interface and will be removed in the future, either through integration into table functions or through full removal. [#6619](https://github.com/typst/typst/issues/6619)
- PDF heading bookmarks now contain the heading's numbering [#6622](https://github.com/typst/typst/issues/6622)
- [Attachments](/docs/reference/pdf/attach/)
- Renamed `pdf.embed` to [`pdf.attach`](/docs/reference/pdf/attach/) (the old name will remain as a deprecated alias until Typst 0.15) [#6705](https://github.com/typst/typst/issues/6705)
- The [`mime`](/docs/reference/pdf/attach/#parameters-mime-type) property of `pdf.attach` is now checked for syntactical correctness **(Minor breaking change)**
- Fixed parsing of the [`data`](/docs/reference/pdf/attach/#parameters-data) argument of `pdf.attach` [#6435](https://github.com/typst/typst/issues/6435)
- Attachments now smartly determine whether they should be compressed [#6256](https://github.com/typst/typst/issues/6256)
- Text extraction (i.e. copy paste)
- Now works correctly even when multiple different characters result in the same glyph [#5420](https://github.com/typst/typst/issues/5420)
- Spaces between words at which a natural line break occurred are now correctly retained for text extraction [#6866](https://github.com/typst/typst/issues/6866)
- Fixed mapping of hyphenation artifacts to Unicode text [#6799](https://github.com/typst/typst/issues/6799)
- Images
- CMYK images now work properly in PDF export [#5420](https://github.com/typst/typst/issues/5420)
- Improved export of text in SVG images with a filter [#5420](https://github.com/typst/typst/issues/5420)
- Improved compatibility of SVG images with Quartz rendering engine (the engine used in Apple Preview) [#5420](https://github.com/typst/typst/issues/5420)
- Improved handling of SVG images with high group nesting depth [#5420](https://github.com/typst/typst/issues/5420)
- Fixed a bug with text in patterns [#5420](https://github.com/typst/typst/issues/5420)
- Fixed gradients with transparency [#5420](https://github.com/typst/typst/issues/5420)
## HTML export
- Added support for many more built-in elements (the [_Model_ category](/docs/reference/model/) is now fully covered)
- The [`image`](/docs/reference/visualize/image/) element [#6578](https://github.com/typst/typst/issues/6578)
- The [`footnote`](/docs/reference/model/footnote/) and [`footnote.entry`](/docs/reference/model/footnote/#definitions-entry) element [#6917](https://github.com/typst/typst/issues/6917)
- The [`outline`](/docs/reference/model/outline/) and [`outline.entry`](/docs/reference/model/outline/#definitions-entry) element [#6606](https://github.com/typst/typst/issues/6606)
- The [`bibliography`](/docs/reference/model/bibliography/) element [#6952](https://github.com/typst/typst/issues/6952)
- The [`smartquote`](/docs/reference/text/smartquote/) element [#6710](https://github.com/typst/typst/issues/6710)
- The [`sub`](/docs/reference/text/sub/) and [`super`](/docs/reference/text/super/) elements [#6422](https://github.com/typst/typst/issues/6422)
- The [`underline`](/docs/reference/text/underline/), [`overline`](/docs/reference/text/overline/), [`strike`](/docs/reference/text/strike/), and [`highlight`](/docs/reference/text/highlight/) elements [#6510](https://github.com/typst/typst/issues/6510)
- The [`smallcaps`](/docs/reference/text/smallcaps/) element [#6600](https://github.com/typst/typst/issues/6600)
- The [`lower`](/docs/reference/text/lower/) and [`upper`](/docs/reference/text/upper/) functions [#6585](https://github.com/typst/typst/issues/6585)
- Added typed HTML API (e.g. [`html.div`](/docs/reference/html/typed/#functions-div)) with individually typed attributes [#6476](https://github.com/typst/typst/issues/6476)
- For example, to generate a `video` element you can now write `#html.video(width: 400, src: "sunrise.mp4")` instead of `#html.elem("video", attrs: (width: "400", src: "sunrise.mp4"))`. Note how the `width` attribute takes an integer instead of a string.
- Added support for intra-doc [`link`](/docs/reference/model/link/) targets [#6602](https://github.com/typst/typst/issues/6602)
- The [`raw`](/docs/reference/text/raw/) element
- Added syntax highlighting support [#6691](https://github.com/typst/typst/issues/6691)
- Block-level `raw` elements now emit both a `<code>` and a `<pre>` tag [#6701](https://github.com/typst/typst/issues/6701)
- The [language tag](/docs/reference/text/raw/#parameters-lang) of `raw` elements is now preserved as a `data-lang` attribute on the `<code>` tag [#6702](https://github.com/typst/typst/issues/6702)
- The [`authors`](/docs/reference/model/document/#parameters-author) and [`keywords`](/docs/reference/model/document/#parameters-keywords) properties of the `document` function now yield corresponding HTML `<meta>` tags [#6134](https://github.com/typst/typst/issues/6134)
- The [`html.elem`](/docs/reference/html/elem/) function now supports custom HTML element names [#6676](https://github.com/typst/typst/issues/6676)
- Improved encoding of [`html.frame`](/docs/reference/html/frame/) [#6605](https://github.com/typst/typst/issues/6605)
- Empty attributes are now encoded with shorthand syntax (e.g. `<div hidden></div>`) [#6479](https://github.com/typst/typst/issues/6479)
- Zero-sized horizontal weak spacing (`h(0pt, weak: true)`) does not cause a "was ignored during HTML export" warning anymore, so it can be used to destruct surrounding spaces without producing any output, as in paged export [#6917](https://github.com/typst/typst/issues/6917)
- Fixed encoding of `<pre>` and `<textarea>` elements that start with a newline [#6487](https://github.com/typst/typst/issues/6487) [#6497](https://github.com/typst/typst/issues/6497)
- Fixed encoding of [raw text elements](https://html.spec.whatwg.org/#raw-text-elements) [#6487](https://github.com/typst/typst/issues/6487) [#6720](https://github.com/typst/typst/issues/6720)
- Fixed sizing of [`html.frame`](/docs/reference/html/frame/) [#6505](https://github.com/typst/typst/issues/6505)
- Fixed [`measure`](/docs/reference/layout/measure/) in HTML export [#7186](https://github.com/typst/typst/issues/7186)
- Fixed nested [`html.frame`s](/docs/reference/html/frame/) [#6509](https://github.com/typst/typst/issues/6509)
- Fixed that a [`box`](/docs/reference/layout/box/) without a body was ignored in HTML export [#6709](https://github.com/typst/typst/issues/6709)
- Fixed encoding of whitespace in HTML [#6750](https://github.com/typst/typst/issues/6750)
## SVG export
- Added support for COLR-flavored color glyphs [#6693](https://github.com/typst/typst/issues/6693)
- Reduced amount of `<g>` grouping elements that are generated [#6247](https://github.com/typst/typst/issues/6247)
## PNG export
- Fixed crash when [text size](/docs/reference/text/text/#parameters-size) is negative [#5940](https://github.com/typst/typst/issues/5940)
## Visualize
- Added support for using PDFs as [images](/docs/reference/visualize/image/) using the new [`hayro`](https://github.com/LaurenzV/hayro) library. PDFs will be embedded directly in PDF export, rasterized in PNG export, and turned into SVGs in SVG and HTML export. _(Thanks to @LaurenzV for creating hayro!)_ [#6623](https://github.com/typst/typst/issues/6623)
- Added support for WebP images [#6311](https://github.com/typst/typst/issues/6311)
- Various minor improvements for SVG images (see the [resvg 0.44 and 0.45 changelogs](https://github.com/linebender/resvg/blob/v0.45.1/CHANGELOG.md#0450---2025-02-26))
- SVG images can now refer to external image files [#6794](https://github.com/typst/typst/issues/6794)
- Clip paths are now properly anti-aliased [#6570](https://github.com/typst/typst/issues/6570)
- Fixed gradients on curves where the last segment is [`curve.line`](/docs/reference/visualize/curve/#definitions-line) [#6647](https://github.com/typst/typst/issues/6647)
- Fixed stroke cap handling of shapes with partial strokes [#5688](https://github.com/typst/typst/issues/5688)
- Fixed corner radius handling of shapes with partial strokes [#6976](https://github.com/typst/typst/issues/6976)
- Fixed crash when sampling across two coinciding gradient stops [#6166](https://github.com/typst/typst/issues/6166)
## Layout
- Added opt-in support for character-level justification in addition to word-level justification, configured via the new [`par.justification-limits`](/docs/reference/model/par/#parameters-justification-limits) property. This is an impactful microtypographical technique that can significantly improve the appearance of justified text. [#6161](https://github.com/typst/typst/issues/6161)
- Fixed wrong linebreak opportunities related to object replacement characters [#6251](https://github.com/typst/typst/issues/6251)
- Fixed an issue where a breakable block would still produce an empty segment even if nothing fit into the first segment, leading to various undesirable behaviors in combination with fills, strokes, and [stickiness](/docs/reference/layout/block/#parameters-sticky) [#6335](https://github.com/typst/typst/issues/6335)
- Fixed crash with set rule for column or rowspan on a grid cell [#6401](https://github.com/typst/typst/issues/6401)
- Fixed [CJK-Latin-spacing](/docs/reference/text/text/#parameters-cjk-latin-spacing) at manual line breaks [#6700](https://github.com/typst/typst/issues/6700) and at sub- and superscript boundaries [#7175](https://github.com/typst/typst/issues/7175)
## Math
- Added [`frac.style`](/docs/reference/math/frac/#parameters-style) property with new options for skewed and inline fractions [#6672](https://github.com/typst/typst/issues/6672)
- Added [`math.equation.alt`](/docs/reference/math/equation/#parameters-alt) property for setting an alternative description for an equation [#6619](https://github.com/typst/typst/issues/6619)
- Text handling
- A single equation can now use multiple fonts [#6365](https://github.com/typst/typst/issues/6365)
- Glyph layout in math now uses proper text shaping, leading to better handling of more complex Unicode features [#6336](https://github.com/typst/typst/issues/6336)
- Generated characters in an equation (e.g. the `√` produced by `sqrt`) can now be targeted by text show rules [#6365](https://github.com/typst/typst/issues/6365)
- Added [`scr`](/docs/reference/math/variants/#functions-scr) function for roundhand script font style [#6309](https://github.com/typst/typst/issues/6309)
- Added `dotless` parameter to [`accent`](/docs/reference/math/accent/) (typically for rendering a dotless accented i or j) [#5939](https://github.com/typst/typst/issues/5939)
- Script-style glyphs are now preferred at reduced math sizes [#6320](https://github.com/typst/typst/issues/6320)
- Fixed [`text.stroke`](/docs/reference/text/text/#parameters-stroke) in math [#6243](https://github.com/typst/typst/issues/6243)
- Broken glyph assemblies are now prevented even when font data is incorrect [#6688](https://github.com/typst/typst/issues/6688)
- Layout
- Fixed a bug with vertical accent positioning [#5941](https://github.com/typst/typst/issues/5941)
- Fixed positioning of bottom accents [#6187](https://github.com/typst/typst/issues/6187)
- Fixed a bug with layout of roots [#6021](https://github.com/typst/typst/issues/6021)
- Improved layout of [`vec`](/docs/reference/math/vec/) and [`cases`](/docs/reference/math/cases/), making it consistent with [`mat`](/docs/reference/math/mat/) [#5934](https://github.com/typst/typst/issues/5934)
- Removed linebreak opportunity before closing bracket in inline math [#6216](https://github.com/typst/typst/issues/6216)
- An [`augment`](/docs/reference/math/mat/#parameters-augment) line can now exist at the start and end of a matrix, not only in between columns and rows [#5806](https://github.com/typst/typst/issues/5806)
- Shorthands and multi-character numbers do not bind more tightly than fractions anymore in cases like `$x>=(y)/z$` [#5925](https://github.com/typst/typst/issues/5925) [#5996](https://github.com/typst/typst/issues/5996) **(Minor breaking change)**
- Named arguments passed to symbols used as function now raise an error instead of being silently ignored [#6192](https://github.com/typst/typst/issues/6192) **(Minor breaking change)**
- The [`mid`](/docs/reference/math/lr/#functions-mid) element does not force the [`"large"` math class](/docs/reference/math/class/) upon its contents anymore and instead defaults to `"relation"` [#5980](https://github.com/typst/typst/issues/5980)
- Fixed error in math parsing when `..` isn't followed by anything [#7105](https://github.com/typst/typst/issues/7105)
- Fixed the default math class of ⅋, ⎰, ⟅, ⎱, ⟆, ⟇, and ، [#5949](https://github.com/typst/typst/issues/5949) [#6537](https://github.com/typst/typst/issues/6537)
_Thanks to @mkorje for his work on math!_
## Model
- Tables
- Added support for multiple [headers](/docs/reference/model/table/#definitions-header) and subheaders in tables [#6168](https://github.com/typst/typst/issues/6168)
- Table headers now force a rowbreak, i.e. an incomplete row before a header will not be filled with cells after the header [#6687](https://github.com/typst/typst/issues/6687)
- Fixed a bug where [headers](/docs/reference/model/table/#definitions-header) and footers could accidentally expand to contain non-header cells [#5919](https://github.com/typst/typst/issues/5919)
- Added [`title`](/docs/reference/model/title/) element for displaying the document title [#5618](https://github.com/typst/typst/issues/5618)
- Added [`figure.alt`](/docs/reference/model/figure/#parameters-alt) property for setting an alternative description for a figure [#6619](https://github.com/typst/typst/issues/6619)
- [Link](/docs/reference/model/link/) hit boxes for text are now vertically a bit larger to avoid issues with automatic link detection in PDF viewers [#6252](https://github.com/typst/typst/issues/6252)
- The [`link`](/docs/reference/model/link/) function will now produce an error when passed an empty string as a URL [#7049](https://github.com/typst/typst/issues/7049) **(Minor breaking change)**
- The value of the [`number`](/docs/reference/model/enum/#definitions-item-number) argument of `enum.item` now takes `auto` instead of `none` for automatic numbering [#6609](https://github.com/typst/typst/issues/6609) **(Minor breaking change)**
- Improved spacing of nested tight lists [#6242](https://github.com/typst/typst/issues/6242)
- Fixed that `quotes: false` was ignored for [inline-level quotes](/docs/reference/model/quote/#parameters-block) [#5991](https://github.com/typst/typst/issues/5991)
- Fixed [hanging indent](/docs/reference/model/heading/#parameters-hanging-indent) for centered, numbered headings [#6839](https://github.com/typst/typst/issues/6839)
- Fixed [`footnote.entry`](/docs/reference/model/footnote/#definitions-entry) show rules breaking links from footnote to entry [#6912](https://github.com/typst/typst/issues/6912)
- Hebrew numbering does not add Geresh and Gershayim anymore [#6122](https://github.com/typst/typst/issues/6122)
## Bibliography
- Built-in styles
- Updated styles to their latest upstream CSL versions [typst/hayagriva#350](https://github.com/typst/hayagriva/issues/350)
- Renamed `"chicago-fullnotes"` to `"chicago-notes"` (the old name remains as a deprecated alias) [#6920](https://github.com/typst/typst/issues/6920)
- Renamed `"modern-humanities-research-association"` to `"modern-humanities-research-association-notes"` (the old name remains as a deprecated alias) [#6994](https://github.com/typst/typst/issues/6994)
- Added support for locator/supplement in alphanumeric style [typst/hayagriva#307](https://github.com/typst/hayagriva/issues/307)
- Hayagriva format
- Added [`chapter` field](https://github.com/typst/hayagriva/blob/v0.9.1/docs/file-format.md#chapter) corresponding to CSL `chapter-number` and BibLaTeX `chapter` [typst/hayagriva#383](https://github.com/typst/hayagriva/issues/383)
- BibLaTeX format
- Fixed parsing of alphanumeric page ranges [typst/biblatex#86](https://github.com/typst/biblatex/issues/86)
- Added support for `%` comment syntax [typst/biblatex#80](https://github.com/typst/biblatex/issues/80)
- Fixed parsing of space-separated single character commands [typst/biblatex#71](https://github.com/typst/biblatex/issues/71)
- Added "primaryclass" alias for "eprintclass" field [typst/biblatex#75](https://github.com/typst/biblatex/issues/75)
- Added support for BibLaTeX `language` field [typst/hayagriva#317](https://github.com/typst/hayagriva/issues/317)
- Improved translation of BibLaTeX fields to `genre` and `serial-number` [typst/hayagriva#296](https://github.com/typst/hayagriva/issues/296) [typst/hayagriva#369](https://github.com/typst/hayagriva/issues/369)
- CSL handling
- The bibliography rendering now uses [`strong`](/docs/reference/model/strong/), [`emph`](/docs/reference/model/emph/), and [`smallcaps`](/docs/reference/text/smallcaps/) to express CSL font styling instead of directly adjusting the [`text`](/docs/reference/text/text/) style, making styling easier [#6984](https://github.com/typst/typst/issues/6984)
- Added support for date seasons, which are displayed when the month is missing [typst/hayagriva#391](https://github.com/typst/hayagriva/issues/391)
- Terms for "AD" and "BC" are now correctly used from the chosen locale [typst/hayagriva#364](https://github.com/typst/hayagriva/issues/364)
- Fixed how subsequent citations with differing supplements translate into CSL `ibid` and `ibid-with-locator` positions [#6171](https://github.com/typst/typst/issues/6171)
- Fixed handling of `ibid` and `ibid-with-locator` positions in styles [typst/hayagriva#301](https://github.com/typst/hayagriva/issues/301)
- Fixed the `location` conditional in CSL styles for citations with no locator [typst/hayagriva#399](https://github.com/typst/hayagriva/issues/399)
- Fixed accesses of the year suffix resulting in wrong CSL renders [typst/hayagriva#400](https://github.com/typst/hayagriva/issues/400)
- Fixed regression where page variables were no longer supported in styles' `<number>` elements [typst/hayagriva#289](https://github.com/typst/hayagriva/issues/289)
- Fixed sorting and formatting of name parts [typst/hayagriva#287](https://github.com/typst/hayagriva/issues/287) [typst/hayagriva#313](https://github.com/typst/hayagriva/issues/313)
- Fixed year suffix collapsing [typst/hayagriva#367](https://github.com/typst/hayagriva/issues/367)
- Fixed delimiters in locale-specific date formatting [typst/hayagriva#385](https://github.com/typst/hayagriva/issues/385)
- Fixed rendering of date ordinals [typst/hayagriva#366](https://github.com/typst/hayagriva/issues/366)
- Fixed rendering and sorting of dates with BC years [typst/hayagriva#334](https://github.com/typst/hayagriva/issues/334) [typst/hayagriva#368](https://github.com/typst/hayagriva/issues/368)
- Fixed sorting for empty sort values [typst/hayagriva#390](https://github.com/typst/hayagriva/issues/390)
## Text
- The [`sub`](/docs/reference/text/sub/) and [`super`](/docs/reference/text/super/) functions now use the `subs` and `sups` OpenType font features instead of special Unicode characters for typographic scripts, fixing semantical, sizing, and positioning issues [#5777](https://github.com/typst/typst/issues/5777)
- The [`raw`](/docs/reference/text/raw/) element
- Tweaked default syntax-highlighting color scheme of [`raw`](/docs/reference/text/raw/) text to make the colors more accessible [#6754](https://github.com/typst/typst/issues/6754)
- JSON keys and string values now use different colors in the default `raw` syntax highlighting [theme](/docs/reference/text/raw/#parameters-theme) [#6873](https://github.com/typst/typst/issues/6873)
- Fixed a crash when a `raw` [syntax](/docs/reference/text/raw/#parameters-syntaxes) contains an unescaped trailing backslash [#6883](https://github.com/typst/typst/issues/6883)
- Fixed tab indentation in [`raw`](/docs/reference/text/raw/) text with CRLF line terminators [#6961](https://github.com/typst/typst/issues/6961)
- Translations
- Added term translations (a term being the "Section" in "Section 1") for many new languages by importing pre-existing translations from LaTeX packages [#6852](https://github.com/typst/typst/issues/6852)
- Added term translations for Indonesian [#6108](https://github.com/typst/typst/issues/6108), Latvian [#6348](https://github.com/typst/typst/issues/6348), Croatian [#6413](https://github.com/typst/typst/issues/6413), Lithuanian [#6587](https://github.com/typst/typst/issues/6587), French [#7010](https://github.com/typst/typst/issues/7010), French (Canada) [#7098](https://github.com/typst/typst/issues/7098), Galician [#7019](https://github.com/typst/typst/issues/7019), Dutch [#7026](https://github.com/typst/typst/issues/7026), Danish [#7031](https://github.com/typst/typst/issues/7031), Slovenian [#7032](https://github.com/typst/typst/issues/7032), Italian [#7050](https://github.com/typst/typst/issues/7050), Chinese [#7044](https://github.com/typst/typst/issues/7044), Spanish [#7051](https://github.com/typst/typst/issues/7051), and Irish (Gaeilge) [#7024](https://github.com/typst/typst/issues/7024)
- Improved term translations for Czech [#6101](https://github.com/typst/typst/issues/6101), Swedish [#6519](https://github.com/typst/typst/issues/6519), Galician [#7019](https://github.com/typst/typst/issues/7019), Dutch [#7026](https://github.com/typst/typst/issues/7026), Chinese [#7044](https://github.com/typst/typst/issues/7044), Spanish [#7051](https://github.com/typst/typst/issues/7051), Irish (Gaeilge) [#7024](https://github.com/typst/typst/issues/7024), and German [#7082](https://github.com/typst/typst/issues/7082)
- Improved smart quotes for French [#5976](https://github.com/typst/typst/issues/5976), Ukrainian [#6372](https://github.com/typst/typst/issues/6372), Russian [#6331](https://github.com/typst/typst/issues/6331), and Arabic [#6626](https://github.com/typst/typst/issues/6626)
- An empty font list is not allowed anymore in [`text.font`](/docs/reference/text/text/#parameters-font) [#6049](https://github.com/typst/typst/issues/6049) **(Minor breaking change)**
- Added a warning when using a variable font as those are not currently supported [#6425](https://github.com/typst/typst/issues/6425)
- Fixed usage of the same font with different [coverage](/docs/reference/text/text/#parameters-font) settings [#6604](https://github.com/typst/typst/issues/6604)
- Fixed hyphens not showing up when hyphenating at specific positions (where invisible metadata exists) [#6807](https://github.com/typst/typst/issues/6807)
- Fixed styling of repeated hyphens in languages with hyphen repetition [#6798](https://github.com/typst/typst/issues/6798)
- Last resort font fallback does not consider default ignorable characters anymore during font selection [#6805](https://github.com/typst/typst/issues/6805)
- Updated New Computer Modern fonts to version 7.0.4 [#6376](https://github.com/typst/typst/issues/6376)
- Updated data and shaper to Unicode 16.0.0 [#5407](https://github.com/typst/typst/issues/5407)
## Scripting
- The `in` operator can now be used to check whether a definition is present in a module [#6498](https://github.com/typst/typst/issues/6498)
- Added `default` parameter to [`array.first`](/docs/reference/foundations/array/#definitions-first), [`array.last`](/docs/reference/foundations/array/#definitions-last) [#5970](https://github.com/typst/typst/issues/5970), [`array.join`](/docs/reference/foundations/array/#definitions-join) [#6932](https://github.com/typst/typst/issues/6932), [`str.first`](/docs/reference/foundations/str/#definitions-first), and [`str.last`](/docs/reference/foundations/str/#definitions-last) [#6554](https://github.com/typst/typst/issues/6554) methods
- Added `by` parameter to [`array.sorted`](/docs/reference/foundations/array/#definitions-sorted) for sorting with a comparison function [#5627](https://github.com/typst/typst/issues/5627)
- Added [`str.normalize`](/docs/reference/foundations/str/#definitions-normalize) function for Unicode normalization [#5631](https://github.com/typst/typst/issues/5631)
- Added [`from`](/docs/reference/layout/direction/#definitions-from), [`to`](/docs/reference/layout/direction/#definitions-to), and [`sign`](/docs/reference/layout/direction/#definitions-sign) methods to `direction` type [#5893](https://github.com/typst/typst/issues/5893)
- [Labels](/docs/reference/foundations/label/) cannot be empty anymore [#6332](https://github.com/typst/typst/issues/6332) **(Minor breaking change)**
- The WebAssembly runtime used by the [`plugin`](/docs/reference/foundations/plugin/) system was updated and now supports SIMD [#6997](https://github.com/typst/typst/issues/6997)
- Numberings and counters now use 64-bit numbers instead of platform-dependent numbers for consistency across platforms [#6026](https://github.com/typst/typst/issues/6026)
- Improved consistency of how large numbers are handled in data loading functions [#6836](https://github.com/typst/typst/issues/6836)
- The [`toml`](/docs/reference/data-loading/toml/) function is now guaranteed to return a [dictionary](/docs/reference/foundations/dictionary/) and [`toml.encode`](/docs/reference/data-loading/toml/#definitions-encode) must receive a dictionary (it already errored before when passed something else, but the new function signature makes the error clearer) [#6743](https://github.com/typst/typst/issues/6743)
- Serialization of [`bytes`](/docs/reference/foundations/bytes/) in human-readable formats now uses [`repr`](/docs/reference/foundations/repr/) [#6743](https://github.com/typst/typst/issues/6743)
- Fixed slicing of last N elements of an array using the [`count`](/docs/reference/foundations/array/#definitions-slice-count) parameter [#6838](https://github.com/typst/typst/issues/6838)
- Fixed crash when the expression wrapped in a `context` expression is an anonymous function [#6975](https://github.com/typst/typst/issues/6975)
- Fixed equality check between [`raw.line`](/docs/reference/text/raw/#definitions-line) elements [#6560](https://github.com/typst/typst/issues/6560)
- Fixed [`repr`](/docs/reference/foundations/repr/) of [labels](/docs/reference/foundations/label/) being potentially syntactically invalid [#6456](https://github.com/typst/typst/issues/6456)
- Fixed [`repr`](/docs/reference/foundations/repr/) of functions modified through [`with`](/docs/reference/foundations/function/#definitions-with) [#6773](https://github.com/typst/typst/issues/6773)
## Introspection
- The following elements are newly locatable (i.e. they can be discovered with [`query`](/docs/reference/introspection/query/), [`locate`](/docs/reference/introspection/locate/), etc. without having a label): `par`, `table`, `enum`, `list`, `terms`, `title`, `figure.caption`, `footnote.entry`, `outline.entry`, `image`, `emph`, `strong`, `link`, `cite`, `raw`, `underline`, `overline`, `strike`, and `highlight` [#6619](https://github.com/typst/typst/issues/6619)
- Fixed issues with logical order in bidirectional text [#5887](https://github.com/typst/typst/issues/5887) [#6796](https://github.com/typst/typst/issues/6796)
- Fixed logical order of cells in right-to-left [`grid`](/docs/reference/layout/grid/) [#6232](https://github.com/typst/typst/issues/6232)
- Fixed logical order of elements in [`grid`](/docs/reference/layout/grid/) cells that span multiple pages [#7198](https://github.com/typst/typst/issues/7198)
- Fixed logical order of metadata at the starts and ends of paragraphs [#6881](https://github.com/typst/typst/issues/6881) [#6909](https://github.com/typst/typst/issues/6909)
- Fixed introspection [positions](/docs/reference/introspection/location/#definitions-position) of inline elements at the very start of a paragraph (previously the Y position of an element at the very start would differ from one in the middle of the first line) [#6881](https://github.com/typst/typst/issues/6881)
## Styling
- Fixed rare infinite loop in show rule application [#6259](https://github.com/typst/typst/issues/6259)
## Performance
- Optimized incremental compilation with a new algorithm that, in particular, eliminates cases of very slow compilation with heavy context usage [#6683](https://github.com/typst/typst/issues/6683)
## Command Line Interface
- Added `typst info` subcommand for emitting build and environment information [#6761](https://github.com/typst/typst/issues/6761)
- Added `typst completions` subcommand for retrieving shell completions [#6568](https://github.com/typst/typst/issues/6568)
- Added `TYPST_IGNORE_SYSTEM_FONTS` environment variable [#6092](https://github.com/typst/typst/issues/6092)
- Added `--ignore-embedded-fonts` flag and `TYPST_IGNORE_EMBEDDED_FONTS` environment variable for disabling the use of fonts embedded into the Typst binary [#7037](https://github.com/typst/typst/issues/7037)
- Added `--no-pdf-tags` flag for disabling the automatic generation of accessibility tags. These are emitted when no particular standard like PDF/UA-1 is selected to provide a baseline of accessibility. [#6619](https://github.com/typst/typst/issues/6619)
- Added `--target` parameter to `typst query` [#6405](https://github.com/typst/typst/issues/6405)
- Added `--deps` and `--deps-format` parameters for emitting a list of files compilation depends on. Supports the three formats `json`, `zero`, and `make`. [#7022](https://github.com/typst/typst/issues/7022)
- Deprecated the `--make-deps` flag in favor of `--deps` with `--deps-format make` [#7022](https://github.com/typst/typst/issues/7022)
- On Linux, the font search will now fall back to known font directories if none were loaded via Fontconfig. [RazrFalcon/fontdb#71](https://github.com/RazrFalcon/fontdb/issues/71)
- The CLI will now warn when trying to watch the standard input [#6381](https://github.com/typst/typst/issues/6381)
- Fixed race condition when two separate Typst CLI processes concurrently try to install a package [#5979](https://github.com/typst/typst/issues/5979)
- Fixed incremental SVG export not writing output SVGs on changes that only affect the page (e.g. changing `page.fill`) [#6810](https://github.com/typst/typst/issues/6810)
- Fixed a rare potential crash when stack space couldn't be grown as expected [#6969](https://github.com/typst/typst/issues/6969)
## Tooling and Diagnostics
- Errors in many kinds of external text files (e.g., bibliographies, JSON files, etc.) are now annotated within these files instead of at the positions where the files are loaded from a Typst file [#6308](https://github.com/typst/typst/issues/6308)
- Warnings originating from within [`eval`](/docs/reference/foundations/eval/) are now correctly emitted [#6100](https://github.com/typst/typst/issues/6100)
- Diagnostic messages and hints
- Improved error messages related to parsing of numbers [#5969](https://github.com/typst/typst/issues/5969)
- The error message for an unsuitable CSL style now mentions the name of the style [#6306](https://github.com/typst/typst/issues/6306)
- Added hints to various deprecated items with the removal timeline [#6617](https://github.com/typst/typst/issues/6617)
- Added hint for the error message when an X/Y pair is expected [#6476](https://github.com/typst/typst/issues/6476)
- Added hint for a label that appears in both the document and the bibliography [#6457](https://github.com/typst/typst/issues/6457)
- Added additional hint for show rule recursion depth error [#5856](https://github.com/typst/typst/issues/5856)
- Fixed inconsistent formatting of code points and strings in error messages [#6487](https://github.com/typst/typst/issues/6487)
- Autocompletion
- Labels will now be deduplicated in completions [#6516](https://github.com/typst/typst/issues/6516)
- Math font autocompletions are now based on the presence of an OpenType MATH table instead of the word "Math" in the name [#6316](https://github.com/typst/typst/issues/6316)
- Autocompletion immediately after a comma in a parameter list is now supported for explicitly triggered completions (e.g. via Ctrl/Cmd+Space) [#6550](https://github.com/typst/typst/issues/6550)
- Citation style aliases are now displayed as autocompletions [#6696](https://github.com/typst/typst/issues/6696)
- Fixed autocompletion false positives with cursor after parameter list [#6475](https://github.com/typst/typst/issues/6475)
- Fixed autocompletion after partial identifier in math [#6415](https://github.com/typst/typst/issues/6415)
- Fixed which definitions are suggested in math [#6415](https://github.com/typst/typst/issues/6415)
- Fixed inapplicable method autocompletions being listed [#5824](https://github.com/typst/typst/issues/5824)
- Tooltips
- Fixed tooltip for scoped functions (e.g. `calc.round`) [#6234](https://github.com/typst/typst/issues/6234)
- Fixed tooltip and details for figure references [#6580](https://github.com/typst/typst/issues/6580)
- Expression tooltips now use `×` instead of `x` to indicate a repeated value [#6163](https://github.com/typst/typst/issues/6163)
- Fixed jump from click (jumping to the source panel with a click in the preview) in presence of transformations and clipping [#6037](https://github.com/typst/typst/issues/6037)
## Symbols
- Added many new symbols and variants; many more than could be listed here. View [the dedicated changelog](https://github.com/typst/codex/blob/v0.2.0/CHANGELOG.md#version-020-october-7-2025) for a full listing.
- Code points that have a symbol and emoji presentation now have the correct variation selector attached depending on whether they appear in `sym` or `emoji`. That said, they still don't render consistently in Typst due to how font fallback works. [typst/codex#114](https://github.com/typst/codex/issues/114)
- The [`symbol`](/docs/reference/foundations/symbol/) function can now be used to create symbols that comprise not just one character, but one full grapheme cluster [#6489](https://github.com/typst/typst/issues/6489)
## Deprecations
- The name `pdf.embed` in favor of the new name [`pdf.attach`](/docs/reference/pdf/attach/) [#6705](https://github.com/typst/typst/issues/6705)
- The `"chicago-fullnotes"` bibliography style in favor of `"chicago-notes"` [#6920](https://github.com/typst/typst/issues/6920)
- The `"modern-humanities-research-association"` bibliography style in favor of `"modern-humanities-research-association-notes"` [#6994](https://github.com/typst/typst/issues/6994)
- The `--make-deps` CLI flag in favor of `--deps` with `--deps-format make` [#7022](https://github.com/typst/typst/issues/7022)
- Various symbols, see the [deprecation section in the dedicated changelog](https://github.com/typst/codex/blob/v0.2.0/CHANGELOG.md#deprecated) for a full listing
## Removals
- Removed compatibility behavior of type/str comparisons (e.g. `int == "integer"`), which was temporarily introduced in Typst 0.8 and deprecated in Typst 0.13 **(Breaking change)**
## Development
- The `Default` impl for `Library` had to be removed for crate splitting and trait coherence reasons, but you can get a drop-in replacement via `use typst::LibraryExt` [#6576](https://github.com/typst/typst/issues/6576)
- The `PdfOptions` struct has a new `tagged` field, which defaults to `true` [#6619](https://github.com/typst/typst/issues/6619) [#7046](https://github.com/typst/typst/issues/7046)
- Fixed a potential panic in `World::font` implementations. Downstream `World` implementations might need to apply [the same fix](https://github.com/typst/typst/pull/6117). [#6117](https://github.com/typst/typst/issues/6117)
- Increased minimum supported Rust version to 1.88 [#6637](https://github.com/typst/typst/issues/6637)
- The Docker container now has the optional non-root user `typst` [#7058](https://github.com/typst/typst/issues/7058)
## Contributors
docs/changelog/0.14.1.md
# 0.14.1
## PDF export
- Fixed regression where links to labelled elements would sometimes not work correctly [LaurenzV/krilla#304](https://github.com/LaurenzV/krilla/issues/304)
- Fixed bug where PDF text attributes could be written incorrectly [#7478](https://github.com/typst/typst/issues/7478)
- Fixed crash in link handling [#7471](https://github.com/typst/typst/issues/7471)
- Fixed crash for zero-sized pages [#7454](https://github.com/typst/typst/issues/7454)
- Fixed crash when a table [`vline`](/docs/reference/model/table/#definitions-vline) or [`hline`](/docs/reference/model/table/#definitions-hline) has an out-of-bounds index [#7448](https://github.com/typst/typst/issues/7448)
- Fixed crash in formatting of font-related PDF export errors [#7460](https://github.com/typst/typst/issues/7460)
- Fixed crash when a [`footnote`](/docs/reference/model/footnote/) or [`place`](/docs/reference/layout/place/) element was queried and reinserted into the document [#7216](https://github.com/typst/typst/issues/7216)
- Fixed crash for PNGs with invalid metadata [LaurenzV/krilla#286](https://github.com/LaurenzV/krilla/issues/286), [LaurenzV/krilla#287](https://github.com/LaurenzV/krilla/issues/287)
- Fixed bug where text in SVGs with `fill-and-stroke` paint order could be exported incorrectly [LaurenzV/krilla#292](https://github.com/LaurenzV/krilla/issues/292)
- Fixed bug with layer isolation in SVGs where blending/masking is used [LaurenzV/krilla#295](https://github.com/LaurenzV/krilla/issues/295)
- Fixed that table headers could be tagged incorrectly in some scenarios [LaurenzV/krilla#289](https://github.com/LaurenzV/krilla/issues/289)
- Fixed issues where generated PDFs could differ between 32-bit and 64-bit systems [LaurenzV/krilla#317](https://github.com/LaurenzV/krilla/issues/317), [LaurenzV/krilla#316](https://github.com/LaurenzV/krilla/issues/316), [LaurenzV/krilla#312](https://github.com/LaurenzV/krilla/issues/312)
- Upgraded JPEG decoder used during PDF export for improved compatibility, fixing a case where a valid JPEG was rejected [LaurenzV/krilla#288](https://github.com/LaurenzV/krilla/issues/288)
- A PDF document information dictionary that would be empty is now fully omitted instead [LaurenzV/krilla#280](https://github.com/LaurenzV/krilla/issues/280)
- A rare crash in PDF tagging was turned into a compiler error [#7450](https://github.com/typst/typst/issues/7450)
## HTML export
- Fixed export of table [headers](/docs/reference/model/table/#definitions-header) and [footers](/docs/reference/model/table/#definitions-footer) with gutter [#7332](https://github.com/typst/typst/issues/7332)
- A [`page`](/docs/reference/layout/page/) set rule in HTML export is now a warning instead of a hard error, in line with how unsupported elements are generally treated [#7513](https://github.com/typst/typst/issues/7513)
## Math
- Fixed regression where `arrow.l.r` could not be used as an [accent](/docs/reference/math/accent/) anymore [#7481](https://github.com/typst/typst/issues/7481)
- Fixed that single-letter strings did not react to spaces around them like multi-letter strings do [#7276](https://github.com/typst/typst/issues/7276)
- Fixed that spacing around [`mat`](/docs/reference/math/mat/) and [`vec`](/docs/reference/math/vec/) with a fence delimiter was whitespace-dependent [#7309](https://github.com/typst/typst/issues/7309)
- Fixed height calculation for horizontally stretched glyphs [#7327](https://github.com/typst/typst/issues/7327)
## Model
- Fixed regression where Typst would error in heading numbering functions that don't handle the counter state `(0,)`. This can occur in the first layout iteration. Such errors are usually automatically caught by Typst, which was not the case here. [#7459](https://github.com/typst/typst/issues/7459)
## Text
- Fixed regression where Typst would synthesize superscripts for some fonts even when [typographic](/docs/reference/text/super/#parameters-typographic) glyphs were available [#7462](https://github.com/typst/typst/issues/7462)
- Fixed regression where some oblique fonts would be classified as italic [#7483](https://github.com/typst/typst/issues/7483)
## Scripting
- Fixed crash due to violated invariants in [`array.sorted`](/docs/reference/foundations/array/#definitions-sorted) [#7520](https://github.com/typst/typst/issues/7520)
- Fixed crashes due to overflow in [`calc.rem`](/docs/reference/foundations/calc/#functions-rem), [`calc.rem-euclid`](/docs/reference/foundations/calc/#functions-rem-euclid), [`calc.div-euclid`](/docs/reference/foundations/calc/#functions-div-euclid), [`calc.quo`](/docs/reference/foundations/calc/#functions-quo), and [`calc.gcd`](/docs/reference/foundations/calc/#functions-gcd) [#7419](https://github.com/typst/typst/issues/7419)
- Upgraded WebAssembly runtime, fixing a bug that [plugins](/docs/reference/foundations/plugin/) could run into [#7438](https://github.com/typst/typst/issues/7438)
## Command Line Interface
- Compiling to standard output in combination with `--deps --deps-format=make` (which results in an error) will not produce an empty Make dependency file as a side effect anymore [#7246](https://github.com/typst/typst/issues/7246)
## Development
- Increased minimum supported Rust version to 1.89 [#7363](https://github.com/typst/typst/issues/7363)
## Contributors
docs/changelog/0.14.2.md
# 0.14.2
## Security
- Updated the WebAssembly runtime used for executing [plugins](/docs/reference/foundations/plugin/). The version used in Typst 0.14.0 and 0.14.1 suffers from a memory handling vulnerability. Based on our investigation, the vulnerability would be very hard to exploit in practice, but an exploit could theoretically be feasible. In any case, **we recommend upgrading to Typst 0.14.2.** This holds in particular for local users. In the web app, the bug is not critical as the browser offers an extra layer of protection. Typst 0.13.1 and below are not affected by this vulnerability. _Technical details:_ The [`wasmi`](https://github.com/wasmi-labs/wasmi/) WebAssembly runtime versions used in 0.14.0 and 0.14.1 have a _use-after-free_ memory handling bug in certain memory growth situations. Specifically, the bug occurs when the plugin tries to grow its memory, but allocating the requested amount of memory fails. Based on our investigation, the bug is hard to trigger in practice as the WebAssembly linear memory is always limited to 4GB on a technical level and modern operating systems rarely fail to serve a 4GB memory allocation request (typically not even under RAM pressure). Once the bug is triggered, it would also still be very challenging to turn it into an actual exploit. Regardless, we recommend upgrading to Typst 0.14.2 for protection against a potential exploit.
## Diagnostics
- Added a hint when [`array.sorted`](/docs/reference/foundations/array/#definitions-sorted) fails because a pair of elements could not be compared. This hint aids with fixing bugs in user code that were surfaced by a change in internal sorting behavior in Typst 0.14.1.
## Contributors
docs/changelog/0.2.0.md
# 0.2.0
## Breaking changes
- Removed support for iterating over index and value in [for loops](/docs/reference/scripting/#loops). This is now handled via unpacking and enumerating. Same goes for the [`map`](/docs/reference/foundations/array/#definitions-map) method.
- [Dictionaries](/docs/reference/foundations/dictionary/) now iterate in insertion order instead of alphabetical order.
## New features
- Added [unpacking syntax](/docs/reference/scripting/#bindings) for let bindings, which allows things like `let (1, 2) = array`
- Added [`enumerate`](/docs/reference/foundations/array/#definitions-enumerate) method
- Added [`path`](/docs/reference/visualize/path/) function for drawing Bézier paths
- Added [`layout`](/docs/reference/layout/layout/) function to access the size of the surrounding page or container
- Added `key` parameter to [`sorted`](/docs/reference/foundations/array/#definitions-sorted) method
## Command line interface
- Fixed `--open` flag blocking the program
- New Computer Modern font is now embedded into the binary
- Shell completions and man pages can now be generated by setting the `GEN_ARTIFACTS` environment variable to a target directory and then building Typst
## Miscellaneous improvements
- Fixed page numbering in outline
- Added basic i18n for a few more languages (AR, NB, CS, NN, PL, SL, ES, UA, VI)
- Added a few numbering patterns (Ihora, Chinese)
- Added `sinc` [operator](/docs/reference/math/op/)
- Fixed bug where math could not be hidden with [`hide`](/docs/reference/layout/hide/)
- Fixed sizing issues with box, block, and shapes
- Fixed some translations
- Fixed inversion of "R" in [`cal`](/docs/reference/math/variants/#functions-cal) and [`frak`](/docs/reference/math/variants/#functions-frak) styles
- Fixed some styling issues in math
- Fixed supplements of references to headings
- Fixed syntax highlighting of identifiers in certain scenarios
- [Ratios](/docs/reference/layout/ratio/) can now be multiplied with more types and be converted to [floats](/docs/reference/foundations/float/) with the [`float`](/docs/reference/foundations/float/) function
## Contributors
docs/changelog/0.3.0.md
# 0.3.0
## Breaking changes
- Renamed a few symbols: What was previous `dot.op` is now just `dot` and the basic dot is `dot.basic`. The same applies to `ast` and `tilde`.
- Renamed `mod` to [`rem`](/docs/reference/foundations/calc/#functions-rem) to more accurately reflect the behavior. It will remain available as `mod` until the next update as a grace period.
- A lone underscore is not a valid identifier anymore, it can now only be used in patterns
- Removed `before` and `after` arguments from [`query`](/docs/reference/introspection/query/). This is now handled through flexible [selectors](/docs/reference/foundations/selector/) combinator methods
- Added support for [attachments](/docs/reference/math/attach/#functions-attach) (sub-, superscripts) that precede the base symbol. The `top` and `bottom` arguments have been renamed to `t` and `b`.
## New features
- Added support for more complex [strokes](/docs/reference/visualize/stroke/) (configurable caps, joins, and dash patterns)
- Added [`cancel`](/docs/reference/math/cancel/) function for equations
- Added support for [destructuring](/docs/reference/scripting/#bindings) in argument lists and assignments
- Added [`alt`](/docs/reference/visualize/image/#parameters-alt) text argument to image function
- Added [`toml`](/docs/reference/data-loading/toml/) function for loading data from a TOML file
- Added [`zip`](/docs/reference/foundations/array/#definitions-zip), [`sum`](/docs/reference/foundations/array/#definitions-sum), and [`product`](/docs/reference/foundations/array/#definitions-product) methods for arrays
- Added `fact`, `perm`, `binom`, `gcd`, `lcm`, `atan2`, `quo`, `trunc`, and `fract` [calculation](/docs/reference/foundations/calc/) functions
## Improvements
- Text in SVGs now displays properly
- Typst now generates a PDF heading outline
- [References](/docs/reference/model/ref/) now provides the referenced element as a field in show rules
- Refined linebreak algorithm for better Chinese justification
- Locations are now a valid kind of selector
- Added a few symbols for algebra
- Added Spanish smart quote support
- Added [`selector`](/docs/reference/foundations/selector/) function to turn a selector-like value into a selector on which combinator methods can be called
- Improved some error messages
- The outline and bibliography headings can now be styled with show-set rules
- Operations on numbers now produce an error instead of overflowing
## Bug fixes
- Fixed wrong linebreak before punctuation that follows inline equations, citations, and other elements
- Fixed a bug with [argument sinks](/docs/reference/foundations/arguments/)
- Fixed strokes with thickness zero
- Fixed hiding and show rules in math
- Fixed alignment in matrices
- Fixed some alignment bugs in equations
- Fixed grid cell alignment
- Fixed alignment of list marker and enum markers in presence of global alignment settings
- Fixed [path](/docs/reference/visualize/path/) closing
- Fixed compiler crash with figure references
- A single trailing line breaks is now ignored in math, just like in text
## Command line interface
- Font path and compilation root can now be set with the environment variables `TYPST_FONT_PATHS` and `TYPST_ROOT`
- The output of `typst fonts` now includes the embedded fonts
## Development
- Added instrumentation for debugging and optimization
- Added `--update` flag and `UPDATE_EXPECT` environment variable to update reference images for tests
- You can now run a specific subtest with `--subtest`
- Tests now run on multiple threads
## Contributors
docs/changelog/0.4.0.md
# 0.4.0
## Footnotes
- Implemented support for footnotes
- The [`footnote`](/docs/reference/model/footnote/) function inserts a footnote
- The [`footnote.entry`](/docs/reference/model/footnote/#definitions-entry) function can be used to customize the footnote listing
- The `"chicago-notes"` [citation style](/docs/reference/model/cite/#parameters-style) is now available
## Documentation
- Added a [Guide for LaTeX Users](/docs/guides/for-latex-users/)
- Now shows default values for optional arguments
- Added richer outlines in "On this Page"
- Added initial support for search keywords: "Table of Contents" will now find the [outline](/docs/reference/model/outline/) function. Suggestions for more keywords are welcome!
- Fixed issue with search result ranking
- Fixed many more small issues
## Math
- **Breaking change**: Alignment points (`&`) in equations now alternate between left and right alignment
- Added support for writing roots with Unicode: For example, `$root(x+y)$` can now also be written as `$√(x+y)$`
- Fixed uneven vertical [`attachment`](/docs/reference/math/attach/#functions-attach) alignment
- Fixed spacing on decorated elements (e.g., spacing around a [canceled](/docs/reference/math/cancel/) operator)
- Fixed styling for stretchable symbols
- Added `tack.r.double`, `tack.l.double`, `dotless.i` and `dotless.j` [symbols](/docs/reference/symbols/sym/)
- Fixed show rules on symbols (e.g. `show sym.tack: set text(blue)`)
- Fixed missing rename from `ast.op` to `ast` that should have been in the previous release
## Scripting
- Added function scopes: A function can now hold related definitions in its own scope, similar to a module. The new [`assert.eq`](/docs/reference/foundations/assert/#definitions-eq) function, for instance, is part of the [`assert`](/docs/reference/foundations/assert/) function's scope. Note that function scopes are currently only available for built-in functions.
- Added [`assert.eq`](/docs/reference/foundations/assert/#definitions-eq) and [`assert.ne`](/docs/reference/foundations/assert/#definitions-ne) functions for simpler equality and inequality assertions with more helpful error messages
- Exposed [list](/docs/reference/model/list/#definitions-item), [enum](/docs/reference/model/enum/#definitions-item), and [term list](/docs/reference/model/terms/#definitions-item) items in their respective functions' scope
- The `at` methods on [strings](/docs/reference/foundations/str/#definitions-at), [arrays](/docs/reference/foundations/array/#definitions-at), [dictionaries](/docs/reference/foundations/dictionary/#definitions-at), and [content](/docs/reference/foundations/content/#definitions-at) now support specifying a default value
- Added support for passing a function to [`replace`](/docs/reference/foundations/str/#definitions-replace) that is called with each match.
- Fixed [replacement](/docs/reference/foundations/str/#definitions-replace) strings: They are now inserted completely verbatim instead of supporting the previous (unintended) magic dollar syntax for capture groups
- Fixed bug with trailing placeholders in destructuring patterns
- Fixed bug with underscore in parameter destructuring
- Fixed crash with nested patterns and when hovering over an invalid pattern
- Better error messages when casting to an [integer](/docs/reference/foundations/int/) or [float](/docs/reference/foundations/float/) fails
## Text and Layout
- Implemented sophisticated CJK punctuation adjustment
- Disabled [overhang](/docs/reference/text/text/#parameters-overhang) for CJK punctuation
- Added basic translations for Traditional Chinese
- Fixed [alignment](/docs/reference/text/raw/#parameters-align) of text inside raw blocks (centering a raw block, e.g. through a figure, will now keep the text itself left-aligned)
- Added support for passing a array instead of a function to configure table cell [alignment](/docs/reference/model/table/#parameters-align) and [fill](/docs/reference/model/table/#parameters-fill) per column
- Fixed automatic figure [`kind`](/docs/reference/model/figure/#parameters-kind) detection
- Made alignment of [enum numbers](/docs/reference/model/enum/#parameters-number-align) configurable, defaulting to `end`
- Figures can now be made breakable with a show-set rule for blocks in figure
- Initial fix for smart quotes in RTL languages
## Export
- Fixed ligatures in PDF export: They are now copyable and searchable
- Exported PDFs now embed ICC profiles for images that have them
- Fixed export of strokes with zero thickness
## Web app
- Projects can now contain folders
- Added upload by drag-and-drop into the file panel
- Files from the file panel can now be dragged into the editor to insert them into a Typst file
- You can now copy-paste images and other files from your computer directly into the editor
- Added a button to resend confirmation email
- Added an option to invert preview colors in dark mode
- Added tips to the loading screen and the Help menu. Feel free to propose more!
- Added syntax highlighting for YAML files
- Allowed middle mouse button click on many buttons to navigate into a new tab
- Allowed more project names
- Fixed overridden Vim mode keybindings
- Fixed many bugs regarding file upload and more
## Miscellaneous Improvements
- Improved performance of counters, state, and queries
- Improved incremental parsing for more efficient recompilations
- Added support for `.yaml` extension in addition to `.yml` for bibliographies
- The CLI now emits escape codes only if the output is a TTY
- For users of the `typst` crate: The `Document` is now `Sync` again and the `World` doesn't have to be `'static` anymore
## Contributors
docs/changelog/0.5.0.md
# 0.5.0
## Text and Layout
- Added [`raw`](/docs/reference/text/raw/) syntax highlighting for many more languages
- Added support for Korean [numbering](/docs/reference/model/numbering/)
- Added basic i18n for a few more languages (NL, SV, DA)
- Improved line breaking for East Asian languages
- Expanded functionality of outline [`indent`](/docs/reference/model/outline/#parameters-indent) property
- Fixed footnotes in columns
- Fixed page breaking bugs with [footnotes](/docs/reference/model/footnote/)
- Fixed bug with handling of footnotes in lists, tables, and figures
- Fixed a bug with CJK punctuation adjustment
- Fixed a crash with rounded rectangles
- Fixed alignment of [`line`](/docs/reference/visualize/line/) elements
## Math
- **Breaking change:** The syntax rules for mathematical [attachments](/docs/reference/math/attach/#functions-attach) were improved: `$f^abs(3)$` now parses as `$f^(abs(3))$` instead of `$(f^abs)(3)$`. To disambiguate, add a space: `$f^zeta (3)$`.
- Added [forced size](/docs/reference/math/sizes/) commands for math (e.g., [`display`](/docs/reference/math/sizes/#functions-display))
- Added [`supplement`](/docs/reference/math/equation/#parameters-supplement) parameter to [`equation`](/docs/reference/math/equation/), used by [references](/docs/reference/model/ref/)
- New [symbols](/docs/reference/symbols/sym/): `bullet`, `xor`, `slash.big`, `sigma.alt`, `tack.r.not`, `tack.r.short`, `tack.r.double.not`
- Fixed a bug with symbols in matrices
- Fixed a crash in the [`attach`](/docs/reference/math/attach/#functions-attach) function
## Scripting
- Added new [`datetime`](/docs/reference/foundations/datetime/) type and [`datetime.today`](/docs/reference/foundations/datetime/#definitions-today) to retrieve the current date
- Added [`str.from-unicode`](/docs/reference/foundations/str/#definitions-from-unicode) and [`str.to-unicode`](/docs/reference/foundations/str/#definitions-to-unicode) functions
- Added [`fields`](/docs/reference/foundations/content/#definitions-fields) method on content
- Added `base` parameter to [`str`](/docs/reference/foundations/str/) function
- Added [`calc.exp`](/docs/reference/foundations/calc/#functions-exp) and [`calc.ln`](/docs/reference/foundations/calc/#functions-ln)
- Improved accuracy of [`calc.pow`](/docs/reference/foundations/calc/#functions-pow) and [`calc.log`](/docs/reference/foundations/calc/#functions-log) for specific bases
- Fixed [removal](/docs/reference/foundations/dictionary/#definitions-remove) order for dictionary
- Fixed `.at(default: ..)` for [strings](/docs/reference/foundations/str/#definitions-at) and [content](/docs/reference/foundations/content/#definitions-at)
- Fixed field access on styled elements
- Removed deprecated `calc.mod` function
## Command line interface
- Added PNG export via `typst compile source.typ output-\{n\}.png`. The output path must contain `\{n\}` if the document has multiple pages.
- Added `--diagnostic-format=short` for Unix-style short diagnostics
- Doesn't emit color codes anymore if stderr isn't a TTY
- Now sets the correct exit when invoked with a nonexistent file
- Now ignores UTF-8 BOM in Typst files
## Miscellaneous Improvements
- Improved errors for mismatched delimiters
- Improved error message for failed length comparisons
- Fixed a bug with images not showing up in Apple Preview
- Fixed multiple bugs with the PDF outline
- Fixed citations and other searchable elements in [`hide`](/docs/reference/layout/hide/)
- Fixed bugs with [reference supplements](/docs/reference/model/ref/#parameters-supplement)
- Fixed Nix flake
## Contributors
docs/changelog/0.6.0.md
# 0.6.0
## Package Management
- Typst now has built-in [package management](/docs/reference/scripting/#packages)
- You can import [published](https://typst.app/universe/) community packages or create and use [system-local](https://github.com/typst/packages#local-packages) ones
- Published packages are also supported in the web app
## Math
- Added support for optical size variants of glyphs in math mode
- Added argument to enable [`limits`](/docs/reference/math/attach/#functions-limits) conditionally depending on whether the equation is set in [`display`](/docs/reference/math/sizes/#functions-display) or [`inline`](/docs/reference/math/sizes/#functions-inline) style
- Added `gt.eq.slant` and `lt.eq.slant` symbols
- Increased precedence of factorials in math mode (`$1/n!$` works correctly now)
- Improved [underlines](/docs/reference/math/underover/#functions-underline) and [overlines](/docs/reference/math/underover/#functions-overline) in math mode
- Fixed usage of [`limits`](/docs/reference/math/attach/#functions-limits) function in show rules
- Fixed bugs with line breaks in equations
## Text and Layout
- Added support for alternating page [margins](/docs/reference/layout/page/#parameters-margin) with the `inside` and `outside` keys
- Added support for specifying the page [`binding`](/docs/reference/layout/page/#parameters-binding)
- Added [`to`](/docs/reference/layout/pagebreak/#parameters-to) argument to pagebreak function to skip to the next even or odd page
- Added basic i18n for a few more languages (TR, SQ, TL)
- Fixed bug with missing table row at page break
- Fixed bug with [underlines](/docs/reference/text/underline/)
- Fixed bug superfluous table lines
- Fixed smart quotes after line breaks
- Fixed a crash related to text layout
## Command line interface
- **Breaking change:** Added requirement for `--root`/`TYPST_ROOT` directory to contain the input file because it designates the _project_ root. Existing setups that use `TYPST_ROOT` to emulate package management should switch to [local packages](https://github.com/typst/packages#local-packages)
- **Breaking change:** Now denies file access outside of the project root
- Added support for local packages and on-demand package download
- Now watches all relevant files, within the root and all packages
- Now displays compilation time
## Miscellaneous Improvements
- Added [`outline.entry`](/docs/reference/model/outline/#definitions-entry) to customize outline entries with show rules
- Added some hints for error messages
- Added some missing syntaxes for [`raw`](/docs/reference/text/raw/) highlighting
- Improved rendering of rotated images in PNG export and web app
- Made [footnotes](/docs/reference/model/footnote/) reusable and referenceable
- Fixed bug with citations and bibliographies in [`locate`](/docs/reference/introspection/locate/)
- Fixed inconsistent tense in documentation
## Development
- Added [contribution guide](https://github.com/typst/typst/blob/main/CONTRIBUTING.md)
- Reworked `World` interface to accommodate for package management and make it a bit simpler to implement _(Breaking change for implementors)_
## Contributors
docs/changelog/0.7.0.md
# 0.7.0
## Text and Layout
- Added support for floating figures through the [`placement`](/docs/reference/model/figure/#parameters-placement) argument on the figure function
- Added support for arbitrary floating content through the [`float`](/docs/reference/layout/place/#parameters-float) argument on the place function
- Added support for loading `.sublime-syntax` files as highlighting [syntaxes](/docs/reference/text/raw/#parameters-syntaxes) for raw blocks
- Added support for loading `.tmTheme` files as highlighting [themes](/docs/reference/text/raw/#parameters-theme) for raw blocks
- Added _bounds_ option to [`top-edge`](/docs/reference/text/text/#parameters-top-edge) and [`bottom-edge`](/docs/reference/text/text/#parameters-bottom-edge) arguments of text function for tight bounding boxes
- Removed nonsensical top- and bottom-edge options, e.g. _ascender_ for the bottom edge **(Breaking change)**
- Added [`script`](/docs/reference/text/text/#parameters-script) argument to text function
- Added [`alternative`](/docs/reference/text/smartquote/#parameters-alternative) argument to smart quote function
- Added basic i18n for Japanese
- Added hyphenation support for `nb` and `nn` language codes in addition to `no`
- Fixed positioning of [placed elements](/docs/reference/layout/place/) in containers
- Fixed overflowing containers due to optimized line breaks
## Export
- Greatly improved export of SVG images to PDF. Many thanks to [@LaurenzV](https://github.com/LaurenzV) for their work on this.
- Added support for the alpha channel of RGBA colors in PDF export
- Fixed a bug with PPI (pixels per inch) for PNG export
## Math
- Improved layout of primes (e.g. in `$a'_1$`)
- Improved display of multi-primes (e.g. in `$a''$`)
- Improved layout of [roots](/docs/reference/math/roots/#functions-root)
- Changed relations to show attachments as [limits](/docs/reference/math/attach/#functions-limits) by default (e.g. in `$a ->^x b$`)
- Large operators and delimiters are now always vertically centered
- [Boxes](/docs/reference/layout/box/) in equations now sit on the baseline instead of being vertically centered by default. Notably, this does not affect [blocks](/docs/reference/layout/block/) because they are not inline elements.
- Added support for [weak spacing](/docs/reference/layout/h/#parameters-weak)
- Added support for OpenType character variants
- Added support for customizing the [math class](/docs/reference/math/class/) of content
- Fixed spacing around `.`, `\/`, and `...`
- Fixed spacing between closing delimiters and large operators
- Fixed a bug with math font weight selection
- Symbols and Operators **(Breaking changes)**
- Added `id`, `im`, and `tr` text [operators](/docs/reference/math/op/)
- Renamed `ident` to `equiv` with alias `eq.triple` and removed `ident.strict` in favor of `eq.quad`
- Renamed `ast.sq` to `ast.square` and `integral.sq` to `integral.square`
- Renamed `.eqq` modifier to `.equiv` (and `.neqq` to `.nequiv`) for `tilde`, `gt`, `lt`, `prec`, and `succ`
- Added `emptyset` as alias for `nothing`
- Added `lt.curly` and `gt.curly` as aliases for `prec` and `succ`
- Added `aleph`, `beth`, and `gimmel` as alias for `alef`, `bet`, and `gimel`
## Scripting
- Fields
- Added `abs` and `em` field to [lengths](/docs/reference/layout/length/)
- Added `ratio` and `length` field to [relative lengths](/docs/reference/layout/relative/)
- Added `x` and `y` field to [2d alignments](/docs/reference/layout/align/#parameters-alignment)
- Added `paint`, `thickness`, `cap`, `join`, `dash`, and `miter-limit` field to [strokes](/docs/reference/visualize/stroke/)
- Accessor and utility methods
- Added [`dedup`](/docs/reference/foundations/array/#definitions-dedup) method to arrays
- Added `pt`, `mm`, `cm`, and `inches` method to [lengths](/docs/reference/layout/length/)
- Added `deg` and `rad` method to [angles](/docs/reference/layout/angle/)
- Added `kind`, `hex`, `rgba`, `cmyk`, and `luma` method to [colors](/docs/reference/visualize/color/)
- Added `axis`, `start`, `end`, and `inv` method to [directions](/docs/reference/layout/stack/#parameters-dir)
- Added `axis` and `inv` method to [alignments](/docs/reference/layout/align/#parameters-alignment)
- Added `inv` method to [2d alignments](/docs/reference/layout/align/#parameters-alignment)
- Added `start` argument to [`enumerate`](/docs/reference/foundations/array/#definitions-enumerate) method on arrays
- Added [`color.mix`](/docs/reference/visualize/color/#definitions-mix) function
- Added `mode` and `scope` arguments to [`eval`](/docs/reference/foundations/eval/) function
- Added [`bytes`](/docs/reference/foundations/bytes/) type for holding large byte buffers
- Added [`encoding`](/docs/reference/data-loading/read/#parameters-encoding) argument to read function to read a file as bytes instead of a string
- Added [`image.decode`](/docs/reference/visualize/image/#definitions-decode) function for decoding an image directly from a string or bytes
- Added [`bytes`](/docs/reference/foundations/bytes/) function for converting a string or an array of integers to bytes
- Added [`array`](/docs/reference/foundations/array/) function for converting bytes to an array of integers
- Added support for converting bytes to a string with the [`str`](/docs/reference/foundations/str/) function
## Tooling and Diagnostics
- Added support for compiler warnings
- Added warning when compilation does not converge within five attempts due to intense use of introspection features
- Added warnings for empty emphasis (`__` and `**`)
- Improved error message for invalid field assignments
- Improved error message after single `#`
- Improved error message when a keyword is used where an identifier is expected
- Fixed parameter autocompletion for functions that are in modules
- Import autocompletion now only shows the latest package version until a colon is typed
- Fixed autocompletion for dictionary key containing a space
- Fixed autocompletion for `for` loops
## Command line interface
- Added `typst query` subcommand to execute a [query](/docs/reference/introspection/query/#command-line-queries) on the command line
- The `--root` and `--font-paths` arguments cannot appear in front of the command anymore **(Breaking change)**
- Local and cached packages are now stored in directories of the form `\{namespace\}/\{name\}/\{version\}` instead of `\{namespace\}/\{name\}-\{version\}` **(Breaking change)**
- Now prioritizes explicitly given fonts (via `--font-paths`) over system and embedded fonts when both exist
- Fixed `typst watch` not working with some text editors
- Fixed displayed compilation time (now includes export)
## Miscellaneous Improvements
- Added [`bookmarked`](/docs/reference/model/heading/#parameters-bookmarked) argument to heading to control whether a heading becomes part of the PDF outline
- Added [`caption-pos`](/docs/reference/model/figure/#definitions-caption-position) argument to control the position of a figure's caption
- Added [`metadata`](/docs/reference/introspection/metadata/) function for exposing an arbitrary value to the introspection system
- Fixed that a [`state`](/docs/reference/introspection/state/) was identified by the pair `(key, init)` instead of just its `key`
- Improved indent logic of [enumerations](/docs/reference/model/enum/). Instead of requiring at least as much indent as the end of the marker, they now require only one more space indent than the start of the marker. As a result, even long markers like `12.` work with just 2 spaces of indent.
- Fixed bug with indent logic of [`raw`](/docs/reference/text/raw/) blocks
- Fixed a parsing bug with dictionaries
## Development
- Extracted parser and syntax tree into `typst-syntax` crate
- The `World::today` implementation of Typst dependents may need fixing if they have the same [bug](https://github.com/typst/typst/issues/1842) that the CLI world had
## Contributors
docs/changelog/0.8.0.md
# 0.8.0
## Scripting
- Plugins (thanks to [@astrale-sharp](https://github.com/astrale-sharp) and [@arnaudgolfouse](https://github.com/arnaudgolfouse))
- Typst can now load [plugins](/docs/reference/foundations/plugin/) that are compiled to WebAssembly
- Anything that can be compiled to WebAssembly can thus be loaded as a plugin
- These plugins are fully encapsulated (no access to file system or network)
- Plugins can be shipped as part of [packages](/docs/reference/scripting/#packages)
- Plugins work just the same in the web app
- Types are now first-class values **(Breaking change)**
- A [type](/docs/reference/foundations/type/) is now itself a value
- Some types can be called like functions (those that have a constructor), e.g. [`int`](/docs/reference/foundations/int/) and [`str`](/docs/reference/foundations/str/)
- Type checks are now of the form `type(10) == int` instead of the old `type(10) == "integer"`. [Compatibility](/docs/reference/foundations/type/#compatibility) with the old way will remain for a while to give package authors time to upgrade, but it will be removed at some point.
- Methods are now syntax sugar for calling a function scoped to a type, meaning that `"hello".len()` is equivalent to `str.len("hello")`
- Added support for [`import`](/docs/reference/scripting/#modules) renaming with `as`
- Added a [`duration`](/docs/reference/foundations/duration/) type
- Added support for [CBOR](/docs/reference/data-loading/cbor/) encoding and decoding
- Added encoding and decoding functions from and to bytes for data formats: [`json.decode`](/docs/reference/data-loading/json/#definitions-decode), [`json.encode`](/docs/reference/data-loading/json/#definitions-encode), and similar functions for other formats
- Added [`array.intersperse`](/docs/reference/foundations/array/#definitions-intersperse) function
- Added [`str.rev`](/docs/reference/foundations/str/#definitions-rev) function
- Added `calc.tau` constant
- Made [bytes](/docs/reference/foundations/bytes/) joinable and addable
- Made [`array.zip`](/docs/reference/foundations/array/#definitions-zip) function variadic
- Fixed bug with [`eval`](/docs/reference/foundations/eval/) when the `mode` was set to `"math"`
- Fixed bug with [`ends-with`](/docs/reference/foundations/str/#definitions-ends-with) function on strings
- Fixed bug with destructuring in combination with break, continue, and return
- Fixed argument types of [hyperbolic functions](/docs/reference/foundations/calc/#functions-cosh), they don't allow angles anymore **(Breaking change)**
- Renamed some color methods: `rgba` becomes `to-rgba`, `cmyk` becomes `to-cmyk`, and `luma` becomes `to-luma` **(Breaking change)**
## Export
- Added SVG export (thanks to [@Enter-tainer](https://github.com/Enter-tainer))
- Fixed bugs with PDF font embedding
- Added support for page labels that reflect the [page numbering](/docs/reference/layout/page/#parameters-numbering) style in the PDF
## Text and Layout
- Added [`highlight`](/docs/reference/text/highlight/) function for highlighting text with a background color
- Added [`polygon.regular`](/docs/reference/visualize/polygon/#definitions-regular) function for drawing a regular polygon
- Added support for tabs in [`raw`](/docs/reference/text/raw/) elements alongside [`tab-width`](/docs/reference/text/raw/#parameters-tab-size) parameter
- The layout engine now tries to prevent "runts" (final lines consisting of just a single word)
- Added Finnish translations
- Added hyphenation support for Polish
- Improved handling of consecutive smart quotes of different kinds
- Fixed vertical alignments for [`number-align`](/docs/reference/layout/page/#parameters-number-align) argument on page function **(Breaking change)**
- Fixed weak pagebreaks after counter updates
- Fixed missing text in SVG when the text font is set to "New Computer Modern"
- Fixed translations for Chinese
- Fixed crash for empty text in show rule
- Fixed leading spaces when there's a linebreak after a number and a comma
- Fixed placement of floating elements in columns and other containers
- Fixed sizing of block containing just a single box
## Math
- Added support for [augmented matrices](/docs/reference/math/mat/#parameters-augment)
- Removed support for automatic matching of fences like `|` and `||` as there were too many false positives. You can use functions like [`abs`](/docs/reference/math/lr/#functions-abs) or [`norm`](/docs/reference/math/lr/#functions-norm) or an explicit [`lr`](/docs/reference/math/lr/#functions-lr) call instead. **(Breaking change)**
- Fixed spacing after number with decimal point in math
- Fixed bug with primes in subscript
- Fixed weak spacing
- Fixed crash when text within math contains a newline
## Tooling and Diagnostics
- Added hints when trying to call a function stored in a dictionary without extra parentheses
- Fixed hint when referencing an equation without numbering
- Added more details to some diagnostics (e.g. when SVG decoding fails)
## Command line interface
- Added `typst update` command for self-updating the CLI (thanks to [@jimvdl](https://github.com/jimvdl))
- Added download progress indicator for packages and updates
- Added `--format` argument to explicitly specify the output format
- The CLI now respects proxy configuration through environment variables and has a new `--cert` option for setting a custom CA certificate
- Fixed crash when field wasn't present and `--one` is passed to `typst query`
## Miscellaneous Improvements
- Added [Page Setup Guide](/docs/guides/page-setup/)
- Added [`figure.caption`](/docs/reference/model/figure/#definitions-caption) function that can be used for simpler figure customization (**Breaking change** because `it.caption` now renders the full caption with supplement in figure show rules and manual outlines)
- Moved `caption-pos` argument to `figure.caption` function and renamed it to `position` **(Breaking change)**
- Added [`separator`](/docs/reference/model/figure/#definitions-caption-separator) argument to `figure.caption` function
- Added support for combination of and/or and before/after [selectors](/docs/reference/foundations/selector/)
- Packages can now specify a [minimum compiler version](https://github.com/typst/packages#package-format) they require to work
- Fixed parser bug where method calls could be moved onto their own line for `#let` expressions in markup **(Breaking change)**
- Fixed bugs in sentence and title case conversion for bibliographies
- Fixed supplements for alphanumeric and author-title bibliography styles
- Fixed off-by-one error in APA bibliography style
## Development
- Made `Span` and `FileId` more type-safe so that all error conditions must be handled by `World` implementors
## Contributors
docs/changelog/0.9.0.md
# 0.9.0
## Bibliography management
- New bibliography engine based on [CSL](https://citationstyles.org/) (Citation Style Language). Ships with about 100 commonly used citation styles and can load custom `.csl` files.
- Added new [`form`](/docs/reference/model/cite/#parameters-form) argument to the `cite` function to produce different forms of citations (e.g. for producing a citation suitable for inclusion in prose)
- The [`cite`](/docs/reference/model/cite/) function now takes only a single label/key instead of allowing multiple. Adjacent citations are merged and formatted according to the citation style's rules automatically. This works both with the reference syntax and explicit calls to the `cite` function. **(Breaking change)**
- The `cite` function now takes a [label](/docs/reference/foundations/label/) instead of a string **(Breaking change)**
- Added [`full`](/docs/reference/model/bibliography/#parameters-full) argument to bibliography function to print the full bibliography even if not all works were cited
- Bibliography entries can now contain Typst equations (wrapped in `$..$` just like in markup), this works both for `.yaml` and `.bib` bibliographies
- The hayagriva YAML format was improved. See its [changelog](https://github.com/typst/hayagriva/blob/main/CHANGELOG.md) for more details. **(Breaking change)**
- A few bugs with `.bib` file parsing were fixed
- Removed `brackets` argument of `cite` function in favor of `form`
## Visualization
- Gradients and colors (thanks to [@Dherse](https://github.com/Dherse))
- Added support for [gradients](/docs/reference/visualize/gradient/) on shapes and text
- Supports linear, radial, and conic gradients
- Added support for defining colors in more color spaces, including [Oklab](/docs/reference/visualize/color/#definitions-oklab), [Linear RGB(A)](/docs/reference/visualize/color/#definitions-linear-rgb), [HSL](/docs/reference/visualize/color/#definitions-hsl), and [HSV](/docs/reference/visualize/color/#definitions-hsv)
- Added [`saturate`](/docs/reference/visualize/color/#definitions-saturate), [`desaturate`](/docs/reference/visualize/color/#definitions-desaturate), and [`rotate`](/docs/reference/visualize/color/#definitions-rotate) functions on colors
- Added [`color.map`](/docs/reference/visualize/color/#predefined-color-maps) module with predefined color maps that can be used with gradients
- Rename `kind` function on colors to [`space`](/docs/reference/visualize/color/#definitions-space)
- Removed `to-rgba`, `to-cmyk`, and `to-luma` functions in favor of a new [`components`](/docs/reference/visualize/color/#definitions-components) function
- Improved rendering of [rectangles](/docs/reference/visualize/rect/) with corner radius and varying stroke widths
- Added support for properly clipping [boxes](/docs/reference/layout/box/#parameters-clip) and [blocks](/docs/reference/layout/block/#parameters-clip) with a border radius
- Added `background` parameter to [`overline`](/docs/reference/text/overline/), [`underline`](/docs/reference/text/underline/), and [`strike`](/docs/reference/text/strike/) functions
- Fixed inaccurate color embedding in PDFs
- Fixed ICC profile handling for images embedded in PDFs
## Text and Layout
- Added support for automatically adding proper [spacing](/docs/reference/text/text/#parameters-cjk-latin-spacing) between CJK and Latin text (enabled by default)
- Added support for automatic adjustment of more CJK punctuation
- Added [`quote`](/docs/reference/model/quote/) element for inserting inline and block quotes with optional attributions
- Added [`raw.line`](/docs/reference/text/raw/#definitions-line) element for customizing the display of individual lines of raw text, e.g. to add line numbers while keeping proper syntax highlighting
- Added support for per-side [inset](/docs/reference/model/table/#parameters-inset) customization to table function
- Added Hungarian and Romanian translations
- Added support for Czech hyphenation
- Added support for setting custom [smart quotes](/docs/reference/text/smartquote/)
- The default [figure separator](/docs/reference/model/figure/#definitions-caption-separator) now reacts to the currently set language and region
- Improved line breaking of links / URLs (especially helpful for bibliographies with many URLs)
- Improved handling of consecutive hyphens in justification algorithm
- Fixed interaction of justification and hanging indent
- Fixed a bug with line breaking of short lines without spaces when justification is enabled
- Fixed font fallback for hyphen generated by hyphenation
- Fixed handling of word joiner and other no-break characters during hyphenation
- Fixed crash when hyphenating after an empty line
- Fixed line breaking of composite emoji like 🏳️🌈
- Fixed missing text in some SVGs
- Fixed font fallback in SVGs
- Fixed behavior of [`to`](/docs/reference/layout/pagebreak/#parameters-to) argument on `pagebreak` function
- Fixed `set align(..)` for equations
- Fixed spacing around [placed](/docs/reference/layout/place/) elements
- Fixed coalescing of [`above`](/docs/reference/layout/block/#parameters-above) and [`below`](/docs/reference/layout/block/#parameters-below) spacing if given in em units and the font sizes differ
- Fixed handling of `extent` parameter of [`underline`](/docs/reference/text/underline/), [`overline`](/docs/reference/text/overline/), and [`strike`](/docs/reference/text/strike/) functions
- Fixed crash for [floating placed elements](/docs/reference/layout/place/#parameters-float) with no specified vertical alignment
- Partially fixed a bug with citations in footnotes
## Math
- Added `gap` argument for [`vec`](/docs/reference/math/vec/#parameters-gap), [`mat`](/docs/reference/math/mat/#parameters-gap), and [`cases`](/docs/reference/math/cases/#parameters-gap) function
- Added `size` argument for [`abs`](/docs/reference/math/lr/#functions-abs), [`norm`](/docs/reference/math/lr/#functions-norm), [`floor`](/docs/reference/math/lr/#functions-floor), [`ceil`](/docs/reference/math/lr/#functions-ceil), and [`round`](/docs/reference/math/lr/#functions-round) functions
- Added [`reverse`](/docs/reference/math/cases/#parameters-reverse) parameter to cases function
- Added support for multinomial coefficients to [`binom`](/docs/reference/math/binom/) function
- Removed `rotation` argument on [`cancel`](/docs/reference/math/cancel/) function in favor of a new and more flexible `angle` argument **(Breaking change)**
- Added `wide` constant, which inserts twice the spacing of `quad`
- Added `csch` and `sech` [operators](/docs/reference/math/op/)
- `↼`, `⇀`, `↔`, and `⟷` can now be used as [accents](/docs/reference/math/accent/)
- Added `integral.dash`, `integral.dash.double`, and `integral.slash` [symbols](/docs/reference/symbols/sym/)
- Added support for specifying negative indices for [augmentation](/docs/reference/math/mat/#parameters-augment) lines to position the line from the back
- Fixed default color of matrix [augmentation](/docs/reference/math/mat/#parameters-augment) lines
- Fixed attachment of primes to inline expressions
- Math content now respects the text [baseline](/docs/reference/text/text/#parameters-baseline) setting
## Performance
- Fixed a bug related to show rules in templates which would effectively disable incremental compilation in affected documents
- Micro-optimized code in several hot paths, which brings substantial performance gains, in particular in incremental compilations
- Improved incremental parsing, which affects the whole incremental compilation pipeline
- Added support for incremental parsing in the CLI
- Added support for incremental SVG encoding during PDF export, which greatly improves export performance for documents with many SVG
## Tooling and Diagnostics
- Improved autocompletion for variables that are in-scope
- Added autocompletion for package imports
- Added autocompletion for [labels](/docs/reference/foundations/label/)
- Added tooltip that shows which variables a function captures (when hovering over the equals sign or arrow of the function)
- Diagnostics are now deduplicated
- Improved diagnostics when trying to apply unary `+` or `-` to types that only support binary `+` and `-`
- Error messages now state which label or citation key isn't present in the document or its bibliography
- Fixed a bug where function argument parsing errors were shadowed by function execution errors (e.g. when trying to call [`array.sorted`](/docs/reference/foundations/array/#definitions-sorted) and passing the key function as a positional argument instead of a named one).
## Export
- Added support for configuring the document's creation [`date`](/docs/reference/model/document/#parameters-date). If the `date` is set to `auto` (the default), the PDF's creation date will be set to the current date and time.
- Added support for configuring document [`keywords`](/docs/reference/model/document/#parameters-keywords)
- Generated PDFs now contain PDF document IDs
- The PDF creator tool metadata now includes the Typst version
## Web app
- Added version picker to pin a project to an older compiler version (with support for Typst 0.6.0+)
- Fixed desyncs between editor and compiler and improved overall stability
- The app now continues to highlight the document when typing while the document is being compiled
## Command line interface
- Added support for discovering fonts through fontconfig
- Now clears the screen instead of resetting the terminal
- Now automatically picks correct file extension for selected output format
- Now only regenerates images for changed pages when using `typst watch` with PNG or SVG export
## Miscellaneous Improvements
- Added [`version`](/docs/reference/foundations/version/) type and `sys.version` constant specifying the current compiler version. Can be used to gracefully support multiple versions.
- The U+2212 MINUS SIGN is now used when displaying a numeric value, in the [`repr`](/docs/reference/foundations/repr/) of any numeric value and to replace a normal hyphen in text mode when before a digit. This improves, in particular, how negative integer values are displayed in math mode.
- Added support for specifying a default value instead of failing for `remove` function in [array](/docs/reference/foundations/array/#definitions-remove) and [dictionary](/docs/reference/foundations/dictionary/#definitions-remove)
- Simplified Page Setup Guide examples
- Switched the documentation from using the word "hashtag" to the word "hash" where appropriate
- Added support for [`array.zip`](/docs/reference/foundations/array/#definitions-zip) without any further arguments
- Fixed crash when a plugin tried to read out of bounds memory
- Fixed crashes when handling infinite [lengths](/docs/reference/layout/length/)
- Fixed introspection (mostly bibliography) bugs due to weak page break close to the end of the document
## Development
- Extracted `typst::ide` into separate `typst_ide` crate
- Removed a few remaining `'static` bounds on `&dyn World`
- Removed unnecessary dependency, which reduces the binary size
- Fixed compilation of `typst` by itself (without `typst-library`)
- Fixed warnings with Nix flake when using `lib.getExe`
## Contributors
docs/changelog/earlier.md
# Earlier
## March 28, 2023
- **Breaking changes:**
- Enumerations now require a space after their marker, that is, `1.ok` must now be written as `1. ok`
- Changed default style for [term lists](/docs/reference/model/terms/): Does not include a colon anymore and has a bit more indent
- Command line interface
- Added `--font-path` argument for CLI
- Embedded default fonts in CLI binary
- Fixed build of CLI if `git` is not installed
- Miscellaneous improvements
- Added support for disabling [matrix](/docs/reference/math/mat/) and [vector](/docs/reference/math/vec/) delimiters. Generally with `#set math.mat(delim: none)` or one-off with `$mat(delim: #none, 1, 2; 3, 4)$`.
- Added [`separator`](/docs/reference/model/terms/#parameters-separator) argument to term lists
- Added [`round`](/docs/reference/math/lr/#functions-round) function for equations
- Numberings now allow zeros. To reset a counter, you can write `#counter(..).update(0)`
- Added documentation for `page()` and `position()` methods on [`location`](/docs/reference/introspection/location/) type
- Added symbols for double, triple, and quadruple dot accent
- Added smart quotes for Norwegian Bokmål
- Added Nix flake
- Fixed bibliography ordering in IEEE style
- Fixed parsing of decimals in math: `$1.2/3.4$`
- Fixed parsing of unbalanced delimiters in fractions: `$1/(2 (x)$`
- Fixed unexpected parsing of numbers as enumerations, e.g. in `1.2`
- Fixed combination of page fill and header
- Fixed compiler crash if [`repeat`](/docs/reference/layout/repeat/) is used in page with automatic width
- Fixed [matrices](/docs/reference/math/mat/) with explicit delimiter
- Fixed [`indent`](/docs/reference/model/terms/#parameters-indent) property of term lists
- Numerous documentation fixes
- Links in bibliographies are now affected by link styling
- Fixed hovering over comments in web app
## March 21, 2023
- Reference and bibliography management
- [Bibliographies](/docs/reference/model/bibliography/) and [citations](/docs/reference/model/cite/) (currently supported styles are APA, Chicago Author Date, IEEE, and MLA)
- You can now [reference](/docs/reference/model/ref/) sections, figures, formulas, and works from the bibliography with `@label`
- You can make an element referenceable with a label:
- `= Introduction <intro>`
- `$ A = pi r^2 $ <area>`
- Introspection system for interactions between different parts of the document
- [`counter`](/docs/reference/introspection/counter/) function
- Access and modify counters for pages, headings, figures, and equations
- Define and use your own custom counters
- Time travel: Find out what the counter value was or will be at some other point in the document (e.g. when you're building a list of figures, you can determine the value of the figure counter at any given figure).
- Counters count in layout order and not in code order
- [`state`](/docs/reference/introspection/state/) function
- Manage arbitrary state across your document
- Time travel: Find out the value of your state at any position in the document
- State is modified in layout order and not in code order
- [`query`](/docs/reference/introspection/query/) function
- Find all occurrences of an element or a label, either in the whole document or before/after some location
- Link to elements, find out their position on the pages and access their fields
- Example use cases: Custom list of figures or page header with current chapter title
- [`locate`](/docs/reference/introspection/locate/) function
- Determines the location of itself in the final layout
- Can be accessed to get the `page` and `x`, `y` coordinates
- Can be used with counters and state to find out their values at that location
- Can be used with queries to find elements before or after its location
- New [`measure`](/docs/reference/layout/measure/) function
- Measure the layouted size of elements
- To be used in combination with the new `style` function that lets you generate different content based on the style context something is inserted into (because that affects the measured size of content)
- Exposed content representation
- Content is not opaque anymore
- Content can be compared for equality
- The tree of content elements can be traversed with code
- Can be observed in hover tooltips or with [`repr`](/docs/reference/foundations/repr/)
- New [methods](/docs/reference/foundations/content/) on content: `func`, `has`, `at`, and `location`
- All optional fields on elements are now settable
- More uniform field names (`heading.title` becomes `heading.body`, `list.items` becomes `list.children`, and a few more changes)
- Further improvements
- Added [`figure`](/docs/reference/model/figure/) function
- Added [`numbering`](/docs/reference/math/equation/#parameters-numbering) parameter on equation function
- Added [`numbering`](/docs/reference/layout/page/#parameters-numbering) and [`number-align`](/docs/reference/layout/page/#parameters-number-align) parameters on page function
- The page function's [`header`](/docs/reference/layout/page/#parameters-header) and [`footer`](/docs/reference/layout/page/#parameters-footer) parameters do not take functions anymore. If you want to customize them based on the page number, use the new [`numbering`](/docs/reference/layout/page/#parameters-numbering) parameter or [`counter`](/docs/reference/introspection/counter/) function instead.
- Added [`footer-descent`](/docs/reference/layout/page/#parameters-footer-descent) and [`header-ascent`](/docs/reference/layout/page/#parameters-header-ascent) parameters
- Better default alignment in header and footer
- Fixed Arabic vowel placement
- Fixed PDF font embedding issues
- Renamed `math.formula` to [`math.equation`](/docs/reference/math/equation/)
- Font family must be a named argument now: `#set text(font: "..")`
- Added support for [hanging indent](/docs/reference/model/par/#parameters-hanging-indent)
- Renamed paragraph `indent` to [`first-line-indent`](/docs/reference/model/par/#parameters-first-line-indent)
- More accurate [logarithm](/docs/reference/foundations/calc/#functions-log) when base is `2` or `10`
- Improved some error messages
- Fixed layout of [`terms`](/docs/reference/model/terms/) list
- Web app improvements
- Added template gallery
- Added buttons to insert headings, equations, raw blocks, and references
- Jump to the source of something by clicking on it in the preview panel (works for text, equations, images, and more)
- You can now upload your own fonts and use them in your project
- Hover debugging and autocompletion now takes multiple files into account and works in show rules
- Hover tooltips now automatically collapse multiple consecutive equal values
- The preview now automatically scrolls to the right place when you type
- Links are now clickable in the preview area
- Toolbar, preview, and editor can now all be hidden
- Added autocompletion for raw block language tags
- Added autocompletion in SVG files
- New back button instead of four-dots button
- Lots of bug fixes
## February 25, 2023
- Font changes
- New default font: Linux Libertine
- New default font for raw blocks: DejaVu Sans Mono
- New default font for math: Book weight of New Computer Modern Math
- Lots of new math fonts available
- Removed Latin Modern fonts in favor of New Computer Modern family
- Removed unnecessary smallcaps fonts which are already accessible through the corresponding main font and the [`smallcaps`](/docs/reference/text/smallcaps/) function
- Improved default spacing for headings
- Added [`panic`](/docs/reference/foundations/panic/) function
- Added [`clusters`](/docs/reference/foundations/str/#definitions-clusters) and [`codepoints`](/docs/reference/foundations/str/#definitions-codepoints) methods for strings
- Support for multiple authors in [`set document`](/docs/reference/model/document/#parameters-author)
- Fixed crash when string is accessed at a position that is not a char boundary
- Fixed semicolon parsing in `#var ;`
- Fixed incremental parsing when inserting backslash at end of `#"abc"`
- Fixed names of a few font families (including Noto Sans Symbols and New Computer Modern families)
- Fixed autocompletion for font families
- Improved incremental compilation for user-defined functions
## February 15, 2023
- [Box](/docs/reference/layout/box/) and [block](/docs/reference/layout/block/) have gained `fill`, `stroke`, `radius`, and `inset` properties
- Blocks may now be explicitly sized, fixed-height blocks can still break across pages
- Blocks can now be configured to be [`breakable`](/docs/reference/layout/block/#parameters-breakable) or not
- [Numbering style](/docs/reference/model/enum/#parameters-numbering) can now be configured for nested enums
- [Markers](/docs/reference/model/list/#parameters-marker) can now be configured for nested lists
- The [`eval`](/docs/reference/foundations/eval/) function now expects code instead of markup and returns an arbitrary value. Markup can still be evaluated by surrounding the string with brackets.
- PDFs generated by Typst now contain XMP metadata
- Link boxes are now disabled in PDF output
- Tables don't produce small empty cells before a pagebreak anymore
- Fixed raw block highlighting bug
## February 12, 2023
- Shapes, images, and transformations (move/rotate/scale/repeat) are now block-level. To integrate them into a paragraph, use a [`box`](/docs/reference/layout/box/) as with other elements.
- A colon is now required in an "everything" show rule: Write `show: it => ..` instead of `show it => ..`. This prevents intermediate states that ruin your whole document.
- Non-math content like a shape or table in a math formula is now centered vertically
- Support for widow and orphan prevention within containers
- Support for [RTL](/docs/reference/text/text/#parameters-dir) in lists, grids, and tables
- Support for explicit `auto` sizing for boxes and shapes
- Support for fractional (i.e. `1fr`) widths for boxes
- Fixed bug where columns jump to next page
- Fixed bug where list items have no leading
- Fixed relative sizing in lists, squares and grid auto columns
- Fixed relative displacement in [`place`](/docs/reference/layout/place/) function
- Fixed that lines don't have a size
- Fixed bug where `set document(..)` complains about being after content
- Fixed parsing of `not in` operation
- Fixed hover tooltips in math
- Fixed bug where a heading show rule may not contain a pagebreak when an outline is present
- Added [`baseline`](/docs/reference/layout/box/#parameters-baseline) property on [`box`](/docs/reference/layout/box/)
- Added [`tg`](/docs/reference/math/op/) and [`ctg`](/docs/reference/math/op/) operators in math
- Added delimiter setting for [`cases`](/docs/reference/math/cases/) function
- Parentheses are now included when accepting a function autocompletion
## February 2, 2023
- Merged text and math symbols, renamed a few symbols (including `infty` to `infinity` with the alias `oo`)
- Fixed missing italic mappings
- Math italics correction is now applied properly
- Parentheses now scale in `$zeta(x/2)$`
- Fixed placement of large root index
- Fixed spacing in `$abs(-x)$`
- Fixed inconsistency between text and identifiers in math
- Accents are now ignored when positioning superscripts
- Fixed vertical alignment in matrices
- Fixed `text` set rule in `raw` show rule
- Heading and list markers now parse consistently
- Allow arbitrary math directly in content
## January 30, 2023
[Go to the announcement blog post.](https://typst.app/blog/2023/january-update)
- New expression syntax in markup/math
- Blocks cannot be directly embedded in markup anymore
- Like other expressions, they now require a leading hash
- More expressions available with hash, including literals (`#"string"`) as well as field access and method call without space: `#emoji.face`
- New import syntax
- `#import "module.typ"` creates binding named `module`
- `#import "module.typ": a, b` or `#import "module.typ": *` to import items
- `#import emoji: face, turtle` to import from already bound module
- New symbol handling
- Removed symbol notation
- Symbols are now in modules: `sym`, `emoji`, and `math`
- Math module also reexports all of `sym`
- Modified through field access, still order-independent
- Unknown modifiers are not allowed anymore
- Support for custom symbol definitions with `symbol` function
- Symbols now listed in documentation
- New `math` module
- Contains all math-related functions
- Variables and function calls directly in math (without hash) access this module instead of the global scope, but can also access local variables
- Can be explicitly used in code, e.g. `#set math.vec(delim: "[")`
- Delimiter matching in math
- Any opening delimiters matches any closing one
- When matched, they automatically scale
- To prevent scaling, escape them
- To forcibly match two delimiters, use `lr` function
- Line breaks may occur between matched delimiters
- Delimiters may also be unbalanced
- You can also use the `lr` function to scale the brackets (or just one bracket) to a specific size manually
- Multi-line math with alignment
- The `\` character inserts a line break
- The `&` character defines an alignment point
- Alignment points also work for underbraces, vectors, cases, and matrices
- Multiple alignment points are supported
- More capable math function calls
- Function calls directly in math can now take code expressions with hash
- They can now also take named arguments
- Within math function calls, semicolons turn preceding arguments to arrays to support matrices: `$mat(1, 2; 3, 4)$`
- Arbitrary content in math
- Text, images, and other arbitrary content can now be embedded in math
- Math now also supports font fallback to support e.g. CJK and emoji
- More math features
- New text operators: `op` function, `lim`, `max`, etc.
- New matrix function: `mat`
- New n-ary roots with `root` function: `$root(3, x)$`
- New under- and overbraces, -brackets, and -lines
- New `abs` and `norm` functions
- New shorthands: `[|`, `|]`, and `||`
- New `attach` function, overridable attachments with `script` and `limit`
- Manual spacing in math, with `h`, `thin`, `med`, `thick` and `quad`
- Symbols and other content may now be used like a function, e.g. `$zeta(x)$`
- Added Fira Math font, removed Noto Sans Math font
- Support for alternative math fonts through `#show math.formula: set text("Fira Math")`
- More library improvements
- New `calc` module, `abs`, `min`, `max`, `even`, `odd` and `mod` moved there
- New `message` argument on `assert` function
- The `pairs` method on dictionaries now returns an array of length-2 arrays instead of taking a closure
- The method call `dict.at("key")` now always fails if `"key"` doesn't exist Previously, it was allowed in assignments. Alternatives are `dict.key = x` and `dict.insert("key", x)`.
- Smarter editor functionality
- Autocompletion for local variables
- Autocompletion for methods available on a value
- Autocompletion for symbols and modules
- Autocompletion for imports
- Hover over an identifier to see its value(s)
- Further editor improvements
- New Font menu with previews
- Single projects may now be shared with share links
- New dashboard experience if projects are shared with you
- Keyboard Shortcuts are now listed in the menus and there are more of them
- New Offline indicator
- Tooltips for all buttons
- Improved account protection
- Moved Status indicator into the error list button
- Further fixes
- Multiple bug fixes for incremental parser
- Fixed closure parameter capturing
- Fixed tons of math bugs
- Bugfixes for performance, file management, editing reliability
- Added redirection to the page originally navigated to after signin
docs/changelog/index.md
# Changelog
Learn what has changed in the latest Typst releases and move your documents forward. This section documents all changes to Typst since its initial public release.
## Versions
- [Typst 0.14.2](/docs/changelog/0.14.2/)
- [Typst 0.14.1](/docs/changelog/0.14.1/)
- [Typst 0.14.0](/docs/changelog/0.14.0/)
- [Typst 0.13.1](/docs/changelog/0.13.1/)
- [Typst 0.13.0](/docs/changelog/0.13.0/)
- [Typst 0.12.0](/docs/changelog/0.12.0/)
- [Typst 0.11.1](/docs/changelog/0.11.1/)
- [Typst 0.11.0](/docs/changelog/0.11.0/)
- [Typst 0.10.0](/docs/changelog/0.10.0/)
- [Typst 0.9.0](/docs/changelog/0.9.0/)
- [Typst 0.8.0](/docs/changelog/0.8.0/)
- [Typst 0.7.0](/docs/changelog/0.7.0/)
- [Typst 0.6.0](/docs/changelog/0.6.0/)
- [Typst 0.5.0](/docs/changelog/0.5.0/)
- [Typst 0.4.0](/docs/changelog/0.4.0/)
- [Typst 0.3.0](/docs/changelog/0.3.0/)
- [Typst 0.2.0](/docs/changelog/0.2.0/)
- [Typst 0.1.0](/docs/changelog/0.1.0/)
- [Earlier](/docs/changelog/earlier/)
docs/guides/accessibility.md
# Accessibility
Making a document accessible means that it can be used and understood by everyone. That not only includes people with permanent or temporary disabilities, but also those with different devices or preferences. To underscore why accessibility is important, consider that people might read your document in more contexts than you expected:
- A user may print the document on paper
- A user may read your document on a phone, with reflow in their PDF reader enabled
- A user may have their computer read the document back to them
- A user may ask artificial intelligence to summarize your document for them
- A user may convert your document to another file format like HTML that is more accessible to them
To accommodate all of these people and scenarios, you should design your document for **Universal Access.** Universal Access is a simple but powerful principle: instead of retrofitting a project for accessibility after the fact, design from the beginning to work for the broadest possible range of people and situations. This will improve the experience for all readers!
Typst can help you to create accessible files that read well on screen readers, look good even when reflowed for a different screen size, and pass automated accessibility checkers. However, to create accessible files, you will have to keep some rules in mind. This guide will help you learn what issues impact accessibility, how to design for Universal Access, and what tools Typst gives you to accomplish this. Much of the guidance here applies to all export targets, but the guide focuses on PDF export. Notable differences to HTML export are called out.
## Basics of Accessibility
Accessible files allow software to do more with them than to just render them. Instead, your computer can understand what each part of the document is supposed to represent and use this information to present the document to the user.
This information is consumed by different software to provide access. When exporting a PDF from Typst, the _PDF viewer_ (sometimes also called a reader) will display the document's pages just as you designed them with Typst's preview. Some people rely on _Assistive Technology_ (AT) such as screen readers, braille displays, screen magnifiers, and more for consuming PDF files. In that case, the semantic information in the file is used to adapt the contents of a file into spoken or written text, or into a different visual representation. Other users will make the PDF viewer reflow the file to create a layout similar to a web page: The content will fit the viewport's width and scroll continuously. Finally, some users will repurpose the PDF into another format, for example plain text for ingestion into a Large Language Model (LLM) or HTML. A special form of repurposing is copy and paste where users use the clipboard to extract content from a file to use it in another application.
Accessibility support differs based on viewer and AT. Some combinations work better than others. In our testing, [Adobe Acrobat](https://www.adobe.com/acrobat.html) paired with [NVDA](https://www.nvaccess.org/download/) on Windows and [VoiceOver](https://support.apple.com/guide/voiceover/welcome/mac) on macOS provided the richest accessibility support. Paired with HTML export, browsers provide a more consistent baseline of accessibility when compared to PDF readers.
Only PDF and HTML export produce accessible files. Neither PNGs nor SVGs are accessible on their own. Both formats can be used in an accessible larger work by providing a [textual representation](#textual-representations).
## Maintaining semantics
To add correct semantic information for AT and repurposing to a file, Typst needs to know what semantic role each part of the file plays. For example, this means that a heading in a compiled PDF should not just be text that is large and bold. Instead, the file should contain the explicit information (known as a _tag_) that a particular text makes up a heading. A screen reader will then announce it as a heading and allow the user to navigate between headings.
If you are using Typst idiomatically, using the built-in markup and elements, Typst automatically adds tags with rich semantic information to your files. Let's take a look at two code examples:
```typst
// ❌ Don't do this
#text(
size: 16pt,
weight: "bold",
)[Heading]
```
```typst
// ✅ Do this
#show heading: set text(size: 16pt)
= Heading
```
Both of these examples look the same. They both contain the text "Heading" in boldface, sized at 16 point. However, only the second example is accessible. By using the heading markup, Typst knows that the semantic meaning of this text is that of a heading and can propagate that information to the final PDF. In the first example, it just knows that it should use boldface and larger type on otherwise normal text and cannot make the assumption that you meant that to be a heading and not a stylistic choice or some other element like a quote.
Using semantics is not limited to headings. Here are a few more examples for elements you should use:
- Use underscores / [`emph`](/docs/reference/model/emph/) instead of the [`text`](/docs/reference/text/text/) function to make text emphasized
- Use stars / [`strong`](/docs/reference/model/strong/) instead of the text function to make text carry strong emphasis
- Use lists ([`list`](/docs/reference/model/list/), [`enum`](/docs/reference/model/enum/), [`terms`](/docs/reference/model/terms/)) instead of normal text with newlines when working with itemized or ordered content
- Use [`quote`](/docs/reference/model/quote/) for inline and block quotes
- Use the built-in [`bibliography`](/docs/reference/model/bibliography/) and [`cite`](/docs/reference/model/cite/) functions instead of manually printing a bibliography
- Use labels and [`ref`](/docs/reference/model/ref/) or `@references` to reference other parts of your documents instead of just typing out a reference
- Use the [`caption` argument of the `figure` element](/docs/reference/model/figure/#definitions-caption) to provide captions instead of adding them as text below the function call
If you want to style the default appearance of an element, do not replace it with your own custom function. Instead, use [set](/docs/reference/styling/#set-rules), show-set, and [show rules](/docs/reference/styling/#show-rules) to customize its appearance. Here is an example on how you can change how strong emphasis looks in your document:
```typst
// Change how text inside of strong emphasis looks
#show strong: set text(tracking: 0.2em, fill: blue, weight: "black")
When setting up your tents, *never forget* to secure the pegs.
```
The show-set rule completely changes the default appearance of the [`strong`](/docs/reference/model/strong/) element, but its semantic meaning will be preserved. If you need even more customization, you can provide show rules with fully custom layout code and Typst will still retain the semantic purpose of the element.
## Reading order
For AT to read the contents of a document in the right order and for repurposing applications, accessible files must make their reading order explicit. This is because the logical reading order can differ from layout order. Floating figures are a common example for such a difference: A figure may be relevant to a paragraph in the center of a page but appear at the top or bottom edge. In non-accessible files, PDF readers and AT have to assume that layout order equals the logical reading order, often leading to confusion for AT users. When the reading order is well-defined, screen readers read a footnote or a floating figure immediately where it makes sense.
Fortunately, Typst markup already implies a single reading order. You can assume that Typst documents will read in the order that content has been placed in the markup. For most documents, this is good enough. However, when using the [`place`](/docs/reference/layout/place/) and [`move`](/docs/reference/layout/move/) function or [floating figures](/docs/reference/model/figure/#parameters-placement), you must pay special attention to place the function call at an appropriate spot in the logical reading order in markup, even if this has no consequence on the layout. Just ask yourself where you would want a screen reader to announce the content that you are placing.
## Layout containers
Typst provides some layout containers like [`grid`](/docs/reference/layout/grid/), [`stack`](/docs/reference/layout/stack/), [`box`](/docs/reference/layout/box/), [`columns`](/docs/reference/layout/columns/), and [`block`](/docs/reference/layout/block/) to visually arrange your content. None of these containers come with any semantic meaning attached. Typst will conserve some of these containers during PDF reflow while other containers will be discarded.
When designing for Universal Access, you need to be aware that AT users often cannot view the visual layout that the container creates. Instead, AT will just read its contents, so it is best to think about these containers as transparent in terms of accessibility. For example, a grid's contents will just be read out flatly, in the order that you have added the cells in the source code. If the layout you created is merely visual and decorative, this is fine. If, however, the layout carries semantic meaning that is apparent to a sighted user viewing the file in a regular PDF reader, it is not accessible. Instead, create an alternative representation of your content that leverages text or wrap your container in the [`figure`](/docs/reference/model/figure/) element to provide an alternative textual description.
Do not use the grid container to represent tabular data. Instead, use [`table`](/docs/reference/model/table/). Tables are accessible to AT users: their AT will allow them to navigate the table two-dimensionally. Tables are conserved during reflow and repurposing. When creating tables, use the [`table.header`](/docs/reference/model/table/#definitions-header) and [`table.footer`](/docs/reference/model/table/#definitions-footer) elements to mark up the semantic roles of individual rows. The table documentation contains an [accessibility section](/docs/reference/model/table/#accessibility) with more information on how to make your tables accessible. Keep in mind that while AT users can access tables, it is often cumbersome to them: Tables are optimized for visual consumption. Being read the contents of a set of cells while having to recall their row and column creates additional mental load. Consider making the core takeaway of the table accessible as text or a caption elsewhere.
Likewise, if you use functions like [`rotate`](/docs/reference/layout/rotate/), [`scale`](/docs/reference/layout/scale/), and [`skew`](/docs/reference/layout/skew/), take care that this transformation either has no semantic meaning or that the meaning is available to AT users elsewhere, i.e. in figure [alt text](#textual-representations) or a caption.
## Artifacts
Some things on a page have no semantic meaning and are irrelevant to the content of a document. We call these items _artifacts._ Artifacts are hidden from AT and repurposing and will vanish during reflow. Here are some examples for artifacts:
- The hyphens inserted by automatic hyphenation at the end of a line
- The headers and footers on each page
- A purely decorative page background image
In general, every element on a page must either have some way for AT to announce it or be an artifact for a document to be considered accessible.
Typst automatically tags many layout artifacts such as headers, footers, page back- and foregrounds, and automatic hyphenation as artifacts. However, if you'd like to add purely decorative content to your document, you can use the [`pdf.artifact`](/docs/reference/pdf/artifact/) function to mark a piece of content as an artifact. If you are unsure if you should mark an element as an artifact, ask yourself this: Would it be purely annoying if a screen reader announced the element to you? Then, it may be an artifact. If, instead, it could be useful to have it announced, then it is not an artifact.
For technical reasons, once in an artifact, content cannot become semantic again. To stack artifacts and semantic contents, use [`place`](/docs/reference/layout/place/) to move the contents on top of one another.
Please note that Typst will mark shapes and paths like [`square`](/docs/reference/visualize/square/) and [`circle`](/docs/reference/visualize/circle/) as artifacts while their content will remain semantically relevant and accessible to AT. If your shapes have a semantic meaning, please wrap them in the [`figure`](/docs/reference/model/figure/) element to provide an alternative textual description.
## Color use and contrast
Universal Access not only means that your documents works with AT, reflow, and repurposing, but also that visual access is possible to everyone, including people with impaired eyesight. Not only does aging often come with worse sight, a significant portion of people have problems differentiating color: About 8% of men and 0.5% of women are color blind.
This means that color must not be the only way you make information accessible to sighted users in your documents. As an example, consider a stacked bar chart with multiple colored segments per bar. Our example shows a chart of the domestic energy production in Germany by kind[1](#1). In the picture, you can see the chart as it would normally appear and a simulation of how it would appear to people with deuteranopia-type color blindness. You can see that the two pairs of the first and last segment both look blue and the center pair looks yellow-ish. The first challenge for the colorblind user is thus to make out the boundary of the "Renewable" and "Fossil Fuels" bar. Then, they must keep track of which bar is which by only their order, adding to their mental load. A way to make this chart even less accessible would be to make the order of segments not match their order in the legend.
How can we improve the chart? First, make sure that no information is solely communicated through color use. One possible way to do this by adding a pattern to each bar. Then, we can help the user make out the boundaries of each segment by adding a high-contrast border. Then, our chart could look something like this:
This could be further improved by choosing colors that are differentiable to people afflicted by common colorblindness types. You could also iterate on the design by choosing two-tone patterns, aligning them to the bars, or changing font use.
You can check your design in the web app by using the built-in color blindness simulator. To use it, open the "View" menu and select the desired mode in the "Simulate color blindness" menu. You can also use other tools on the web to [simulate the color perception of various color blindnesses](https://daltonlens.org/colorblindness-simulator) if you are not using our web app.
Also consider the color contrast between background and foreground. For example, when you are using light gray text for footnotes, they could become hard to read. Another situation that often leads to low contrast is superimposing text on an image.
In our example, we can see two designs for callout boxes. Because these boxes aim to help the user avoid a hazard, it is paramount that they can actually read them. However, in the first box, the background is fairly light, making it hard to make out the box. Worse, the red text is difficult to read on the light red background. The text has a 2.8:1 contrast ratio, failing the bar of 4.5:1 contrast the Web Content Accessibility Guidelines (WCAG) set. Likewise, the box has an 1.4:1 contrast ratio with the white page background, falling short of the 3:1 threshold for graphical objects.
Colors in the second example have been adjusted to meet WCAG AA color contrast thresholds. It should be markedly easier to read the text in the box, even if you have good vision!
There are [tools to compare how much contrast a pair of colors has](https://webaim.org/resources/contrastchecker/) as foreground and background. The most common one is the WCAG color contrast ratio. For a given font size, a color pair may either fail the test, get to the AA level, or reach the higher AAA level. Aim for at least AA contrast for all your color pairings.
| Content | AA Ratio | AAA Ratio |
| --- | --- | --- |
| Large text (≥18pt, or bold and ≥14pt) | 3:1 | 4.5:1 |
| Small text | 4.5:1 | 7:1 |
| Non-text content | 3:1 | 3:1 |
Note that common accessibility frameworks like WCAG make an exception for purely decorative text and logos: Due to their graphic character, they can have contrast ratios that fail to achieve AA contrast ratio.
## Textual representations
To support AT use and some repurposing workflows, all elements with a semantic meaning must have a textual representation. Think about it in terms of Universal Access: If an item is not an [artifact](#artifacts), it has a semantic meaning. If, however, AT cannot ingest the item, the full semantic meaning of a document is not available to AT users. Hence, to provide Universal Access, use the mechanisms built into Typst to provide alternative representations.
When you add an image, be sure to use the [`alt` argument of the image function](/docs/reference/visualize/image/#parameters-alt) to describe what's visible in the image. This alternative description (sometimes known as alt text) should describe the gist of the image: Think about how you would describe the image to a friend if you called them on the phone. To write good alternative descriptions, consider the context in which the image appears:
```typst
#image("heron.jpg", alt: "?")
Herons have feet with interdigital
webbing, allowing for good mobility
when swimming, and wings that span
up to 2.3 m.
```
What could be a good alternative description for [this image](https://commons.wikimedia.org/wiki/File:Reiher_im_Flug.jpg)? Let's consider a few examples for what _not_ to do:
- `"Image of a heron"` ❌ The screen reader will already announce the image on its own, so saying this is an image is redundant. In this example, the AT user would hear "Image, Image of a heron".
- `"A bird"` ❌ The alternative description is not specific enough. For example, it is relevant to a user that the image depicts a heron and both its feet and wings are visible.
- `"Gray heron in flight. Picture by Makasch1966 on Wikimedia Commons, CC Attribution 4.0 International license"` ❌ The alternative description should not include details not visible in the image, such as attribution, jokes, or metadata. Keep in mind that it is not accessible to sighted users. That information belongs elsewhere.
- `"Gray heron flying low, heading from the right to left. Its feet are extended and slightly point downwards, touching a blurred horizon where a dark forest becomes visible. The bird's wings are extended and arc upwards. There are out-of-focus branches visible in the lower left corner of the image."` ❌ The alternative description is too verbose. Use your discretion and determine how important the image is to the content. Think about how long a sighted user would realistically look at the image; your alt text should take about the same effort to 'consume.' For example, the anatomic description contained above could be appropriate for a longer discussion in a zoology textbook while the compositional information is useful when writing about photography. The context the example image comes with is relatively short, so write a more brief description.
Instead, in the given example, you could use this alternative text:
- `"Heron in flight with feet and wings spread"` ✅ This alternative description describes the image, is relevant to the context, and matches its brevity.
There are resources available on the web [to learn more about writing good alternative descriptions](https://webaim.org/techniques/alttext/). The requirement to add alternative text to images applies to all image formats. Typst does not currently retain the tags of a PDF image in the compiled document, even if the PDF image file on its own was accessible.
Do not use images of text; likewise, do not use the path operations to draw text manually. Typst will not be able to process text in any images to make it accessible in the same way that native text is. There is one exception to this rule: Use an image of text when the appearance of the text is essential to the semantic meaning of the document and cannot be reproduced with Typst natively. In that case, you must describe both the textual content and the essential visual characteristics in the alternative description.
Like the image function, the figure function has a [`alt` attribute](/docs/reference/model/figure/#parameters-alt). When you use this attribute, many screen readers and other AT will not announce the content inside of the figure and instead just read the alternative description. Your alternative description must be comprehensive enough so that the AT user does not need to access the body of the figure. Only use the alternative description if the content of the figure are not otherwise accessible. For example, do not use the `alt` attribute of a figure if it contains a `table` element, but do use it if you used shapes within that come with a semantic meaning. If you specify both `alt` and `caption`, both will be read by AT. When your figure contains an image, set the alternative description on the [image itself](/docs/reference/visualize/image/#parameters-alt), not on the figure. Do not set both, as the image description would be overridden by the figure description.
```typst
#figure(
alt: "Star with a blue outline",
curve(
stroke: blue,
curve.move((25pt, 0pt)),
curve.line((10pt, 50pt)),
curve.line((50pt, 20pt)),
curve.line((0pt, 20pt)),
curve.line((40pt, 50pt)),
curve.close(),
),
)
```
Finally, you can specify an alternative description on math using [`math.equation`](/docs/reference/math/equation/). Describe your formula as if read out loud in natural language. Currently, adding an alternative description is required for accessible math for all export formats. Not adding an alternative description for your formula will result in a failure of PDF/UA-1 export. In the future, Typst will automatically make math accessible in HTML and PDF 2.0 by leveraging MathML technology.
```typst
#math.equation(
alt: "a squared plus b squared equals c squared",
block: true,
$ a^2 + b^2 = c^2 $,
)
```
Another element that represents itself as text are links. It is best to avoid non-descriptive link texts such as _here_ or _go._ These link texts also hurt Search Engine Optimization (SEO) if that is a consideration for your document. Instead, try to have the link contain text about where it is pointing to. Note that, unless you are aiming for the highest level of accessibility, it is also okay if the link itself is not descriptive but its purpose can be understood from the content immediately surrounding it.
## Natural Language
In order for screen readers to pronounce your document correctly and translation software to work properly, you must indicate in which natural language your document is written. Use the rule [`#set text(lang: "..")`](/docs/reference/text/text/#parameters-lang) at the very start of your document or your template's capability to set a language. If you do not do so, Typst will assume that your content is in English. The natural language you choose not only impacts accessibility, but also how Typst will apply hyphenation, what typesetting conventions are applied, the labels of figures and references, and, in the web app, what language is used for spellcheck.
If you are using a language with significant variation between regions, such as Chinese or English, also use [the `region` argument](/docs/reference/text/text/#parameters-region). For example, Chinese as it is spoken in Hong Kong would look like this:
```typst
#set text(lang: "zh", region: "HK")
```
To specify your language, use ISO 639 codes. For regions, use the [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) code. ISO 639 contains three variants, one for two-letter language codes like "de" for German [(ISO 639-1)](https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes) and two for three-letter language codes like "deu" ([ISO 639-2](https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes) and [ISO 639-3](https://en.wikipedia.org/wiki/List_of_ISO_639-3_codes)). If your language has a two-letter ISO 639-1 code, always prefer using that. ISO 639-2 and 639-3 share most codes, but there are some differences. When your language code differs between the two standards, use ISO 639-2 when exporting to PDF 1.7 (Typst's default) and below and ISO 639-3 for export to PDF 2.0 and HTML.
There are three special language codes defined by both ISO 639-2 and ISO 639-3 that you can use when providing a normal language code is difficult:
- `zxx` for text that is not in a natural language
- `und` for text for which you cannot determine the natural language
- `mis` for text in languages that have not been assigned a language code
If your document contains text in multiple languages, you can use the text function or a scoped text set rule to enclose instances of other languages:
```typst
This is #text(lang: "fr")[français].
#[
#set text(lang: "es")
Este es un fragmento más largo
del texto en español.
]
```
## Document Title and Headings
Titling your document makes it easier to retrieve it and to navigate between it and other documents, both for AT users and regular users of PDF viewers. This is why accessibility standards such as WCAG and PDF/UA require you to set a machine-readable title for your document.
To do so in Typst, place this set rule in your document before any content:
```typst
#set document(title: "GlorboCorp Q1 2023 Revenue Report")
```
This will set the [title in the document's metadata](/docs/reference/model/document/#parameters-title) and in the title bar of the PDF viewer or web browser. If this results in an error when using a template, consider whether your template may provide an alternative way to set the document title.
Most likely, you will also want to include the title visibly in your document. To do so, use the [`title`](/docs/reference/model/title/) element. When you add a call to the title element without any arguments, it will print the contents of what you set as the document's title. Alternatively, you can customize the title by passing content as the positional body argument. Do not use the title element more than once in your document.
Never use a heading for your document title; instead, use the title element. Should you have experience with HTML, it is important to remember that the semantics of the heading element in Typst differ from HTML headings. It is encouraged to use multiple first-level headings for section headings in Typst documents. When exporting to HTML, a [title](/docs/reference/model/title/) will be serialized as a `h1` tag while a [first-level heading](/docs/reference/model/heading/#parameters-level) will be serialized as a `h2` tag. In PDF export, the title and headings will be correctly tagged based on the PDF version targeted.
It is important that the sequence of headings you use is sequential: Never skip a heading level when going deeper. This means that a third-level heading must be followed by a heading of level four or lower, but never a heading of level five or higher.
```typst
// ❌ Don't do this:
= First level heading
=== Third level heading
```
Note that in order to pass the [automated accessibility check in Adobe Acrobat](https://helpx.adobe.com/acrobat/using/create-verify-pdf-accessibility.html#Bookmarks), documents with 21 pages or more must contain outlined headings.
## Accessibility Standards and Legislation
Typst can help you to assert that your document is accessible by checking it against international standards. For PDF export, there are multiple standards for accessible files, most notably the PDF/UA standard. Its first part (PDF/UA-1) is already supported by Typst while support for the second part (PDF/UA-2) is planned for the future. Below, you can find an explanation of all relevant standards:
- **Tagged PDF:** Tagged PDFs contain machine-readable data about the semantic structure of a document that AT can parse. Typst will write Tagged PDFs by default, but keep in mind that Typst can only write appropriate tags if it knows about the semantic structure of your document. Refer to the Section [_Maintaining semantics_](#maintaining-semantics) to learn how to use Typst's elements to communicate semantics. To provide Universal Access, you are also responsible to provide textual representation of non-text content yourself.
- **PDF/UA-1:** The PDF/UA standard explains how to write a PDF 1.7 file optimized for Universal Access. It implies Tagged PDF, enforces alternative descriptions for images and mathematics, requires a document title, and introduces rules how document contents like tables should be structured. If you are following this guide, you are already avoiding most of the compiler errors that can occur during PDF/UA-1 export.
- **PDF/UA-2:** There is also the more recent part PDF/UA-2 that targets PDF 2.0 files. It improves accessibility for mathematics and some semantic elements. Support for PDF/UA-2 not yet available in Typst, but planned.
- **Well Tagged PDF (WTPDF):** This is an industry standard that is very similar to PDF/UA-2. Like PDF/UA-2, it is not currently supported by Typst. Originally, it was drafted because both parts of the PDF/UA specification were only available at a high cost from the International Standards Organization. Hence, [WTPDF](https://pdfa.org/wtpdf/) was designed so that all conforming files can also declare conformance with PDF/UA-2. By now, [both parts of the PDF/UA specification are available free of charge](https://pdfa.org/sponsored-standards/), decreasing the relevance of WTPDF.
- **PDF/A-1a:** The PDF/A standard describes how to produce PDF files that are well-suited for archival. Parts one to three of the PDF/A standard feature multiple conformance levels. The strictest conformance level A contains rules for accessibility as only files meeting those rules remain usable to the broadest range of people in the far future. Level A implies conformance with Tagged PDF and forces you to provide alternative descriptions for images. Other PDF/A rules not relating to accessibility, e.g. about transparency, colors, and more also apply. This part of the PDF/A standard is based on the outdated PDF 1.4 specification. Only use it if your venue requires it or if you need a very compatible file. Otherwise, PDF/UA-1 and the second and third part of PDF/A provide better alternatives.
- **PDF/A-2a** and **PDF/A-3a:** Like the first part of PDF/A, these standards focus on creating files suitable for archival and long-term storage. Both of these standards target the newer PDF version 1.7 instead of PDF 1.4. Here too, the strictest conformance level A contains rules for accessibility. In addition to the rules in PDF/A-1a, these standards disallow the use of characters in the [Unicode Private Use Area](https://en.wikipedia.org/wiki/Private_Use_Areas) whose meaning is not universally defined. Improvements over PDF/A-1 include the ability to use transparency and better reflow. When choosing between these two parts of the PDF/A standard, choose PDF/A-2a unless you need to [attach](/docs/reference/pdf/attach/) other files. Note that conformance level A has been removed from PDF/A-4 in favor of the dedicated PDF/UA standard.
The [PDF reference page](/docs/reference/pdf/#pdf-standards) contains more information about each supported standard. To enable either PDF/UA, PDF/A-2a, or PDF/A-3a, use the [appropriate flag in the CLI](/docs/reference/pdf/#command-line) or use the export dropdown and click on PDF in the web app. At the moment, you must choose between PDF/A and PDF/UA. For accessibility-focused documents, we recommend the latter.
When you select one of these standards for PDF export, Typst will detect if you are in violation of their rules and fail the export with a descriptive error message. For the strictest accessibility check currently available, choose PDF/UA-1. Do not disable tagging unless you have a good reason, as tags provide a baseline of accessibility across all documents you export.
Maybe you already noticed that some of the factors that go into Universal Access are hard to check automatically. For example, Typst will currently not automatically check that your color contrasts are sufficient or whether the configured natural language matches the actual natural language (although the amount of spellcheck errors should provide a hint if you are using the web app). There are two international standards that address some of these human factors in more detail:
- The **Web Content Accessibility Guidelines (WCAG)**: Designed by the W3C, a big international consortium behind the technologies that power the internet, WCAG describes how to make a web site accessible. All of these rules are applicable to Typst's HTML output, and many of them apply to its PDF output. WCAG separates its rules into the three levels A, AA, and AAA. It is recommended that normal documents aim for AA. If you have high standards for Universal Access, you can also consider AAA Success Criteria. However, Typst does not yet expose all PDF features needed for AAA compliance, e.g. an AT-accessible way to define expansions for abbreviations.
- The **European Norm EN 301 549**: Its Section 9 describes how to create accessible websites and its Section 10 describes what rules apply to non-web documents, including PDFs created by Typst. It points out which WCAG clauses are also applicable to PDFs. Conformance with this standard is a good start for complying with EU and national accessibility laws.
Keep in mind that in order to conform with EN 301 549 and the relevant WCAG provisions, your document must be tagged. If you aim for conformance, we strongly suggest using PDF/UA-1 for export to automate many of the checks for the success criteria within.
Many territories have accessibility legislation that requires you to create accessible files under some circumstances. Here are only some of them:
- **European Accessibility Act (EAA, EU 2019/882)**: This regulation applies to e-books, consumer banking services, e-commerce services, and more. It requires the files distributed in these applications to be accessible.
- **Americans with Disabilities Act (ADA)**: The Department of Justice will [require public sector organizations to provide files](https://www.ada.gov/law-and-regs/regulations/title-ii-2010-regulations/) in accordance to WCAG under Title II of the ADA by 2026. Likewise, [private organizations can be held liable](https://www.boia.org/blog/the-robles-v.-dominos-settlement-and-why-it-matters) for inaccessible digital services under the ADA and state law.
Using this guide can help you reach compliance with either regulation.
## Testing for Accessibility
In order to test whether your PDF document is accessible, you can use automated tools and manual testing. Some standards like PDF/UA and PDF/A can be checked exclusively through automated tools, while some rules in WCAG and other standards require manual checks. Many of the automatable checks are automatically passed by Typst when Tagged PDF is enabled. For many other automatable checks, you can enable PDF/UA-1 export so that Typst will run them instead. Automated tools can only provide a baseline of accessibility. For truly Universal Access, it is best if you try the document yourself with AT.
Here is a list of automated checkers to try to test for conformance:
- **veraPDF:** This open-source tool can check if your PDF file conforms to the parts of the PDF/A and PDF/UA standards it declared conformance with. Use this tool if you have chosen one of these standards during export. Failures are considered bugs in Typst and should be [reported on GitHub](https://github.com/typst/typst/issues).
- **PDF Accessibility Checker (PAC):** The freeware PAC checks whether your document complies with PDF/UA and WCAG rules. When you receive a hard error in the PDF/UA tab, this is considered a bug in Typst and should be [reported on GitHub](https://github.com/typst/typst/issues). Warnings in the PDF/UA and Quality tabs may either be bugs, problems in your document, or neither. Check on the [Forum](https://forum.typst.app/) or on [Discord](https://discord.gg/2uDybryKPe) if you are unsure. Errors and warnings in the WCAG tab indicate problems with your document.
- **Accessibility Check in Adobe Acrobat Pro:** The accessibility checker in the paid version of Adobe Acrobat checks all PDF documents for problems. Instead of checking compliance with a well-known international or industry standard, Adobe has created their own suite of tests. Because the rules behind these tests sometimes contradict international standards like PDF/UA, some of Acrobat's checks are expected to fail for Typst documents[2](#2). Other checks, such as the contrast check are useful and indicate problems with your document.
When doing manual checking, you can start with a checklist. If your organization places emphasis on accessibility, they will sometimes have their own list. In absence of one, you can try lists by universities such as [Universität Bremen (in English)](https://www.uni-bremen.de/fileadmin/user_upload/universitaet/Digitale_Transformation/Projekt_BALLON/Checklisten/2._Auflage_englisch/Checklist_for_accessible_PDF_ENG-US_ver2.pdf) or governments such as in [Canada](https://a11y.canada.ca/en/pdf-accessibility-checklist/) or by the [US Social Security Administration](https://www.ssa.gov/accessibility/checklists/PDF_508_Compliance_Checklist.pdf). Although these checklists differ in verbosity, they all cover the most essential manual checks. Many of the technical checks in them can be skipped if you choose PDF/UA-1 export in Typst. If unsure which checklist to use, choose one from an organization culturally similar to yours.
However, to reach the highest standard of accessibility for widely circulated documents, consider checking your document with AT. Although there are many AT products and PDF viewers, it is typically sufficient to test a single combination. Which is best differs depending on your operating system:
- Windows: Test with [Adobe Acrobat](https://www.adobe.com/acrobat.html) and [NVDA](https://www.nvaccess.org/download/). NVDA is free, open-source software. A free version of Acrobat is available.
- macOS: Test with [Adobe Acrobat](https://www.adobe.com/acrobat.html) and [VoiceOver](https://support.apple.com/guide/voiceover/welcome/mac). VoiceOver is the screen reader that is built into macOS and other Apple platforms.
- Linux: Test with [Evince](https://wiki.gnome.org/Apps/Evince/) or [Okular](https://okular.kde.org/) and [Orca](https://orca.gnome.org). All three tools are free, open-source software. However, AT support across Linux platforms lags behind what is available on Windows and macOS. Likewise, Evince and Okular have less accessibility support than Acrobat. We strongly suggest testing with Acrobat instead.
When first getting into testing, consider completing the interactive training program your screen reader offers, if any. Building confidence with a screen reader helps you experience your document like a full-time screen reader user. When checking your document, check that it not only makes all the same information accessible that is available to a sighted user, but also that it is easy to navigate. The experience your users will have will vary based on the pairing of PDF viewer and AT they use.
## Limits and considerations for export formats
Even when you design your document with accessibility in mind, you should be aware of the limitations of your export format. Fundamentally, AT support for PDF files is more difficult to implement than for other formats such as HTML. PDF was conceived in 1993 to accurately render print documents on a computer. Accessibility features were first added with PDF 1.4 in 2001, and improved in PDF 1.5 (2003) and PDF 2.0 (2017). By contrast, HTML offers a richer semantic model and more flexibility, so AT support in browsers generally surpasses what is possible in PDF viewers.
Also keep in mind that PDF files are mostly static. This allows you to disregard many WCAG and EN 301 549 rules designed for interactive content and multimedia. However, the lack of interactivity also makes it more difficult for users to customize a document's layout to their needs.
For example, [WCAG Success Criterion 1.4.12](https://www.w3.org/WAI/WCAG21/Understanding/text-spacing.html) (codified in Clause 10.1.4.12 of EN 301 549) prescribes that a user must be able to increase character, letter, line, and paragraph spacing to very wide values. This benefits users with reduced vision or dyslexia. The Success Criterion does not require you to design your document with these layout parameters. Instead, it only requires a mechanism through which users can increase these parameters when reading the document. For HTML files, it is easy to comply with this Success Criterion because the browser lets the user override these spacing parameters on a page. For PDF, the situation is more nuanced: Theoretically, Typst adds tags and attributes designed for reflow to a file. A PDF reader, when reflowing, could allow its user to increase spacings beyond what is codified in these tags. In practice, we are not aware of a PDF viewer with this feature. Instead, this Success Criterion can be satisfied by repurposing the PDF into a HTML file and opening it in a browser.
In practice, even if your file is technically compliant, you cannot expect your users to know about these workarounds. Therefore, if you are aiming to meet the highest standards of Universal Access, consider distributing an HTML version of your document alongside your PDF. Export this file directly using Typst's [HTML export](/docs/reference/html/) (in preview). Even though HTML export will not conserve many aspects of your visual layout, it will produce a file that leverages semantic HTML and technologies like [Digital Publishing ARIA](https://www.w3.org/TR/dpub-aria-1.1/) to provide Universal Access. It will be of a higher quality than a PDF file repurposed to HTML.
Finally, keep in mind that PDFs are designed for print. Hence, you should not assume that interactive features like links are available to users who chose to print your document.
As mentioned above, files created by PNG and SVG export are not accessible.
[^1]: Dataset from the German Federal Statistics Authority (Statistisches Bundesamt, Destatis). ["Bruttostromerzeugung nach Energieträgern in Deutschland ab 1990"](https://www.destatis.de/DE/Themen/Branchen-Unternehmen/Energie/Erzeugung/bar-chart-race.html), 2025, available under the _Data licence Germany – attribution – version 2.0._
[^2]: For example, when using footnotes, the check "Lbl and LBody must be children of LI" in the "List" section is expected to fail.
docs/guides/for-latex-users.md
# For LaTeX Users
This page is a good starting point if you have used LaTeX before and want to try out Typst. We will explore the main differences between these two systems from a user perspective. Although Typst is not built upon LaTeX and has a different syntax, you will learn how to use your LaTeX skills to get a head start.
Just like LaTeX, Typst is a markup-based typesetting system: You compose your document in a text file and mark it up with commands and other syntax. Then, you use a compiler to typeset the source file into a PDF. However, Typst also differs from LaTeX in several aspects: For one, Typst uses more dedicated syntax (like you may know from Markdown) for common tasks. Typst's commands are also more principled: They all work the same, so unlike in LaTeX, you just need to understand a few general concepts instead of learning different conventions for each package. Moreover Typst compiles faster than LaTeX: Compilation usually takes milliseconds, not seconds, so the web app and the compiler can both provide instant previews.
In the following, we will cover some of the most common questions a user switching from LaTeX will have when composing a document in Typst. If you prefer a step-by-step introduction to Typst, check out our [tutorial](/docs/tutorial/).
## Installation
You have two ways to use Typst: In [our web app](https://typst.app/signup/) or by [installing the compiler](https://github.com/typst/typst/releases) on your computer. When you use the web app, we provide a batteries-included collaborative editor and run Typst in your browser, no installation required.
If you choose to use Typst on your computer instead, you can download the compiler as a single, small binary which any user can run, no root privileges required. Unlike popular LaTeX distributions such as TeX Live, packages are downloaded when you first use them and then cached locally, keeping your Typst installation lean. You can use your own editor and decide where to store your files with the local compiler.
## How do I create a new, empty document?
That's easy. You just create a new, empty text file (the file extension is `.typ`). No boilerplate is needed to get started. Simply start by writing your text. It will be set on an empty A4-sized page. If you are using the web app, click "+ Empty document" to create a new project with a file and enter the editor. [Paragraph breaks](/docs/reference/model/parbreak/) work just as they do in LaTeX, just use a blank line.
```typst
Hey there!
Here are two paragraphs. The
output is shown to the right.
```
If you want to start from an preexisting LaTeX document instead, you can use [Pandoc](https://pandoc.org) to convert your source code to Typst markup. This conversion is also built into our web app, so you can upload your `.tex` file to start your project in Typst.
## How do I create section headings, emphasis, ...?
LaTeX uses the command `\section` to create a section heading. Nested headings are indicated with `\subsection`, `\subsubsection`, etc. Depending on your document class, there is also `\part` or `\chapter`.
In Typst, [headings](/docs/reference/model/heading/) are less verbose: You prefix the line with the heading on it with an equals sign and a space to get a first-order heading: `= Introduction`. If you need a second-order heading, you use two equals signs: `== In this paper`. You can nest headings as deeply as you'd like by adding more equals signs.
Emphasis (usually rendered as italic text) is expressed by enclosing text in `_underscores_` and strong emphasis (usually rendered in boldface) by using `*stars*` instead.
Here is a list of common markup commands used in LaTeX and their Typst equivalents. You can also check out the [full syntax cheat sheet](/docs/reference/syntax/).
| Element | LaTeX | Typst | See |
| --- | --- | --- | --- |
| Strong emphasis | `\textbf\{strong\}` | `*strong*` | [`strong`](/docs/reference/model/strong/) |
| Emphasis | `\emph\{emphasis\}` | `_emphasis_` | [`emph`](/docs/reference/model/emph/) |
| Link | `\url\{https://typst.app\}` | `https://typst.app/` | [`link`](/docs/reference/model/link/) |
| Label | `\label\{intro\}` | `<intro>` | [`label`](/docs/reference/foundations/label/) |
| Reference | `\ref\{intro\}` | `@intro` | [`ref`](/docs/reference/model/ref/) |
| Citation | `\cite\{humphrey97\}` | `@humphrey97` | [`cite`](/docs/reference/model/cite/) |
| Monospace (typewriter) | `\texttt\{mono\}` | `text` or `mono` functions | [`text`](/docs/reference/text/text/), [`mono`](/docs/reference/math/variants/#functions-mono) |
| Code | `lstlisting` environment | ``print(f"\{x\}")`` | [`raw`](/docs/reference/text/raw/) |
| Verbatim | `verbatim` environment | ``#typst-code()`` | [`raw`](/docs/reference/text/raw/) |
| Bullet list | `itemize` environment | `- List` | [`list`](/docs/reference/model/list/) |
| Numbered list | `enumerate` environment | `+ List` | [`enum`](/docs/reference/model/enum/) |
| Term list | `description` environment | `/ Term: List` | [`terms`](/docs/reference/model/terms/) |
| Figure | `figure` environment | `figure` function | [`figure`](/docs/reference/model/figure/) |
| Table | `table` environment | `table` function | [`table`](/docs/reference/model/table/) |
| Equation | `$x$`, `align` / `equation` environments | `$x$`, `$ x = y $` | [`equation`](/docs/reference/math/equation/) |
[Lists](/docs/reference/model/list/) do not rely on environments in Typst. Instead, they have lightweight syntax like headings. To create an unordered list (`itemize`), prefix each line of an item with a hyphen:
```typst
To write this list in Typst...
```latex
\begin{itemize}
\item Fast
\item Flexible
\item Intuitive
\end{itemize}
```
...just type this:
- Fast
- Flexible
- Intuitive
```
Nesting lists works just by using proper indentation. Adding a blank line in between items results in a more [widely](/docs/reference/model/list/#parameters-tight) spaced list.
To get a [numbered list](/docs/reference/model/enum/) (`enumerate`) instead, use a `+` instead of the hyphen. For a [term list](/docs/reference/model/terms/) (`description`), write `/ Term: Description` instead.
Note that the [`raw` function](/docs/reference/text/raw/) and syntax (e.g. ``raw``) only work for verbatim (unformatted) text. If you require formatting, you can use the [`text` function](/docs/reference/text/text/) with a monospace font instead, like in the example below:
```typst
#text(
font: "DejaVu Sans Mono",
size: 0.8em,
)[monospace *bold*]
```
## How do I use a command?
LaTeX heavily relies on commands (prefixed by backslashes). It uses these _macros_ to affect the typesetting process and to insert and manipulate content. Some commands accept arguments, which are most frequently enclosed in curly braces: `\cite\{rasmus\}`.
Typst differentiates between [markup mode and code mode](/docs/reference/scripting/#blocks). The default is markup mode, where you compose text and apply syntactic constructs such as `*stars for bold text*`. Code mode, on the other hand, parallels programming languages like Python, providing the option to input and execute segments of code.
Within Typst's markup, you can switch to code mode for a single command (or rather, _expression_) using a hash (`#`). This is how you call functions to, for example, split your project into different [files](/docs/reference/scripting/#modules) or render text based on some [condition](/docs/reference/scripting/#conditionals). Within code mode, it is possible to include normal markup [_content_](/docs/reference/foundations/content/) by using square brackets. Within code mode, this content is treated just as any other normal value for a variable.
```typst
First, a rectangle:
#rect()
Let me show how to do
#underline([_underlined_ text])
We can also do some maths:
#calc.max(3, 2 * 4)
And finally a little loop:
#for x in range(3) [
Hi #x.
]
```
A function call always involves the name of the function ([`rect`](/docs/reference/visualize/rect/), [`underline`](/docs/reference/text/underline/), [`calc.max`](/docs/reference/foundations/calc/#functions-max), [`range`](/docs/reference/foundations/array/#definitions-range)) followed by parentheses (as opposed to LaTeX where the square brackets and curly braces are optional if the macro requires no arguments). The expected list of arguments passed within those parentheses depends on the concrete function and is specified in the [reference](/docs/reference/).
### Arguments
A function can have multiple arguments. Some arguments are positional, i.e., you just provide the value: The function `#lower("SCREAM")` returns its argument in all-lowercase. Many functions use named arguments instead of positional arguments to increase legibility. For example, the dimensions and stroke of a rectangle are defined with named arguments:
```typst
#rect(
width: 2cm,
height: 1cm,
stroke: red,
)
```
You specify a named argument by first entering its name (above, it's `width`, `height`, and `stroke`), then a colon, followed by the value (`2cm`, `1cm`, `red`). You can find the available named arguments in the [reference page](/docs/reference/) for each function or in the autocomplete panel when typing. Named arguments are similar to how some LaTeX environments are configured, for example, you would type `\begin\{enumerate\}[label=\{\alph*)\}]` to start a list with the labels `a)`, `b)`, and so on.
Often, you want to provide some [content](/docs/reference/foundations/content/) to a function. For example, the LaTeX command `\underline\{Alternative A\}` would translate to `#underline([Alternative A])` in Typst. The square brackets indicate that a value is [content](/docs/reference/foundations/content/). Within these brackets, you can use normal markup. However, that's a lot of parentheses for a pretty simple construct. This is why you can also move trailing content arguments after the parentheses (and omit the parentheses if they would end up empty).
```typst
Typst is an #underline[alternative]
to LaTeX.
#rect(fill: aqua)[Get started here!]
```
### Data types
You likely already noticed that the arguments have distinctive data types. Typst supports many [data types](/docs/reference/foundations/type/). Below, there is a table with some of the most important ones and how to write them. In order to specify values of any of these types, you have to be in code mode!
| Data type | Example |
| --- | --- |
| [Content](/docs/reference/foundations/content/) | `[*fast* typesetting]` |
| [String](/docs/reference/foundations/str/) | `"Pietro S. Author"` |
| [Integer](/docs/reference/foundations/int/) | `23` |
| [Floating point number](/docs/reference/foundations/float/) | `1.459` |
| [Absolute length](/docs/reference/layout/length/) | `12pt`, `5in`, `0.3cm`, ... |
| [Relative length](/docs/reference/layout/ratio/) | `65%` |
The difference between content and string is that content can contain markup, including function calls, while a string really is just a plain sequence of characters.
Typst provides [control flow constructs](/docs/reference/scripting/#conditionals) and [operators](/docs/reference/scripting/#operators) such as `+` for adding things or `==` for checking equality between two variables.
You can also store values, including functions, in your own [variables](/docs/reference/scripting/#bindings). This can be useful to perform computations on them, create reusable automations, or reference a value multiple times. The variable binding is accomplished with the let keyword, which works similar to `\newcommand`:
```typst
// Store the integer `5`.
#let five = 5
// Define a function that
// increments a value.
#let inc(i) = i + 1
// Reference the variables.
I have #five fingers.
If I had one more, I'd have
#inc(five) fingers. Whoa!
```
### Commands to affect the remaining document
In LaTeX, some commands like `\textbf\{bold text\}` receive an argument in curly braces and only affect that argument. Other commands such as `\bfseries bold text` act as switches (LaTeX calls this a declaration), altering the appearance of all subsequent content within the document or current scope.
In Typst, the same function can be used both to affect the appearance for the remainder of the document, a block (or scope), or just its arguments. For example, `#text(weight: "bold")[bold text]` will only embolden its argument, while `#set text(weight: "bold")` will embolden any text until the end of the current block, or the end of the document, if there is none. The effects of a function are immediately obvious based on whether it is used in a call or a [set rule.](/docs/reference/styling/#set-rules)
```typst
I am starting out with small text.
#set text(14pt)
This is a bit #text(18pt)[larger,]
don't you think?
```
Set rules may appear anywhere in the document. They can be thought of as default argument values of their respective function:
```typst
#set enum(numbering: "I.")
Good results can only be obtained by
+ following best practices
+ being aware of current results
of other researchers
+ checking the data for biases
```
The `+` is syntactic sugar (think of it as an abbreviation) for a call to the [`enum`](/docs/reference/model/enum/) function, to which we apply a set rule above. [Most syntax is linked to a function in this way.](/docs/reference/syntax/) If you need to style an element beyond what its arguments enable, you can completely redefine its appearance with a [show rule](/docs/reference/styling/#show-rules) (somewhat comparable to `\renewcommand`).
You can achieve the effects of LaTeX commands like `\textbf`, `\textsf`, `\rmfamily`, `\mdseries`, and `\itshape` with the [`font`](/docs/reference/text/text/#parameters-font), [`style`](/docs/reference/text/text/#parameters-style), and [`weight`](/docs/reference/text/text/#parameters-weight) arguments of the `text` function. The text function can be used in a set rule (declaration style) or with a content argument. To replace `\textsc`, you can use the [`smallcaps`](/docs/reference/text/smallcaps/) function, which renders its content argument as smallcaps. Should you want to use it declaration style (like `\scshape`), you can use an [_everything_ show rule](/docs/reference/styling/#show-rules) that applies the function to the rest of the scope:
```typst
#show: smallcaps
Boisterous Accusations
```
## How do I load a document class?
In LaTeX, you start your main `.tex` file with the `\documentclass\{article\}` command to define how your document is supposed to look. In that command, you may have replaced `article` with another value such as `report` and `amsart` to select a different look.
When using Typst, you style your documents with [functions](/docs/reference/foundations/function/). Typically, you use a template that provides a function that styles your whole document. First, you import the function from a template file. Then, you apply it to your whole document. This is accomplished with a [show rule](/docs/reference/styling/#show-rules) that wraps the following document in a given function. The following example illustrates how it works:
```typst
#import "conf.typ": conf
#show: conf.with(
title: [
Towards Improved Modelling
],
authors: (
(
name: "Theresa Tungsten",
affiliation: "Artos Institute",
email: "tung@artos.edu",
),
(
name: "Eugene Deklan",
affiliation: "Honduras State",
email: "e.deklan@hstate.hn",
),
),
abstract: lorem(80),
)
Let's get started writing this
article by putting insightful
paragraphs right here!
```
The [`import`](/docs/reference/scripting/#modules) statement makes [functions](/docs/reference/foundations/function/) (and other definitions) from another file available. In this example, it imports the `conf` function from the `conf.typ` file. This function formats a document as a conference article. We use a show rule to apply it to the document and also configure some metadata of the article. After applying the show rule, we can start writing our article right away!
You can also use templates from Typst Universe (which is Typst's equivalent of CTAN) using an import statement like this: `#import "@preview/elsearticle:0.2.1": elsearticle`. Check the documentation of an individual template to learn the name of its template function. Templates and packages from Typst Universe are automatically downloaded when you first use them.
In the web app, you can choose to create a project from a template on Typst Universe or even create your own using the template wizard. Locally, you can use the `typst init` CLI to create a new project from a template. Check out [the list of templates](https://typst.app/universe/search/?kind=templates) published on Typst Universe. You can also take a look at the [`awesome-typst` repository](https://github.com/qjcg/awesome-typst) to find community templates that aren't available through Universe.
You can also [create your own, custom templates.](/docs/tutorial/making-a-template/) They are shorter and more readable than the corresponding LaTeX `.sty` files by orders of magnitude, so give it a try!
> Functions are Typst's "commands" and can transform their arguments to an output value, including document _content._ Functions are "pure", which means that they cannot have any effects beyond creating an output value / output content. This is in stark contrast to LaTeX macros that can have arbitrary effects on your document.
> To let a function style your whole document, the show rule processes everything that comes after it and calls the function specified after the colon with the result as an argument. The `.with` part is a _method_ that takes the `conf` function and pre-configures some of its arguments before passing it on to the show rule.
## How do I load packages?
Typst is "batteries included," so the equivalent of many popular LaTeX packages is built right-in. Below, we compiled a table with frequently loaded packages and their corresponding Typst functions.
| LaTeX Package | Typst Alternative |
| --- | --- |
| graphicx, svg | [`image`](/docs/reference/visualize/image/) function |
| tabularx, tabularray | [`table`](/docs/reference/model/table/), [`grid`](/docs/reference/layout/grid/) functions |
| fontenc, inputenc, unicode-math | Just start writing! |
| babel, polyglossia | [`text`](/docs/reference/text/text/#parameters-lang) function: `#set text(lang: "zh")` |
| amsmath | [Math mode](/docs/reference/math/) |
| amsfonts, amssymb | [`sym`](/docs/reference/symbols/) module and [syntax](/docs/reference/syntax/#math) |
| geometry, fancyhdr | [`page`](/docs/reference/layout/page/) function |
| xcolor | [`text`](/docs/reference/text/text/#parameters-fill) function: `#set text(fill: rgb("#0178A4"))` |
| hyperref | [`link`](/docs/reference/model/link/) function |
| bibtex, biblatex, natbib | [`cite`](/docs/reference/model/cite/), [`bibliography`](/docs/reference/model/bibliography/) functions |
| lstlisting, minted | [`raw`](/docs/reference/text/raw/) function and syntax |
| parskip | [`block`](/docs/reference/layout/block/#parameters-spacing) and [`par`](/docs/reference/model/par/#parameters-first-line-indent) functions |
| csquotes | Set the [`text`](/docs/reference/text/text/#parameters-lang) language and type `"` or `'` |
| caption | [`figure`](/docs/reference/model/figure/) function |
| enumitem | [`list`](/docs/reference/model/list/), [`enum`](/docs/reference/model/enum/), [`terms`](/docs/reference/model/terms/) functions |
| nicefrac | [`frac.style`](/docs/reference/math/frac/#parameters-style) property |
Although _many_ things are built-in, not everything can be. That's why Typst has its own [package ecosystem](https://typst.app/universe/) where the community share its creations and automations. Let's take, for instance, the _CeTZ_ package: This package allows you to create complex drawings and plots. To use CeTZ in your document, you can just write:
```typst
#import "@preview/cetz:0.4.1"
```
(The `@preview` is a _namespace_ that is used while the package manager is still in its early and experimental state. It will be replaced in the future.)
Aside from the official package hub, you might also want to check out the [awesome-typst repository](https://github.com/qjcg/awesome-typst), which compiles a curated list of resources created for Typst.
If you need to load functions and variables from another file within your project, for example to use a template, you can use the same [`import`](/docs/reference/scripting/#modules) statement with a file name rather than a package specification. To instead include the textual content of another file, you can use an [`include`](/docs/reference/scripting/#modules) statement. It will retrieve the content of the specified file and put it in your document.
## How do I input maths?
To enter math mode in Typst, just enclose your equation in dollar signs. You can enter display mode by adding spaces or newlines between the equation's contents and its enclosing dollar signs.
```typst
The sum of the numbers from
$1$ to $n$ is:
$ sum_(k=1)^n k = (n(n+1))/2 $
```
[Math mode](/docs/reference/math/) works differently than regular markup or code mode. Numbers and single characters are displayed verbatim, while multiple consecutive (non-number) characters will be interpreted as Typst variables.
Typst pre-defines a lot of useful variables in math mode. All Greek (`alpha`, `beta`, ...) and some Hebrew letters (`alef`, `bet`, ...) are available through their name. Some symbols are additionally available through shorthands, such as `<=`, `>=`, and `->`.
Refer to the [symbol pages](/docs/reference/symbols/) for a full list of the symbols. If a symbol is missing, you can also access it through a [Unicode escape sequence](/docs/reference/syntax/#escapes).
Alternate and related forms of symbols can often be selected by [appending a modifier](/docs/reference/foundations/symbol/) after a period. For example, `arrow.l.squiggly` inserts a squiggly left-pointing arrow. If you want to insert multiletter text in your expression instead, enclose it in double quotes:
```typst
$ delta "if" x <= 5 $
```
In Typst, delimiters will scale automatically for their expressions, just as if `\left` and `\right` commands were implicitly inserted in LaTeX. You can customize delimiter behaviour using the [`lr` function](/docs/reference/math/lr/#functions-lr). To prevent a pair of delimiters from scaling, you can escape them with backslashes.
Typst will automatically set terms around a slash `/` as a fraction while honoring operator precedence. All round parentheses not made redundant by the fraction will appear in the output.
```typst
$ f(x) = (x + 1) / x $
```
[Sub- and superscripts](/docs/reference/math/attach/#functions-attach) work similarly in Typst and LaTeX. `$x^2$` will produce a superscript, `$x_2$` yields a subscript. If you want to include more than one value in a sub- or superscript, enclose their contents in parentheses: `$x_(a -> epsilon)$`.
Since variables in math mode do not need to be prepended with a `#` (or a `\` like in LaTeX), you can also call functions without these special characters:
```typst
$ f(x, y) := cases(
1 "if" (x dot y)/2 <= 0,
2 "if" x "is even",
3 "if" x in NN,
4 "else",
) $
```
The above example uses the [`cases` function](/docs/reference/math/cases/) to describe f. Within the cases function, arguments are delimited using commas and the arguments are also interpreted as math. If you need to interpret arguments as Typst values instead, prefix them with a `#`:
```typst
$ (a + b)^2
= a^2
+ text(fill: #maroon, 2 a b)
+ b^2 $
```
You can use all Typst functions within math mode and insert any content. If you want them to work normally, with code mode in the argument list, you can prefix their call with a `#`. Nobody can stop you from using rectangles or emoji as your variables anymore:
```typst
$ sum^10_(🤓=1)
#rect(width: 4mm, height: 2mm)/🤓
= 🧠 maltese $
```
If you'd like to enter your mathematical symbols directly as Unicode, that is possible, too!
Math calls can have two-dimensional argument lists using `;` as a delimiter. The most common use for this is the [`mat` function](/docs/reference/math/mat/) that creates matrices:
```typst
$ mat(
1, 2, ..., 10;
2, 2, ..., 10;
dots.v, dots.v, dots.down, dots.v;
10, 10, ..., 10;
) $
```
## How do I get the "LaTeX look?"
Papers set in LaTeX have an unmistakeable look. This is mostly due to their font, Computer Modern, justification, narrow line spacing, and wide margins.
The example below
- sets wide [margins](/docs/reference/layout/page/#parameters-margin)
- enables [justification](/docs/reference/model/par/#parameters-justify), [tighter lines](/docs/reference/model/par/#parameters-leading) and [first-line-indent](/docs/reference/model/par/#parameters-first-line-indent)
- [sets the font](/docs/reference/text/text/#parameters-font) to "New Computer Modern", an OpenType derivative of Computer Modern for both text and [code blocks](/docs/reference/text/raw/)
- disables paragraph [spacing](/docs/reference/layout/block/#parameters-spacing)
- increases [spacing](/docs/reference/layout/block/#parameters-spacing) around [headings](/docs/reference/model/heading/)
```typst
#set page(margin: 1.75in)
#set par(leading: 0.55em, spacing: 0.55em, first-line-indent: 1.8em, justify: true)
#set text(font: "New Computer Modern")
#show raw: set text(font: "New Computer Modern Mono")
#show heading: set block(above: 1.4em, below: 1em)
```
This should be a good starting point! If you want to go further, why not create a reusable template?
## Bibliographies
Typst includes a fully-featured bibliography system that is compatible with BibTeX files. You can continue to use your `.bib` literature libraries by loading them with the [`bibliography`](/docs/reference/model/bibliography/) function. Another possibility is to use [Typst's YAML-based native format](https://github.com/typst/hayagriva/blob/main/docs/file-format.md).
Typst uses the Citation Style Language to define and process citation and bibliography styles. You can compare CSL files to BibLaTeX's `.bbx` files. The compiler already includes [over 80 citation styles](/docs/reference/model/bibliography/#parameters-style), but you can use any CSL-compliant style from the [CSL repository](https://github.com/citation-style-language/styles) or write your own.
You can cite an entry in your bibliography or reference a label in your document with the same syntax: `@key` (this would reference an entry called `key`). Alternatively, you can use the [`cite`](/docs/reference/model/cite/) function.
Alternative forms for your citation, such as year only and citations for natural use in prose (cf. `\citet` and `\textcite`) are available with [`#cite(<key>, form: "prose")`](/docs/reference/model/cite/#parameters-form).
You can find more information on the documentation page of the [`bibliography`](/docs/reference/model/bibliography/) function.
## What limitations does Typst currently have compared to LaTeX?
Although Typst can be a LaTeX replacement for many today, there are still features that Typst does not (yet) support. Here is a list of them which, where applicable, contains possible workarounds.
- **Well-established plotting ecosystem.** LaTeX users often create elaborate charts along with their documents in PGF/TikZ. The Typst ecosystem does not yet offer the same breadth of available options, but the ecosystem around the [`cetz` package](https://typst.app/universe/package/cetz) is catching up quickly.
- **Change page margins without a pagebreak.** In LaTeX, margins can always be adjusted, even without a pagebreak. To change margins in Typst, you use the [`page` function](/docs/reference/layout/page/) which will force a page break. If you just want a few paragraphs to stretch into the margins, then reverting to the old margins, you can use the [`pad` function](/docs/reference/layout/pad/) with negative padding.
docs/guides/index.md
# Guides
Welcome to the Guides section! Here, you'll find helpful material for specific user groups or use cases. Please see the list below for the available guides. Feel free to propose other topics for guides!
## List of Guides
- [Guide for LaTeX Users](/docs/guides/for-latex-users/)
- [Page Setup Guide](/docs/guides/page-setup/)
- [Table Guide](/docs/guides/tables/)
- [Accessibility Guide](/docs/guides/accessibility/)
docs/guides/page-setup.md
# Page Setup
Your page setup is a big part of the first impression your document gives. Line lengths, margins, and columns influence [appearance](https://practicaltypography.com/page-margins.html) and [legibility](https://designregression.com/article/line-length-revisited-following-the-research) while the right headers and footers will help your reader easily navigate your document. This guide will help you to customize pages, margins, headers, footers, and page numbers so that they are the right fit for your content and you can get started with writing.
In Typst, each page has a width, a height, and margins on all four sides. The top and bottom margins may contain a header and footer. The set rule of the [`page`](/docs/reference/layout/page/) element is where you control all of the page setup. If you make changes with this set rule, Typst will ensure that there is a new and conforming empty page afterward, so it may insert a page break. Therefore, it is best to specify your [`page`](/docs/reference/layout/page/) set rule at the start of your document or in your template.
```typst
#set rect(
width: 100%,
height: 100%,
inset: 4pt,
)
#set page(
paper: "iso-b7",
header: rect(fill: aqua)[Header],
footer: rect(fill: aqua)[Footer],
number-align: center,
)
#rect(fill: aqua.lighten(40%))
```
This example visualizes the dimensions for page content, headers, and footers. The page content is the page size (ISO B7) minus each side's default margin. In the top and the bottom margin, there are stroked rectangles visualizing the header and footer. They do not touch the main content, instead, they are offset by 30% of the respective margin. You can control this offset by specifying the [`header-ascent`](/docs/reference/layout/page/#parameters-header-ascent) and [`footer-descent`](/docs/reference/layout/page/#parameters-footer-descent) arguments.
Below, the guide will go more into detail on how to accomplish common page setup requirements with examples.
## Customize page size and margins
Typst's default page size is A4 paper. Depending on your region and your use case, you will want to change this. You can do this by using the [`page`](/docs/reference/layout/page/) set rule and passing it a string argument to use a common page size. Options include the complete ISO 216 series (e.g. `"a4"` and `"iso-c2"`), customary US formats like `"us-legal"` or `"us-letter"`, and more. Check out the reference for the [page's paper argument](/docs/reference/layout/page/#parameters-paper) to learn about all available options.
```typst
#set page("us-letter")
This page likes freedom.
```
If you need to customize your page size to some dimensions, you can specify the named arguments [`width`](/docs/reference/layout/page/#parameters-width) and [`height`](/docs/reference/layout/page/#parameters-height) instead.
```typst
#set page(width: 12cm, height: 12cm)
This page is a square.
```
### Change the page's margins
Margins are a vital ingredient for good typography: [Typographers consider lines that fit between 45 and 75 characters best length for legibility](http://webtypography.net/2.1.2) and your margins and [columns](#columns) help define line widths. By default, Typst will create margins proportional to the page size of your document. To set custom margins, you will use the [`margin`](/docs/reference/layout/page/#parameters-margin) argument in the [`page`](/docs/reference/layout/page/) set rule.
The `margin` argument will accept a length if you want to set all margins to the same width. However, you often want to set different margins on each side. To do this, you can pass a dictionary:
```typst
#set page(margin: (
top: 3cm,
bottom: 2cm,
x: 1.5cm,
))
#lorem(100)
```
The page margin dictionary can have keys for each side (`top`, `bottom`, `left`, `right`), but you can also control left and right together by setting the `x` key of the margin dictionary, like in the example. Likewise, the top and bottom margins can be adjusted together by setting the `y` key.
If you do not specify margins for all sides in the margin dictionary, the old margins will remain in effect for the unset sides. To prevent this and set all remaining margins to a common size, you can use the `rest` key. For example, `#set page(margin: (left: 1.5in, rest: 1in))` will set the left margin to 1.5 inches and the remaining margins to one inch.
### Different margins on alternating pages
Sometimes, you'll need to alternate horizontal margins for even and odd pages, for example, to have more room towards the spine of a book than on the outsides of its pages. Typst keeps track of whether a page is to the left or right of the binding. You can use this information and set the `inside` or `outside` keys of the margin dictionary. The `inside` margin points towards the spine, and the `outside` margin points towards the edge of the bound book.
```typst
#set page(margin: (inside: 2.5cm, outside: 2cm, y: 1.75cm))
```
Typst will assume that documents written in Left-to-Right scripts are bound on the left while books written in Right-to-Left scripts are bound on the right. However, you will need to change this in some cases: If your first page is output by a different app, the binding is reversed from Typst's perspective. Also, some books, like English-language Mangas are customarily bound on the right, despite English using Left-to-Right script. To change the binding side and explicitly set where the `inside` and `outside` are, set the [`binding`](/docs/reference/layout/page/#parameters-binding) argument in the [`page`](/docs/reference/layout/page/) set rule.
```typst
// Produce a book bound on the right,
// even though it is set in Spanish.
#set text(lang: "es")
#set page(binding: right)
```
If `binding` is `left`, `inside` margins will be on the left on odd pages, and vice versa.
## Add headers and footers
Headers and footers are inserted in the top and bottom margins of every page. You can add custom headers and footers or just insert a page number.
In case you need more than just a page number, the best way to insert a header and a footer are the [`header`](/docs/reference/layout/page/#parameters-header) and [`footer`](/docs/reference/layout/page/#parameters-footer) arguments of the [`page`](/docs/reference/layout/page/) set rule. You can pass any content as their values:
```typst
#set page(header: [
_Lisa Strassner's Thesis_
#h(1fr)
National Academy of Sciences
])
#lorem(150)
```
Headers are bottom-aligned by default so that they do not collide with the top edge of the page. You can change this by wrapping your header in the [`align`](/docs/reference/layout/align/) function.
### Different header and footer on specific pages
You'll need different headers and footers on some pages. For example, you may not want a header and footer on the title page. The example below shows how to conditionally remove the header on the first page:
```typst
#set page(header: context {
if counter(page).get().first() > 1 [
_Lisa Strassner's Thesis_
#h(1fr)
National Academy of Sciences
]
})
#lorem(150)
```
This example may look intimidating, but let's break it down: By using the `context` keyword, we are telling Typst that the header depends on where we are in the document. We then ask Typst if the page [counter](/docs/reference/introspection/counter/) is larger than one at our (context-dependent) current position. The page counter starts at one, so we are skipping the header on a single page. Counters may have multiple levels. This feature is used for items like headings, but the page counter will always have a single level, so we can just look at the first one.
You can, of course, add an `else` to this example to add a different header to the first page instead.
### Adapt headers and footers on pages with specific elements
The technique described in the previous section can be adapted to perform more advanced tasks using Typst's labels. For example, pages with big tables could omit their headers to help keep clutter down. We will mark our tables with a `<big-table>` [label](/docs/reference/foundations/label/) and use the [query system](/docs/reference/introspection/query/) to find out if such a label exists on the current page:
```typst
#set page(header: context {
let matches = query(<big-table>)
let current = counter(page).get()
let has-table = matches.any(m =>
counter(page).at(m.location()) == current
)
if not has-table [
_Lisa Strassner's Thesis_
#h(1fr)
National Academy of Sciences
]
})
#lorem(100)
#pagebreak()
#table(
columns: 2 * (1fr,),
[A], [B],
[C], [D],
) <big-table>
```
Here, we query for all instances of the `<big-table>` label. We then check that none of the tables are on the page at our current position. If so, we print the header. This example also uses variables to be more concise. Just as above, you could add an `else` to add another header instead of deleting it.
## Add and customize page numbers
Page numbers help readers keep track of and reference your document more easily. The simplest way to insert page numbers is the [`numbering`](/docs/reference/layout/page/#parameters-numbering) argument of the [`page`](/docs/reference/layout/page/) set rule. You can pass a [_numbering pattern_](/docs/reference/model/numbering/#parameters-numbering) string that shows how you want your pages to be numbered.
```typst
#set page(numbering: "1")
This is a numbered page.
```
Above, you can check out the simplest conceivable example. It adds a single Arabic page number at the center of the footer. You can specify other characters than `"1"` to get other numerals. For example, `"i"` will yield lowercase Roman numerals. Any character that is not interpreted as a number will be output as-is. For example, put dashes around your page number by typing this:
```typst
#set page(numbering: "— 1 —")
This is a — numbered — page.
```
You can add the total number of pages by entering a second number character in the string.
```typst
#set page(numbering: "1 of 1")
This is one of many numbered pages.
```
Go to the [`numbering` function reference](/docs/reference/model/numbering/#parameters-numbering) to learn more about the arguments you can pass here.
In case you need to right- or left-align the page number, use the [`number-align`](/docs/reference/layout/page/#parameters-number-align) argument of the [`page`](/docs/reference/layout/page/) set rule. Alternating alignment between even and odd pages is not currently supported using this property. To do this, you'll need to specify a custom footer with your footnote and query the page counter as described in the section on conditionally omitting headers and footers.
### Custom footer with page numbers
Sometimes, you need to add other content than a page number to your footer. However, once a footer is specified, the [`numbering`](/docs/reference/layout/page/#parameters-numbering) argument of the [`page`](/docs/reference/layout/page/) set rule is ignored. This section shows you how to add a custom footer with page numbers and more.
```typst
#set page(footer: context [
*American Society of Proceedings*
#h(1fr)
#counter(page).display(
"1/1",
both: true,
)
])
This page has a custom footer.
```
First, we add some strongly emphasized text on the left and add free space to fill the line. Then, we call `counter(page)` to retrieve the page counter and use its `display` function to show its current value. We also set `both` to `true` so that our numbering pattern applies to the current _and_ final page number.
We can also get more creative with the page number. For example, let's insert a circle for each page.
```typst
#set page(footer: context [
*Fun Typography Club*
#h(1fr)
#let (num,) = counter(page).get()
#let circles = num * (
box(circle(
radius: 2pt,
fill: navy,
)),
)
#box(
inset: (bottom: 1pt),
circles.join(h(1pt))
)
])
This page has a custom footer.
```
In this example, we use the number of pages to create an array of [circles](/docs/reference/visualize/circle/). The circles are wrapped in a [box](/docs/reference/layout/box/) so they can all appear on the same line because they are blocks and would otherwise create paragraph breaks. The length of this [array](/docs/reference/foundations/array/) depends on the current page number.
We then insert the circles at the right side of the footer, with 1pt of space between them. The join method of an array will attempt to [_join_](/docs/reference/scripting/#blocks) the different values of an array into a single value, interspersed with its argument. In our case, we get a single content value with circles and spaces between them that we can use with the align function. Finally, we use another box to ensure that the text and the circles can share a line and use the [`inset` argument](/docs/reference/layout/box/#parameters-inset) to raise the circles a bit so they line up nicely with the text.
### Reset the page number and skip pages
Do you, at some point in your document, need to reset the page number? Maybe you want to start with the first page only after the title page. Or maybe you need to skip a few page numbers because you will insert pages into the final printed product.
The right way to modify the page number is to manipulate the page [counter](/docs/reference/introspection/counter/). The simplest manipulation is to set the counter back to 1.
```typst
#counter(page).update(1)
```
This line will reset the page counter back to one. It should be placed at the start of a page because it will otherwise create a page break. You can also update the counter given its previous value by passing a function:
```typst
#counter(page).update(n => n + 5)
```
In this example, we skip five pages. `n` is the current value of the page counter and `n + 5` is the return value of our function.
In case you need to retrieve the actual page number instead of the value of the page counter, you can use the [`page`](/docs/reference/introspection/location/#definitions-page) method on the return value of the [`here`](/docs/reference/introspection/here/) function:
```typst
#counter(page).update(n => n + 5)
// This returns one even though the
// page counter was incremented by 5.
#context here().page()
```
You can also obtain the page numbering pattern from the location returned by `here` with the [`page-numbering`](/docs/reference/introspection/location/#definitions-page-numbering) method.
## Add columns
Add columns to your document to fit more on a page while maintaining legible line lengths. Columns are vertical blocks of text which are separated by some whitespace. This space is called the gutter.
To lay out your content in columns, just specify the desired number of columns in a [`page`](/docs/reference/layout/page/#parameters-columns) set rule. To adjust the amount of space between the columns, add a set rule on the [`columns` function](/docs/reference/layout/columns/), specifying the `gutter` parameter.
```typst
#set page(columns: 2)
#set columns(gutter: 12pt)
#lorem(30)
```
Very commonly, scientific papers have a single-column title and abstract, while the main body is set in two-columns. To achieve this effect, Typst's [`place` function](/docs/reference/layout/place/) can temporarily escape the two-column layout by specifying `float: true` and `scope: "parent"`:
```typst
#set page(columns: 2)
#set par(justify: true)
#place(
top + center,
float: true,
scope: "parent",
text(1.4em, weight: "bold")[
Impacts of Odobenidae
],
)
== About seals in the wild
#lorem(80)
```
_Floating placement_ refers to elements being pushed to the top or bottom of the column or page, with the remaining content flowing in between. It is also frequently used for [figures](/docs/reference/model/figure/#parameters-placement).
### Use columns anywhere in your document
To create columns within a nested layout, e.g. within a rectangle, you can use the [`columns` function](/docs/reference/layout/columns/) directly. However, it really should only be used within nested layouts. At the page-level, the page set rule is preferable because it has better interactions with things like page-level floats, footnotes, and line numbers.
```typst
#rect(
width: 6cm,
height: 3.5cm,
columns(2, gutter: 12pt)[
In the dimly lit gas station,
a solitary taxi stood silently,
its yellow paint fading with
time. Its windows were dark,
its engine idle, and its tires
rested on the cold concrete.
]
)
```
### Balanced columns
If the columns on the last page of a document differ greatly in length, they may create a lopsided and unappealing layout. That's why typographers will often equalize the length of columns on the last page. This effect is called balancing columns. Typst cannot yet balance columns automatically. However, you can balance columns manually by placing [`#colbreak()`](/docs/reference/layout/colbreak/) at an appropriate spot in your markup, creating the desired column break manually.
## One-off modifications
You do not need to override your page settings if you need to insert a single page with a different setup. For example, you may want to insert a page that's flipped to landscape to insert a big table or change the margin and columns for your title page. In this case, you can call [`page`](/docs/reference/layout/page/) as a function with your content as an argument and the overrides as the other arguments. This will insert enough new pages with your overridden settings to place your content on them. Typst will revert to the page settings from the set rule after the call.
```typst
#page(flipped: true)[
= Multiplication table
#table(
columns: 5 * (1fr,),
..for x in range(1, 10) {
for y in range(1, 6) {
(str(x*y),)
}
}
)
]
```
docs/guides/tables.md
# Tables
Tables are a great way to present data to your readers in an easily readable, compact, and organized manner. They are not only used for numerical values, but also survey responses, task planning, schedules, and more. Because of this wide set of possible applications, there is no single best way to lay out a table. Instead, think about the data you want to highlight, your document's overarching design, and ultimately how your table can best serve your readers.
Typst can help you with your tables by automating styling, importing data from other applications, and more! This guide takes you through a few of the most common questions you may have when adding a table to your document with Typst. Feel free to skip to the section most relevant to you – we designed this guide to be read out of order.
If you want to look up a detail of how tables work, you should also [check out their reference page](/docs/reference/model/table/). And if you are looking for a table of contents rather than a normal table, the reference page of the [`outline` function](/docs/reference/model/outline/) is the right place to learn more.
## How to create a basic table?
In order to create a table in Typst, use the [`table` function](/docs/reference/model/table/). For a basic table, you need to tell the table function two things:
- The number of columns
- The content for each of the table cells
So, let's say you want to create a table with two columns describing the ingredients for a cookie recipe:
```typst
#table(
columns: 2,
[*Amount*], [*Ingredient*],
[360g], [Baking flour],
[250g], [Butter (room temp.)],
[150g], [Brown sugar],
[100g], [Cane sugar],
[100g], [70% cocoa chocolate],
[100g], [35-40% cocoa chocolate],
[2], [Eggs],
[Pinch], [Salt],
[Drizzle], [Vanilla extract],
)
```
This example shows how to call, configure, and populate a table. Both the column count and cell contents are passed to the table as arguments. The [argument list](/docs/reference/foundations/function/) is surrounded by round parentheses. In it, we first pass the column count as a named argument. Then, we pass multiple [content blocks](/docs/reference/foundations/content/) as positional arguments. Each content block contains the contents for a single cell.
To make the example more legible, we have placed two content block arguments on each line, mimicking how they would appear in the table. You could also write each cell on its own line. Typst does not care on which line you place the arguments. Instead, Typst will place the content cells from left to right (or right to left, if that is the writing direction of your language) and then from top to bottom. It will automatically add enough rows to your table so that it fits all of your content.
It is best to wrap the header row of your table in the [`table.header` function](/docs/reference/model/table/#definitions-header). This clarifies your intent and will also allow Typst to make the output more [accessible](/docs/guides/accessibility/) to users with a screen reader:
```typst
#table(
columns: 2,
table.header[*Amount*][*Ingredient*],
[360g], [Baking flour],
// ... the remaining cells
)
```
You could also write a show rule that automatically [strongly emphasizes](/docs/reference/model/strong/) the contents of the first cells for all tables. This quickly becomes useful if your document contains multiple tables!
```typst
#show table.cell.where(y: 0): strong
#table(
columns: 2,
table.header[Amount][Ingredient],
[360g], [Baking flour],
// ... the remaining cells
)
```
We are using a show rule with a selector for cell coordinates here instead of applying our styles directly to `table.header`. This is due to a current limitation of Typst that will be fixed in a future release.
Congratulations, you have created your first table! Now you can proceed to [change column sizes](#column-sizes), [adjust the strokes](#strokes), [add striped rows](#fills), and more!
## How to change the column sizes?
If you create a table and specify the number of columns, Typst will make each column large enough to fit its largest cell. Often, you want something different, for example, to make a table span the whole width of the page. You can provide a list, specifying how wide you want each column to be, through the `columns` argument. There are a few different ways to specify column widths:
- First, there is `auto`. This is the default behavior and tells Typst to grow the column to fit its contents. If there is not enough space, Typst will try its best to distribute the space among the `auto`-sized columns.
- [Lengths](/docs/reference/layout/length/) like `6cm`, `0.7in`, or `120pt`. As usual, you can also use the font-dependent `em` unit. This is a multiple of your current font size. It's useful if you want to size your table so that it always fits about the same amount of text, independent of font size.
- A [ratio in percent](/docs/reference/layout/ratio/) such as `40%`. This will make the column take up 40% of the total horizontal space available to the table, so either the inner width of the page or the table's container. You can also mix ratios and lengths into [relative lengths](/docs/reference/layout/relative/). Be mindful that even if you specify a list of column widths that sum up to 100%, your table could still become larger than its container. This is because there can be [gutter](/docs/reference/model/table/#parameters-gutter) between columns that is not included in the column widths. If you want to make a table fill the page, the next option is often very useful.
- A [fractional part of the free space](/docs/reference/layout/fraction/) using the `fr` unit, such as `1fr`. This unit allows you to distribute the available space to columns. It works as follows: First, Typst sums up the lengths of all columns that do not use `fr`s. Then, it determines how much horizontal space is left. This horizontal space then gets distributed to all columns denominated in `fr`s. During this process, a `2fr` column will become twice as wide as a `1fr` column. This is where the name comes from: The width of the column is its fraction of the total fractionally sized columns.
Let's put this to use with a table that contains the dates, numbers, and descriptions of some routine checks. The first two columns are `auto`-sized and the last column is `1fr` wide as to fill the whole page.
```typst
#table(
columns: (auto, auto, 1fr),
table.header[Date][°No][Description],
[24/01/03], [813], [Filtered participant pool],
[24/01/03], [477], [Transitioned to sec. regimen],
[24/01/11], [051], [Cycled treatment substrate],
)
```
Here, we have passed our list of column lengths as an [array](/docs/reference/foundations/array/), enclosed in round parentheses, with its elements separated by commas. The first two columns are automatically sized, so that they take on the size of their content and the third column is sized as `1fr` so that it fills up the remainder of the space on the page. If you wanted to instead change the second column to be a bit more spacious, you could replace its entry in the `columns` array with a value like `6em`.
## How to caption and reference my table?
A table is just as valuable as the information your readers draw from it. You can enhance the effectiveness of both your prose and your table by making a clear connection between the two with a cross-reference. Typst can help you with automatic [references](/docs/reference/model/ref/) and the [`figure` function](/docs/reference/model/figure/).
Just like with images, wrapping a table in the `figure` function allows you to add a caption and a label, so you can reference the figure elsewhere. Wrapping your table in a figure also lets you use the figure's `placement` parameter to float it to the top or bottom of a page.
Let's take a look at a captioned table and how to reference it in prose:
```typst
#show table.cell.where(y: 0): set text(weight: "bold")
#figure(
table(
columns: 4,
stroke: none,
table.header[Test Item][Specification][Test Result][Compliance],
[Voltage], [220V ± 5%], [218V], [Pass],
[Current], [5A ± 0.5A], [4.2A], [Fail],
),
caption: [Probe results for design A],
) <probe-a>
The results from @probe-a show that the design is not yet optimal.
We will show how its performance can be improved in this section.
```
The example shows how to wrap a table in a figure, set a caption and a label, and how to reference that label. We start by using the `figure` function. It expects the contents of the figure as a positional argument. We just put the table function call in its argument list, omitting the `#` character because it is only needed when calling a function in markup mode. We also add the caption as a named argument (above or below) the table.
After the figure call, we put a label in angle brackets (`<probe-a>`). This tells Typst to remember this element and make it referenceable under this name throughout your document. We can then reference it in prose by using the at sign and the label name `@probe-a`. Typst will print a nicely formatted reference and automatically update the label if the table's number changes.
## How to get a striped table?
Many tables use striped rows or columns instead of strokes to differentiate between rows and columns. This effect is often called _zebra stripes._ Tables with zebra stripes are popular in Business and commercial Data Analytics applications, while academic applications tend to use strokes instead.
To add zebra stripes to a table, we use the `table` function's `fill` argument. It can take three kinds of arguments:
- A single color (this can also be a gradient or a tiling) to fill all cells with. Because we want some cells to have another color, this is not useful if we want to build zebra tables.
- An array with colors which Typst cycles through for each column. We can use an array with two elements to get striped columns.
- A function that takes the horizontal coordinate `x` and the vertical coordinate `y` of a cell and returns its fill. We can use this to create horizontal stripes or [checkerboard patterns](/docs/reference/layout/grid/#definitions-cell).
Let's start with an example of a horizontally striped table:
```typst
#set text(font: "IBM Plex Sans")
// Medium bold table header.
#show table.cell.where(y: 0): set text(weight: "medium")
// Bold titles.
#show table.cell.where(x: 1): set text(weight: "bold")
// See the strokes section for details on this!
#let frame(stroke) = (x, y) => (
left: if x > 0 { 0pt } else { stroke },
right: stroke,
top: if y < 2 { stroke } else { 0pt },
bottom: stroke,
)
#set table(
fill: (rgb("EAF2F5"), none),
stroke: frame(1pt + rgb("21222C")),
)
#table(
columns: (0.4fr, 1fr, 1fr, 1fr),
table.header[Month][Title][Author][Genre],
[January], [The Great Gatsby], [F. Scott Fitzgerald], [Classic],
[February], [To Kill a Mockingbird], [Harper Lee], [Drama],
[March], [1984], [George Orwell], [Dystopian],
[April], [The Catcher in the Rye], [J.D. Salinger], [Coming-of-Age],
)
```
This example shows a book club reading list. The line `fill: (rgb("EAF2F5"), none)` in `table`'s set rule is all that is needed to add striped columns. It tells Typst to alternate between coloring columns with a light blue (in the [`rgb`](/docs/reference/visualize/color/#definitions-rgb) function call) and nothing (`none`). Note that we extracted all of our styling from the `table` function call itself into set and show rules, so that we can automatically reuse it for multiple tables.
Because setting the stripes itself is easy we also added some other styles to make it look nice. The other code in the example provides a dark blue [stroke](#stroke-functions) around the table and below the first line and emboldens the first row and the column with the book title. See the [strokes](#strokes) section for details on how we achieved this stroke configuration.
Let's next take a look at how we can change only the set rule to achieve horizontal stripes instead:
```typst
#set table(
fill: (_, y) => if calc.odd(y) { rgb("EAF2F5") },
stroke: frame(1pt + rgb("21222C")),
)
```
We just need to replace the set rule from the previous example with this one and get horizontal stripes instead. Here, we are passing a function to `fill`. It discards the horizontal coordinate with an underscore and then checks if the vertical coordinate `y` of the cell is odd. If so, the cell gets a light blue fill, otherwise, no fill is returned.
Of course, you can make this function arbitrarily complex. For example, if you want to stripe the rows with a light and darker shade of blue, you could do something like this:
```typst
#set table(
fill: (_, y) => (none, rgb("EAF2F5"), rgb("DDEAEF")).at(calc.rem(y, 3)),
stroke: frame(1pt + rgb("21222C")),
)
```
This example shows an alternative approach to write our fill function. The function uses an array with three colors and then cycles between its values for each row by indexing the array with the remainder of `y` divided by 3.
Finally, here is a bonus example that uses the _stroke_ to achieve striped rows:
```typst
#set table(
stroke: (x, y) => (
y: 1pt,
left: if x > 0 { 0pt } else if calc.even(y) { 1pt },
right: if calc.even(y) { 1pt },
),
)
```
### Manually overriding a cell's fill color
Sometimes, the fill of a cell needs not to vary based on its position in the table, but rather based on its contents. We can use the [`table.cell` element](/docs/reference/model/table/#definitions-cell) in the `table`'s parameter list to wrap a cell's content and override its fill.
For example, here is a list of all German presidents, with the cell borders colored in the color of their party.
```typst
#set text(font: "Roboto")
#let cdu(name) = ([CDU], table.cell(fill: black, text(fill: white, name)))
#let spd(name) = ([SPD], table.cell(fill: red, text(fill: white, name)))
#let fdp(name) = ([FDP], table.cell(fill: yellow, name))
#table(
columns: (auto, auto, 1fr),
stroke: (x: none),
table.header[Tenure][Party][President],
[1949-1959], ..fdp[Theodor Heuss],
[1959-1969], ..cdu[Heinrich Lübke],
[1969-1974], ..spd[Gustav Heinemann],
[1974-1979], ..fdp[Walter Scheel],
[1979-1984], ..cdu[Karl Carstens],
[1984-1994], ..cdu[Richard von Weizsäcker],
[1994-1999], ..cdu[Roman Herzog],
[1999-2004], ..spd[Johannes Rau],
[2004-2010], ..cdu[Horst Köhler],
[2010-2012], ..cdu[Christian Wulff],
[2012-2017], [n/a], [Joachim Gauck],
[2017-], ..spd[Frank-Walter-Steinmeier],
)
```
In this example, we make use of variables because there only have been a total of three parties whose members have become president (and one unaffiliated president). Their colors will repeat multiple times, so we store a function that produces an array with their party's name and a table cell with that party's color and the president's name (`cdu`, `spd`, and `fdp`). We then use these functions in the `table` argument list instead of directly adding the name. We use the [spread operator](/docs/reference/foundations/arguments/#spreading) `..` to turn the items of the arrays into single cells. We could also write something like `[FDP], table.cell(fill: yellow)[Theodor Heuss]` for each cell directly in the `table`'s argument list, but that becomes unreadable, especially for the parties whose colors are dark so that they require white text. We also delete vertical strokes and set the font to Roboto.
The party column and the cell color in this example communicate redundant information on purpose: Communicating important data using color only is a bad accessibility practice. It disadvantages users with vision impairment and is in violation of universal access standards, such as the [WCAG 2.1 Success Criterion 1.4.1](https://www.w3.org/WAI/WCAG21/Understanding/use-of-color.html). To improve this table, we added a column printing the party name. Alternatively, you could have made sure to choose a color-blindness friendly palette and mark up your cells with an additional label that screen readers can read out loud. The latter feature is not currently supported by Typst, but will be added in a future release. You can check how colors look for color-blind readers with [this Chrome extension](https://chromewebstore.google.com/detail/colorblindly/floniaahmccleoclneebhhmnjgdfijgg), [Photoshop](https://helpx.adobe.com/photoshop/using/proofing-colors.html), or [GIMP](https://docs.gimp.org/2.10/en/gimp-display-filter-dialog.html).
## How to adjust the lines in a table?
By default, Typst adds strokes between each row and column of a table. You can adjust these strokes in a variety of ways. Which one is the most practical, depends on the modification you want to make and your intent:
- Do you want to style all tables in your document, irrespective of their size and content? Use the `table` function's [stroke](/docs/reference/model/table/#parameters-stroke) argument in a set rule.
- Do you want to customize all lines in a single table? Use the `table` function's [stroke](/docs/reference/model/table/#parameters-stroke) argument when calling the table function.
- Do you want to change, add, or remove the stroke around a single cell? Use the `table.cell` element in the argument list of your table call.
- Do you want to change, add, or remove a single horizontal or vertical stroke in a single table? Use the [`table.hline`](/docs/reference/model/table/#definitions-hline) and [`table.vline`](/docs/reference/model/table/#definitions-vline) elements in the argument list of your table call.
We will go over all of these options with examples next! First, we will tackle the `table` function's [stroke](/docs/reference/model/table/#parameters-stroke) argument. Here, you can adjust both how the table's lines get drawn and configure which lines are drawn at all.
Let's start by modifying the color and thickness of the stroke:
```typst
#table(
columns: 4,
stroke: 0.5pt + rgb("666675"),
[*Monday*], [11.5], [13.0], [4.0],
[*Tuesday*], [8.0], [14.5], [5.0],
[*Wednesday*], [9.0], [18.5], [13.0],
)
```
This makes the table lines a bit less wide and uses a bluish gray. You can see that we added a width in point to a color to achieve our customized stroke. This addition yields a value of the [stroke type](/docs/reference/visualize/stroke/). Alternatively, you can use the dictionary representation for strokes which allows you to access advanced features such as dashed lines.
The previous example showed how to use the stroke argument in the table function's invocation. Alternatively, you can specify the stroke argument in the `table`'s set rule. This will have exactly the same effect on all subsequent `table` calls as if the stroke argument was specified in the argument list. This is useful if you are writing a template or want to style your whole document.
```typst
// Renders the exact same as the last example
#set table(stroke: 0.5pt + rgb("666675"))
#table(
columns: 4,
[*Monday*], [11.5], [13.0], [4.0],
[*Tuesday*], [8.0], [14.5], [5.0],
[*Wednesday*], [9.0], [18.5], [13.0],
)
```
For small tables, you sometimes want to suppress all strokes because they add too much visual noise. To do this, just set the stroke argument to `none`:
```typst
#table(
columns: 4,
stroke: none,
[*Monday*], [11.5], [13.0], [4.0],
[*Tuesday*], [8.0], [14.5], [5.0],
[*Wednesday*], [9.0], [18.5], [13.0],
)
```
If you want more fine-grained control of where lines get placed in your table, you can also pass a dictionary with the keys `top`, `left`, `right`, `bottom` (controlling the respective cell sides), `x`, `y` (controlling vertical and horizontal strokes), and `rest` (covers all strokes not styled by other dictionary entries). All keys are optional; omitted keys will use their previously set value, or the default value if never set. For example, to get a table with only horizontal lines, you can do this:
```typst
#table(
columns: 2,
stroke: (x: none),
align: horizon,
[☒], [Close cabin door],
[☐], [Start engines],
[☐], [Radio tower],
[☐], [Push back],
)
```
This turns off all vertical strokes and leaves the horizontal strokes in place. To achieve the reverse effect (only horizontal strokes), set the stroke argument to `(y: none)` instead.
[Further down in the guide](#stroke-functions), we cover how to use a function in the stroke argument to customize all strokes individually. This is how you achieve more complex stroking patterns.
### Adding individual lines in the table
If you want to add a single horizontal or vertical line in your table, for example to separate a group of rows, you can use the [`table.hline`](/docs/reference/model/table/#definitions-hline) and [`table.vline`](/docs/reference/model/table/#definitions-vline) elements for horizontal and vertical lines, respectively. Add them to the argument list of the `table` function just like you would add individual cells and a header.
Let's take a look at the following example from the reference:
```typst
#set table.hline(stroke: 0.6pt)
#table(
stroke: none,
columns: (auto, 1fr),
// Morning schedule abridged.
[14:00], [Talk: Tracked Layout],
[15:00], [Talk: Automations],
[16:00], [Workshop: Tables],
table.hline(),
[19:00], [Day 1 Attendee Mixer],
)
```
In this example, you can see that we have placed a call to `table.hline` between the cells, producing a horizontal line at that spot. We also used a set rule on the element to reduce its stroke width to make it fit better with the weight of the font.
By default, Typst places horizontal and vertical lines after the current row or column, depending on their position in the argument list. You can also manually move them to a different position by adding the `y` (for `hline`) or `x` (for `vline`) argument. For example, the code below would produce the same result:
```typst
#set table.hline(stroke: 0.6pt)
#table(
stroke: none,
columns: (auto, 1fr),
// Morning schedule abridged.
table.hline(y: 3),
[14:00], [Talk: Tracked Layout],
[15:00], [Talk: Automations],
[16:00], [Workshop: Tables],
[19:00], [Day 1 Attendee Mixer],
)
```
Let's imagine you are working with a template that shows none of the table strokes except for one between the first and second row. Now, since you have one table that also has labels in the first column, you want to add an extra vertical line to it. However, you do not want this vertical line to cross into the top row. You can achieve this with the `start` argument:
```typst
// Base template already configured tables, but we need some
// extra configuration for this table.
#{
set table(align: (x, _) => if x == 0 { left } else { right })
show table.cell.where(x: 0): smallcaps
table(
columns: (auto, 1fr, 1fr, 1fr),
table.vline(x: 1, start: 1),
table.header[Trainset][Top Speed][Length][Weight],
[TGV Réseau], [320 km/h], [200m], [383t],
[ICE 403], [330 km/h], [201m], [409t],
[Shinkansen N700], [300 km/h], [405m], [700t],
)
}
```
In this example, we have added `table.vline` at the start of our positional argument list. But because the line is not supposed to go to the left of the first column, we specified the `x` argument as `1`. We also set the `start` argument to `1` so that the line does only start after the first row.
The example also contains two more things: We use the align argument with a function to right-align the data in all but the first column and use a show rule to make the first column of table cells appear in small capitals. Because these styles are specific to this one table, we put everything into a [code block](/docs/reference/scripting/#blocks), so that the styling does not affect any further tables.
### Overriding the strokes of a single cell
Imagine you want to change the stroke around a single cell. Maybe your cell is very important and needs highlighting! For this scenario, there is the [`table.cell` function](/docs/reference/model/table/#definitions-cell). Instead of adding your content directly in the argument list of the table, you wrap it in a `table.cell` call. Now, you can use `table.cell`'s argument list to override the table properties, such as the stroke, for this cell only.
Here's an example with a matrix of two of the Big Five personality factors, with one intersection highlighted.
```typst
#table(
columns: 3,
stroke: (x: none),
table.header[][*High Neuroticism*][*Low Neuroticism*],
[*High Agreeableness*],
table.cell(stroke: orange + 2pt)[
_Sensitive_ \ Prone to emotional distress but very empathetic.
],
[_Compassionate_ \ Caring and stable, often seen as a supportive figure.],
[*Low Agreeableness*],
[_Contentious_ \ Competitive and easily agitated.],
[_Detached_ \ Independent and calm, may appear aloof.],
)
```
Above, you can see that we used the `table.cell` element in the table's argument list and passed the cell content to it. We have used its `stroke` argument to set a wider orange stroke. Despite the fact that we disabled vertical strokes on the table, the orange stroke appeared on all sides of the modified cell, showing that the table's stroke configuration is overwritten.
### Complex document-wide stroke customization
This section explains how to customize all lines at once in one or multiple tables. This allows you to draw only the first horizontal line or omit the outer lines, without knowing how many cells the table has. This is achieved by providing a function to the table's `stroke` parameter. The function should return a stroke given the zero-indexed x and y position of the current cell. You should only need these functions if you are a template author, do not use a template, or need to heavily customize your tables. Otherwise, your template should set appropriate default table strokes.
For example, this is a set rule that draws all horizontal lines except for the very first and last line.
```typst
#show table.cell.where(x: 0): set text(style: "italic")
#show table.cell.where(y: 0): set text(style: "normal", weight: "bold")
#set table(stroke: (_, y) => if y > 0 { (top: 0.8pt) })
#table(
columns: 3,
align: center + horizon,
table.header[Technique][Advantage][Drawback],
[Diegetic], [Immersive], [May be contrived],
[Extradiegetic], [Breaks immersion], [Obtrusive],
[Omitted], [Fosters engagement], [May fracture audience],
)
```
In the set rule, we pass a function that receives two arguments, assigning the vertical coordinate to `y` and discarding the horizontal coordinate. It then returns a stroke dictionary with a `0.8pt` top stroke for all but the first line. The cells in the first line instead implicitly receive `none` as the return value. You can easily modify this function to just draw the inner vertical lines instead as `(x, _) => if x > 0 \{ (left: 0.8pt) \}`.
Let's try a few more stroking functions. The next function will only draw a line below the first row:
```typst
#set table(stroke: (_, y) => if y == 0 { (bottom: 1pt) })
// Table as seen above
```
If you understood the first example, it becomes obvious what happens here. We check if we are in the first row. If so, we return a bottom stroke. Otherwise, we'll return `none` implicitly.
The next example shows how to draw all but the outer lines:
```typst
#set table(stroke: (x, y) => (
left: if x > 0 { 0.8pt },
top: if y > 0 { 0.8pt },
))
// Table as seen above
```
This example uses both the `x` and `y` coordinates. It omits the left stroke in the first column and the top stroke in the first row. The right and bottom lines are not drawn.
Finally, here is a table that draws all lines except for the vertical lines in the first row and horizontal lines in the table body. It looks a bit like a calendar.
```typst
#set table(stroke: (x, y) => (
left: if x == 0 or y > 0 { 1pt } else { 0pt },
right: 1pt,
top: if y <= 1 { 1pt } else { 0pt },
bottom: 1pt,
))
// Table as seen above
```
This example is a bit more complex. We start by drawing all the strokes on the right of the cells. But this means that we have drawn strokes in the top row, too, and we don't need those! We use the fact that `left` will override `right` and only draw the left line if we are not in the first row or if we are in the first column. In all other cases, we explicitly remove the left line. Finally, we draw the horizontal lines by first setting the bottom line and then for the first two rows with the `top` key, suppressing all other top lines. The last line appears because there is no `top` line that could suppress it.
### How to achieve a double line?
Typst does not yet have a native way to draw double strokes, but there are multiple ways to emulate them, for example with [tilings](/docs/reference/visualize/tiling/). We will show a different workaround in this section: Table gutters.
Tables can space their cells apart using the `gutter` argument. When a gutter is applied, a stroke is drawn on each of the now separated cells. We can selectively add gutter between the rows or columns for which we want to draw a double line. The `row-gutter` and `column-gutter` arguments allow us to do this. They accept arrays of gutter values. Let's take a look at an example:
```typst
#table(
columns: 3,
stroke: (x: none),
row-gutter: (2.2pt, auto),
table.header[Date][Exercise Type][Calories Burned],
[2023-03-15], [Swimming], [400],
[2023-03-17], [Weightlifting], [250],
[2023-03-18], [Yoga], [200],
)
```
We can see that we used an array for `row-gutter` that specifies a `2.2pt` gap between the first and second row. It then continues with `auto` (which is the default, in this case `0pt` gutter) which will be the gutter between all other rows, since it is the last entry in the array.
## How to align the contents of the cells in my table?
You can use multiple mechanisms to align the content in your table. You can either use the `table` function's `align` argument to set the alignment for your whole table (or use it in a set rule to set the alignment for tables throughout your document) or the [`align`](/docs/reference/layout/align/) function (or `table.cell`'s `align` argument) to override the alignment of a single cell.
When using the `table` function's align argument, you can choose between three methods to specify an [alignment](/docs/reference/layout/alignment/):
- Just specify a single alignment like `right` (aligns in the top-right corner) or `center + horizon` (centers all cell content). This changes the alignment of all cells.
- Provide an array. Typst will cycle through this array for each column.
- Provide a function that is passed the horizontal `x` and vertical `y` coordinate of a cell and returns an alignment.
For example, this travel itinerary right-aligns the day column and left-aligns everything else by providing an array in the `align` argument:
```typst
#set text(font: "IBM Plex Sans")
#show table.cell.where(y: 0): set text(weight: "bold")
#table(
columns: 4,
align: (right, left, left, left),
fill: (_, y) => if calc.odd(y) { green.lighten(90%) },
stroke: none,
table.header[Day][Location][Hotel or Apartment][Activities],
[1], [Paris, France], [Hôtel de l'Europe], [Arrival, Evening River Cruise],
[2], [Paris, France], [Hôtel de l'Europe], [Louvre Museum, Eiffel Tower],
[3], [Lyon, France], [Lyon City Hotel], [City Tour, Local Cuisine Tasting],
[4], [Geneva, Switzerland], [Lakeview Inn], [Lake Geneva, Red Cross Museum],
[5], [Zermatt, Switzerland], [Alpine Lodge], [Visit Matterhorn, Skiing],
)
```
However, this example does not yet look perfect — the header cells should be bottom-aligned. Let's use a function instead to do so:
```typst
#set text(font: "IBM Plex Sans")
#show table.cell.where(y: 0): set text(weight: "bold")
#table(
columns: 4,
align: (x, y) =>
if x == 0 { right } else { left } +
if y == 0 { bottom } else { top },
fill: (_, y) => if calc.odd(y) { green.lighten(90%) },
stroke: none,
table.header[Day][Location][Hotel or Apartment][Activities],
[1], [Paris, France], [Hôtel de l'Europe], [Arrival, Evening River Cruise],
[2], [Paris, France], [Hôtel de l'Europe], [Louvre Museum, Eiffel Tower],
// ... remaining days omitted
)
```
In the function, we calculate a horizontal and vertical alignment based on whether we are in the first column (`x == 0`) or the first row (`y == 0`). We then make use of the fact that we can add horizontal and vertical alignments with `+` to receive a single, two-dimensional alignment.
You can find an example of using `table.cell` to change a single cell's alignment on [its reference page](/docs/reference/model/table/#definitions-cell).
## How to merge cells?
When a table contains logical groupings or the same data in multiple adjacent cells, merging multiple cells into a single, larger cell can be advantageous. Another use case for cell groups are table headers with multiple rows: That way, you can group for example a sales data table by quarter in the first row and by months in the second row.
A merged cell spans multiple rows and/or columns. You can achieve it with the [`table.cell`](/docs/reference/model/table/#definitions-cell) function's `rowspan` and `colspan` arguments: Just specify how many rows or columns you want your cell to span.
The example below contains an attendance calendar for an office with in-person and remote days for each team member. To make the table more glanceable, we merge adjacent cells with the same value:
```typst
#let ofi = [Office]
#let rem = [_Remote_]
#let lea = [*On leave*]
#show table.cell.where(y: 0): set text(
fill: white,
weight: "bold",
)
#table(
columns: 6 * (1fr,),
align: (x, y) => if x == 0 or y == 0 { left } else { center },
stroke: (x, y) => (
// Separate black cells with white strokes.
left: if y == 0 and x > 0 { white } else { black },
rest: black,
),
fill: (_, y) => if y == 0 { black },
table.header(
[Team member],
[Monday],
[Tuesday],
[Wednesday],
[Thursday],
[Friday]
),
[Evelyn Archer],
table.cell(colspan: 2, ofi),
table.cell(colspan: 2, rem),
ofi,
[Lila Montgomery],
table.cell(colspan: 5, lea),
[Nolan Pearce],
rem,
table.cell(colspan: 2, ofi),
rem,
ofi,
)
```
In the example, we first define variables with "Office", "Remote", and "On leave" so we don't have to write these labels out every time. We can then use these variables in the table body either directly or in a `table.cell` call if the team member spends multiple consecutive days in office, remote, or on leave.
The example also contains a black header (created with `table`'s `fill` argument) with white strokes (`table`'s `stroke` argument) and white text (set by the `table.cell` set rule). Finally, we align all the content of all table cells in the body in the center. If you want to know more about the functions passed to `align`, `stroke`, and `fill`, you can check out the sections on [alignment](/docs/reference/layout/alignment/), [strokes](#stroke-functions), and [striped tables](#fills).
This table would be a great candidate for fully automated generation from an external data source! Check out the [section about importing data](#importing-data) to learn more about that.
## How to rotate a table?
When tables have many columns, a portrait paper orientation can quickly get cramped. Hence, you'll sometimes want to switch your tables to landscape orientation. There are two ways to accomplish this in Typst:
- If you want to rotate only the table but not the other content of the page and the page itself, use the [`rotate` function](/docs/reference/layout/rotate/) with the `reflow` argument set to `true`.
- If you want to rotate the whole page the table is on, you can use the [`page` function](/docs/reference/layout/page/) with its `flipped` argument set to `true`. The header, footer, and page number will now also appear on the long edge of the page. This has the advantage that the table will appear right side up when read on a computer, but it also means that a page in your document has different dimensions than all the others, which can be jarring to your readers.
Below, we will demonstrate both techniques with a student grade book table.
First, we will rotate the table on the page. The example also places some text on the right of the table.
```typst
#set page("a5", columns: 2, numbering: "— 1 —")
#show table.cell.where(y: 0): set text(weight: "bold")
#rotate(
-90deg,
reflow: true,
table(
columns: (1fr,) + 5 * (auto,),
inset: (x: 0.6em,),
stroke: (_, y) => (
x: 1pt,
top: if y <= 1 { 1pt } else { 0pt },
bottom: 1pt,
),
align: (left, right, right, right, right, left),
table.header(
[Student Name],
[Assignment 1], [Assignment 2],
[Mid-term], [Final Exam],
[Total Grade],
),
[Jane Smith], [78%], [82%], [75%], [80%], [B],
[Alex Johnson], [90%], [95%], [94%], [96%], [A+],
[John Doe], [85%], [90%], [88%], [92%], [A],
[Maria Garcia], [88%], [84%], [89%], [85%], [B+],
[Zhang Wei], [93%], [89%], [90%], [91%], [A-],
[Marina Musterfrau], [96%], [91%], [74%], [69%], [B-],
),
)
#lorem(80)
```
What we have here is a two-column document on ISO A5 paper with page numbers on the bottom. The table has six columns and contains a few customizations to [stroke](#strokes), alignment and spacing. But the most important part is that the table is wrapped in a call to the `rotate` function with the `reflow` argument being `true`. This will make the table rotate 90 degrees counterclockwise. The reflow argument is needed so that the table's rotation affects the layout. If it was omitted, Typst would lay out the page as if the table was not rotated (`true` might become the default in the future).
The example also shows how to produce many columns of the same size: To the initial `1fr` column, we add an array with five `auto` items that we create by multiplying an array with one `auto` item by five. Note that arrays with just one item need a trailing comma to distinguish them from merely parenthesized expressions.
The second example shows how to rotate the whole page, so that the table stays upright:
```typst
#set page("a5", numbering: "— 1 —")
#show table.cell.where(y: 0): set text(weight: "bold")
#page(flipped: true)[
#table(
columns: (1fr,) + 5 * (auto,),
inset: (x: 0.6em,),
stroke: (_, y) => (
x: 1pt,
top: if y <= 1 { 1pt } else { 0pt },
bottom: 1pt,
),
align: (left, right, right, right, right, left),
table.header(
[Student Name],
[Assignment 1], [Assignment 2],
[Mid-term], [Final Exam],
[Total Grade],
),
[Jane Smith], [78%], [82%], [75%], [80%], [B],
[Alex Johnson], [90%], [95%], [94%], [96%], [A+],
[John Doe], [85%], [90%], [88%], [92%], [A],
[Maria Garcia], [88%], [84%], [89%], [85%], [B+],
[Zhang Wei], [93%], [89%], [90%], [91%], [A-],
[Marina Musterfrau], [96%], [91%], [74%], [69%], [B-],
)
#pad(x: 15%, top: 1.5em)[
= Winter 2023/24 results
#lorem(80)
]
]
```
Here, we take the same table and the other content we want to set with it and put it into a call to the [`page`](/docs/reference/layout/page/) function while supplying `true` to the `flipped` argument. This will instruct Typst to create new pages with width and height swapped and place the contents of the function call onto a new page. Notice how the page number is also on the long edge of the paper now. At the bottom of the page, we use the [`pad`](/docs/reference/layout/pad/) function to constrain the width of the paragraph to achieve a nice and legible line length.
## How to break a table across pages?
It is best to contain a table on a single page. However, some tables just have many rows, so breaking them across pages becomes unavoidable. Fortunately, Typst supports breaking tables across pages out of the box. If you are using the [`table.header`](/docs/reference/model/table/#definitions-header) and [`table.footer`](/docs/reference/model/table/#definitions-footer) functions, their contents will be repeated on each page as the first and last rows, respectively. If you want to disable this behavior, you can set `repeat` to `false` on either of them.
If you have placed your table inside of a [figure](/docs/reference/model/figure/), it becomes unable to break across pages by default. However, you can change this behavior. Let's take a look:
```typst
#set page(width: 9cm, height: 6cm)
#show table.cell.where(y: 0): set text(weight: "bold")
#show figure: set block(breakable: true)
#figure(
caption: [Training regimen for Marathon],
table(
columns: 3,
fill: (_, y) => if y == 0 { gray.lighten(75%) },
table.header[Week][Distance (km)][Time (hh:mm:ss)],
[1], [5], [00:30:00],
[2], [7], [00:45:00],
[3], [10], [01:00:00],
[4], [12], [01:10:00],
[5], [15], [01:25:00],
[6], [18], [01:40:00],
[7], [20], [01:50:00],
[8], [22], [02:00:00],
[...], [...], [...],
table.footer[_Goal_][_42.195_][_02:45:00_],
)
)
```
A figure automatically produces a [block](/docs/reference/layout/block/) which cannot break by default. However, we can reconfigure the block of the figure using a show rule to make it `breakable`. Now, the figure spans multiple pages with the headers and footers repeating.
## How to import data into a table?
Often, you need to put data that you obtained elsewhere into a table. Sometimes, this is from Microsoft Excel or Google Sheets, sometimes it is from a dataset on the web or from your experiment. Fortunately, Typst can load many [common file formats](/docs/reference/data-loading/), so you can use scripting to include their data in a table.
The most common file format for tabular data is CSV. You can obtain a CSV file from Excel by choosing "Save as" in the _File_ menu and choosing the file format "CSV UTF-8 (Comma-delimited) (.csv)". Save the file and, if you are using the web app, upload it to your project.
In our case, we will be building a table about Moore's Law. For this purpose, we are using a statistic with [how many transistors the average microprocessor consists of per year from Our World in Data](https://ourworldindata.org/grapher/transistors-per-microprocessor). Let's start by pressing the "Download" button to get a CSV file with the raw data.
Be sure to move the file to your project or somewhere Typst can see it, if you are using the CLI. Once you did that, we can open the file to see how it is structured:
```typst
Entity,Code,Year,Transistors per microprocessor
World,OWID_WRL,1971,2308.2417
World,OWID_WRL,1972,3554.5222
World,OWID_WRL,1974,6097.5625
```
The file starts with a header and contains four columns: Entity (which is to whom the metric applies), Code, the year, and the number of transistors per microprocessor. Only the last two columns change between each row, so we can disregard "Entity" and "Code".
First, let's start by loading this file with the [`csv`](/docs/reference/data-loading/csv/) function. It accepts the file name of the file we want to load as a string argument:
```typst
#let moore = csv("moore.csv")
```
We have loaded our file (assuming we named it `moore.csv`) and [bound it](/docs/reference/scripting/#bindings) to the new variable `moore`. This will not produce any output, so there's nothing to see yet. If we want to examine what Typst loaded, we can either hover the name of the variable in the web app or print some items from the array:
```typst
#let moore = csv("moore.csv")
#moore.slice(0, 3)
```
With the arguments `(0, 3)`, the [`slice`](/docs/reference/foundations/array/#definitions-slice) method returns the first three items in the array (with the indices 0, 1, and 2). We can see that each row is its own array with one item per cell.
Now, let's write a loop that will transform this data into an array of cells that we can use with the table function.
```typst
#let moore = csv("moore.csv")
#table(
columns: 2,
..for (.., year, count) in moore {
(year, count)
}
)
```
The example above uses a for loop that iterates over the rows in our CSV file and returns an array for each iteration. We use the for loop's [destructuring](/docs/reference/scripting/#bindings) capability to discard all but the last two items of each row. We then create a new array with just these two. Because Typst will concatenate the array results of all the loop iterations, we get a one-dimensional array in which the year column and the number of transistors alternate. We can then insert the array as cells. For this we use the [spread operator](/docs/reference/foundations/arguments/#spreading) (`..`). By prefixing an array, or, in our case an expression that yields an array, with two dots, we tell Typst that the array's items should be used as positional arguments.
Alternatively, we can also use the [`map`](/docs/reference/foundations/array/#definitions-map), [`slice`](/docs/reference/foundations/array/#definitions-slice), and [`flatten`](/docs/reference/foundations/array/#definitions-flatten) array methods to write this in a more functional style:
```typst
#let moore = csv("moore.csv")
#table(
columns: 2,
..moore.map(m => m.slice(2, 4)).flatten(),
)
```
This example renders the same as the previous one, but we first load the CSV and then transform each row using `map`. The function we pass to `map` is applied to each row of the data and returns a new array that replaces the original row. Here, we use `.slice(2, 4)` to extract only the third and fourth column, since these are the ones we want to keep. Because `moore` is a two-dimensional array (each row is itself an array), the result of mapping is still a nested array. The `flatten` function converts this nested structure into a one-dimensional array, which is required when spreading the data into the `table` function. Finally, we explicitly specify `columns: 2` because we are keeping exactly two columns from each row.
Now that we have nice code for our table, we should try to also make the table itself nice! The transistor counts go from millions in 1995 to trillions in 2021 and changes are difficult to see with so many digits. We could try to present our data logarithmically to make it more digestible:
```typst
#let moore = csv("moore.csv")
#let moore-log = moore.slice(1).map(m => {
let (.., year, count) = m
let log = calc.log(float(count))
let rounded = str(calc.round(log, digits: 2))
(year, rounded)
})
#show table.cell.where(x: 0): strong
#table(
columns: moore-log.first().len(),
align: right,
fill: (_, y) => if calc.odd(y) { rgb("D7D9E0") },
stroke: none,
table.header[Year][Transistor count ($log_10$)],
table.hline(stroke: rgb("4D4C5B")),
..moore-log.flatten(),
)
```
In this example, we first drop the header row from the data since we are adding our own. Then, we discard all but the last two columns as above. We do this by [destructuring](/docs/reference/scripting/#bindings) the array `m`, discarding all but the two last items. We then convert the string in `count` to a floating point number, calculate its logarithm and store it in the variable `log`. Finally, we round it to two digits, convert it to a string, and store it in the variable `rounded`. Then, we return an array with `year` and `rounded` that replaces the original row. In our table, we have added our custom header that tells the reader that we've applied a logarithm to the values. Then, we spread the flattened data as above.
We also styled the table with [stripes](#fills), a [horizontal line](#individual-lines) below the first row, [aligned](#alignment) everything to the right, and emboldened the first column. Click on the links to go to the relevant guide sections and see how it's done!
## What if I need the table function for something that isn't a table?
Tabular layouts of content can be useful not only for matrices of closely related data, like shown in the examples throughout this guide, but also for presentational purposes. Typst differentiates between grids that are for layout and presentational purposes only and tables, in which the arrangement of the cells itself conveys information.
To make this difference clear to other software and allow templates to heavily style tables, Typst has two functions for grid and table layout:
- The [`table`](/docs/reference/model/table/) function explained throughout this guide which is intended for tabular data.
- The [`grid`](/docs/reference/layout/grid/) function which is intended for presentational purposes and page layout.
Both elements work the same way and have the same arguments. You can apply everything you have learned about tables in this guide to grids. There are only three differences:
- You'll need to use the [`grid.cell`](/docs/reference/layout/grid/#definitions-cell), [`grid.vline`](/docs/reference/layout/grid/#definitions-vline), and [`grid.hline`](/docs/reference/layout/grid/#definitions-hline) elements instead of [`table.cell`](/docs/reference/model/table/#definitions-cell), [`table.vline`](/docs/reference/model/table/#definitions-vline), and [`table.hline`](/docs/reference/model/table/#definitions-hline).
- The grid has different defaults: It draws no strokes by default and has no spacing (`inset`) inside of its cells.
- Elements like `figure` do not react to grids since they are supposed to have no semantical bearing on the document structure.
docs/index.md
# Overview
Welcome to Typst's documentation! Typst is a new markup-based typesetting system for the sciences. It is designed to be an alternative both to advanced tools like LaTeX and simpler tools like Word and Google Docs. Our goal with Typst is to build a typesetting tool that is highly capable _and_ a pleasure to use.
This documentation is split into two parts: A beginner-friendly tutorial that introduces Typst through a practical use case and a comprehensive reference that explains all of Typst's concepts and features.
We also invite you to join the community we're building around Typst. Typst is still a very young project, so your feedback is more than valuable.
docs/reference/context.md
# Context
Sometimes, we want to create content that reacts to its location in the document. This could be a localized phrase that depends on the configured text language or something as simple as a heading number which prints the right value based on how many headings came before it. However, Typst code isn't directly aware of its location in the document. Some code at the beginning of the source text could yield content that ends up at the back of the document.
To produce content that is reactive to its surroundings, we must thus specifically instruct Typst: We do this with the `context` keyword, which precedes an expression and ensures that it is computed with knowledge of its environment. In return, the context expression itself ends up opaque. We cannot directly access whatever results from it in our code, precisely because it is contextual: There is no one correct result, there may be multiple results in different places of the document. For this reason, everything that depends on the contextual data must happen inside of the context expression.
Aside from explicit context expressions, context is also established implicitly in some places that are also aware of their location in the document: [Show rules](/docs/reference/styling/#show-rules) provide context[1](#1) and numberings in the outline, for instance, also provide the proper context to resolve counters.
## Style context
With set rules, we can adjust style properties for parts or the whole of our document. We cannot access these without a known context, as they may change throughout the course of the document. When context is available, we can retrieve them simply by accessing them as fields on the respective element function.
```typst
#set text(lang: "de")
#context text.lang
```
As explained above, a context expression is reactive to the different environments it is placed into. In the example below, we create a single context expression, store it in the `value` variable and use it multiple times. Each use properly reacts to the current surroundings.
```typst
#let value = context text.lang
#value
#set text(lang: "de")
#value
#set text(lang: "fr")
#value
```
Crucially, upon creation, `value` becomes opaque [content](/docs/reference/foundations/content/) that we cannot peek into. It can only be resolved when placed somewhere because only then the context is known. The body of a context expression may be evaluated zero, one, or multiple times, depending on how many different places it is put into.
## Location context
We've already seen that context gives us access to set rule values. But it can do more: It also lets us know _where_ in the document we currently are, relative to other elements, and absolutely on the pages. We can use this information to create very flexible interactions between different document parts. This underpins features like heading numbering, the table of contents, or page headers dependent on section headings.
Some functions like [`counter.get`](/docs/reference/introspection/counter/#definitions-get) implicitly access the current location. In the example below, we want to retrieve the value of the heading counter. Since it changes throughout the document, we need to first enter a context expression. Then, we use `get` to retrieve the counter's current value. This function accesses the current location from the context to resolve the counter value. Counters have multiple levels and `get` returns an array with the resolved numbers. Thus, we get the following result:
```typst
#set heading(numbering: "1.")
= Introduction
#lorem(5)
#context counter(heading).get()
= Background
#lorem(5)
#context counter(heading).get()
```
For more flexibility, we can also use the [`here`](/docs/reference/introspection/here/) function to directly extract the current [location](/docs/reference/introspection/location/) from the context. The example below demonstrates this:
- We first have `counter(heading).get()`, which resolves to `(2,)` as before.
- We then use the more powerful [`counter.at`](/docs/reference/introspection/counter/#definitions-at) with [`here`](/docs/reference/introspection/here/), which in combination is equivalent to `get`, and thus get `(2,)`.
- Finally, we use `at` with a [label](/docs/reference/foundations/label/) to retrieve the value of the counter at a _different_ location in the document, in our case that of the introduction heading. This yields `(1,)`. Typst's context system gives us time travel abilities and lets us retrieve the values of any counters and states at _any_ location in the document.
```typst
#set heading(numbering: "1.")
= Introduction <intro>
#lorem(5)
= Background <back>
#lorem(5)
#context [
#counter(heading).get() \
#counter(heading).at(here()) \
#counter(heading).at(<intro>)
]
```
As mentioned before, we can also use context to get the physical position of elements on the pages. We do this with the [`locate`](/docs/reference/introspection/locate/) function, which works similarly to `counter.at`: It takes a location or other [selector](/docs/reference/foundations/selector/) that resolves to a unique element (could also be a label) and returns the position on the pages for that element.
```typst
Background is at: \
#context locate(<back>).position()
= Introduction <intro>
#lorem(5)
#pagebreak()
= Background <back>
#lorem(5)
```
There are other functions that make use of the location context, most prominently [`query`](/docs/reference/introspection/query/). Take a look at the [introspection](/docs/reference/introspection/) category for more details on those.
## Nested contexts
Context is also accessible from within function calls nested in context blocks. In the example below, `foo` itself becomes a contextual function, just like [`to-absolute`](/docs/reference/layout/length/#definitions-to-absolute) is.
```typst
#let foo() = 1em.to-absolute()
#context {
foo() == text.size
}
```
Context blocks can be nested. Contextual code will then always access the innermost context. The example below demonstrates this: The first `text.lang` will access the outer context block's styles and as such, it will **not** see the effect of `set text(lang: "fr")`. The nested context block around the second `text.lang`, however, starts after the set rule and will thus show its effect.
```typst
#set text(lang: "de")
#context [
#set text(lang: "fr")
#text.lang \
#context text.lang
]
```
You might wonder why Typst ignores the French set rule when computing the first `text.lang` in the example above. The reason is that, in the general case, Typst cannot know all the styles that will apply as set rules can be applied to content after it has been constructed. Below, `text.lang` is already computed when the template function is applied. As such, it cannot possibly be aware of the language change to French in the template.
```typst
#let template(body) = {
set text(lang: "fr")
upper(body)
}
#set text(lang: "de")
#context [
#show: template
#text.lang \
#context text.lang
]
```
The second `text.lang`, however, _does_ react to the language change because evaluation of its surrounding context block is deferred until the styles for it are known. This illustrates the importance of picking the right insertion point for a context to get access to precisely the right styles.
The same also holds true for the location context. Below, the first `c.display()` call will access the outer context block and will thus not see the effect of `c.update(2)` while the second `c.display()` accesses the inner context and will thus see it.
```typst
#let c = counter("mycounter")
#c.update(1)
#context [
#c.update(2)
#c.display() \
#context c.display()
]
```
## Compiler iterations
To resolve contextual interactions, the Typst compiler processes your document multiple times. For instance, to resolve a `locate` call, Typst first provides a placeholder position, layouts your document and then recompiles with the known position from the finished layout. The same approach is taken to resolve counters, states, and queries. In certain cases, Typst may even need more than two iterations to resolve everything. While that's sometimes a necessity, it may also be a sign of misuse of contextual functions (e.g. of [state](/docs/reference/introspection/state/#caution)). If Typst cannot resolve everything within five attempts, it will stop and output the warning "layout did not converge within 5 attempts."
A very careful reader might have noticed that not all of the functions presented above actually make use of the current location. While `counter(heading).get()` definitely depends on it, `counter(heading).at(<intro>)`, for instance, does not. However, it still requires context. While its value is always the same _within_ one compilation iteration, it may change over the course of multiple compiler iterations. If one could call it directly at the top level of a module, the whole module and its exports could change over the course of multiple compiler iterations, which would not be desirable.
[^1]: Currently, all show rules provide [style context](#style-context), but only show rules on [locatable](/docs/reference/introspection/location/#locatable) elements provide a [location context](#location-context).
docs/reference/data-loading/cbor.md
# CBOR
# cbor
Reads structured data from a CBOR file.
The file must contain a valid CBOR serialization. The CBOR values will be converted into corresponding Typst values as listed in the [table below](#conversion).
The function returns a dictionary, an array or, depending on the CBOR file, another CBOR data type.
## Conversion details
| CBOR value | Converted into Typst |
| --- | --- |
| integer | [`int`](/docs/reference/foundations/int/) (or [`float`](/docs/reference/foundations/float/)) |
| bytes | [`bytes`](/docs/reference/foundations/bytes/) |
| float | [`float`](/docs/reference/foundations/float/) |
| text | [`str`](/docs/reference/foundations/str/) |
| bool | [`bool`](/docs/reference/foundations/bool/) |
| null | `none` |
| array | [`array`](/docs/reference/foundations/array/) |
| map | [`dictionary`](/docs/reference/foundations/dictionary/) |
| Typst value | Converted into CBOR |
| --- | --- |
| types that can be converted from CBOR | corresponding CBOR value |
| [`symbol`](/docs/reference/foundations/symbol/) | text |
| [`content`](/docs/reference/foundations/content/) | a map describing the content |
| other types ([`length`](/docs/reference/layout/length/), etc.) | text via [`repr`](/docs/reference/foundations/repr/) |
### Notes
- Be aware that CBOR integers larger than 263-1 or smaller than -263 will be converted to floating point numbers, which may result in an approximative value.
- CBOR tags are not supported, and an error will be thrown.
- The `repr` function is [for debugging purposes only](/docs/reference/foundations/repr/#debugging-only), and its output is not guaranteed to be stable across Typst versions.
```typst
#cbor(
source
) -> any
```
## Parameters
- source:
- description: A [path](/docs/reference/syntax/#paths) to a CBOR file or raw CBOR bytes.
- type: str | bytes
- default: None
## Definitions
### cbor.decode
Reads structured data from CBOR bytes.
```typst
#cbor.decode(
data
) -> any
```
#### Parameters
- data:
- description: CBOR data.
- type: bytes
- default: None
### cbor.encode
Encode structured data into CBOR bytes.
```typst
#cbor.encode(
value
) -> bytes
```
#### Parameters
- value:
- description: Value to be encoded.
- type: any
- default: None
docs/reference/data-loading/csv.md
# CSV
# csv
Reads structured data from a CSV file.
The CSV file will be read and parsed into a 2-dimensional array of strings: Each row in the CSV file will be represented as an array of strings, and all rows will be collected into a single array. Header rows will not be stripped.
## Example
```typst
#let results = csv("example.csv")
#table(
columns: 2,
[*Condition*], [*Result*],
..results.flatten(),
)
```
```typst
#csv(
source,
delimiter: str,
row-type: type
) -> array
```
## Parameters
- source:
- description: A [path](/docs/reference/syntax/#paths) to a CSV file or raw CSV bytes.
- type: str | bytes
- default: None
- delimiter:
- description: The delimiter that separates columns in the CSV file. Must be a single ASCII character.
- type: str
- default: ","
- row-type:
- description: How to represent the file\'s rows. - If set to `array`, each row is represented as a plain array of strings. - If set to `dictionary`, each row is represented as a dictionary mapping from header keys to strings. This option only makes sense when a header row is present in the CSV file.
- type: type
- default: array
## Definitions
### csv.decode
Reads structured data from a CSV string/bytes.
```typst
#csv.decode(
data,
delimiter: str,
row-type: type
) -> array
```
#### Parameters
- data:
- description: CSV data.
- type: str | bytes
- default: None
- delimiter:
- description: The delimiter that separates columns in the CSV file. Must be a single ASCII character.
- type: str
- default: ","
- row-type:
- description: How to represent the file\'s rows. - If set to `array`, each row is represented as a plain array of strings. - If set to `dictionary`, each row is represented as a dictionary mapping from header keys to strings. This option only makes sense when a header row is present in the CSV file.
- type: type
- default: array
docs/reference/data-loading/index.md
# Data Loading
Data loading from external files.
These functions help you with loading and embedding data, for example from the results of an experiment.
## Encoding
Some of the functions are also capable of encoding, e.g. [`cbor.encode`](/docs/reference/data-loading/cbor/#definitions-encode). They facilitate passing structured data to [plugins](/docs/reference/foundations/plugin/).
However, each data format has its own native types. Therefore, for an arbitrary Typst value, the encode-to-decode roundtrip might be lossy. In general, numbers, strings, and [arrays](/docs/reference/foundations/array/) or [dictionaries](/docs/reference/foundations/dictionary/) composed of them can be reliably converted, while other types may fall back to strings via [`repr`](/docs/reference/foundations/repr/), which is [for debugging purposes only](/docs/reference/foundations/repr/#debugging-only). Please refer to the page of each data format for details.
## Definitions
| Name | Description |
| --- | --- |
| [`cbor`](/reference/data-loading/cbor/) | Reads structured data from a CBOR file. |
| [`csv`](/reference/data-loading/csv/) | Reads structured data from a CSV file. |
| [`json`](/reference/data-loading/json/) | Reads structured data from a JSON file. |
| [`read`](/reference/data-loading/read/) | Reads plain text or data from a file. |
| [`toml`](/reference/data-loading/toml/) | Reads structured data from a TOML file. |
| [`xml`](/reference/data-loading/xml/) | Reads structured data from an XML file. |
| [`yaml`](/reference/data-loading/yaml/) | Reads structured data from a YAML file. |
docs/reference/data-loading/json.md
# JSON
# json
Reads structured data from a JSON file.
The file must contain a valid JSON value, such as object or array. The JSON values will be converted into corresponding Typst values as listed in the [table below](#conversion).
The function returns a dictionary, an array or, depending on the JSON file, another JSON data type.
The JSON files in the example contain objects with the keys `temperature`, `unit`, and `weather`.
## Example
```typst
#let forecast(day) = block[
#box(square(
width: 2cm,
inset: 8pt,
fill: if day.weather == "sunny" {
yellow
} else {
aqua
},
align(
bottom + right,
strong(day.weather),
),
))
#h(6pt)
#set text(22pt, baseline: -8pt)
#day.temperature °#day.unit
]
#forecast(json("monday.json"))
#forecast(json("tuesday.json"))
```
## Conversion details
| JSON value | Converted into Typst |
| --- | --- |
| `null` | `none` |
| bool | [`bool`](/docs/reference/foundations/bool/) |
| number | [`float`](/docs/reference/foundations/float/) or [`int`](/docs/reference/foundations/int/) |
| string | [`str`](/docs/reference/foundations/str/) |
| array | [`array`](/docs/reference/foundations/array/) |
| object | [`dictionary`](/docs/reference/foundations/dictionary/) |
| Typst value | Converted into JSON |
| --- | --- |
| types that can be converted from JSON | corresponding JSON value |
| [`bytes`](/docs/reference/foundations/bytes/) | string via [`repr`](/docs/reference/foundations/repr/) |
| [`symbol`](/docs/reference/foundations/symbol/) | string |
| [`content`](/docs/reference/foundations/content/) | an object describing the content |
| other types ([`length`](/docs/reference/layout/length/), etc.) | string via [`repr`](/docs/reference/foundations/repr/) |
### Notes
- In most cases, JSON numbers will be converted to floats or integers depending on whether they are whole numbers. However, be aware that integers larger than 263-1 or smaller than -263 will be converted to floating-point numbers, which may result in an approximative value.
- Bytes are not encoded as JSON arrays for performance and readability reasons. Consider using [`cbor.encode`](/docs/reference/data-loading/cbor/#definitions-encode) for binary data.
- The `repr` function is [for debugging purposes only](/docs/reference/foundations/repr/#debugging-only), and its output is not guaranteed to be stable across Typst versions.
```typst
#json(
source
) -> any
```
## Parameters
- source:
- description: A [path](/docs/reference/syntax/#paths) to a JSON file or raw JSON bytes.
- type: str | bytes
- default: None
## Definitions
### json.decode
Reads structured data from a JSON string/bytes.
```typst
#json.decode(
data
) -> any
```
#### Parameters
- data:
- description: JSON data.
- type: str | bytes
- default: None
### json.encode
Encodes structured data into a JSON string.
```typst
#json.encode(
value,
pretty: bool
) -> str
```
#### Parameters
- value:
- description: Value to be encoded.
- type: any
- default: None
- pretty:
- description: Whether to pretty print the JSON with newlines and indentation.
- type: bool
- default: true
docs/reference/data-loading/read.md
# Read
# read
Reads plain text or data from a file.
By default, the file will be read as UTF-8 and returned as a [string](/docs/reference/foundations/str/).
If you specify `encoding: none`, this returns raw [bytes](/docs/reference/foundations/bytes/) instead.
## Example
```typst
An example for a HTML file: \
#let text = read("example.html")
#raw(text, block: true, lang: "html")
Raw bytes:
#read("tiger.jpg", encoding: none)
```
```typst
#read(
path,
encoding: none | str
) -> str bytes
```
## Parameters
- path:
- description: Path to a file. For more details, see the [Paths section](/docs/reference/syntax/#paths).
- type: str
- default: None
- encoding:
- description: The encoding to read the file with. If set to `none`, this function returns raw bytes.
- type: none | str
- default: "utf8"
docs/reference/data-loading/toml.md
# TOML
# toml
Reads structured data from a TOML file.
The file must contain a valid TOML table. The TOML values will be converted into corresponding Typst values as listed in the [table below](#conversion).
The function returns a dictionary representing the TOML table.
The TOML file in the example consists of a table with the keys `title`, `version`, and `authors`.
## Example
```typst
#let details = toml("details.toml")
Title: #details.title \
Version: #details.version \
Authors: #(details.authors
.join(", ", last: " and "))
```
## Conversion details
First of all, TOML documents are tables. Other values must be put in a table to be encoded or decoded.
| TOML value | Converted into Typst |
| --- | --- |
| string | [`str`](/docs/reference/foundations/str/) |
| integer | [`int`](/docs/reference/foundations/int/) |
| float | [`float`](/docs/reference/foundations/float/) |
| boolean | [`bool`](/docs/reference/foundations/bool/) |
| datetime | [`datetime`](/docs/reference/foundations/datetime/) |
| array | [`array`](/docs/reference/foundations/array/) |
| table | [`dictionary`](/docs/reference/foundations/dictionary/) |
| Typst value | Converted into TOML |
| --- | --- |
| types that can be converted from TOML | corresponding TOML value |
| `none` | ignored |
| [`bytes`](/docs/reference/foundations/bytes/) | string via [`repr`](/docs/reference/foundations/repr/) |
| [`symbol`](/docs/reference/foundations/symbol/) | string |
| [`content`](/docs/reference/foundations/content/) | a table describing the content |
| other types ([`length`](/docs/reference/layout/length/), etc.) | string via [`repr`](/docs/reference/foundations/repr/) |
### Notes
- Be aware that TOML integers larger than 263-1 or smaller than -263 cannot be represented losslessly in Typst, and an error will be thrown according to the [specification](https://toml.io/en/v1.0.0#integer).
- Bytes are not encoded as TOML arrays for performance and readability reasons. Consider using [`cbor.encode`](/docs/reference/data-loading/cbor/#definitions-encode) for binary data.
- The `repr` function is [for debugging purposes only](/docs/reference/foundations/repr/#debugging-only), and its output is not guaranteed to be stable across Typst versions.
```typst
#toml(
source
) -> dictionary
```
## Parameters
- source:
- description: A [path](/docs/reference/syntax/#paths) to a TOML file or raw TOML bytes.
- type: str | bytes
- default: None
## Definitions
### toml.decode
Reads structured data from a TOML string/bytes.
```typst
#toml.decode(
data
) -> dictionary
```
#### Parameters
- data:
- description: TOML data.
- type: str | bytes
- default: None
### toml.encode
Encodes structured data into a TOML string.
```typst
#toml.encode(
value,
pretty: bool
) -> str
```
#### Parameters
- value:
- description: Value to be encoded. TOML documents are tables. Therefore, only dictionaries are suitable.
- type: dictionary
- default: None
- pretty:
- description: Whether to pretty-print the resulting TOML.
- type: bool
- default: true
docs/reference/data-loading/xml.md
# XML
# xml
Reads structured data from an XML file.
The XML file is parsed into an array of dictionaries and strings. XML nodes can be elements or strings. Elements are represented as dictionaries with the following keys:
- `tag`: The name of the element as a string.
- `attrs`: A dictionary of the element's attributes as strings.
- `children`: An array of the element's child nodes.
The XML file in the example contains a root `news` tag with multiple `article` tags. Each article has a `title`, `author`, and `content` tag. The `content` tag contains one or more paragraphs, which are represented as `p` tags.
## Example
```typst
#let find-child(elem, tag) = {
elem.children
.find(e => "tag" in e and e.tag == tag)
}
#let article(elem) = {
let title = find-child(elem, "title")
let author = find-child(elem, "author")
let pars = find-child(elem, "content")
[= #title.children.first()]
text(10pt, weight: "medium")[
Published by
#author.children.first()
]
for p in pars.children {
if type(p) == dictionary {
parbreak()
p.children.first()
}
}
}
#let data = xml("example.xml")
#for elem in data.first().children {
if type(elem) == dictionary {
article(elem)
}
}
```
```typst
#xml(
source
) -> any
```
## Parameters
- source:
- description: A [path](/docs/reference/syntax/#paths) to an XML file or raw XML bytes.
- type: str | bytes
- default: None
## Definitions
### xml.decode
Reads structured data from an XML string/bytes.
```typst
#xml.decode(
data
) -> any
```
#### Parameters
- data:
- description: XML data.
- type: str | bytes
- default: None
docs/reference/data-loading/yaml.md
# YAML
# yaml
Reads structured data from a YAML file.
The file must contain a valid YAML object or array. The YAML values will be converted into corresponding Typst values as listed in the [table below](#conversion).
The function returns a dictionary, an array or, depending on the YAML file, another YAML data type.
The YAML files in the example contain objects with authors as keys, each with a sequence of their own submapping with the keys "title" and "published".
## Example
```typst
#let bookshelf(contents) = {
for (author, works) in contents {
author
for work in works [
- #work.title (#work.published)
]
}
}
#bookshelf(
yaml("scifi-authors.yaml")
)
```
## Conversion details
| YAML value | Converted into Typst |
| --- | --- |
| null-values (`null`, `~` or empty ``) | `none` |
| boolean | [`bool`](/docs/reference/foundations/bool/) |
| number | [`float`](/docs/reference/foundations/float/) or [`int`](/docs/reference/foundations/int/) |
| string | [`str`](/docs/reference/foundations/str/) |
| sequence | [`array`](/docs/reference/foundations/array/) |
| mapping | [`dictionary`](/docs/reference/foundations/dictionary/) |
| Typst value | Converted into YAML |
| --- | --- |
| types that can be converted from YAML | corresponding YAML value |
| [`bytes`](/docs/reference/foundations/bytes/) | string via [`repr`](/docs/reference/foundations/repr/) |
| [`symbol`](/docs/reference/foundations/symbol/) | string |
| [`content`](/docs/reference/foundations/content/) | a mapping describing the content |
| other types ([`length`](/docs/reference/layout/length/), etc.) | string via [`repr`](/docs/reference/foundations/repr/) |
### Notes
- In most cases, YAML numbers will be converted to floats or integers depending on whether they are whole numbers. However, be aware that integers larger than 263-1 or smaller than -263 will be converted to floating-point numbers, which may result in an approximative value.
- Custom YAML tags are ignored, though the loaded value will still be present.
- Bytes are not encoded as YAML sequences for performance and readability reasons. Consider using [`cbor.encode`](/docs/reference/data-loading/cbor/#definitions-encode) for binary data.
- The `repr` function is [for debugging purposes only](/docs/reference/foundations/repr/#debugging-only), and its output is not guaranteed to be stable across Typst versions.
```typst
#yaml(
source
) -> any
```
## Parameters
- source:
- description: A [path](/docs/reference/syntax/#paths) to a YAML file or raw YAML bytes.
- type: str | bytes
- default: None
## Definitions
### yaml.decode
Reads structured data from a YAML string/bytes.
```typst
#yaml.decode(
data
) -> any
```
#### Parameters
- data:
- description: YAML data.
- type: str | bytes
- default: None
### yaml.encode
Encode structured data into a YAML string.
```typst
#yaml.encode(
value
) -> str
```
#### Parameters
- value:
- description: Value to be encoded.
- type: any
- default: None
docs/reference/foundations/arguments.md
# Arguments
Captured arguments to a function.
## Argument Sinks
Like built-in functions, custom functions can also take a variable number of arguments. You can specify an _argument sink_ which collects all excess arguments as `..sink`. The resulting `sink` value is of the `arguments` type. It exposes methods to access the positional and named arguments.
```typst
#let format(title, ..authors) = {
let by = authors
.pos()
.join(", ", last: " and ")
[*#title* \ _Written by #by;_]
}
#format("ArtosFlow", "Jane", "Joe")
```
## Spreading
Inversely to an argument sink, you can _spread_ arguments, arrays and dictionaries into a function call with the `..spread` operator:
```typst
#let array = (2, 3, 5)
#calc.min(..array)
#let dict = (fill: blue)
#text(..dict)[Hello]
```
## Constructor
## arguments
Construct spreadable arguments in place.
This function behaves like `let args(..sink) = sink`.
```typst
#let args = arguments(stroke: red, inset: 1em, [Body])
#box(..args)
```
```typst
#arguments(
arguments
) -> arguments
```
### Parameters
- arguments:
- description: The arguments to construct.
- type: any
- default: None
## Methods
## arguments.at
Returns the positional argument at the specified index, or the named argument with the specified name.
If the key is an [integer](/docs/reference/foundations/int/), this is equivalent to first calling [`pos`](/docs/reference/foundations/arguments/#definitions-pos) and then [`array.at`](/docs/reference/foundations/array/#definitions-at). If it is a [string](/docs/reference/foundations/str/), this is equivalent to first calling [`named`](/docs/reference/foundations/arguments/#definitions-named) and then [`dictionary.at`](/docs/reference/foundations/dictionary/#definitions-at).
```typst
#arguments.at(
key,
default: any
) -> any
```
### Parameters
- key:
- description: The index or name of the argument to get.
- type: int | str
- default: None
- default:
- description: A default value to return if the key is invalid.
- type: any
- default: None
## arguments.pos
Returns the captured positional arguments as an array.
## arguments.named
Returns the captured named arguments as a dictionary.
docs/reference/foundations/array.md
# Array
A sequence of values.
You can construct an array by enclosing a comma-separated sequence of values in parentheses. The values do not have to be of the same type.
You can access and update array items with the `.at()` method. Indices are zero-based and negative indices wrap around to the end of the array. You can iterate over an array using a [for loop](/docs/reference/scripting/#loops). Arrays can be added together with the `+` operator, [joined together](/docs/reference/scripting/#blocks) and multiplied with integers.
**Note:** An array of length one needs a trailing comma, as in `(1,)`. This is to disambiguate from a simple parenthesized expressions like `(1 + 2) * 3`. An empty array is written as `()`.
## Example
```typst
#let values = (1, 7, 4, -3, 2)
#values.at(0) \
#(values.at(0) = 3)
#values.at(-1) \
#values.find(calc.even) \
#values.filter(calc.odd) \
#values.map(calc.abs) \
#values.rev() \
#(1, (2, 3)).flatten() \
#(("A", "B", "C")
.join(", ", last: " and "))
```
## Constructor
## array
Converts a value to an array.
Note that this function is only intended for conversion of a collection-like value to an array, not for creation of an array from individual items. Use the array syntax `(1, 2, 3)` (or `(1,)` for a single-element array) instead.
```typst
#let hi = "Hello 😃"
#array(bytes(hi))
```
```typst
#array(
value
) -> array
```
### Parameters
- value:
- description: The value that should be converted to an array.
- type: bytes | array | version
- default: None
## Methods
## array.len
The number of values in the array.
## array.first
Returns the first item in the array. May be used on the left-hand side an assignment. Returns the default value if the array is empty or fails with an error is no default value was specified.
```typst
#array.first(
default: any
) -> any
```
### Parameters
- default:
- description: A default value to return if the array is empty.
- type: any
- default: None
## array.last
Returns the last item in the array. May be used on the left-hand side of an assignment. Returns the default value if the array is empty or fails with an error is no default value was specified.
```typst
#array.last(
default: any
) -> any
```
### Parameters
- default:
- description: A default value to return if the array is empty.
- type: any
- default: None
## array.at
Returns the item at the specified index in the array. May be used on the left-hand side of an assignment. Returns the default value if the index is out of bounds or fails with an error if no default value was specified.
```typst
#array.at(
index,
default: any
) -> any
```
### Parameters
- index:
- description: The index at which to retrieve the item. If negative, indexes from the back.
- type: int
- default: None
- default:
- description: A default value to return if the index is out of bounds.
- type: any
- default: None
## array.push
Adds a value to the end of the array.
```typst
#array.push(
value
) ->
```
### Parameters
- value:
- description: The value to insert at the end of the array.
- type: any
- default: None
## array.pop
Removes the last item from the array and returns it. Fails with an error if the array is empty.
## array.insert
Inserts a value into the array at the specified index, shifting all subsequent elements to the right. Fails with an error if the index is out of bounds.
To replace an element of an array, use [`at`](/docs/reference/foundations/array/#definitions-at).
```typst
#array.insert(
index,
value
) ->
```
### Parameters
- index:
- description: The index at which to insert the item. If negative, indexes from the back.
- type: int
- default: None
- value:
- description: The value to insert into the array.
- type: any
- default: None
## array.remove
Removes the value at the specified index from the array and return it.
```typst
#array.remove(
index,
default: any
) -> any
```
### Parameters
- index:
- description: The index at which to remove the item. If negative, indexes from the back.
- type: int
- default: None
- default:
- description: A default value to return if the index is out of bounds.
- type: any
- default: None
## array.slice
Extracts a subslice of the array. Fails with an error if the start or end index is out of bounds.
```typst
#array.slice(
start,
end,
count: int
) -> array
```
### Parameters
- start:
- description: The start index (inclusive). If negative, indexes from the back.
- type: int
- default: None
- end:
- description: The end index (exclusive). If omitted, the whole slice until the end of the array is extracted. If negative, indexes from the back.
- type: none | int
- default: none
- count:
- description: The number of items to extract. This is equivalent to passing `start + count` as the `end` position. Mutually exclusive with `end`.
- type: int
- default: None
## array.contains
Whether the array contains the specified value.
This method also has dedicated syntax: You can write `2 in (1, 2, 3)` instead of `(1, 2, 3).contains(2)`.
```typst
#array.contains(
value
) -> bool
```
### Parameters
- value:
- description: The value to search for.
- type: any
- default: None
## array.find
Searches for an item for which the given function returns `true` and returns the first match or `none` if there is no match.
```typst
#array.find(
searcher
) -> any none
```
### Parameters
- searcher:
- description: The function to apply to each item. Must return a boolean.
- type: function
- default: None
## array.position
Searches for an item for which the given function returns `true` and returns the index of the first match or `none` if there is no match.
```typst
#array.position(
searcher
) -> none int
```
### Parameters
- searcher:
- description: The function to apply to each item. Must return a boolean.
- type: function
- default: None
## array.range
Create an array consisting of a sequence of numbers.
If you pass just one positional parameter, it is interpreted as the `end` of the range. If you pass two, they describe the `start` and `end` of the range.
This function is available both in the array function's scope and globally.
```typst
#range(5) \
#range(2, 5) \
#range(20, step: 4) \
#range(21, step: 4) \
#range(5, 2, step: -1)
```
```typst
#array.range(
start,
end,
step: int
) -> array
```
### Parameters
- start:
- description: The start of the range (inclusive).
- type: int
- default: 0
- end:
- description: The end of the range (exclusive).
- type: int
- default: None
- step:
- description: The distance between the generated numbers.
- type: int
- default: 1
## array.filter
Produces a new array with only the items from the original one for which the given function returns true.
```typst
#array.filter(
test
) -> array
```
### Parameters
- test:
- description: The function to apply to each item. Must return a boolean.
- type: function
- default: None
## array.map
Produces a new array in which all items from the original one were transformed with the given function.
```typst
#array.map(
mapper
) -> array
```
### Parameters
- mapper:
- description: The function to apply to each item.
- type: function
- default: None
## array.enumerate
Returns a new array with the values alongside their indices.
The returned array consists of `(index, value)` pairs in the form of length-2 arrays. These can be [destructured](/docs/reference/scripting/#bindings) with a let binding or for loop.
```typst
#for (i, value) in ("A", "B", "C").enumerate() {
[#i: #value \ ]
}
#("A", "B", "C").enumerate(start: 1)
```
```typst
#array.enumerate(
start: int
) -> array
```
### Parameters
- start:
- description: The index returned for the first pair of the returned list.
- type: int
- default: 0
## array.zip
Zips the array with other arrays.
Returns an array of arrays, where the `i`th inner array contains all the `i`th elements from each original array.
If the arrays to be zipped have different lengths, they are zipped up to the last element of the shortest array and all remaining elements are ignored.
This function is variadic, meaning that you can zip multiple arrays together at once: `(1, 2).zip(("A", "B"), (10, 20))` yields `((1, "A", 10), (2, "B", 20))`.
```typst
#array.zip(
exact: bool,
others
) -> array
```
### Parameters
- exact:
- description: Whether all arrays have to have the same length. For example, `(1, 2).zip((1, 2, 3), exact: true)` produces an error.
- type: bool
- default: false
- others:
- description: The arrays to zip with.
- type: array
- default: None
## array.fold
Folds all items into a single value using an accumulator function.
```typst
#let array = (1, 2, 3, 4)
#array.fold(0, (acc, x) => acc + x)
```
```typst
#array.fold(
init,
folder
) -> any
```
### Parameters
- init:
- description: The initial value to start with.
- type: any
- default: None
- folder:
- description: The folding function. Must have two parameters: One for the accumulated value and one for an item.
- type: function
- default: None
## array.sum
Sums all items (works for all types that can be added).
```typst
#array.sum(
default: any
) -> any
```
### Parameters
- default:
- description: What to return if the array is empty. Must be set if the array can be empty.
- type: any
- default: None
## array.product
Calculates the product of all items (works for all types that can be multiplied).
```typst
#array.product(
default: any
) -> any
```
### Parameters
- default:
- description: What to return if the array is empty. Must be set if the array can be empty.
- type: any
- default: None
## array.any
Whether the given function returns `true` for any item in the array.
```typst
#array.any(
test
) -> bool
```
### Parameters
- test:
- description: The function to apply to each item. Must return a boolean.
- type: function
- default: None
## array.all
Whether the given function returns `true` for all items in the array.
```typst
#array.all(
test
) -> bool
```
### Parameters
- test:
- description: The function to apply to each item. Must return a boolean.
- type: function
- default: None
## array.flatten
Combine all nested arrays into a single flat one.
## array.rev
Return a new array with the same items, but in reverse order.
## array.split
Split the array at occurrences of the specified value.
```typst
#(1, 1, 2, 3, 2, 4, 5).split(2)
```
```typst
#array.split(
at
) -> array
```
### Parameters
- at:
- description: The value to split at.
- type: any
- default: None
## array.join
Combine all items in the array into one.
```typst
#array.join(
separator,
last: any,
default: any | none
) -> any
```
### Parameters
- separator:
- description: A value to insert between each item of the array.
- type: any | none
- default: none
- last:
- description: An alternative separator between the last two items.
- type: any
- default: None
- default:
- description: What to return if the array is empty.
- type: any | none
- default: none
## array.intersperse
Returns an array with a copy of the separator value placed between adjacent elements.
```typst
#("A", "B", "C").intersperse("-")
```
```typst
#array.intersperse(
separator
) -> array
```
### Parameters
- separator:
- description: The value that will be placed between each adjacent element.
- type: any
- default: None
## array.chunks
Splits an array into non-overlapping chunks, starting at the beginning, ending with a single remainder chunk.
All chunks but the last have `chunk-size` elements. If `exact` is set to `true`, the remainder is dropped if it contains less than `chunk-size` elements.
```typst
#let array = (1, 2, 3, 4, 5, 6, 7, 8)
#array.chunks(3) \
#array.chunks(3, exact: true)
```
```typst
#array.chunks(
chunk-size,
exact: bool
) -> array
```
### Parameters
- chunk-size:
- description: How many elements each chunk may at most contain.
- type: int
- default: None
- exact:
- description: Whether to keep the remainder if its size is less than `chunk-size`.
- type: bool
- default: false
## array.windows
Returns sliding windows of `window-size` elements over an array.
If the array length is less than `window-size`, this will return an empty array.
```typst
#let array = (1, 2, 3, 4, 5, 6, 7, 8)
#array.windows(5)
```
```typst
#array.windows(
window-size
) -> array
```
### Parameters
- window-size:
- description: How many elements each window will contain.
- type: int
- default: None
## array.sorted
Return a sorted version of this array, optionally by a given key function. The sorting algorithm used is stable.
Returns an error if a pair of values selected for comparison could not be compared, or if the key or comparison function (if given) yield an error.
To sort according to multiple criteria at once, e.g. in case of equality between some criteria, the key function can return an array. The results are in lexicographic order.
```typst
#let array = (
(a: 2, b: 4),
(a: 1, b: 5),
(a: 2, b: 3),
)
#array.sorted(key: it => (it.a, it.b))
```
```typst
#array.sorted(
key: function,
by: function
) -> array
```
### Parameters
- key:
- description: If given, applies this function to each element in the array to determine the keys to sort by.
- type: function
- default: None
- by:
- description: If given, uses this function to compare every two elements in the array. The function will receive two elements in the array for comparison, and should return a boolean indicating their order: `true` indicates that the elements are in order, while `false` indicates that they should be swapped. To keep the sort stable, if the two elements are equal, the function should return `true`. If this function does not order the elements properly (e.g., by returning `false` for both `(x, y)` and `(y, x)`, or for `(x, x)`), the resulting array will be in unspecified order. When used together with `key`, `by` will be passed the keys instead of the elements. ```typst #( "sorted", "by", "decreasing", "length", ).sorted( key: s => s.len(), by: (l, r) => l >= r, ) ```
- type: function
- default: None
## array.dedup
Deduplicates all items in the array.
Returns a new array with all duplicate items removed. Only the first element of each duplicate is kept.
```typst
#(3, 3, 1, 2, 3).dedup()
```
```typst
#array.dedup(
key: function
) -> array
```
### Parameters
- key:
- description: If given, applies this function to each element in the array to determine the keys to deduplicate by. ```typst #("apple", "banana", " apple ").dedup(key: s => s.trim()) ```
- type: function
- default: None
## array.to-dict
Converts an array of pairs into a dictionary. The first value of each pair is the key, the second the value.
If the same key occurs multiple times, the last value is selected.
```typst
#(
("apples", 2),
("peaches", 3),
("apples", 5),
).to-dict()
```
## array.reduce
Reduces the elements to a single one, by repeatedly applying a reducing operation.
If the array is empty, returns `none`, otherwise, returns the result of the reduction.
The reducing function is a closure with two arguments: an "accumulator", and an element.
For arrays with at least one element, this is the same as [`array.fold`](/docs/reference/foundations/array/#definitions-fold) with the first element of the array as the initial accumulator value, folding every subsequent element into it.
```typst
#let array = (2, 1, 4, 3)
#array.reduce((acc, x) => calc.max(acc, x))
```
```typst
#array.reduce(
reducer
) -> any
```
### Parameters
- reducer:
- description: The reducing function. Must have two parameters: One for the accumulated value and one for an item.
- type: function
- default: None
docs/reference/foundations/assert.md
# Assert
# assert
Ensures that a condition is fulfilled.
Fails with an error if the condition is not fulfilled. Does not produce any output in the document.
If you wish to test equality between two values, see [`assert.eq`](/docs/reference/foundations/assert/#definitions-eq) and [`assert.ne`](/docs/reference/foundations/assert/#definitions-ne).
## Example
```typst
#assert(1 < 2, message: "math broke")
```
```typst
#assert(
condition,
message: str
) ->
```
## Parameters
- condition:
- description: The condition that must be true for the assertion to pass.
- type: bool
- default: None
- message:
- description: The error message when the assertion fails.
- type: str
- default: None
## Definitions
### assert.eq
Ensures that two values are equal.
Fails with an error if the first value is not equal to the second. Does not produce any output in the document.
```typst
#assert.eq(10, 10)
```
```typst
#assert.eq(
left,
right,
message: str
) ->
```
#### Parameters
- left:
- description: The first value to compare.
- type: any
- default: None
- right:
- description: The second value to compare.
- type: any
- default: None
- message:
- description: An optional message to display on error instead of the representations of the compared values.
- type: str
- default: None
### assert.ne
Ensures that two values are not equal.
Fails with an error if the first value is equal to the second. Does not produce any output in the document.
```typst
#assert.ne(3, 4)
```
```typst
#assert.ne(
left,
right,
message: str
) ->
```
#### Parameters
- left:
- description: The first value to compare.
- type: any
- default: None
- right:
- description: The second value to compare.
- type: any
- default: None
- message:
- description: An optional message to display on error instead of the representations of the compared values.
- type: str
- default: None
docs/reference/foundations/auto.md
# Auto
A value that indicates a smart default.
The auto type has exactly one value: `auto`.
Parameters that support the `auto` value have some smart default or contextual behaviour. A good example is the [text direction](/docs/reference/text/text/#parameters-dir) parameter. Setting it to `auto` lets Typst automatically determine the direction from the [text language](/docs/reference/text/text/#parameters-lang).
docs/reference/foundations/bool.md
# Boolean
A type with two states.
The boolean type has two values: `true` and `false`. It denotes whether something is active or enabled.
## Example
```typst
#false \
#true \
#(1 < 2)
```
docs/reference/foundations/bytes.md
# Bytes
A sequence of bytes.
This is conceptually similar to an array of [integers](/docs/reference/foundations/int/) between `0` and `255`, but represented much more efficiently. You can iterate over it using a [for loop](/docs/reference/scripting/#loops).
You can convert
- a [string](/docs/reference/foundations/str/) or an [array](/docs/reference/foundations/array/) of integers to bytes with the [`bytes`](/docs/reference/foundations/bytes/) constructor
- bytes to a string with the [`str`](/docs/reference/foundations/str/) constructor, with UTF-8 encoding
- bytes to an array of integers with the [`array`](/docs/reference/foundations/array/) constructor
When [reading](/docs/reference/data-loading/read/) data from a file, you can decide whether to load it as a string or as raw bytes.
```typst
#bytes((123, 160, 22, 0)) \
#bytes("Hello 😃")
#let data = read(
"rhino.png",
encoding: none,
)
// Magic bytes.
#array(data.slice(0, 4)) \
#str(data.slice(1, 4))
```
## Constructor
## bytes
Converts a value to bytes.
- Strings are encoded in UTF-8.
- Arrays of integers between `0` and `255` are converted directly. The dedicated byte representation is much more efficient than the array representation and thus typically used for large byte buffers (e.g. image data).
```typst
#bytes("Hello 😃") \
#bytes((123, 160, 22, 0))
```
```typst
#bytes(
value
) -> bytes
```
### Parameters
- value:
- description: The value that should be converted to bytes.
- type: str | bytes | array
- default: None
## Methods
## bytes.len
The length in bytes.
## bytes.at
Returns the byte at the specified index. Returns the default value if the index is out of bounds or fails with an error if no default value was specified.
```typst
#bytes.at(
index,
default: any
) -> any
```
### Parameters
- index:
- description: The index at which to retrieve the byte.
- type: int
- default: None
- default:
- description: A default value to return if the index is out of bounds.
- type: any
- default: None
## bytes.slice
Extracts a subslice of the bytes. Fails with an error if the start or end index is out of bounds.
```typst
#bytes.slice(
start,
end,
count: int
) -> bytes
```
### Parameters
- start:
- description: The start index (inclusive).
- type: int
- default: None
- end:
- description: The end index (exclusive). If omitted, the whole slice until the end is extracted.
- type: none | int
- default: none
- count:
- description: The number of items to extract. This is equivalent to passing `start + count` as the `end` position. Mutually exclusive with `end`.
- type: int
- default: None
docs/reference/foundations/calc.md
# Calculation
Module for calculations and processing of numeric values.
These definitions are part of the `calc` module and not imported by default. In addition to the functions listed below, the `calc` module also defines the constants `pi`, `tau`, `e`, and `inf`.
# calc.abs
Calculates the absolute value of a numeric value.
```typst
#calc.abs(-5) \
#calc.abs(5pt - 2cm) \
#calc.abs(2fr) \
#calc.abs(decimal("-342.440"))
```
```typst
#calc.abs(
value
) -> any
```
## Parameters
- value:
- description: The value whose absolute value to calculate.
- type: int | float | length | angle | ratio | fraction | decimal
- default: None
# calc.pow
Raises a value to some exponent.
```typst
#calc.pow(2, 3) \
#calc.pow(decimal("2.5"), 2)
```
```typst
#calc.pow(
base,
exponent
) -> int float decimal
```
## Parameters
- base:
- description: The base of the power. If this is a [`decimal`](/docs/reference/foundations/decimal/), the exponent can only be an [integer](/docs/reference/foundations/int/).
- type: int | float | decimal
- default: None
- exponent:
- description: The exponent of the power.
- type: int | float
- default: None
# calc.exp
Raises a value to some exponent of e.
```typst
#calc.exp(1)
```
```typst
#calc.exp(
exponent
) -> float
```
## Parameters
- exponent:
- description: The exponent of the power.
- type: int | float
- default: None
# calc.sqrt
Calculates the square root of a number.
```typst
#calc.sqrt(16) \
#calc.sqrt(2.5)
```
```typst
#calc.sqrt(
value
) -> float
```
## Parameters
- value:
- description: The number whose square root to calculate. Must be non-negative.
- type: int | float
- default: None
# calc.root
Calculates the real nth root of a number.
If the number is negative, then n must be odd.
```typst
#calc.root(16.0, 4) \
#calc.root(27.0, 3)
```
```typst
#calc.root(
radicand,
index
) -> float
```
## Parameters
- radicand:
- description: The expression to take the root of.
- type: float
- default: None
- index:
- description: Which root of the radicand to take.
- type: int
- default: None
# calc.sin
Calculates the sine of an angle.
When called with an integer or a float, they will be interpreted as radians.
```typst
#calc.sin(1.5) \
#calc.sin(90deg)
```
```typst
#calc.sin(
angle
) -> float
```
## Parameters
- angle:
- description: The angle whose sine to calculate.
- type: int | float | angle
- default: None
# calc.cos
Calculates the cosine of an angle.
When called with an integer or a float, they will be interpreted as radians.
```typst
#calc.cos(1.5) \
#calc.cos(90deg)
```
```typst
#calc.cos(
angle
) -> float
```
## Parameters
- angle:
- description: The angle whose cosine to calculate.
- type: int | float | angle
- default: None
# calc.tan
Calculates the tangent of an angle.
When called with an integer or a float, they will be interpreted as radians.
```typst
#calc.tan(1.5) \
#calc.tan(90deg)
```
```typst
#calc.tan(
angle
) -> float
```
## Parameters
- angle:
- description: The angle whose tangent to calculate.
- type: int | float | angle
- default: None
# calc.asin
Calculates the arcsine of a number.
```typst
#calc.asin(0) \
#calc.asin(1)
```
```typst
#calc.asin(
value
) -> angle
```
## Parameters
- value:
- description: The number whose arcsine to calculate. Must be between -1 and 1.
- type: int | float
- default: None
# calc.acos
Calculates the arccosine of a number.
```typst
#calc.acos(0) \
#calc.acos(1)
```
```typst
#calc.acos(
value
) -> angle
```
## Parameters
- value:
- description: The number whose arccosine to calculate. Must be between -1 and 1.
- type: int | float
- default: None
# calc.atan
Calculates the arctangent of a number.
```typst
#calc.atan(0) \
#calc.atan(1)
```
```typst
#calc.atan(
value
) -> angle
```
## Parameters
- value:
- description: The number whose arctangent to calculate.
- type: int | float
- default: None
# calc.atan2
Calculates the four-quadrant arctangent of a coordinate.
The arguments are `(x, y)`, not `(y, x)`.
```typst
#calc.atan2(1, 1) \
#calc.atan2(-2, -3)
```
```typst
#calc.atan2(
x,
y
) -> angle
```
## Parameters
- x:
- description: The X coordinate.
- type: int | float
- default: None
- y:
- description: The Y coordinate.
- type: int | float
- default: None
# calc.sinh
Calculates the hyperbolic sine of a hyperbolic angle.
```typst
#calc.sinh(0) \
#calc.sinh(1.5)
```
```typst
#calc.sinh(
value
) -> float
```
## Parameters
- value:
- description: The hyperbolic angle whose hyperbolic sine to calculate.
- type: float
- default: None
# calc.cosh
Calculates the hyperbolic cosine of a hyperbolic angle.
```typst
#calc.cosh(0) \
#calc.cosh(1.5)
```
```typst
#calc.cosh(
value
) -> float
```
## Parameters
- value:
- description: The hyperbolic angle whose hyperbolic cosine to calculate.
- type: float
- default: None
# calc.tanh
Calculates the hyperbolic tangent of a hyperbolic angle.
```typst
#calc.tanh(0) \
#calc.tanh(1.5)
```
```typst
#calc.tanh(
value
) -> float
```
## Parameters
- value:
- description: The hyperbolic angle whose hyperbolic tangent to calculate.
- type: float
- default: None
# calc.log
Calculates the logarithm of a number.
If the base is not specified, the logarithm is calculated in base 10.
```typst
#calc.log(100)
```
```typst
#calc.log(
value,
base: float
) -> float
```
## Parameters
- value:
- description: The number whose logarithm to calculate. Must be strictly positive.
- type: int | float
- default: None
- base:
- description: The base of the logarithm. May not be zero.
- type: float
- default: 10.0
# calc.ln
Calculates the natural logarithm of a number.
```typst
#calc.ln(calc.e)
```
```typst
#calc.ln(
value
) -> float
```
## Parameters
- value:
- description: The number whose logarithm to calculate. Must be strictly positive.
- type: int | float
- default: None
# calc.fact
Calculates the factorial of a number.
```typst
#calc.fact(5)
```
```typst
#calc.fact(
number
) -> int
```
## Parameters
- number:
- description: The number whose factorial to calculate. Must be non-negative.
- type: int
- default: None
# calc.perm
Calculates a permutation.
Returns the `k`-permutation of `n`, or the number of ways to choose `k` items from a set of `n` with regard to order.
```typst
$ "perm"(n, k) &= n!/((n - k)!) \
"perm"(5, 3) &= #calc.perm(5, 3) $
```
```typst
#calc.perm(
base,
numbers
) -> int
```
## Parameters
- base:
- description: The base number. Must be non-negative.
- type: int
- default: None
- numbers:
- description: The number of permutations. Must be non-negative.
- type: int
- default: None
# calc.binom
Calculates a binomial coefficient.
Returns the `k`-combination of `n`, or the number of ways to choose `k` items from a set of `n` without regard to order.
```typst
#calc.binom(10, 5)
```
```typst
#calc.binom(
n,
k
) -> int
```
## Parameters
- n:
- description: The upper coefficient. Must be non-negative.
- type: int
- default: None
- k:
- description: The lower coefficient. Must be non-negative.
- type: int
- default: None
# calc.gcd
Calculates the greatest common divisor of two integers.
This will error if the result of integer division would be larger than the maximum 64-bit signed integer.
```typst
#calc.gcd(7, 42)
```
```typst
#calc.gcd(
a,
b
) -> int
```
## Parameters
- a:
- description: The first integer.
- type: int
- default: None
- b:
- description: The second integer.
- type: int
- default: None
# calc.lcm
Calculates the least common multiple of two integers.
```typst
#calc.lcm(96, 13)
```
```typst
#calc.lcm(
a,
b
) -> int
```
## Parameters
- a:
- description: The first integer.
- type: int
- default: None
- b:
- description: The second integer.
- type: int
- default: None
# calc.floor
Rounds a number down to the nearest integer.
If the number is already an integer, it is returned unchanged.
Note that this function will always return an [integer](/docs/reference/foundations/int/), and will error if the resulting [`float`](/docs/reference/foundations/float/) or [`decimal`](/docs/reference/foundations/decimal/) is larger than the maximum 64-bit signed integer or smaller than the minimum for that type.
```typst
#calc.floor(500.1)
#assert(calc.floor(3) == 3)
#assert(calc.floor(3.14) == 3)
#assert(calc.floor(decimal("-3.14")) == -4)
```
```typst
#calc.floor(
value
) -> int
```
## Parameters
- value:
- description: The number to round down.
- type: int | float | decimal
- default: None
# calc.ceil
Rounds a number up to the nearest integer.
If the number is already an integer, it is returned unchanged.
Note that this function will always return an [integer](/docs/reference/foundations/int/), and will error if the resulting [`float`](/docs/reference/foundations/float/) or [`decimal`](/docs/reference/foundations/decimal/) is larger than the maximum 64-bit signed integer or smaller than the minimum for that type.
```typst
#calc.ceil(500.1)
#assert(calc.ceil(3) == 3)
#assert(calc.ceil(3.14) == 4)
#assert(calc.ceil(decimal("-3.14")) == -3)
```
```typst
#calc.ceil(
value
) -> int
```
## Parameters
- value:
- description: The number to round up.
- type: int | float | decimal
- default: None
# calc.trunc
Returns the integer part of a number.
If the number is already an integer, it is returned unchanged.
Note that this function will always return an [integer](/docs/reference/foundations/int/), and will error if the resulting [`float`](/docs/reference/foundations/float/) or [`decimal`](/docs/reference/foundations/decimal/) is larger than the maximum 64-bit signed integer or smaller than the minimum for that type.
```typst
#calc.trunc(15.9)
#assert(calc.trunc(3) == 3)
#assert(calc.trunc(-3.7) == -3)
#assert(calc.trunc(decimal("8493.12949582390")) == 8493)
```
```typst
#calc.trunc(
value
) -> int
```
## Parameters
- value:
- description: The number to truncate.
- type: int | float | decimal
- default: None
# calc.fract
Returns the fractional part of a number.
If the number is an integer, returns `0`.
```typst
#calc.fract(-3.1)
#assert(calc.fract(3) == 0)
#assert(calc.fract(decimal("234.23949211")) == decimal("0.23949211"))
```
```typst
#calc.fract(
value
) -> int float decimal
```
## Parameters
- value:
- description: The number to truncate.
- type: int | float | decimal
- default: None
# calc.round
Rounds a number to the nearest integer.
Half-integers are rounded away from zero.
Optionally, a number of decimal places can be specified. If negative, its absolute value will indicate the amount of significant integer digits to remove before the decimal point.
Note that this function will return the same type as the operand. That is, applying `round` to a [`float`](/docs/reference/foundations/float/) will return a `float`, and to a [`decimal`](/docs/reference/foundations/decimal/), another `decimal`. You may explicitly convert the output of this function to an integer with [`int`](/docs/reference/foundations/int/), but note that such a conversion will error if the `float` or `decimal` is larger than the maximum 64-bit signed integer or smaller than the minimum integer.
In addition, this function can error if there is an attempt to round beyond the maximum or minimum integer or `decimal`. If the number is a `float`, such an attempt will cause `float.inf` or `-float.inf` to be returned for maximum and minimum respectively.
```typst
#calc.round(3.1415, digits: 2)
#assert(calc.round(3) == 3)
#assert(calc.round(3.14) == 3)
#assert(calc.round(3.5) == 4.0)
#assert(calc.round(3333.45, digits: -2) == 3300.0)
#assert(calc.round(-48953.45, digits: -3) == -49000.0)
#assert(calc.round(3333, digits: -2) == 3300)
#assert(calc.round(-48953, digits: -3) == -49000)
#assert(calc.round(decimal("-6.5")) == decimal("-7"))
#assert(calc.round(decimal("7.123456789"), digits: 6) == decimal("7.123457"))
#assert(calc.round(decimal("3333.45"), digits: -2) == decimal("3300"))
#assert(calc.round(decimal("-48953.45"), digits: -3) == decimal("-49000"))
```
```typst
#calc.round(
value,
digits: int
) -> int float decimal
```
## Parameters
- value:
- description: The number to round.
- type: int | float | decimal
- default: None
- digits:
- description: If positive, the number of decimal places. If negative, the number of significant integer digits that should be removed before the decimal point.
- type: int
- default: 0
# calc.clamp
Clamps a number between a minimum and maximum value.
```typst
#calc.clamp(5, 0, 4)
#assert(calc.clamp(5, 0, 10) == 5)
#assert(calc.clamp(5, 6, 10) == 6)
#assert(calc.clamp(decimal("5.45"), 2, decimal("45.9")) == decimal("5.45"))
#assert(calc.clamp(decimal("5.45"), decimal("6.75"), 12) == decimal("6.75"))
```
```typst
#calc.clamp(
value,
min,
max
) -> int float decimal
```
## Parameters
- value:
- description: The number to clamp.
- type: int | float | decimal
- default: None
- min:
- description: The inclusive minimum value.
- type: int | float | decimal
- default: None
- max:
- description: The inclusive maximum value.
- type: int | float | decimal
- default: None
# calc.min
Determines the minimum of a sequence of values.
```typst
#calc.min(1, -3, -5, 20, 3, 6) \
#calc.min("typst", "is", "cool")
```
```typst
#calc.min(
values
) -> any
```
## Parameters
- values:
- description: The sequence of values from which to extract the minimum. Must not be empty.
- type: any
- default: None
# calc.max
Determines the maximum of a sequence of values.
```typst
#calc.max(1, -3, -5, 20, 3, 6) \
#calc.max("typst", "is", "cool")
```
```typst
#calc.max(
values
) -> any
```
## Parameters
- values:
- description: The sequence of values from which to extract the maximum. Must not be empty.
- type: any
- default: None
# calc.even
Determines whether an integer is even.
```typst
#calc.even(4) \
#calc.even(5) \
#range(10).filter(calc.even)
```
```typst
#calc.even(
value
) -> bool
```
## Parameters
- value:
- description: The number to check for evenness.
- type: int
- default: None
# calc.odd
Determines whether an integer is odd.
```typst
#calc.odd(4) \
#calc.odd(5) \
#range(10).filter(calc.odd)
```
```typst
#calc.odd(
value
) -> bool
```
## Parameters
- value:
- description: The number to check for oddness.
- type: int
- default: None
# calc.rem
Calculates the remainder of two numbers.
The value `calc.rem(x, y)` always has the same sign as `x`, and is smaller in magnitude than `y`.
This can error if given a [`decimal`](/docs/reference/foundations/decimal/) input and the dividend is too small in magnitude compared to the divisor.
```typst
#calc.rem(7, 3) \
#calc.rem(7, -3) \
#calc.rem(-7, 3) \
#calc.rem(-7, -3) \
#calc.rem(1.75, 0.5)
```
```typst
#calc.rem(
dividend,
divisor
) -> int float decimal
```
## Parameters
- dividend:
- description: The dividend of the remainder.
- type: int | float | decimal
- default: None
- divisor:
- description: The divisor of the remainder.
- type: int | float | decimal
- default: None
# calc.div-euclid
Performs euclidean division of two numbers.
The result of this computation is that of a division rounded to the integer `n` such that the dividend is greater than or equal to `n` times the divisor.
This can error if the resulting number is larger than the maximum value or smaller than the minimum value for its type.
```typst
#calc.div-euclid(7, 3) \
#calc.div-euclid(7, -3) \
#calc.div-euclid(-7, 3) \
#calc.div-euclid(-7, -3) \
#calc.div-euclid(1.75, 0.5) \
#calc.div-euclid(decimal("1.75"), decimal("0.5"))
```
```typst
#calc.div-euclid(
dividend,
divisor
) -> int float decimal
```
## Parameters
- dividend:
- description: The dividend of the division.
- type: int | float | decimal
- default: None
- divisor:
- description: The divisor of the division.
- type: int | float | decimal
- default: None
# calc.rem-euclid
This calculates the least nonnegative remainder of a division.
Warning: Due to a floating point round-off error, the remainder may equal the absolute value of the divisor if the dividend is much smaller in magnitude than the divisor and the dividend is negative. This only applies for floating point inputs.
In addition, this can error if given a [`decimal`](/docs/reference/foundations/decimal/) input and the dividend is too small in magnitude compared to the divisor.
```typst
#calc.rem-euclid(7, 3) \
#calc.rem-euclid(7, -3) \
#calc.rem-euclid(-7, 3) \
#calc.rem-euclid(-7, -3) \
#calc.rem-euclid(1.75, 0.5) \
#calc.rem-euclid(decimal("1.75"), decimal("0.5"))
```
```typst
#calc.rem-euclid(
dividend,
divisor
) -> int float decimal
```
## Parameters
- dividend:
- description: The dividend of the remainder.
- type: int | float | decimal
- default: None
- divisor:
- description: The divisor of the remainder.
- type: int | float | decimal
- default: None
# calc.quo
Calculates the quotient (floored division) of two numbers.
Note that this function will always return an [integer](/docs/reference/foundations/int/), and will error if the resulting number is larger than the maximum 64-bit signed integer or smaller than the minimum for that type.
```typst
$ "quo"(a, b) &= floor(a/b) \
"quo"(14, 5) &= #calc.quo(14, 5) \
"quo"(3.46, 0.5) &= #calc.quo(3.46, 0.5) $
```
```typst
#calc.quo(
dividend,
divisor
) -> int
```
## Parameters
- dividend:
- description: The dividend of the quotient.
- type: int | float | decimal
- default: None
- divisor:
- description: The divisor of the quotient.
- type: int | float | decimal
- default: None
# calc.norm
Calculates the p-norm of a sequence of values.
```typst
#calc.norm(1, 2, -3, 0.5) \
#calc.norm(p: 3, 1, 2)
```
```typst
#calc.norm(
p: float,
values
) -> float
```
## Parameters
- p:
- description: The p value to calculate the p-norm of.
- type: float
- default: 2.0
- values:
- description: The sequence of values from which to calculate the p-norm. Returns `0.0` if empty.
- type: float
- default: None
docs/reference/foundations/content.md
# Content
A piece of document content.
This type is at the heart of Typst. All markup you write and most [functions](/docs/reference/foundations/function/) you call produce content values. You can create a content value by enclosing markup in square brackets. This is also how you pass content to functions.
## Example
```typst
Type of *Hello!* is
#type([*Hello!*])
```
Content can be added with the `+` operator, [joined together](/docs/reference/scripting/#blocks) and multiplied with integers. Wherever content is expected, you can also pass a [string](/docs/reference/foundations/str/) or `none`.
## Representation
Content consists of elements with fields. When constructing an element with its _element function,_ you provide these fields as arguments and when you have a content value, you can access its fields with [field access syntax](/docs/reference/scripting/#field-access).
Some fields are required: These must be provided when constructing an element and as a consequence, they are always available through field access on content of that type. Required fields are marked as such in the documentation.
Most fields are optional: Like required fields, they can be passed to the element function to configure them for a single element. However, these can also be configured with [set rules](/docs/reference/styling/#set-rules) to apply them to all elements within a scope. Optional fields are only available with field access syntax when they were explicitly passed to the element function, not when they result from a set rule.
Each element has a default appearance. However, you can also completely customize its appearance with a [show rule](/docs/reference/styling/#show-rules). The show rule is passed the element. It can access the element's field and produce arbitrary content from it.
In the web app, you can hover over a content variable to see exactly which elements the content is composed of and what fields they have. Alternatively, you can inspect the output of the [`repr`](/docs/reference/foundations/repr/) function.
## Methods
## content.func
The content's element function. This function can be used to create the element contained in this content. It can be used in set and show rules for the element. Can be compared with global functions to check whether you have a specific kind of element.
## content.has
Whether the content has the specified field.
```typst
#content.has(
field
) -> bool
```
### Parameters
- field:
- description: The field to look for.
- type: str
- default: None
## content.at
Access the specified field on the content. Returns the default value if the field does not exist or fails with an error if no default value was specified.
```typst
#content.at(
field,
default: any
) -> any
```
### Parameters
- field:
- description: The field to access.
- type: str
- default: None
- default:
- description: A default value to return if the field does not exist.
- type: any
- default: None
## content.fields
Returns the fields of this content.
```typst
#rect(
width: 10cm,
height: 10cm,
).fields()
```
## content.location
The location of the content. This is only available on content returned by [query](/docs/reference/introspection/query/) or provided by a [show rule](/docs/reference/styling/#show-rules), for other content it will be `none`. The resulting location can be used with [counters](/docs/reference/introspection/counter/), [state](/docs/reference/introspection/state/) and [queries](/docs/reference/introspection/query/).
docs/reference/foundations/datetime.md
# Datetime
Represents a date, a time, or a combination of both.
Can be created by either specifying a custom datetime using this type's constructor function or getting the current date with [`datetime.today`](/docs/reference/foundations/datetime/#definitions-today).
## Example
```typst
#let date = datetime(
year: 2020,
month: 10,
day: 4,
)
#date.display() \
#date.display(
"y:[year repr:last_two]"
)
#let time = datetime(
hour: 18,
minute: 2,
second: 23,
)
#time.display() \
#time.display(
"h:[hour repr:12][period]"
)
```
## Datetime and Duration
You can get a [duration](/docs/reference/foundations/duration/) by subtracting two datetime:
```typst
#let first-of-march = datetime(day: 1, month: 3, year: 2024)
#let first-of-jan = datetime(day: 1, month: 1, year: 2024)
#let distance = first-of-march - first-of-jan
#distance.hours()
```
You can also add/subtract a datetime and a duration to retrieve a new, offset datetime:
```typst
#let date = datetime(day: 1, month: 3, year: 2024)
#let two-days = duration(days: 2)
#let two-days-earlier = date - two-days
#let two-days-later = date + two-days
#date.display() \
#two-days-earlier.display() \
#two-days-later.display()
```
## Format
You can specify a customized formatting using the [`display`](/docs/reference/foundations/datetime/#definitions-display) method. The format of a datetime is specified by providing _components_ with a specified number of _modifiers_. A component represents a certain part of the datetime that you want to display, and with the help of modifiers you can define how you want to display that component. In order to display a component, you wrap the name of the component in square brackets (e.g. `[year]` will display the year). In order to add modifiers, you add a space after the component name followed by the name of the modifier, a colon and the value of the modifier (e.g. `[month repr:short]` will display the short representation of the month).
The possible combination of components and their respective modifiers is as follows:
- `year`: Displays the year of the datetime.
- `padding`: Can be either `zero`, `space` or `none`. Specifies how the year is padded.
- `repr` Can be either `full` in which case the full year is displayed or `last_two` in which case only the last two digits are displayed.
- `sign`: Can be either `automatic` or `mandatory`. Specifies when the sign should be displayed.
- `month`: Displays the month of the datetime.
- `padding`: Can be either `zero`, `space` or `none`. Specifies how the month is padded.
- `repr`: Can be either `numerical`, `long` or `short`. Specifies if the month should be displayed as a number or a word. Unfortunately, when choosing the word representation, it can currently only display the English version. In the future, it is planned to support localization.
- `day`: Displays the day of the datetime.
- `padding`: Can be either `zero`, `space` or `none`. Specifies how the day is padded.
- `week_number`: Displays the week number of the datetime.
- `padding`: Can be either `zero`, `space` or `none`. Specifies how the week number is padded.
- `repr`: Can be either `ISO`, `sunday` or `monday`. In the case of `ISO`, week numbers are between 1 and 53, while the other ones are between 0 and 53.
- `weekday`: Displays the weekday of the date.
- `repr` Can be either `long`, `short`, `sunday` or `monday`. In the case of `long` and `short`, the corresponding English name will be displayed (same as for the month, other languages are currently not supported). In the case of `sunday` and `monday`, the numerical value will be displayed (assuming Sunday and Monday as the first day of the week, respectively).
- `one_indexed`: Can be either `true` or `false`. Defines whether the numerical representation of the week starts with 0 or 1.
- `hour`: Displays the hour of the date.
- `padding`: Can be either `zero`, `space` or `none`. Specifies how the hour is padded.
- `repr`: Can be either `24` or `12`. Changes whether the hour is displayed in the 24-hour or 12-hour format.
- `period`: The AM/PM part of the hour
- `case`: Can be `lower` to display it in lower case and `upper` to display it in upper case.
- `minute`: Displays the minute of the date.
- `padding`: Can be either `zero`, `space` or `none`. Specifies how the minute is padded.
- `second`: Displays the second of the date.
- `padding`: Can be either `zero`, `space` or `none`. Specifies how the second is padded.
Keep in mind that not always all components can be used. For example, if you create a new datetime with `datetime(year: 2023, month: 10, day: 13)`, it will be stored as a plain date internally, meaning that you cannot use components such as `hour` or `minute`, which would only work on datetimes that have a specified time.
## Constructor
## datetime
Creates a new datetime.
You can specify the [datetime](/docs/reference/foundations/datetime/) using a year, month, day, hour, minute, and second.
_Note_: Depending on which components of the datetime you specify, Typst will store it in one of the following three ways:
- If you specify year, month and day, Typst will store just a date.
- If you specify hour, minute and second, Typst will store just a time.
- If you specify all of year, month, day, hour, minute and second, Typst will store a full datetime.
Depending on how it is stored, the [`display`](/docs/reference/foundations/datetime/#definitions-display) method will choose a different formatting by default.
```typst
#datetime(
year: 2012,
month: 8,
day: 3,
).display()
```
```typst
#datetime(
year: int,
month: int,
day: int,
hour: int,
minute: int,
second: int
) -> datetime
```
### Parameters
- year:
- description: The year of the datetime.
- type: int
- default: None
- month:
- description: The month of the datetime.
- type: int
- default: None
- day:
- description: The day of the datetime.
- type: int
- default: None
- hour:
- description: The hour of the datetime.
- type: int
- default: None
- minute:
- description: The minute of the datetime.
- type: int
- default: None
- second:
- description: The second of the datetime.
- type: int
- default: None
## Methods
## datetime.today
Returns the current date.
In the CLI, this can be overridden with the `--creation-timestamp` argument or by setting the [`SOURCE_DATE_EPOCH`](https://reproducible-builds.org/specs/source-date-epoch/) environment variable. In both cases, the value should be given as a UNIX timestamp.
```typst
Today's date is
#datetime.today().display().
```
```typst
#datetime.today(
offset: auto | int
) -> datetime
```
### Parameters
- offset:
- description: An offset to apply to the current UTC date. If set to `auto`, the offset will be the local offset.
- type: auto | int
- default: auto
## datetime.display
Displays the datetime in a specified format.
Depending on whether you have defined just a date, a time or both, the default format will be different. If you specified a date, it will be `[year]-[month]-[day]`. If you specified a time, it will be `[hour]:[minute]:[second]`. In the case of a datetime, it will be `[year]-[month]-[day] [hour]:[minute]:[second]`.
See the [format syntax](/docs/reference/foundations/datetime/#format) for more information.
```typst
#datetime.display(
pattern
) -> str
```
### Parameters
- pattern:
- description: The format used to display the datetime.
- type: auto | str
- default: auto
## datetime.year
The year if it was specified, or `none` for times without a date.
## datetime.month
The month if it was specified, or `none` for times without a date.
## datetime.weekday
The weekday (counting Monday as 1) or `none` for times without a date.
## datetime.day
The day if it was specified, or `none` for times without a date.
## datetime.hour
The hour if it was specified, or `none` for dates without a time.
## datetime.minute
The minute if it was specified, or `none` for dates without a time.
## datetime.second
The second if it was specified, or `none` for dates without a time.
## datetime.ordinal
The ordinal (day of the year), or `none` for times without a date.
docs/reference/foundations/decimal.md
# Decimal
A fixed-point decimal number type.
This type should be used for precise arithmetic operations on numbers represented in base 10. A typical use case is representing currency.
## Example
```typst
Decimal: #(decimal("0.1") + decimal("0.2")) \
Float: #(0.1 + 0.2)
```
## Construction and casts
To create a decimal number, use the `decimal(string)` constructor, such as in `decimal("3.141592653")` **(note the double quotes!)**. This constructor preserves all given fractional digits, provided they are representable as per the limits specified below (otherwise, an error is raised).
You can also convert any [integer](/docs/reference/foundations/int/) to a decimal with the `decimal(int)` constructor, e.g. `decimal(59)`. However, note that constructing a decimal from a [floating-point number](/docs/reference/foundations/float/), while supported, **is an imprecise conversion and therefore discouraged.** A warning will be raised if Typst detects that there was an accidental `float` to `decimal` cast through its constructor, e.g. if writing `decimal(3.14)` (note the lack of double quotes, indicating this is an accidental `float` cast and therefore imprecise). It is recommended to use strings for constant decimal values instead (e.g. `decimal("3.14")`).
The precision of a `float` to `decimal` cast can be slightly improved by rounding the result to 15 digits with [`calc.round`](/docs/reference/foundations/calc/#functions-round), but there are still no precision guarantees for that kind of conversion.
## Operations
Basic arithmetic operations are supported on two decimals and on pairs of decimals and integers.
Built-in operations between `float` and `decimal` are not supported in order to guard against accidental loss of precision. They will raise an error instead.
Certain `calc` functions, such as trigonometric functions and power between two real numbers, are also only supported for `float` (although raising `decimal` to integer exponents is supported). You can opt into potentially imprecise operations with the `float(decimal)` constructor, which casts the `decimal` number into a `float`, allowing for operations without precision guarantees.
## Displaying decimals
To display a decimal, simply insert the value into the document. To only display a certain number of digits, [round](/docs/reference/foundations/calc/#functions-round) the decimal first. Localized formatting of decimals and other numbers is not yet supported, but planned for the future.
You can convert decimals to strings using the [`str`](/docs/reference/foundations/str/) constructor. This way, you can post-process the displayed representation, e.g. to replace the period with a comma (as a stand-in for proper built-in localization to languages that use the comma).
## Precision and limits
A `decimal` number has a limit of 28 to 29 significant base-10 digits. This includes the sum of digits before and after the decimal point. As such, numbers with more fractional digits have a smaller range. The maximum and minimum `decimal` numbers have a value of `79228162514264337593543950335` and `-79228162514264337593543950335` respectively. In contrast with [`float`](/docs/reference/foundations/float/), this type does not support infinity or NaN, so overflowing or underflowing operations will raise an error.
Typical operations between `decimal` numbers, such as addition, multiplication, and [power](/docs/reference/foundations/calc/#functions-pow) to an integer, will be highly precise due to their fixed-point representation. Note, however, that multiplication and division may not preserve all digits in some edge cases: while they are considered precise, digits past the limits specified above are rounded off and lost, so some loss of precision beyond the maximum representable digits is possible. Note that this behavior can be observed not only when dividing, but also when multiplying by numbers between 0 and 1, as both operations can push a number's fractional digits beyond the limits described above, leading to rounding. When those two operations do not surpass the digit limits, they are fully precise.
## Constructor
## decimal
Converts a value to a `decimal`.
It is recommended to use a string to construct the decimal number, or an [integer](/docs/reference/foundations/int/) (if desired). The string must contain a number in the format `"3.14159"` (or `"-3.141519"` for negative numbers). The fractional digits are fully preserved; if that's not possible due to the limit of significant digits (around 28 to 29) having been reached, an error is raised as the given decimal number wouldn't be representable.
While this constructor can be used with [floating-point numbers](/docs/reference/foundations/float/) to cast them to `decimal`, doing so is **discouraged** as **this cast is
inherently imprecise.** It is easy to accidentally perform this cast by writing `decimal(1.234)` (note the lack of double quotes), which is why Typst will emit a warning in that case. Please write `decimal("1.234")` instead for that particular case (initialization of a constant decimal). Also note that floats that are NaN or infinite cannot be cast to decimals and will raise an error.
```typst
#decimal("1.222222222222222")
```
```typst
#decimal(
value
) -> decimal
```
### Parameters
- value:
- description: The value that should be converted to a decimal.
- type: bool | int | float | str | decimal
- default: None
docs/reference/foundations/dictionary.md
# Dictionary
A map from string keys to values.
You can construct a dictionary by enclosing comma-separated `key: value` pairs in parentheses. The values do not have to be of the same type. Since empty parentheses already yield an empty array, you have to use the special `(:)` syntax to create an empty dictionary.
A dictionary is conceptually similar to an [array](/docs/reference/foundations/array/), but it is indexed by strings instead of integers. You can access and create dictionary entries with the `.at()` method. If you know the key statically, you can alternatively use [field access notation](/docs/reference/scripting/#fields) (`.key`) to access the value. To check whether a key is present in the dictionary, use the `in` keyword.
You can iterate over the pairs in a dictionary using a [for loop](/docs/reference/scripting/#loops). This will iterate in the order the pairs were inserted / declared initially.
Dictionaries can be added with the `+` operator and [joined together](/docs/reference/scripting/#blocks). They can also be [spread](/docs/reference/foundations/arguments/#spreading) into a function call or another dictionary[1](#1) with the `..spread` operator. In each case, if a key appears multiple times, the last value will override the others.
## Example
```typst
#let dict = (
name: "Typst",
born: 2019,
)
#dict.name \
#(dict.launch = 20)
#dict.len() \
#dict.keys() \
#dict.values() \
#dict.at("born") \
#dict.insert("city", "Berlin")
#("name" in dict)
```
[^1]: When spreading into a dictionary, if all items between the parentheses are spread, you have to use the special `(:..spread)` syntax. Otherwise, it will spread into an array.
## Constructor
## dictionary
Converts a value into a dictionary.
Note that this function is only intended for conversion of a dictionary-like value to a dictionary, not for creation of a dictionary from individual pairs. Use the dictionary syntax `(key: value)` instead.
```typst
#dictionary(sys).at("version")
```
```typst
#dictionary(
value
) -> dictionary
```
### Parameters
- value:
- description: The value that should be converted to a dictionary.
- type: module
- default: None
## Methods
## dictionary.len
The number of pairs in the dictionary.
## dictionary.at
Returns the value associated with the specified key in the dictionary. May be used on the left-hand side of an assignment if the key is already present in the dictionary. Returns the default value if the key is not part of the dictionary or fails with an error if no default value was specified.
```typst
#dictionary.at(
key,
default: any
) -> any
```
### Parameters
- key:
- description: The key at which to retrieve the item.
- type: str
- default: None
- default:
- description: A default value to return if the key is not part of the dictionary.
- type: any
- default: None
## dictionary.insert
Inserts a new pair into the dictionary. If the dictionary already contains this key, the value is updated.
To insert multiple pairs at once, you can just alternatively another dictionary with the `+=` operator.
```typst
#dictionary.insert(
key,
value
) ->
```
### Parameters
- key:
- description: The key of the pair that should be inserted.
- type: str
- default: None
- value:
- description: The value of the pair that should be inserted.
- type: any
- default: None
## dictionary.remove
Removes a pair from the dictionary by key and return the value.
```typst
#dictionary.remove(
key,
default: any
) -> any
```
### Parameters
- key:
- description: The key of the pair to remove.
- type: str
- default: None
- default:
- description: A default value to return if the key does not exist.
- type: any
- default: None
## dictionary.keys
Returns the keys of the dictionary as an array in insertion order.
## dictionary.values
Returns the values of the dictionary as an array in insertion order.
## dictionary.pairs
Returns the keys and values of the dictionary as an array of pairs. Each pair is represented as an array of length two.
docs/reference/foundations/duration.md
# Duration
Represents a positive or negative span of time.
## Constructor
## duration
Creates a new duration.
You can specify the [duration](/docs/reference/foundations/duration/) using weeks, days, hours, minutes and seconds. You can also get a duration by subtracting two [datetimes](/docs/reference/foundations/datetime/).
```typst
#duration(
days: 3,
hours: 12,
).hours()
```
```typst
#duration(
seconds: int,
minutes: int,
hours: int,
days: int,
weeks: int
) -> duration
```
### Parameters
- seconds:
- description: The number of seconds.
- type: int
- default: 0
- minutes:
- description: The number of minutes.
- type: int
- default: 0
- hours:
- description: The number of hours.
- type: int
- default: 0
- days:
- description: The number of days.
- type: int
- default: 0
- weeks:
- description: The number of weeks.
- type: int
- default: 0
## Methods
## duration.seconds
The duration expressed in seconds.
This function returns the total duration represented in seconds as a floating-point number rather than the second component of the duration.
## duration.minutes
The duration expressed in minutes.
This function returns the total duration represented in minutes as a floating-point number rather than the second component of the duration.
## duration.hours
The duration expressed in hours.
This function returns the total duration represented in hours as a floating-point number rather than the second component of the duration.
## duration.days
The duration expressed in days.
This function returns the total duration represented in days as a floating-point number rather than the second component of the duration.
## duration.weeks
The duration expressed in weeks.
This function returns the total duration represented in weeks as a floating-point number rather than the second component of the duration.
docs/reference/foundations/eval.md
# Evaluate
# eval
Evaluates a string as Typst code.
This function should only be used as a last resort.
## Example
```typst
#eval("1 + 1") \
#eval("(1, 2, 3, 4)").len() \
#eval("*Markup!*", mode: "markup") \
```
```typst
#eval(
source,
mode: str,
scope: dictionary
) -> any
```
## Parameters
- source:
- description: A string of Typst code to evaluate.
- type: str
- default: None
- mode:
- description: The [syntactical mode](/docs/reference/syntax/#modes) in which the string is parsed. ```typst #eval("= Heading", mode: "markup") #eval("1_2^3", mode: "math") ```
- type: str
- default: "code"
- scope:
- description: A scope of definitions that are made available. ```typst #eval("x + 1", scope: (x: 2)) \\ #eval( "abc/xyz", mode: "math", scope: ( abc: $a + b + c$, xyz: $x + y + z$, ), ) ```
- type: dictionary
- default: (:)
docs/reference/foundations/float.md
# Float
A floating-point number.
A limited-precision representation of a real number. Typst uses 64 bits to store floats. Wherever a float is expected, you can also pass an [integer](/docs/reference/foundations/int/).
You can convert a value to a float with this type's constructor.
NaN and positive infinity are available as `float.nan` and `float.inf` respectively.
## Example
```typst
#3.14 \
#1e4 \
#(10 / 4)
```
## Constructor
## float
Converts a value to a float.
- Booleans are converted to `0.0` or `1.0`.
- Integers are converted to the closest 64-bit float. For integers with absolute value less than `calc.pow(2, 53)`, this conversion is exact.
- Ratios are divided by 100%.
- Strings are parsed in base 10 to the closest 64-bit float. Exponential notation is supported.
```typst
#float(false) \
#float(true) \
#float(4) \
#float(40%) \
#float("2.7") \
#float("1e5")
```
```typst
#float(
value
) -> float
```
### Parameters
- value:
- description: The value that should be converted to a float.
- type: bool | int | float | ratio | str | decimal
- default: None
## Methods
## float.is-nan
Checks if a float is not a number.
In IEEE 754, more than one bit pattern represents a NaN. This function returns `true` if the float is any of those bit patterns.
```typst
#float.is-nan(0) \
#float.is-nan(1) \
#float.is-nan(float.nan)
```
## float.is-infinite
Checks if a float is infinite.
Floats can represent positive infinity and negative infinity. This function returns `true` if the float is an infinity.
```typst
#float.is-infinite(0) \
#float.is-infinite(1) \
#float.is-infinite(float.inf)
```
## float.signum
Calculates the sign of a floating point number.
- If the number is positive (including `+0.0`), returns `1.0`.
- If the number is negative (including `-0.0`), returns `-1.0`.
- If the number is NaN, returns `float.nan`.
```typst
#(5.0).signum() \
#(-5.0).signum() \
#(0.0).signum() \
#float.nan.signum()
```
## float.from-bytes
Interprets bytes as a float.
```typst
#float.from-bytes(bytes((0, 0, 0, 0, 0, 0, 240, 63))) \
#float.from-bytes(bytes((63, 240, 0, 0, 0, 0, 0, 0)), endian: "big")
```
```typst
#float.from-bytes(
bytes,
endian: str
) -> float
```
### Parameters
- bytes:
- description: The bytes that should be converted to a float. Must have a length of either 4 or 8. The bytes are then interpreted in [IEEE 754](https://en.wikipedia.org/wiki/IEEE_754)\'s binary32 (single-precision) or binary64 (double-precision) format depending on the length of the bytes.
- type: bytes
- default: None
- endian:
- description: The endianness of the conversion.
- type: str
- default: "little"
## float.to-bytes
Converts a float to bytes.
```typst
#array(1.0.to-bytes(endian: "big")) \
#array(1.0.to-bytes())
```
```typst
#float.to-bytes(
endian: str,
size: int
) -> bytes
```
### Parameters
- endian:
- description: The endianness of the conversion.
- type: str
- default: "little"
- size:
- description: The size of the resulting bytes. This must be either 4 or 8. The call will return the representation of this float in either [IEEE 754](https://en.wikipedia.org/wiki/IEEE_754)\'s binary32 (single-precision) or binary64 (double-precision) format depending on the provided size.
- type: int
- default: 8
docs/reference/foundations/function.md
# Function
A mapping from argument values to a return value.
You can call a function by writing a comma-separated list of function _arguments_ enclosed in parentheses directly after the function name. Additionally, you can pass any number of trailing content block arguments to a function _after_ the normal argument list. If the normal argument list would become empty, it can be omitted. Typst supports positional and named arguments. The former are identified by position and type, while the latter are written as `name: value`.
Within math mode, function calls have special behaviour. See the [math documentation](/docs/reference/math/) for more details.
## Example
```typst
// Call a function.
#list([A], [B])
// Named arguments and trailing
// content blocks.
#enum(start: 2)[A][B]
// Version without parentheses.
#list[A][B]
```
Functions are a fundamental building block of Typst. Typst provides functions for a variety of typesetting tasks. Moreover, the markup you write is backed by functions and all styling happens through functions. This reference lists all available functions and how you can use them. Please also refer to the documentation about [set](/docs/reference/styling/#set-rules) and [show](/docs/reference/styling/#show-rules) rules to learn about additional ways you can work with functions in Typst.
## Element functions
Some functions are associated with _elements_ like [headings](/docs/reference/model/heading/) or [tables](/docs/reference/model/table/). When called, these create an element of their respective kind. In contrast to normal functions, they can further be used in [set rules](/docs/reference/styling/#set-rules), [show rules](/docs/reference/styling/#show-rules), and [selectors](/docs/reference/foundations/selector/).
## Function scopes
Functions can hold related definitions in their own scope, similar to a [module](/docs/reference/scripting/#modules). Examples of this are [`assert.eq`](/docs/reference/foundations/assert/#definitions-eq) or [`list.item`](/docs/reference/model/list/#definitions-item). However, this feature is currently only available for built-in functions.
## Defining functions
You can define your own function with a [let binding](/docs/reference/scripting/#bindings) that has a parameter list after the binding's name. The parameter list can contain mandatory positional parameters, named parameters with default values and [argument sinks](/docs/reference/foundations/arguments/).
The right-hand side of a function binding is the function body, which can be a block or any other expression. It defines the function's return value and can depend on the parameters. If the function body is a [code block](/docs/reference/scripting/#blocks), the return value is the result of joining the values of each expression in the block.
Within a function body, the `return` keyword can be used to exit early and optionally specify a return value. If no explicit return value is given, the body evaluates to the result of joining all expressions preceding the `return`.
Functions that don't return any meaningful value return [`none`](/docs/reference/foundations/none/) instead. The return type of such functions is not explicitly specified in the documentation. (An example of this is [`array.push`](/docs/reference/foundations/array/#definitions-push)).
```typst
#let alert(body, fill: red) = {
set text(white)
set align(center)
rect(
fill: fill,
inset: 8pt,
radius: 4pt,
[*Warning:\ #body*],
)
}
#alert[
Danger is imminent!
]
#alert(fill: blue)[
KEEP OFF TRACKS
]
```
## Importing functions
Functions can be imported from one file ([`module`](/docs/reference/scripting/#modules)) into another using `import`. For example, assume that we have defined the `alert` function from the previous example in a file called `foo.typ`. We can import it into another file by writing `import "foo.typ": alert`.
## Unnamed functions
You can also create an unnamed function without creating a binding by specifying a parameter list followed by `=>` and the function body. If your function has just one parameter, the parentheses around the parameter list are optional. Unnamed functions are mainly useful for show rules, but also for settable properties that take functions like the page function's [`footer`](/docs/reference/layout/page/#parameters-footer) property.
```typst
#show "once?": it => [#it #it]
once?
```
## Note on function purity
In Typst, all functions are _pure._ This means that for the same arguments, they always return the same result. They cannot "remember" things to produce another value when they are called a second time.
The only exception are built-in methods like [`array.push(value)`](/docs/reference/foundations/array/#definitions-push). These can modify the values they are called on.
## Methods
## function.with
Returns a new function that has the given arguments pre-applied.
```typst
#function.with(
arguments
) -> function
```
### Parameters
- arguments:
- description: The arguments to apply to the function.
- type: any
- default: None
## function.where
Returns a selector that filters for elements belonging to this function whose fields have the values of the given arguments.
```typst
#show heading.where(level: 2): set text(blue)
= Section
== Subsection
=== Sub-subsection
```
```typst
#function.where(
fields
) -> selector
```
### Parameters
- fields:
- description: The fields to filter for.
- type: any
- default: None
docs/reference/foundations/index.md
# Foundations
Foundational types and functions.
Here, you'll find documentation for basic data types like [integers](/docs/reference/foundations/int/) and [strings](/docs/reference/foundations/str/) as well as details about core computational functions.
## Definitions
| Name | Description |
| --- | --- |
| [`arguments`](/reference/foundations/arguments/) | Captured arguments to a function. |
| [`array`](/reference/foundations/array/) | A sequence of values. |
| [`assert`](/reference/foundations/assert/) | Ensures that a condition is fulfilled. |
| [`auto`](/reference/foundations/auto/) | A value that indicates a smart default. |
| [`bool`](/reference/foundations/bool/) | A type with two states. |
| [`bytes`](/reference/foundations/bytes/) | A sequence of bytes. |
| [`calc`](/reference/foundations/calc/) | Module for calculations and processing of numeric values. |
| [`content`](/reference/foundations/content/) | A piece of document content. |
| [`datetime`](/reference/foundations/datetime/) | Represents a date, a time, or a combination of both. |
| [`decimal`](/reference/foundations/decimal/) | A fixed-point decimal number type. |
| [`dictionary`](/reference/foundations/dictionary/) | A map from string keys to values. |
| [`duration`](/reference/foundations/duration/) | Represents a positive or negative span of time. |
| [`eval`](/reference/foundations/eval/) | Evaluates a string as Typst code. |
| [`float`](/reference/foundations/float/) | A floating-point number. |
| [`function`](/reference/foundations/function/) | A mapping from argument values to a return value. |
| [`int`](/reference/foundations/int/) | A whole number. |
| [`label`](/reference/foundations/label/) | A label for an element. |
| [`module`](/reference/foundations/module/) | A collection of variables and functions that are commonly related to a single theme. |
| [`none`](/reference/foundations/none/) | A value that indicates the absence of any other value. |
| [`panic`](/reference/foundations/panic/) | Fails with an error. |
| [`plugin`](/reference/foundations/plugin/) | Loads a WebAssembly module. |
| [`regex`](/reference/foundations/regex/) | A regular expression. |
| [`repr`](/reference/foundations/repr/) | Returns the string representation of a value. |
| [`selector`](/reference/foundations/selector/) | A filter for selecting elements within the document. |
| [`std`](/reference/foundations/std/) | A module that contains all globally accessible items. |
| [`str`](/reference/foundations/str/) | A sequence of Unicode codepoints. |
| [`symbol`](/reference/foundations/symbol/) | A Unicode symbol. |
| [`sys`](/reference/foundations/sys/) | Module for system interactions. |
| [`target`](/reference/foundations/target/) | Returns the current export target. |
| [`type`](/reference/foundations/type/) | Describes a kind of value. |
| [`version`](/reference/foundations/version/) | A version with an arbitrary number of components. |
docs/reference/foundations/int.md
# Integer
A whole number.
The number can be negative, zero, or positive. As Typst uses 64 bits to store integers, integers cannot be smaller than `-9223372036854775808` or larger than `9223372036854775807`. Integer literals are always positive, so a negative integer such as `-1` is semantically the negation `-` of the positive literal `1`. A positive integer greater than the maximum value and a negative integer less than or equal to the minimum value cannot be represented as an integer literal, and are instead parsed as a `float`. The minimum integer value can still be obtained through integer arithmetic.
The number can also be specified as hexadecimal, octal, or binary by starting it with a zero followed by either `x`, `o`, or `b`.
You can convert a value to an integer with this type's constructor.
## Example
```typst
#(1 + 2) \
#(2 - 5) \
#(3 + 4 < 8)
#0xff \
#0o10 \
#0b1001
```
## Constructor
## int
Converts a value to an integer. Raises an error if there is an attempt to produce an integer larger than the maximum 64-bit signed integer or smaller than the minimum 64-bit signed integer.
- Booleans are converted to `0` or `1`.
- Floats and decimals are rounded to the next 64-bit integer towards zero.
- Strings are parsed in base 10.
```typst
#int(false) \
#int(true) \
#int(2.7) \
#int(decimal("3.8")) \
#(int("27") + int("4"))
```
```typst
#int(
value
) -> int
```
### Parameters
- value:
- description: The value that should be converted to an integer.
- type: bool | int | float | str | decimal
- default: None
## Methods
## int.signum
Calculates the sign of an integer.
- If the number is positive, returns `1`.
- If the number is negative, returns `-1`.
- If the number is zero, returns `0`.
```typst
#(5).signum() \
#(-5).signum() \
#(0).signum()
```
## int.bit-not
Calculates the bitwise NOT of an integer.
For the purposes of this function, the operand is treated as a signed integer of 64 bits.
```typst
#4.bit-not() \
#(-1).bit-not()
```
## int.bit-and
Calculates the bitwise AND between two integers.
For the purposes of this function, the operands are treated as signed integers of 64 bits.
```typst
#128.bit-and(192)
```
```typst
#int.bit-and(
rhs
) -> int
```
### Parameters
- rhs:
- description: The right-hand operand of the bitwise AND.
- type: int
- default: None
## int.bit-or
Calculates the bitwise OR between two integers.
For the purposes of this function, the operands are treated as signed integers of 64 bits.
```typst
#64.bit-or(32)
```
```typst
#int.bit-or(
rhs
) -> int
```
### Parameters
- rhs:
- description: The right-hand operand of the bitwise OR.
- type: int
- default: None
## int.bit-xor
Calculates the bitwise XOR between two integers.
For the purposes of this function, the operands are treated as signed integers of 64 bits.
```typst
#64.bit-xor(96)
```
```typst
#int.bit-xor(
rhs
) -> int
```
### Parameters
- rhs:
- description: The right-hand operand of the bitwise XOR.
- type: int
- default: None
## int.bit-lshift
Shifts the operand's bits to the left by the specified amount.
For the purposes of this function, the operand is treated as a signed integer of 64 bits. An error will occur if the result is too large to fit in a 64-bit integer.
```typst
#33.bit-lshift(2) \
#(-1).bit-lshift(3)
```
```typst
#int.bit-lshift(
shift
) -> int
```
### Parameters
- shift:
- description: The amount of bits to shift. Must not be negative.
- type: int
- default: None
## int.bit-rshift
Shifts the operand's bits to the right by the specified amount. Performs an arithmetic shift by default (extends the sign bit to the left, such that negative numbers stay negative), but that can be changed by the `logical` parameter.
For the purposes of this function, the operand is treated as a signed integer of 64 bits.
```typst
#64.bit-rshift(2) \
#(-8).bit-rshift(2) \
#(-8).bit-rshift(2, logical: true)
```
```typst
#int.bit-rshift(
shift,
logical: bool
) -> int
```
### Parameters
- shift:
- description: The amount of bits to shift. Must not be negative. Shifts larger than 63 are allowed and will cause the return value to saturate. For non-negative numbers, the return value saturates at `0`, while, for negative numbers, it saturates at `-1` if `logical` is set to `false`, or `0` if it is `true`. This behavior is consistent with just applying this operation multiple times. Therefore, the shift will always succeed.
- type: int
- default: None
- logical:
- description: Toggles whether a logical (unsigned) right shift should be performed instead of arithmetic right shift. If this is `true`, negative operands will not preserve their sign bit, and bits which appear to the left after the shift will be `0`. This parameter has no effect on non-negative operands.
- type: bool
- default: false
## int.from-bytes
Converts bytes to an integer.
```typst
#int.from-bytes(bytes((0, 0, 0, 0, 0, 0, 0, 1))) \
#int.from-bytes(bytes((1, 0, 0, 0, 0, 0, 0, 0)), endian: "big")
```
```typst
#int.from-bytes(
bytes,
endian: str,
signed: bool
) -> int
```
### Parameters
- bytes:
- description: The bytes that should be converted to an integer. Must be of length at most 8 so that the result fits into a 64-bit signed integer.
- type: bytes
- default: None
- endian:
- description: The endianness of the conversion.
- type: str
- default: "little"
- signed:
- description: Whether the bytes should be treated as a signed integer. If this is `true` and the most significant bit is set, the resulting number will negative.
- type: bool
- default: true
## int.to-bytes
Converts an integer to bytes.
```typst
#array(10000.to-bytes(endian: "big")) \
#array(10000.to-bytes(size: 4))
```
```typst
#int.to-bytes(
endian: str,
size: int
) -> bytes
```
### Parameters
- endian:
- description: The endianness of the conversion.
- type: str
- default: "little"
- size:
- description: The size in bytes of the resulting bytes (must be at least zero). If the integer is too large to fit in the specified size, the conversion will truncate the remaining bytes based on the endianness. To keep the same resulting value, if the endianness is big-endian, the truncation will happen at the rightmost bytes. Otherwise, if the endianness is little-endian, the truncation will happen at the leftmost bytes. Be aware that if the integer is negative and the size is not enough to make the number fit, when passing the resulting bytes to `int.from-bytes`, the resulting number might be positive, as the most significant bit might not be set to 1.
- type: int
- default: 8
docs/reference/foundations/label.md
# Label
A label for an element.
Inserting a label into content attaches it to the closest preceding element that is not a space. The preceding element must be in the same scope as the label, which means that `Hello #[<label>]`, for instance, wouldn't work.
A labelled element can be [referenced](/docs/reference/model/ref/), [queried](/docs/reference/introspection/query/) for, and [styled](/docs/reference/styling/) through its label.
Once constructed, you can get the name of a label using [`str`](/docs/reference/foundations/str/#constructor).
## Example
```typst
#show <a>: set text(blue)
#show label("b"): set text(red)
= Heading <a>
*Strong* #label("b")
```
## Syntax
This function also has dedicated syntax: You can create a label by enclosing its name in angle brackets. This works both in markup and code. A label's name can contain letters, numbers, `_`, `-`, `:`, and `.`. A label cannot be empty.
Note that there is a syntactical difference when using the dedicated syntax for this function. In the code below, the `<a>` terminates the heading and thus attaches to the heading itself, whereas the `#label("b")` is part of the heading and thus attaches to the heading's text.
```typst
// Equivalent to `#heading[Introduction] <a>`.
= Introduction <a>
// Equivalent to `#heading[Conclusion #label("b")]`.
= Conclusion #label("b")
```
Currently, labels can only be attached to elements in markup mode, not in code mode. This might change in the future.
## Constructor
## label
Creates a label from a string.
```typst
#label(
name
) -> label
```
### Parameters
- name:
- description: The name of the label. Unlike the [dedicated syntax](#syntax), this constructor accepts any non-empty string, including names with special characters.
- type: str
- default: None
docs/reference/foundations/module.md
# Module
A collection of variables and functions that are commonly related to a single theme.
A module can
- be built-in
- stem from a [file import](/docs/reference/scripting/#modules)
- stem from a [package import](/docs/reference/scripting/#packages) (and thus indirectly its entrypoint file)
- result from a call to the [plugin](/docs/reference/foundations/plugin/) function
You can access definitions from the module using [field access notation](/docs/reference/scripting/#fields) and interact with it using the [import and include syntaxes](/docs/reference/scripting/#modules).
```typst
#import "utils.typ"
#utils.add(2, 5)
#import utils: sub
#sub(1, 4)
```
You can check whether a definition is present in a module using the `in` operator, with a string on the left-hand side. This can be useful to [conditionally access](/docs/reference/foundations/std/#conditional-access) definitions in a module.
```typst
#("table" in std) \
#("nope" in std)
```
Alternatively, it is possible to convert a module to a dictionary, and therefore access its contents dynamically, using the [dictionary constructor](/docs/reference/foundations/dictionary/#constructor).
docs/reference/foundations/none.md
# None
A value that indicates the absence of any other value.
The none type has exactly one value: `none`.
When inserted into the document, it is not visible. This is also the value that is produced by empty code blocks. It can be [joined](/docs/reference/scripting/#blocks) with any value, yielding the other value.
## Example
```typst
Not visible: #none
```
docs/reference/foundations/panic.md
# Panic
# panic
Fails with an error.
Arguments are displayed to the user (not rendered in the document) as strings, converting with `repr` if necessary.
## Example
The code below produces the error `panicked with: "this is wrong"`.
```typst
#panic("this is wrong")
```
```typst
#panic(
values
) ->
```
## Parameters
- values:
- description: The values to panic with and display to the user.
- type: any
- default: None
docs/reference/foundations/plugin.md
# Plugin
# plugin
Loads a WebAssembly module.
The resulting [module](/docs/reference/foundations/module/) will contain one Typst [function](/docs/reference/foundations/function/) for each function export of the loaded WebAssembly module.
Typst WebAssembly plugins need to follow a specific [protocol](/docs/reference/foundations/plugin/#protocol). To run as a plugin, a program needs to be compiled to a 32-bit shared WebAssembly library. Plugin functions may accept multiple [byte buffers](/docs/reference/foundations/bytes/) as arguments and return a single byte buffer. They should typically be wrapped in idiomatic Typst functions that perform the necessary conversions between native Typst types and bytes by leveraging [`str`](/docs/reference/foundations/str/#constructor), [`bytes`](/docs/reference/foundations/bytes/#constructor), and [data loading functions](/docs/reference/data-loading/).
For security reasons, plugins run in isolation from your system. This means that printing, reading files, or similar things are not supported.
## Example
```typst
#let myplugin = plugin("hello.wasm")
#let concat(a, b) = str(
myplugin.concatenate(
bytes(a),
bytes(b),
)
)
#concat("hello", "world")
```
Since the plugin function returns a module, it can be used with import syntax:
```typst
#import plugin("hello.wasm"): concatenate
```
## Purity
Plugin functions **must be pure:** A plugin function call must not have any observable side effects on future plugin calls and given the same arguments, it must always return the same value.
The reason for this is that Typst functions must be pure (which is quite fundamental to the language design) and, since Typst function can call plugin functions, this requirement is inherited. In particular, if a plugin function is called twice with the same arguments, Typst might cache the results and call your function only once. Moreover, Typst may run multiple instances of your plugin in multiple threads, with no state shared between them.
Typst does not enforce plugin function purity (for efficiency reasons), but calling an impure function will lead to unpredictable and irreproducible results and must be avoided.
That said, mutable operations _can be_ useful for plugins that require costly runtime initialization. Due to the purity requirement, such initialization cannot be performed through a normal function call. Instead, Typst exposes a [plugin transition API](/docs/reference/foundations/plugin/#definitions-transition), which executes a function call and then creates a derived module with new functions which will observe the side effects produced by the transition call. The original plugin remains unaffected.
## Plugins and Packages
Any Typst code can make use of a plugin simply by including a WebAssembly file and loading it. However, because the byte-based plugin interface is quite low-level, plugins are typically exposed through a package containing the plugin and idiomatic wrapper functions.
## WASI
Many compilers will use the [WASI ABI](https://wasi.dev/) by default or as their only option (e.g. emscripten), which allows printing, reading files, etc. This ABI will not directly work with Typst. You will either need to compile to a different target or [stub all functions](https://github.com/astrale-sharp/wasm-minimal-protocol/tree/master/crates/wasi-stub).
## Protocol
To be used as a plugin, a WebAssembly module must conform to the following protocol:
### Exports
A plugin module can export functions to make them callable from Typst. To conform to the protocol, an exported function should:
- Take `n` 32-bit integer arguments `a_1`, `a_2`, ..., `a_n` (interpreted as lengths, so `usize/size_t` may be preferable), and return one 32-bit integer.
- The function should first allocate a buffer `buf` of length `a_1 + a_2 + ... + a_n`, and then call `wasm_minimal_protocol_write_args_to_buffer(buf.ptr)`.
- The `a_1` first bytes of the buffer now constitute the first argument, the `a_2` next bytes the second argument, and so on.
- The function can now do its job with the arguments and produce an output buffer. Before returning, it should call `wasm_minimal_protocol_send_result_to_host` to send its result back to the host.
- To signal success, the function should return `0`.
- To signal an error, the function should return `1`. The written buffer is then interpreted as an UTF-8 encoded error message.
### Imports
Plugin modules need to import two functions that are provided by the runtime. (Types and functions are described using WAT syntax.)
- `(import "typst_env" "wasm_minimal_protocol_write_args_to_buffer" (func (param i32)))` Writes the arguments for the current function into a plugin-allocated buffer. When a plugin function is called, it [receives the lengths](#exports) of its input buffers as arguments. It should then allocate a buffer whose capacity is at least the sum of these lengths. It should then call this function with a `ptr` to the buffer to fill it with the arguments, one after another.
- `(import "typst_env" "wasm_minimal_protocol_send_result_to_host" (func (param i32 i32)))` Sends the output of the current function to the host (Typst). The first parameter shall be a pointer to a buffer (`ptr`), while the second is the length of that buffer (`len`). The memory pointed at by `ptr` can be freed immediately after this function returns. If the message should be interpreted as an error message, it should be encoded as UTF-8.
## Resources
For more resources, check out the [wasm-minimal-protocol repository](https://github.com/astrale-sharp/wasm-minimal-protocol). It contains:
- A list of example plugin implementations and a test runner for these examples
- Wrappers to help you write your plugin in Rust (Zig wrapper in development)
- A stubber for WASI
```typst
#plugin(
source
) -> module
```
## Parameters
- source:
- description: A [path](/docs/reference/syntax/#paths) to a WebAssembly file or raw WebAssembly bytes.
- type: str | bytes
- default: None
## Definitions
### plugin.transition
Calls a plugin function that has side effects and returns a new module with plugin functions that are guaranteed to have observed the results of the mutable call.
Note that calling an impure function through a normal function call (without use of the transition API) is forbidden and leads to unpredictable behaviour. Read the [section on purity](/docs/reference/foundations/plugin/#purity) for more details.
In the example below, we load the plugin `hello-mut.wasm` which exports two functions: The `get()` function retrieves a global array as a string. The `add(value)` function adds a value to the global array.
We call `add` via the transition API. The call `mutated.get()` on the derived module will observe the addition. Meanwhile the original module remains untouched as demonstrated by the `base.get()` call.
_Note:_ Due to limitations in the internal WebAssembly implementation, the transition API can only guarantee to reflect changes in the plugin's memory, not in WebAssembly globals. If your plugin relies on changes to globals being visible after transition, you might want to avoid use of the transition API for now. We hope to lift this limitation in the future.
```typst
#let base = plugin("hello-mut.wasm")
#assert.eq(base.get(), "[]")
#let mutated = plugin.transition(base.add, "hello")
#assert.eq(base.get(), "[]")
#assert.eq(mutated.get(), "[hello]")
```
```typst
#plugin.transition(
func,
arguments
) -> module
```
#### Parameters
- func:
- description: The plugin function to call.
- type: function
- default: None
- arguments:
- description: The byte buffers to call the function with.
- type: bytes
- default: None
docs/reference/foundations/regex.md
# Regex
A regular expression.
Can be used as a [show rule selector](/docs/reference/styling/#show-rules) and with [string methods](/docs/reference/foundations/str/) like `find`, `split`, and `replace`.
[See here](https://docs.rs/regex/latest/regex/#syntax) for a specification of the supported syntax.
## Example
```typst
// Works with string methods.
#"a,b;c".split(regex("[,;]"))
// Works with show rules.
#show regex("\\d+"): set text(red)
The numbers 1 to 10.
```
## Constructor
## regex
Create a regular expression from a string.
```typst
#regex(
regex
) -> regex
```
### Parameters
- regex:
- description: The regular expression as a string. Both Typst strings and regular expressions use backslashes for escaping. To produce a regex escape sequence that is also valid in Typst, you need to escape the backslash itself (e.g., writing `regex("\\\\\\\\")` for the regex `\\\\`). Regex escape sequences that are not valid Typst escape sequences (e.g., `\\d` and `\\b`) can be entered into strings directly, but it\'s good practice to still escape them to avoid ambiguity (i.e., `regex("\\\\b\\\\d")`). See the [list of valid string escape sequences](/docs/reference/foundations/str/#escapes). If you need many escape sequences, you can also create a raw element and extract its text to use it for your regular expressions: `regex(`\\d+\\.\\d+\\.\\d+`.text)`.
- type: str
- default: None
docs/reference/foundations/repr.md
# Representation
# repr
Returns the string representation of a value.
When inserted into content, most values are displayed as this representation in monospace with syntax-highlighting. The exceptions are `none`, integers, floats, strings, content, and functions.
## Example
```typst
#none vs #repr(none) \
#"hello" vs #repr("hello") \
#(1, 2) vs #repr((1, 2)) \
#[*Hi*] vs #repr([*Hi*])
```
## For debugging purposes only
This function is for debugging purposes. Its output should not be considered stable and may change at any time.
To be specific, having the same `repr` does not guarantee that values are equivalent, and `repr` is not a strict inverse of [`eval`](/docs/reference/foundations/eval/). In the following example, for readability, the [`length`](/docs/reference/layout/length/) is rounded to two significant digits and the parameter list and body of the [unnamed `function`](/docs/reference/foundations/function/#unnamed) are omitted.
```typst
#assert(2pt / 3 < 0.67pt)
#repr(2pt / 3)
#repr(x => x + 1)
```
```typst
#repr(
value
) -> str
```
## Parameters
- value:
- description: The value whose string representation to produce.
- type: any
- default: None
docs/reference/foundations/selector.md
# Selector
A filter for selecting elements within the document.
To construct a selector you can:
- use an [element function](/docs/reference/foundations/function/#element-functions)
- filter for an element function with [specific fields](/docs/reference/foundations/function/#definitions-where)
- use a [string](/docs/reference/foundations/str/) or [regular expression](/docs/reference/foundations/regex/)
- use a [`<label>`](/docs/reference/foundations/label/)
- use a [`location`](/docs/reference/introspection/location/)
- call the [`selector`](/docs/reference/foundations/selector/) constructor to convert any of the above types into a selector value and use the methods below to refine it
Selectors are used to [apply styling rules](/docs/reference/styling/#show-rules) to elements. You can also use selectors to [query](/docs/reference/introspection/query/) the document for certain types of elements.
Furthermore, you can pass a selector to several of Typst's built-in functions to configure their behaviour. One such example is the [outline](/docs/reference/model/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
```typst
#context query(
heading.where(level: 1)
.or(heading.where(level: 2))
)
= This will be found
== So will this
=== But this will not.
```
## Constructor
## selector
Turns a value into a selector. The following values are accepted:
- An element function like a `heading` or `figure`.
- A [string](/docs/reference/foundations/str/) or [regular expression](/docs/reference/foundations/regex/).
- A `<label>`.
- A [`location`](/docs/reference/introspection/location/).
- A more complex selector like `heading.where(level: 1)`.
```typst
#selector(
target
) -> selector
```
### Parameters
- target:
- description: Can be an element function like a `heading` or `figure`, a `<label>` or a more complex selector like `heading.where(level: 1)`.
- type: str | regex | label | selector | location | function
- default: None
## Methods
## selector.or
Selects all elements that match this or any of the other selectors.
```typst
#selector.or(
others
) -> selector
```
### Parameters
- others:
- description: The other selectors to match on.
- type: str | regex | label | selector | location | function
- default: None
## selector.and
Selects all elements that match this and all of the other selectors.
```typst
#selector.and(
others
) -> selector
```
### Parameters
- others:
- description: The other selectors to match on.
- type: str | regex | label | selector | location | function
- default: None
## selector.before
Returns a modified selector that will only match elements that occur before the first match of `end`.
```typst
#selector.before(
end,
inclusive: bool
) -> selector
```
### Parameters
- end:
- description: The original selection will end at the first match of `end`.
- type: label | selector | location | function
- default: None
- inclusive:
- description: Whether `end` itself should match or not. This is only relevant if both selectors match the same type of element. Defaults to `true`.
- type: bool
- default: true
## selector.after
Returns a modified selector that will only match elements that occur after the first match of `start`.
```typst
#selector.after(
start,
inclusive: bool
) -> selector
```
### Parameters
- start:
- description: The original selection will start at the first match of `start`.
- type: label | selector | location | function
- default: None
- inclusive:
- description: Whether `start` itself should match or not. This is only relevant if both selectors match the same type of element. Defaults to `true`.
- type: bool
- default: true
docs/reference/foundations/std.md
# Standard Library
A module that contains all globally accessible items.
## Using "shadowed" definitions
The `std` module is useful whenever you overrode a name from the global scope (this is called _shadowing_). For instance, you might have used the name `text` for a parameter. To still access the `text` element, write `std.text`.
```typst
#let par = [My special paragraph.]
#let special(text) = {
set std.text(style: "italic")
set std.par.line(numbering: "1")
text
}
#special(par)
#lorem(10)
```
## Conditional access
You can also use this in combination with the [dictionary constructor](/docs/reference/foundations/dictionary/) to conditionally access global definitions. This can, for instance, be useful to use new or experimental functionality when it is available, while falling back to an alternative implementation if used on an older Typst version. In particular, this allows us to create [polyfills](https://en.wikipedia.org/wiki/Polyfill_(programming)).
This can be as simple as creating an alias to prevent warning messages, for example, conditionally using `pattern` in Typst version 0.12, but using [`tiling`](/docs/reference/visualize/tiling/) in newer versions. Since the parameters accepted by the `tiling` function match those of the older `pattern` function, using the `tiling` function when available and falling back to `pattern` otherwise will unify the usage across all versions. Note that, when creating a polyfill, [`sys.version`](/docs/reference/foundations/sys/) can also be very useful.
```typst
#let tiling = if "tiling" in std { tiling } else { pattern }
...
```
docs/reference/foundations/str.md
# String
A sequence of Unicode codepoints.
You can iterate over the grapheme clusters of the string using a [for loop](/docs/reference/scripting/#loops). Grapheme clusters are basically characters but keep together things that belong together, e.g. multiple codepoints that together form a flag emoji. Strings can be added with the `+` operator, [joined together](/docs/reference/scripting/#blocks) and multiplied with integers.
Typst provides utility methods for string manipulation. Many of these methods (e.g., [`split`](/docs/reference/foundations/str/#definitions-split), [`trim`](/docs/reference/foundations/str/#definitions-trim) and [`replace`](/docs/reference/foundations/str/#definitions-replace)) operate on _patterns:_ A pattern can be either a string or a [regular expression](/docs/reference/foundations/regex/). This makes the methods quite versatile.
All lengths and indices are expressed in terms of UTF-8 bytes. Indices are zero-based and negative indices wrap around to the end of the string.
You can convert a value to a string with this type's constructor.
## Example
```typst
#"hello world!" \
#"\"hello\n world\"!" \
#"1 2 3".split() \
#"1,2;3".split(regex("[,;]")) \
#(regex("\\d+") in "ten euros") \
#(regex("\\d+") in "10 euros")
```
## Escape sequences
Just like in markup, you can escape a few symbols in strings:
- `\\` for a backslash
- `\"` for a quote
- `\n` for a newline
- `\r` for a carriage return
- `\t` for a tab
- `\u\{1f600\}` for a hexadecimal Unicode escape sequence
## Constructor
## str
Converts a value to a string.
- Integers are formatted in base 10. This can be overridden with the optional `base` parameter.
- Floats are formatted in base 10 and never in exponential notation.
- Negative integers and floats are formatted with the Unicode minus sign ("−" U+2212) instead of the ASCII minus sign ("-" U+002D).
- From labels the name is extracted.
- Bytes are decoded as UTF-8.
If you wish to convert from and to Unicode code points, see the [`to-unicode`](/docs/reference/foundations/str/#definitions-to-unicode) and [`from-unicode`](/docs/reference/foundations/str/#definitions-from-unicode) functions.
```typst
#str(10) \
#str(4000, base: 16) \
#str(2.7) \
#str(1e8) \
#str(<intro>)
```
```typst
#str(
value,
base: int
) -> str
```
### Parameters
- value:
- description: The value that should be converted to a string.
- type: int | float | str | bytes | label | decimal | version | type
- default: None
- base:
- description: The base (radix) to display integers in, between 2 and 36.
- type: int
- default: 10
## Methods
## str.len
The length of the string in UTF-8 encoded bytes.
## str.first
Extracts the first grapheme cluster of the string.
Returns the provided default value if the string is empty or fails with an error if no default value was specified.
```typst
#str.first(
default: str
) -> str
```
### Parameters
- default:
- description: A default value to return if the string is empty.
- type: str
- default: None
## str.last
Extracts the last grapheme cluster of the string.
Returns the provided default value if the string is empty or fails with an error if no default value was specified.
```typst
#str.last(
default: str
) -> str
```
### Parameters
- default:
- description: A default value to return if the string is empty.
- type: str
- default: None
## str.at
Extracts the first grapheme cluster after the specified index. Returns the default value if the index is out of bounds or fails with an error if no default value was specified.
```typst
#str.at(
index,
default: any
) -> any
```
### Parameters
- index:
- description: The byte index. If negative, indexes from the back.
- type: int
- default: None
- default:
- description: A default value to return if the index is out of bounds.
- type: any
- default: None
## str.slice
Extracts a substring of the string. Fails with an error if the start or end index is out of bounds.
```typst
#str.slice(
start,
end,
count: int
) -> str
```
### Parameters
- start:
- description: The start byte index (inclusive). If negative, indexes from the back.
- type: int
- default: None
- end:
- description: The end byte index (exclusive). If omitted, the whole slice until the end of the string is extracted. If negative, indexes from the back.
- type: none | int
- default: none
- count:
- description: The number of bytes to extract. This is equivalent to passing `start + count` as the `end` position. Mutually exclusive with `end`.
- type: int
- default: None
## str.clusters
Returns the grapheme clusters of the string as an array of substrings.
## str.codepoints
Returns the Unicode codepoints of the string as an array of substrings.
## str.to-unicode
Converts a character into its corresponding code point.
```typst
#"a".to-unicode() \
#("a\u{0300}"
.codepoints()
.map(str.to-unicode))
```
```typst
#str.to-unicode(
character
) -> int
```
### Parameters
- character:
- description: The character that should be converted.
- type: str
- default: None
## str.from-unicode
Converts a unicode code point into its corresponding string.
```typst
#str.from-unicode(97)
```
```typst
#str.from-unicode(
value
) -> str
```
### Parameters
- value:
- description: The code point that should be converted.
- type: int
- default: None
## str.normalize
Normalizes the string to the given Unicode normal form.
This is useful when manipulating strings containing Unicode combining characters.
```typst
#assert.eq("é".normalize(form: "nfd"), "e\u{0301}")
#assert.eq("ſ́".normalize(form: "nfkc"), "ś")
```
```typst
#str.normalize(
form: str
) -> str
```
### Parameters
- form:
- description:
- type: str
- default: "nfc"
## str.contains
Whether the string contains the specified pattern.
This method also has dedicated syntax: You can write `"bc" in "abcd"` instead of `"abcd".contains("bc")`.
```typst
#str.contains(
pattern
) -> bool
```
### Parameters
- pattern:
- description: The pattern to search for.
- type: str | regex
- default: None
## str.starts-with
Whether the string starts with the specified pattern.
```typst
#str.starts-with(
pattern
) -> bool
```
### Parameters
- pattern:
- description: The pattern the string might start with.
- type: str | regex
- default: None
## str.ends-with
Whether the string ends with the specified pattern.
```typst
#str.ends-with(
pattern
) -> bool
```
### Parameters
- pattern:
- description: The pattern the string might end with.
- type: str | regex
- default: None
## str.find
Searches for the specified pattern in the string and returns the first match as a string or `none` if there is no match.
```typst
#str.find(
pattern
) -> none str
```
### Parameters
- pattern:
- description: The pattern to search for.
- type: str | regex
- default: None
## str.position
Searches for the specified pattern in the string and returns the index of the first match as an integer or `none` if there is no match.
```typst
#str.position(
pattern
) -> none int
```
### Parameters
- pattern:
- description: The pattern to search for.
- type: str | regex
- default: None
## str.match
Searches for the specified pattern in the string and returns a dictionary with details about the first match or `none` if there is no match.
The returned dictionary has the following keys:
- `start`: The start offset of the match
- `end`: The end offset of the match
- `text`: The text that matched.
- `captures`: An array containing a string for each matched capturing group. The first item of the array contains the first matched capturing, not the whole match! This is empty unless the `pattern` was a regex with capturing groups.
```typst
#let pat = regex("not (a|an) (apple|cat)")
#"I'm a doctor, not an apple.".match(pat) \
#"I am not a cat!".match(pat)
```
```typst
#assert.eq("Is there a".match("for this?"), none)
#"The time of my life.".match(regex("[mit]+e"))
```
```typst
#str.match(
pattern
) -> none dictionary
```
### Parameters
- pattern:
- description: The pattern to search for.
- type: str | regex
- default: None
## str.matches
Searches for the specified pattern in the string and returns an array of dictionaries with details about all matches. For details about the returned dictionaries, see [above](/docs/reference/foundations/str/#definitions-match).
```typst
#"Day by Day.".matches("Day")
```
```typst
#str.matches(
pattern
) -> array
```
### Parameters
- pattern:
- description: The pattern to search for.
- type: str | regex
- default: None
## str.replace
Replace at most `count` occurrences of the given pattern with a replacement string or function (beginning from the start). If no count is given, all occurrences are replaced.
```typst
#str.replace(
pattern,
replacement,
count: int
) -> str
```
### Parameters
- pattern:
- description: The pattern to search for.
- type: str | regex
- default: None
- replacement:
- description: The string to replace the matches with or a function that gets a dictionary for each match and can return individual replacement strings. The dictionary passed to the function has the same shape as the dictionary returned by [`match`](/docs/reference/foundations/str/#definitions-match).
- type: str | function
- default: None
- count:
- description: If given, only the first `count` matches of the pattern are placed.
- type: int
- default: None
## str.trim
Removes matches of a pattern from one or both sides of the string, once or repeatedly and returns the resulting string.
```typst
#str.trim(
pattern,
at: alignment,
repeat: bool
) -> str
```
### Parameters
- pattern:
- description: The pattern to search for. If `none`, trims white spaces.
- type: none | str | regex
- default: none
- at:
- description: Can be `start` or `end` to only trim the start or end of the string. If omitted, both sides are trimmed.
- type: alignment
- default: None
- repeat:
- description: Whether to repeatedly removes matches of the pattern or just once. Defaults to `true`.
- type: bool
- default: true
## str.split
Splits a string at matches of a specified pattern and returns an array of the resulting parts.
When the empty string is used as a separator, it separates every character (i.e., Unicode code point) in the string, along with the beginning and end of the string. In practice, this means that the resulting list of parts will contain the empty string at the start and end of the list.
```typst
#str.split(
pattern
) -> array
```
### Parameters
- pattern:
- description: The pattern to split at. Defaults to whitespace.
- type: none | str | regex
- default: none
## str.rev
Reverse the string.
docs/reference/foundations/symbol.md
# Symbol
A Unicode symbol.
Typst defines common symbols so that they can easily be written with standard keyboards. The symbols are defined in modules, from which they can be accessed using [field access notation](/docs/reference/scripting/#fields):
- General symbols are defined in the [`sym` module](/docs/reference/symbols/sym/) and are accessible without the `sym.` prefix in math mode.
- Emoji are defined in the [`emoji` module](/docs/reference/symbols/emoji/)
Moreover, you can define custom symbols with this type's constructor function.
```typst
#sym.arrow.r \
#sym.gt.eq.not \
$gt.eq.not$ \
#emoji.face.halo
```
Many symbols have different variants, which can be selected by appending the modifiers with dot notation. The order of the modifiers is not relevant. Visit the documentation pages of the symbol modules and click on a symbol to see its available variants.
```typst
$arrow.l$ \
$arrow.r$ \
$arrow.t.quad$
```
## Constructor
## symbol
Create a custom symbol with modifiers.
```typst
#let envelope = symbol(
"🖂",
("stamped", "🖃"),
("stamped.pen", "🖆"),
("lightning", "🖄"),
("fly", "🖅"),
)
#envelope
#envelope.stamped
#envelope.stamped.pen
#envelope.lightning
#envelope.fly
```
```typst
#symbol(
variants
) -> symbol
```
### Parameters
- variants:
- description: The variants of the symbol. Can be a just a string consisting of a single character for the modifierless variant or an array with two strings specifying the modifiers and the symbol. Individual modifiers should be separated by dots. When displaying a symbol, Typst selects the first from the variants that have all attached modifiers and the minimum number of other modifiers.
- type: str | array
- default: None
docs/reference/foundations/sys.md
# System
Module for system interactions.
This module defines the following items:
- The `sys.version` constant (of type [`version`](/docs/reference/foundations/version/)) that specifies the currently active Typst compiler version.
- The `sys.inputs` [dictionary](/docs/reference/foundations/dictionary/), which makes external inputs available to the project. An input specified in the command line as `--input key=value` becomes available under `sys.inputs.key` as `"value"`. To include spaces in the value, it may be enclosed with single or double quotes. The value is always of type [string](/docs/reference/foundations/str/). More complex data may be parsed manually using functions like [`json`](/docs/reference/data-loading/json/).
docs/reference/foundations/target.md
# Target
# target
Returns the current export target.
This function returns either
- `"paged"` (for PDF, PNG, and SVG export), or
- `"html"` (for HTML export).
The design of this function is not yet finalized and for this reason it is guarded behind the `html` feature. Visit the [HTML documentation page](/docs/reference/html/) for more details.
## When to use it
This function allows you to format your document properly across both HTML and paged export targets. It should primarily be used in templates and show rules, rather than directly in content. This way, the document's contents can be fully agnostic to the export target and content can be shared between PDF and HTML export.
## Varying targets
This function is [contextual](/docs/reference/context/) as the target can vary within a single compilation: When exporting to HTML, the target will be `"paged"` while within an [`html.frame`](/docs/reference/html/frame/).
## Example
```typst
#let kbd(it) = context {
if target() == "html" {
html.elem("kbd", it)
} else {
set text(fill: rgb("#1f2328"))
let r = 3pt
box(
fill: rgb("#f6f8fa"),
stroke: rgb("#d1d9e0b3"),
outset: (y: r),
inset: (x: r),
radius: r,
raw(it)
)
}
}
Press #kbd("F1") for help.
```
docs/reference/foundations/type.md
# Type
Describes a kind of value.
To style your document, you need to work with values of different kinds: Lengths specifying the size of your elements, colors for your text and shapes, and more. Typst categorizes these into clearly defined _types_ and tells you where it expects which type of value.
Apart from basic types for numeric values and [typical](/docs/reference/foundations/int/) [types](/docs/reference/foundations/float/) [known](/docs/reference/foundations/str/) [from](/docs/reference/foundations/array/) [programming](/docs/reference/foundations/dictionary/) languages, Typst provides a special type for [_content._](/docs/reference/foundations/content/) A value of this type can hold anything that you can enter into your document: Text, elements like headings and shapes, and style information.
## Example
```typst
#let x = 10
#if type(x) == int [
#x is an integer!
] else [
#x is another value...
]
An image is of type
#type(image("glacier.jpg")).
```
The type of `10` is `int`. Now, what is the type of `int` or even `type`?
```typst
#type(int) \
#type(type)
```
Unlike other types like `int`, [none](/docs/reference/foundations/none/) and [auto](/docs/reference/foundations/auto/) do not have a name representing them. To test if a value is one of these, compare your value to them directly, e.g:
```typst
#let val = none
#if val == none [
Yep, it's none.
]
```
Note that `type` will return [`content`](/docs/reference/foundations/content/) for all document elements. To programmatically determine which kind of content you are dealing with, see [`content.func`](/docs/reference/foundations/content/#definitions-func).
## Constructor
## type
Determines a value's type.
```typst
#type(12) \
#type(14.7) \
#type("hello") \
#type(<glacier>) \
#type([Hi]) \
#type(x => x + 1) \
#type(type)
```
```typst
#type(
value
) -> type
```
### Parameters
- value:
- description: The value whose type\'s to determine.
- type: any
- default: None
docs/reference/foundations/version.md
# Version
A version with an arbitrary number of components.
The first three components have names that can be used as fields: `major`, `minor`, `patch`. All following components do not have names.
The list of components is semantically extended by an infinite list of zeros. This means that, for example, `0.8` is the same as `0.8.0`. As a special case, the empty version (that has no components at all) is the same as `0`, `0.0`, `0.0.0`, and so on.
The current version of the Typst compiler is available as `sys.version`.
You can convert a version to an array of explicitly given components using the [`array`](/docs/reference/foundations/array/) constructor.
## Constructor
## version
Creates a new version.
It can have any number of components (even zero).
```typst
#version() \
#version(1) \
#version(1, 2, 3, 4) \
#version((1, 2, 3, 4)) \
#version((1, 2), 3)
```
As a practical use case, this allows comparing the current version ([`sys.version`](/docs/reference/foundations/version/)) to a specific one.
```typst
Current version: #sys.version \
#(sys.version >= version(0, 14, 0)) \
#(version(3, 2, 0) > version(4, 1, 0))
```
```typst
#version(
components
) -> version
```
### Parameters
- components:
- description: The components of the version (array arguments are flattened)
- type: int | array
- default: None
## Methods
## version.at
Retrieves a component of a version.
The returned integer is always non-negative. Returns `0` if the version isn't specified to the necessary length.
```typst
#version.at(
index
) -> int
```
### Parameters
- index:
- description: The index at which to retrieve the component. If negative, indexes from the back of the explicitly given components.
- type: int
- default: None
docs/reference/html/elem.md
# Elem
# html.elem
An HTML element that can contain Typst content.
Typst's HTML export automatically generates the appropriate tags for most elements. However, sometimes, it is desirable to retain more control. For example, when using Typst to generate your blog, you could use this function to wrap each article in an `<article>` tag.
Typst is aware of what is valid HTML. A tag and its attributes must form syntactically valid HTML. Some tags, like `meta` do not accept content. Hence, you must not provide a body for them. We may add more checks in the future, so be sure that you are generating valid HTML when using this function.
Normally, Typst will generate `html`, `head`, and `body` tags for you. If you instead create them with this function, Typst will omit its own tags.
```typst
#html.elem("div", attrs: (style: "background: aqua"))[
A div with _Typst content_ inside!
]
```
```typst
#html.elem(
tag,
attrs: dictionary,
body
) -> content
```
## Parameters
- tag:
- description: The element\'s tag.
- type: str
- default: None
- attrs:
- description: The element\'s HTML attributes.
- type: dictionary
- default: (:)
- body:
- description: The contents of the HTML element. The body can be arbitrary Typst content.
- type: none | content
- default: none
docs/reference/html/frame.md
# Frame
# html.frame
An element that lays out its content as an inline SVG.
Sometimes, converting Typst content to HTML is not desirable. This can be the case for plots and other content that relies on positioning and styling to convey its message.
This function allows you to use the Typst layout engine that would also be used for PDF, SVG, and PNG export to render a part of your document exactly how it would appear when exported in one of these formats. It embeds the content as an inline SVG.
```typst
#html.frame(
body
) -> content
```
## Parameters
- body:
- description: The content that shall be laid out.
- type: content
- default: None
docs/reference/html/index.md
# HTML
> Typst's HTML export is currently under active development. The feature is still very incomplete and only available for experimentation behind a feature flag. Do not use this feature for production use cases. In the CLI, you can experiment with HTML export by passing `--features html` or setting the `TYPST_FEATURES` environment variables to `html`. In the web app, HTML export is not available at this time. Visit the [tracking issue](https://github.com/typst/typst/issues/5512) to follow progress on HTML export and learn more about planned features.
HTML files describe a document structurally. The aim of Typst's HTML export is to capture the structure of an input document and produce semantically rich HTML that retains this structure. The resulting HTML should be accessible, human-readable, and editable by hand and downstream tools.
PDF, PNG, and SVG export, in contrast, all produce _visual_ representations of a fully-laid out document. This divergence in the formats' intents means that Typst cannot simply produce perfect HTML for your existing Typst documents. It cannot always know what the best semantic HTML representation of your content is.
Instead, it gives _you_ full control: You can check the current export format through the [`target`](/docs/reference/foundations/target/) function and when it is set to HTML, generate [raw HTML elements](/docs/reference/html/elem/). The primary intended use of these elements is in templates and show rules. This way, the document's contents can be fully agnostic to the export target and content can be shared between PDF and HTML export.
Currently, Typst will always output a single HTML file. Support for outputting directories with multiple HTML documents and assets, as well as support for outputting fragments that can be integrated into other HTML documents is planned.
Typst currently does not output CSS style sheets, instead focussing on emitting semantic markup. You can of course write your own CSS styles and still benefit from sharing your _content_ between PDF and HTML. For the future, we plan to give you the option of automatically emitting CSS, taking more of your existing set rules into account.
## Exporting as HTML
### Command Line
Pass `--format html` to the `compile` or `watch` subcommand or provide an output file name that ends with `.html`. Note that you must also pass `--features html` or set `TYPST_FEATURES=html` to enable this experimental export target.
When using `typst watch`, Typst will spin up a live-reloading HTTP server. You can configure it as follows:
- Pass `--port` to change the port. (Defaults to the first free port in the range 3000-3005.)
- Pass `--no-reload` to disable injection of a live reload script. (The HTML that is written to disk isn't affected either way.)
- Pass `--no-serve` to disable the server altogether.
### Web App
Not currently available.
## HTML-specific functionality
Typst exposes HTML-specific functionality in the global `html` module. See below for the definitions it contains.
## Definitions
| Name | Description |
| --- | --- |
| [`elem`](/reference/html/elem/) | An HTML element that can contain Typst content. |
| [`frame`](/reference/html/frame/) | An element that lays out its content as an inline SVG. |
| [`typed`](/reference/html/typed/) | A typed layer over raw HTML elements. |
docs/reference/html/typed.md
# Typed HTML
A typed layer over raw HTML elements.
The `html` module provides a typed layer over the raw [`html.elem`](/docs/reference/html/elem/) function that allows you to conveniently create HTML elements. HTML attributes are exposed as function parameters that accept Typst types and automatically take care of converting those into the appropriate HTML.
Some parameters are common to all typed HTML functions. These are listed at the bottom in the [Global Attributes](#global-attributes) section instead of explicitly on each element for readability.
## Example
```typst
#html.video(
controls: true,
width: 1280,
height: 720,
src: "sunrise.mp4",
)[
Your browser does not support the video tag.
]
```
# html.a
Hyperlink.
```typst
#html.a(
download: str,
href: str,
hreflang: str,
ping: str | array,
referrerpolicy: none | str,
rel: str | array,
target: str,
type: str,
body
) -> content
```
## Parameters
- download:
- description: Whether to download the resource instead of navigating to it, and its filename if so.
- type: str
- default: None
- href:
- description: Address of the hyperlink.
- type: str
- default: None
- hreflang:
- description: Language of the linked resource.
- type: str
- default: None
- ping:
- description: URLs to ping.
- type: str | array
- default: None
- referrerpolicy:
- description: Referrer policy for fetches initiated by the element.
- type: none | str
- default: None
- rel:
- description: Relationship between the location in the document containing the hyperlink and the destination resource.
- type: str | array
- default: None
- target:
- description: Navigable for hyperlink navigation.
- type: str
- default: None
- type:
- description: Hint for the type of the referenced resource.
- type: str
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.abbr
Abbreviation.
```typst
#html.abbr(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.address
Contact information for a page or article element.
```typst
#html.address(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.area
Hyperlink or dead area on an image map.
```typst
#html.area(
alt: str,
coords: array,
download: str,
href: str,
ping: str | array,
referrerpolicy: none | str,
rel: str | array,
shape: str,
target: str
) -> content
```
## Parameters
- alt:
- description: Replacement text for use when images are not available.
- type: str
- default: None
- coords:
- description: Coordinates for the shape to be created in an image map. Expects an array of floating point numbers.
- type: array
- default: None
- download:
- description: Whether to download the resource instead of navigating to it, and its filename if so.
- type: str
- default: None
- href:
- description: Address of the hyperlink.
- type: str
- default: None
- ping:
- description: URLs to ping.
- type: str | array
- default: None
- referrerpolicy:
- description: Referrer policy for fetches initiated by the element.
- type: none | str
- default: None
- rel:
- description: Relationship between the location in the document containing the hyperlink and the destination resource.
- type: str | array
- default: None
- shape:
- description: The kind of shape to be created in an image map.
- type: str
- default: None
- target:
- description: Navigable for hyperlink navigation.
- type: str
- default: None
# html.article
Self-contained syndicatable or reusable composition.
```typst
#html.article(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.aside
Sidebar for tangentially related content.
```typst
#html.aside(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.audio
Audio player.
```typst
#html.audio(
autoplay: bool,
controls: bool,
crossorigin: str,
loop: bool,
muted: bool,
preload: none | auto | str,
src: str,
body
) -> content
```
## Parameters
- autoplay:
- description: Hint that the media resource can be started automatically when the page is loaded.
- type: bool
- default: None
- controls:
- description: Show user agent controls.
- type: bool
- default: None
- crossorigin:
- description: How the element handles crossorigin requests.
- type: str
- default: None
- loop:
- description: Whether to loop the media resource.
- type: bool
- default: None
- muted:
- description: Whether to mute the media resource by default.
- type: bool
- default: None
- preload:
- description: Hints how much buffering the media resource will likely need.
- type: none | auto | str
- default: None
- src:
- description: Address of the resource.
- type: str
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.b
Keywords.
```typst
#html.b(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.base
Base URL and default target navigable for hyperlinks and forms.
```typst
#html.base(
href: str,
target: str
) -> content
```
## Parameters
- href:
- description: Document base URL.
- type: str
- default: None
- target:
- description: Default navigable for hyperlink navigation and form submission.
- type: str
- default: None
# html.bdi
Text directionality isolation.
```typst
#html.bdi(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.bdo
Text directionality formatting.
```typst
#html.bdo(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.blockquote
A section quoted from another source.
```typst
#html.blockquote(
cite: str,
body
) -> content
```
## Parameters
- cite:
- description: Link to the source of the quotation or more information about the edit.
- type: str
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.body
Document body.
```typst
#html.body(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.br
Line break, e.g. in poem or postal address.
# html.button
Button control.
```typst
#html.button(
command: str,
commandfor: str,
disabled: bool,
form: str,
formaction: str,
formenctype: str,
formmethod: str,
formnovalidate: bool,
formtarget: str,
name: str,
popovertarget: str,
popovertargetaction: str,
type: str,
value: str,
body
) -> content
```
## Parameters
- command:
- description: Indicates to the targeted element which action to take.
- type: str
- default: None
- commandfor:
- description: Targets another element to be invoked.
- type: str
- default: None
- disabled:
- description: Whether the form control is disabled.
- type: bool
- default: None
- form:
- description: Associates the element with a form element.
- type: str
- default: None
- formaction:
- description: URL to use for form submission.
- type: str
- default: None
- formenctype:
- description: Entry list encoding type to use for form submission.
- type: str
- default: None
- formmethod:
- description: Variant to use for form submission.
- type: str
- default: None
- formnovalidate:
- description: Bypass form control validation for form submission.
- type: bool
- default: None
- formtarget:
- description: Navigable for form submission.
- type: str
- default: None
- name:
- description: Name of the element to use for form submission and in the form.elements API.
- type: str
- default: None
- popovertarget:
- description: Targets a popover element to toggle, show, or hide.
- type: str
- default: None
- popovertargetaction:
- description: Indicates whether a targeted popover element is to be toggled, shown, or hidden.
- type: str
- default: None
- type:
- description: Type of button.
- type: str
- default: None
- value:
- description: Value to be used for form submission.
- type: str
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.canvas
Scriptable bitmap canvas.
```typst
#html.canvas(
height: int,
width: int,
body
) -> content
```
## Parameters
- height:
- description: Vertical dimension.
- type: int
- default: None
- width:
- description: Horizontal dimension.
- type: int
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.caption
Table caption.
```typst
#html.caption(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.cite
Title of a work.
```typst
#html.cite(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.code
Computer code.
```typst
#html.code(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.col
Table column.
```typst
#html.col(
span: int
) -> content
```
## Parameters
- span:
- description: Number of columns spanned by the element.
- type: int
- default: None
# html.colgroup
Group of columns in a table.
```typst
#html.colgroup(
span: int,
body
) -> content
```
## Parameters
- span:
- description: Number of columns spanned by the element.
- type: int
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.data
Machine-readable equivalent.
```typst
#html.data(
value: str,
body
) -> content
```
## Parameters
- value:
- description: Machine-readable value.
- type: str
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.datalist
Container for options for combo box control.
```typst
#html.datalist(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.dd
Content for corresponding dt element(s).
```typst
#html.dd(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.del
A removal from the document.
```typst
#html.del(
cite: str,
datetime: datetime,
body
) -> content
```
## Parameters
- cite:
- description: Link to the source of the quotation or more information about the edit.
- type: str
- default: None
- datetime:
- description: Date and (optionally) time of the change.
- type: datetime
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.details
Disclosure control for hiding details.
```typst
#html.details(
name: str,
open: bool,
body
) -> content
```
## Parameters
- name:
- description: Name of group of mutually-exclusive details elements.
- type: str
- default: None
- open:
- description: Whether the details are visible.
- type: bool
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.dfn
Defining instance.
```typst
#html.dfn(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.dialog
Dialog box or window.
```typst
#html.dialog(
open: bool,
body
) -> content
```
## Parameters
- open:
- description: Whether the dialog box is showing.
- type: bool
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.div
Generic flow container, or container for name-value groups in dl elements.
```typst
#html.div(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.dl
Association list consisting of zero or more name-value groups.
```typst
#html.dl(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.dt
Legend for corresponding dd element(s).
```typst
#html.dt(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.em
Stress emphasis.
```typst
#html.em(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.embed
Plugin.
```typst
#html.embed(
height: int,
src: str,
type: str,
width: int
) -> content
```
## Parameters
- height:
- description: Vertical dimension.
- type: int
- default: None
- src:
- description: Address of the resource.
- type: str
- default: None
- type:
- description: Type of embedded resource.
- type: str
- default: None
- width:
- description: Horizontal dimension.
- type: int
- default: None
# html.fieldset
Group of form controls.
```typst
#html.fieldset(
disabled: bool,
form: str,
name: str,
body
) -> content
```
## Parameters
- disabled:
- description: Whether the descendant form controls, except any inside legend, are disabled.
- type: bool
- default: None
- form:
- description: Associates the element with a form element.
- type: str
- default: None
- name:
- description: Name of the element to use for form submission and in the form.elements API.
- type: str
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.figcaption
Caption for figure.
```typst
#html.figcaption(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.figure
Figure with optional caption.
```typst
#html.figure(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.footer
Footer for a page or section.
```typst
#html.footer(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.form
User-submittable form.
```typst
#html.form(
accept-charset: str,
action: str,
autocomplete: bool,
enctype: str,
method: str,
name: str,
novalidate: bool,
rel: str | array,
target: str,
body
) -> content
```
## Parameters
- accept-charset:
- description: Character encodings to use for form submission.
- type: str
- default: None
- action:
- description: URL to use for form submission.
- type: str
- default: None
- autocomplete:
- description: Default setting for autofill feature for controls in the form.
- type: bool
- default: None
- enctype:
- description: Entry list encoding type to use for form submission.
- type: str
- default: None
- method:
- description: Variant to use for form submission.
- type: str
- default: None
- name:
- description: Name of form to use in the document.forms API.
- type: str
- default: None
- novalidate:
- description: Bypass form control validation for form submission.
- type: bool
- default: None
- rel:
- description: Relationship between the document containing the form and its action destination
- type: str | array
- default: None
- target:
- description: Navigable for form submission.
- type: str
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.h1
Heading.
```typst
#html.h1(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.h2
Heading.
```typst
#html.h2(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.h3
Heading.
```typst
#html.h3(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.h4
Heading.
```typst
#html.h4(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.h5
Heading.
```typst
#html.h5(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.h6
Heading.
```typst
#html.h6(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.head
Container for document metadata.
```typst
#html.head(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.header
Introductory or navigational aids for a page or section.
```typst
#html.header(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.hgroup
Heading container.
```typst
#html.hgroup(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.hr
Thematic break.
# html.html
Root element.
```typst
#html.html(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.i
Alternate voice.
```typst
#html.i(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.iframe
Child navigable.
```typst
#html.iframe(
allow: str,
allowfullscreen: bool,
height: int,
loading: str,
name: str,
referrerpolicy: none | str,
sandbox: str | array,
src: str,
srcdoc: str,
width: int,
body
) -> content
```
## Parameters
- allow:
- description: Permissions policy to be applied to the iframe\'s contents.
- type: str
- default: None
- allowfullscreen:
- description: Whether to allow the iframe\'s contents to use requestFullscreen().
- type: bool
- default: None
- height:
- description: Vertical dimension.
- type: int
- default: None
- loading:
- description: Used when determining loading deferral.
- type: str
- default: None
- name:
- description: Name of content navigable.
- type: str
- default: None
- referrerpolicy:
- description: Referrer policy for fetches initiated by the element.
- type: none | str
- default: None
- sandbox:
- description: Security rules for nested content.
- type: str | array
- default: None
- src:
- description: Address of the resource.
- type: str
- default: None
- srcdoc:
- description: A document to render in the iframe.
- type: str
- default: None
- width:
- description: Horizontal dimension.
- type: int
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.img
Image.
```typst
#html.img(
alt: str,
crossorigin: str,
decoding: auto | str,
fetchpriority: auto | str,
height: int,
ismap: bool,
loading: str,
referrerpolicy: none | str,
sizes: array,
src: str,
srcset: array,
usemap: str,
width: int
) -> content
```
## Parameters
- alt:
- description: Replacement text for use when images are not available.
- type: str
- default: None
- crossorigin:
- description: How the element handles crossorigin requests.
- type: str
- default: None
- decoding:
- description: Decoding hint to use when processing this image for presentation.
- type: auto | str
- default: None
- fetchpriority:
- description: Sets the priority for fetches initiated by the element.
- type: auto | str
- default: None
- height:
- description: Vertical dimension.
- type: int
- default: None
- ismap:
- description: Whether the image is a server-side image map.
- type: bool
- default: None
- loading:
- description: Used when determining loading deferral.
- type: str
- default: None
- referrerpolicy:
- description: Referrer policy for fetches initiated by the element.
- type: none | str
- default: None
- sizes:
- description: Image sizes for different page layouts. Expects an array of dictionaries with the keys `condition` (string) and `size` (length).
- type: array
- default: None
- src:
- description: Address of the resource.
- type: str
- default: None
- srcset:
- description: Images to use in different situations, e.g., high-resolution displays, small monitors, etc. Expects an array of dictionaries with the keys `src` (string) and `width` (integer) or `density` (float).
- type: array
- default: None
- usemap:
- description: Name of image map to use.
- type: str
- default: None
- width:
- description: Horizontal dimension.
- type: int
- default: None
# html.input
Form control.
```typst
#html.input(
accept: str | array,
alpha: bool,
alt: str,
autocomplete: str | array,
checked: bool,
colorspace: str,
dirname: str,
disabled: bool,
form: str,
formaction: str,
formenctype: str,
formmethod: str,
formnovalidate: bool,
formtarget: str,
height: int,
list: str,
max: float | datetime | str,
maxlength: int,
min: float | datetime | str,
minlength: int,
multiple: bool,
name: str,
pattern: str,
placeholder: str,
popovertarget: str,
popovertargetaction: str,
readonly: bool,
required: bool,
size: int,
src: str,
step: float | str,
type: str,
value: float | color | datetime | str | array,
width: int
) -> content
```
## Parameters
- accept:
- description: Hint for expected file type in file upload controls.
- type: str | array
- default: None
- alpha:
- description: Allow the color\'s alpha component to be set.
- type: bool
- default: None
- alt:
- description: Replacement text for use when images are not available.
- type: str
- default: None
- autocomplete:
- description: Hint for form autofill feature.
- type: str | array
- default: None
- checked:
- description: Whether the control is checked.
- type: bool
- default: None
- colorspace:
- description: The color space of the serialized color.
- type: str
- default: None
- dirname:
- description: Name of form control to use for sending the element\'s directionality in form submission.
- type: str
- default: None
- disabled:
- description: Whether the form control is disabled.
- type: bool
- default: None
- form:
- description: Associates the element with a form element.
- type: str
- default: None
- formaction:
- description: URL to use for form submission.
- type: str
- default: None
- formenctype:
- description: Entry list encoding type to use for form submission.
- type: str
- default: None
- formmethod:
- description: Variant to use for form submission.
- type: str
- default: None
- formnovalidate:
- description: Bypass form control validation for form submission.
- type: bool
- default: None
- formtarget:
- description: Navigable for form submission.
- type: str
- default: None
- height:
- description: Vertical dimension.
- type: int
- default: None
- list:
- description: List of autocomplete options.
- type: str
- default: None
- max:
- description: Maximum value.
- type: float | datetime | str
- default: None
- maxlength:
- description: Maximum length of value.
- type: int
- default: None
- min:
- description: Minimum value.
- type: float | datetime | str
- default: None
- minlength:
- description: Minimum length of value.
- type: int
- default: None
- multiple:
- description: Whether to allow multiple values.
- type: bool
- default: None
- name:
- description: Name of the element to use for form submission and in the form.elements API.
- type: str
- default: None
- pattern:
- description: Pattern to be matched by the form control\'s value.
- type: str
- default: None
- placeholder:
- description: User-visible label to be placed within the form control.
- type: str
- default: None
- popovertarget:
- description: Targets a popover element to toggle, show, or hide.
- type: str
- default: None
- popovertargetaction:
- description: Indicates whether a targeted popover element is to be toggled, shown, or hidden.
- type: str
- default: None
- readonly:
- description: Whether to allow the value to be edited by the user.
- type: bool
- default: None
- required:
- description: Whether the control is required for form submission.
- type: bool
- default: None
- size:
- description: Size of the control.
- type: int
- default: None
- src:
- description: Address of the resource.
- type: str
- default: None
- step:
- description: Granularity to be matched by the form control\'s value.
- type: float | str
- default: None
- type:
- description: Type of form control.
- type: str
- default: None
- value:
- description: Value of the form control.
- type: float | color | datetime | str | array
- default: None
- width:
- description: Horizontal dimension.
- type: int
- default: None
# html.ins
An addition to the document.
```typst
#html.ins(
cite: str,
datetime: datetime,
body
) -> content
```
## Parameters
- cite:
- description: Link to the source of the quotation or more information about the edit.
- type: str
- default: None
- datetime:
- description: Date and (optionally) time of the change.
- type: datetime
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.kbd
User input.
```typst
#html.kbd(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.label
Caption for a form control.
```typst
#html.label(
for: str,
body
) -> content
```
## Parameters
- for:
- description: Associate the label with form control.
- type: str
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.legend
Caption for fieldset.
```typst
#html.legend(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.li
List item.
```typst
#html.li(
value: int,
body
) -> content
```
## Parameters
- value:
- description: Ordinal value of the list item.
- type: int
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.link
Link metadata.
```typst
#html.link(
as: str,
blocking: str | array,
color: color,
crossorigin: str,
disabled: bool,
fetchpriority: auto | str,
href: str,
hreflang: str,
imagesizes: array,
imagesrcset: array,
integrity: str,
media: str,
referrerpolicy: none | str,
rel: str | array,
sizes: array,
type: str
) -> content
```
## Parameters
- as:
- description: Potential destination for a preload request (for rel="preload" and rel="modulepreload").
- type: str
- default: None
- blocking:
- description: Whether the element is potentially render-blocking.
- type: str | array
- default: None
- color:
- description: Color to use when customizing a site\'s icon (for rel="mask-icon").
- type: color
- default: None
- crossorigin:
- description: How the element handles crossorigin requests.
- type: str
- default: None
- disabled:
- description: Whether the link is disabled.
- type: bool
- default: None
- fetchpriority:
- description: Sets the priority for fetches initiated by the element.
- type: auto | str
- default: None
- href:
- description: Address of the hyperlink.
- type: str
- default: None
- hreflang:
- description: Language of the linked resource.
- type: str
- default: None
- imagesizes:
- description: Image sizes for different page layouts (for rel="preload"). Expects an array of dictionaries with the keys `condition` (string) and `size` (length).
- type: array
- default: None
- imagesrcset:
- description: Images to use in different situations, e.g., high-resolution displays, small monitors, etc. (for rel="preload"). Expects an array of dictionaries with the keys `src` (string) and `width` (integer) or `density` (float).
- type: array
- default: None
- integrity:
- description: Integrity metadata used in Subresource Integrity checks.
- type: str
- default: None
- media:
- description: Applicable media.
- type: str
- default: None
- referrerpolicy:
- description: Referrer policy for fetches initiated by the element.
- type: none | str
- default: None
- rel:
- description: Relationship between the document containing the hyperlink and the destination resource.
- type: str | array
- default: None
- sizes:
- description: Sizes of the icons (for rel="icon"). Expects an array of sizes. Each size is specified as an array of two integers (width and height).
- type: array
- default: None
- type:
- description: Hint for the type of the referenced resource.
- type: str
- default: None
# html.main
Container for the dominant contents of the document.
```typst
#html.main(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.map
Image map.
```typst
#html.map(
name: str,
body
) -> content
```
## Parameters
- name:
- description: Name of image map to reference from the usemap attribute.
- type: str
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.mark
Highlight.
```typst
#html.mark(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.menu
Menu of commands.
```typst
#html.menu(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.meta
Text metadata.
```typst
#html.meta(
charset: str,
content: str,
http-equiv: str,
media: str,
name: str
) -> content
```
## Parameters
- charset:
- description: Character encoding declaration.
- type: str
- default: None
- content:
- description: Value of the element.
- type: str
- default: None
- http-equiv:
- description: Pragma directive.
- type: str
- default: None
- media:
- description: Applicable media.
- type: str
- default: None
- name:
- description: Metadata name.
- type: str
- default: None
# html.meter
Gauge.
```typst
#html.meter(
high: float,
low: float,
max: float,
min: float,
optimum: float,
value: float,
body
) -> content
```
## Parameters
- high:
- description: Low limit of high range.
- type: float
- default: None
- low:
- description: High limit of low range.
- type: float
- default: None
- max:
- description: Upper bound of range.
- type: float
- default: None
- min:
- description: Lower bound of range.
- type: float
- default: None
- optimum:
- description: Optimum value in gauge.
- type: float
- default: None
- value:
- description: Current value of the element.
- type: float
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.nav
Section with navigational links.
```typst
#html.nav(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.noscript
Fallback content for script.
```typst
#html.noscript(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.object
Image, child navigable, or plugin.
```typst
#html.object(
data: str,
form: str,
height: int,
name: str,
type: str,
width: int,
body
) -> content
```
## Parameters
- data:
- description: Address of the resource.
- type: str
- default: None
- form:
- description: Associates the element with a form element.
- type: str
- default: None
- height:
- description: Vertical dimension.
- type: int
- default: None
- name:
- description: Name of content navigable.
- type: str
- default: None
- type:
- description: Type of embedded resource.
- type: str
- default: None
- width:
- description: Horizontal dimension.
- type: int
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.ol
Ordered list.
```typst
#html.ol(
reversed: bool,
start: int,
type: str,
body
) -> content
```
## Parameters
- reversed:
- description: Number the list backwards.
- type: bool
- default: None
- start:
- description: Starting value of the list.
- type: int
- default: None
- type:
- description: Kind of list marker.
- type: str
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.optgroup
Group of options in a list box.
```typst
#html.optgroup(
disabled: bool,
label: str,
body
) -> content
```
## Parameters
- disabled:
- description: Whether the form control is disabled.
- type: bool
- default: None
- label:
- description: User-visible label.
- type: str
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.option
Option in a list box or combo box control.
```typst
#html.option(
disabled: bool,
label: str,
selected: bool,
value: str,
body
) -> content
```
## Parameters
- disabled:
- description: Whether the form control is disabled.
- type: bool
- default: None
- label:
- description: User-visible label.
- type: str
- default: None
- selected:
- description: Whether the option is selected by default.
- type: bool
- default: None
- value:
- description: Value to be used for form submission.
- type: str
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.output
Calculated output value.
```typst
#html.output(
for: str | array,
form: str,
name: str,
body
) -> content
```
## Parameters
- for:
- description: Specifies controls from which the output was calculated.
- type: str | array
- default: None
- form:
- description: Associates the element with a form element.
- type: str
- default: None
- name:
- description: Name of the element to use for form submission and in the form.elements API.
- type: str
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.p
Paragraph.
```typst
#html.p(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.picture
Image.
```typst
#html.picture(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.pre
Block of preformatted text.
```typst
#html.pre(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.progress
Progress bar.
```typst
#html.progress(
max: float,
value: float,
body
) -> content
```
## Parameters
- max:
- description: Upper bound of range.
- type: float
- default: None
- value:
- description: Current value of the element.
- type: float
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.q
Quotation.
```typst
#html.q(
cite: str,
body
) -> content
```
## Parameters
- cite:
- description: Link to the source of the quotation or more information about the edit.
- type: str
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.rp
Parenthesis for ruby annotation text.
```typst
#html.rp(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.rt
Ruby annotation text.
```typst
#html.rt(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.ruby
Ruby annotation(s).
```typst
#html.ruby(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.s
Inaccurate text.
```typst
#html.s(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.samp
Computer output.
```typst
#html.samp(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.script
Embedded script.
```typst
#html.script(
async: bool,
blocking: str | array,
crossorigin: str,
defer: bool,
fetchpriority: auto | str,
integrity: str,
nomodule: bool,
referrerpolicy: none | str,
src: str,
type: str,
body
) -> content
```
## Parameters
- async:
- description: Execute script when available, without blocking while fetching.
- type: bool
- default: None
- blocking:
- description: Whether the element is potentially render-blocking.
- type: str | array
- default: None
- crossorigin:
- description: How the element handles crossorigin requests.
- type: str
- default: None
- defer:
- description: Defer script execution.
- type: bool
- default: None
- fetchpriority:
- description: Sets the priority for fetches initiated by the element.
- type: auto | str
- default: None
- integrity:
- description: Integrity metadata used in Subresource Integrity checks.
- type: str
- default: None
- nomodule:
- description: Prevents execution in user agents that support module scripts.
- type: bool
- default: None
- referrerpolicy:
- description: Referrer policy for fetches initiated by the element.
- type: none | str
- default: None
- src:
- description: Address of the resource.
- type: str
- default: None
- type:
- description: Type of script.
- type: str
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.search
Container for search controls.
```typst
#html.search(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.section
Generic document or application section.
```typst
#html.section(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.select
List box control.
```typst
#html.select(
autocomplete: str | array,
disabled: bool,
form: str,
multiple: bool,
name: str,
required: bool,
size: int,
body
) -> content
```
## Parameters
- autocomplete:
- description: Hint for form autofill feature.
- type: str | array
- default: None
- disabled:
- description: Whether the form control is disabled.
- type: bool
- default: None
- form:
- description: Associates the element with a form element.
- type: str
- default: None
- multiple:
- description: Whether to allow multiple values.
- type: bool
- default: None
- name:
- description: Name of the element to use for form submission and in the form.elements API.
- type: str
- default: None
- required:
- description: Whether the control is required for form submission.
- type: bool
- default: None
- size:
- description: Size of the control.
- type: int
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.slot
Shadow tree slot.
```typst
#html.slot(
name: str,
body
) -> content
```
## Parameters
- name:
- description: Name of shadow tree slot.
- type: str
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.small
Side comment.
```typst
#html.small(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.source
Image source for img or media source for video or audio.
```typst
#html.source(
height: int,
media: str,
sizes: array,
src: str,
srcset: array,
type: str,
width: int
) -> content
```
## Parameters
- height:
- description: Vertical dimension.
- type: int
- default: None
- media:
- description: Applicable media.
- type: str
- default: None
- sizes:
- description: Image sizes for different page layouts. Expects an array of dictionaries with the keys `condition` (string) and `size` (length).
- type: array
- default: None
- src:
- description: Address of the resource.
- type: str
- default: None
- srcset:
- description: Images to use in different situations, e.g., high-resolution displays, small monitors, etc. Expects an array of dictionaries with the keys `src` (string) and `width` (integer) or `density` (float).
- type: array
- default: None
- type:
- description: Type of embedded resource.
- type: str
- default: None
- width:
- description: Horizontal dimension.
- type: int
- default: None
# html.span
Generic phrasing container.
```typst
#html.span(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.strong
Importance.
```typst
#html.strong(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.style
Embedded styling information.
```typst
#html.style(
blocking: str | array,
media: str,
body
) -> content
```
## Parameters
- blocking:
- description: Whether the element is potentially render-blocking.
- type: str | array
- default: None
- media:
- description: Applicable media.
- type: str
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.sub
Subscript.
```typst
#html.sub(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.summary
Caption for details.
```typst
#html.summary(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.sup
Superscript.
```typst
#html.sup(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.table
Table.
```typst
#html.table(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.tbody
Group of rows in a table.
```typst
#html.tbody(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.td
Table cell.
```typst
#html.td(
colspan: int,
headers: str | array,
rowspan: int,
body
) -> content
```
## Parameters
- colspan:
- description: Number of columns that the cell is to span.
- type: int
- default: None
- headers:
- description: The header cells for this cell.
- type: str | array
- default: None
- rowspan:
- description: Number of rows that the cell is to span.
- type: int
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.template
Template.
```typst
#html.template(
shadowrootclonable: bool,
shadowrootcustomelementregistry: bool,
shadowrootdelegatesfocus: bool,
shadowrootmode: str,
shadowrootserializable: bool,
body
) -> content
```
## Parameters
- shadowrootclonable:
- description: Sets clonable on a declarative shadow root.
- type: bool
- default: None
- shadowrootcustomelementregistry:
- description: Enables declarative shadow roots to indicate they will use a custom element registry.
- type: bool
- default: None
- shadowrootdelegatesfocus:
- description: Sets delegates focus on a declarative shadow root.
- type: bool
- default: None
- shadowrootmode:
- description: Enables streaming declarative shadow roots.
- type: str
- default: None
- shadowrootserializable:
- description: Sets serializable on a declarative shadow root.
- type: bool
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.textarea
Multiline text controls.
```typst
#html.textarea(
autocomplete: str | array,
cols: int,
dirname: str,
disabled: bool,
form: str,
maxlength: int,
minlength: int,
name: str,
placeholder: str,
readonly: bool,
required: bool,
rows: int,
wrap: str,
body
) -> content
```
## Parameters
- autocomplete:
- description: Hint for form autofill feature.
- type: str | array
- default: None
- cols:
- description: Maximum number of characters per line.
- type: int
- default: None
- dirname:
- description: Name of form control to use for sending the element\'s directionality in form submission.
- type: str
- default: None
- disabled:
- description: Whether the form control is disabled.
- type: bool
- default: None
- form:
- description: Associates the element with a form element.
- type: str
- default: None
- maxlength:
- description: Maximum length of value.
- type: int
- default: None
- minlength:
- description: Minimum length of value.
- type: int
- default: None
- name:
- description: Name of the element to use for form submission and in the form.elements API.
- type: str
- default: None
- placeholder:
- description: User-visible label to be placed within the form control.
- type: str
- default: None
- readonly:
- description: Whether to allow the value to be edited by the user.
- type: bool
- default: None
- required:
- description: Whether the control is required for form submission.
- type: bool
- default: None
- rows:
- description: Number of lines to show.
- type: int
- default: None
- wrap:
- description: How the value of the form control is to be wrapped for form submission.
- type: str
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.tfoot
Group of footer rows in a table.
```typst
#html.tfoot(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.th
Table header cell.
```typst
#html.th(
abbr: str,
colspan: int,
headers: str | array,
rowspan: int,
scope: str,
body
) -> content
```
## Parameters
- abbr:
- description: Alternative label to use for the header cell when referencing the cell in other contexts.
- type: str
- default: None
- colspan:
- description: Number of columns that the cell is to span.
- type: int
- default: None
- headers:
- description: The header cells for this cell.
- type: str | array
- default: None
- rowspan:
- description: Number of rows that the cell is to span.
- type: int
- default: None
- scope:
- description: Specifies which cells the header cell applies to.
- type: str
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.thead
Group of heading rows in a table.
```typst
#html.thead(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.time
Machine-readable equivalent of date- or time-related data.
```typst
#html.time(
datetime: datetime | duration,
body
) -> content
```
## Parameters
- datetime:
- description: Machine-readable value.
- type: datetime | duration
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.title
Document title.
```typst
#html.title(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.tr
Table row.
```typst
#html.tr(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.track
Timed text track.
```typst
#html.track(
default: bool,
kind: str,
label: str,
src: str,
srclang: str
) -> content
```
## Parameters
- default:
- description: Enable the track if no other text track is more suitable.
- type: bool
- default: None
- kind:
- description: The type of text track.
- type: str
- default: None
- label:
- description: User-visible label.
- type: str
- default: None
- src:
- description: Address of the resource.
- type: str
- default: None
- srclang:
- description: Language of the text track.
- type: str
- default: None
# html.u
Unarticulated annotation.
```typst
#html.u(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.ul
List.
```typst
#html.ul(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.var
Variable.
```typst
#html.var(
body
) -> content
```
## Parameters
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.video
Video player.
```typst
#html.video(
autoplay: bool,
controls: bool,
crossorigin: str,
height: int,
loop: bool,
muted: bool,
playsinline: bool,
poster: str,
preload: none | auto | str,
src: str,
width: int,
body
) -> content
```
## Parameters
- autoplay:
- description: Hint that the media resource can be started automatically when the page is loaded.
- type: bool
- default: None
- controls:
- description: Show user agent controls.
- type: bool
- default: None
- crossorigin:
- description: How the element handles crossorigin requests.
- type: str
- default: None
- height:
- description: Vertical dimension.
- type: int
- default: None
- loop:
- description: Whether to loop the media resource.
- type: bool
- default: None
- muted:
- description: Whether to mute the media resource by default.
- type: bool
- default: None
- playsinline:
- description: Encourage the user agent to display video content within the element\'s playback area.
- type: bool
- default: None
- poster:
- description: Poster frame to show prior to video playback.
- type: str
- default: None
- preload:
- description: Hints how much buffering the media resource will likely need.
- type: none | auto | str
- default: None
- src:
- description: Address of the resource.
- type: str
- default: None
- width:
- description: Horizontal dimension.
- type: int
- default: None
- body:
- description: The contents of the HTML element.
- type: content
- default: None
# html.wbr
Line breaking opportunity.
docs/reference/index.md
# Reference
This reference documentation is a comprehensive guide to all of Typst's syntax, concepts, types, and functions. If you are completely new to Typst, we recommend starting with the [tutorial](/docs/tutorial/) and then coming back to the reference to learn more about Typst's features as you need them.
## Language
The reference starts with a language part that gives an overview over [Typst's syntax](/docs/reference/syntax/) and contains information about concepts involved in [styling documents,](/docs/reference/styling/) using [Typst's scripting capabilities.](/docs/reference/scripting/)
## Functions
The second part includes chapters on all functions used to insert, style, transform, and layout content in Typst documents. Each function is documented with a description of its purpose, a list of its parameters, and examples of how to use it.
The final part of the reference explains all functions that are used within Typst's code mode to manipulate and transform data. Just as in the previous part, each function is documented with a description of its purpose, a list of its parameters, and examples of how to use it.
docs/reference/introspection/counter.md
# Counter
Counts through pages, elements, and more.
With the counter function, you can access and modify counters for pages, headings, figures, and more. Moreover, you can define custom counters for other things you want to count.
Since counters change throughout the course of the document, their current value is _contextual._ It is recommended to read the chapter on [context](/docs/reference/context/) before continuing here.
## Accessing a counter
To access the raw value of a counter, we can use the [`get`](/docs/reference/introspection/counter/#definitions-get) function. This function returns an [array](/docs/reference/foundations/array/): Counters can have multiple levels (in the case of headings for sections, subsections, and so on), and each item in the array corresponds to one level.
```typst
#set heading(numbering: "1.")
= Introduction
Raw value of heading counter is
#context counter(heading).get()
```
## Displaying a counter
Often, we want to display the value of a counter in a more human-readable way. To do that, we can call the [`display`](/docs/reference/introspection/counter/#definitions-display) function on the counter. This function retrieves the current counter value and formats it either with a provided or with an automatically inferred [numbering](/docs/reference/model/numbering/).
```typst
#set heading(numbering: "1.")
= Introduction
Some text here.
= Background
The current value is: #context {
counter(heading).display()
}
Or in roman numerals: #context {
counter(heading).display("I")
}
```
## Modifying a counter
To modify a counter, you can use the `step` and `update` methods:
- The `step` method increases the value of the counter by one. Because counters can have multiple levels , it optionally takes a `level` argument. If given, the counter steps at the given depth.
- The `update` method allows you to arbitrarily modify the counter. In its basic form, you give it an integer (or an array for multiple levels). For more flexibility, you can instead also give it a function that receives the current value and returns a new value.
The heading counter is stepped before the heading is displayed, so `Analysis` gets the number seven even though the counter is at six after the second update.
```typst
#set heading(numbering: "1.")
= Introduction
#counter(heading).step()
= Background
#counter(heading).update(3)
#counter(heading).update(n => n * 2)
= Analysis
Let's skip 7.1.
#counter(heading).step(level: 2)
== Analysis
Still at #context {
counter(heading).display()
}
```
## Page counter
The page counter is special. It is automatically stepped at each pagebreak. But like other counters, you can also step it manually. For example, you could have Roman page numbers for your preface, then switch to Arabic page numbers for your main content and reset the page counter to one.
```typst
#set page(numbering: "(i)")
= Preface
The preface is numbered with
roman numerals.
#set page(numbering: "1 / 1")
#counter(page).update(1)
= Main text
Here, the counter is reset to one.
We also display both the current
page and total number of pages in
Arabic numbers.
```
## Custom counters
To define your own counter, call the `counter` function with a string as a key. This key identifies the counter globally.
```typst
#let mine = counter("mycounter")
#context mine.display() \
#mine.step()
#context mine.display() \
#mine.update(c => c * 3)
#context mine.display()
```
## How to step
When you define and use a custom counter, in general, you should first step the counter and then display it. This way, the stepping behaviour of a counter can depend on the element it is stepped for. If you were writing a counter for, let's say, theorems, your theorem's definition would thus first include the counter step and only then display the counter and the theorem's contents.
```typst
#let c = counter("theorem")
#let theorem(it) = block[
#c.step()
*Theorem #context c.display():*
#it
]
#theorem[$1 = 1$]
#theorem[$2 < 3$]
```
The rationale behind this is best explained on the example of the heading counter: An update to the heading counter depends on the heading's level. By stepping directly before the heading, we can correctly step from `1` to `1.1` when encountering a level 2 heading. If we were to step after the heading, we wouldn't know what to step to.
Because counters should always be stepped before the elements they count, they always start at zero. This way, they are at one for the first display (which happens after the first step).
## Time travel
Counters can travel through time! You can find out the final value of the counter before it is reached and even determine what the value was at any particular location in the document.
```typst
#let mine = counter("mycounter")
= Values
#context [
Value here: #mine.get() \
At intro: #mine.at(<intro>) \
Final value: #mine.final()
]
#mine.update(n => n + 3)
= Introduction <intro>
#lorem(10)
#mine.step()
#mine.step()
```
## Other kinds of state
The `counter` type is closely related to [state](/docs/reference/introspection/state/) type. Read its documentation for more details on state management in Typst and why it doesn't just use normal variables for counters.
## Constructor
## counter
Create a new counter identified by a key.
```typst
#counter(
key
) -> counter
```
### Parameters
- key:
- description: The key that identifies this counter globally. - If it is a string, creates a custom counter that is only affected by manual updates, - If it is the [`page`](/docs/reference/layout/page/) function, counts through pages, - If it is a [selector](/docs/reference/foundations/selector/), counts through elements that match the selector. For example, - provide an element function: counts elements of that type, - provide a [`where`](/docs/reference/foundations/function/#definitions-where) selector: counts a type of element with specific fields, - provide a [`<label>`](/docs/reference/foundations/label/): counts elements with that label.
- type: str | label | selector | location | function
- default: None
## Methods
## counter.get
Retrieves the value of the counter at the current location. Always returns an array of integers, even if the counter has just one number.
This is equivalent to `counter.at(here())`.
## counter.display
Displays the current value of the counter with a numbering and returns the formatted output.
```typst
#counter.display(
numbering,
both: bool
) -> any
```
### Parameters
- numbering:
- description: A [numbering pattern or a function](/docs/reference/model/numbering/), which specifies how to display the counter. If given a function, that function receives each number of the counter as a separate argument. If the amount of numbers varies, e.g. for the heading argument, you can use an [argument sink](/docs/reference/foundations/arguments/). If this is omitted or set to `auto`, displays the counter with the numbering style for the counted element or with the pattern `"1.1"` if no such style exists.
- type: auto | str | function
- default: auto
- both:
- description: If enabled, displays the current and final top-level count together. Both can be styled through a single numbering pattern. This is used by the page numbering property to display the current and total number of pages when a pattern like `"1 / 1"` is given.
- type: bool
- default: false
## counter.at
Retrieves the value of the counter at the given location. Always returns an array of integers, even if the counter has just one number.
The `selector` must match exactly one element in the document. The most useful kinds of selectors for this are [labels](/docs/reference/foundations/label/) and [locations](/docs/reference/introspection/location/).
```typst
#counter.at(
selector
) -> int array
```
### Parameters
- selector:
- description: The place at which the counter\'s value should be retrieved.
- type: label | selector | location | function
- default: None
## counter.final
Retrieves the value of the counter at the end of the document. Always returns an array of integers, even if the counter has just one number.
## counter.step
Increases the value of the counter by one.
The update will be in effect at the position where the returned content is inserted into the document. If you don't put the output into the document, nothing happens! This would be the case, for example, if you write `let _ = counter(page).step()`. Counter updates are always applied in layout order and in that case, Typst wouldn't know when to step the counter.
```typst
#counter.step(
level: int
) -> content
```
### Parameters
- level:
- description: The depth at which to step the counter. Defaults to `1`.
- type: int
- default: 1
## counter.update
Updates the value of the counter.
Just like with `step`, the update only occurs if you put the resulting content into the document.
```typst
#counter.update(
update
) -> content
```
### Parameters
- update:
- description: If given an integer or array of integers, sets the counter to that value. If given a function, that function receives the previous counter value (with each number as a separate argument) and has to return the new value (integer or array).
- type: int | array | function
- default: None
docs/reference/introspection/here.md
# Here
# here
Provides the current location in the document.
You can think of `here` as a low-level building block that directly extracts the current location from the active [context](/docs/reference/context/). Some other functions use it internally: For instance, `counter.get()` is equivalent to `counter.at(here())`.
Within show rules on [locatable](/docs/reference/introspection/location/#locatable) elements, `here()` will match the location of the shown element.
If you want to display the current page number, refer to the documentation of the [`counter`](/docs/reference/introspection/counter/) type. While `here` can be used to determine the physical page number, typically you want the logical page number that may, for instance, have been reset after a preface.
## Examples
Determining the current position in the document in combination with the [`position`](/docs/reference/introspection/location/#definitions-position) method:
```typst
#context [
I am located at
#here().position()
]
```
Running a [query](/docs/reference/introspection/query/) for elements before the current position:
```typst
= Introduction
= Background
There are
#context query(
selector(heading).before(here())
).len()
headings before me.
= Conclusion
```
Refer to the [`selector`](/docs/reference/foundations/selector/) type for more details on before/after selectors.
docs/reference/introspection/index.md
# Introspection
Interactions between document parts.
This category is home to Typst's introspection capabilities: With the `counter` function, you can access and manipulate page, section, figure, and equation counters or create custom ones. Meanwhile, the `query` function lets you search for elements in the document to construct things like a list of figures or headers which show the current chapter title.
Most of the functions are _contextual._ It is recommended to read the chapter on [context](/docs/reference/context/) before continuing here.
## Definitions
| Name | Description |
| --- | --- |
| [`counter`](/reference/introspection/counter/) | Counts through pages, elements, and more. |
| [`here`](/reference/introspection/here/) | Provides the current location in the document. |
| [`locate`](/reference/introspection/locate/) | Determines the location of an element in the document. |
| [`location`](/reference/introspection/location/) | Identifies an element in the document. |
| [`metadata`](/reference/introspection/metadata/) | Exposes a value to the query system without producing visible content. |
| [`query`](/reference/introspection/query/) | Finds elements in the document. |
| [`state`](/reference/introspection/state/) | Manages stateful parts of your document. |
docs/reference/introspection/locate.md
# Locate
# locate
Determines the location of an element in the document.
Takes a selector that must match exactly one element and returns that element's [`location`](/docs/reference/introspection/location/). This location can, in particular, be used to retrieve the physical [`page`](/docs/reference/introspection/location/#definitions-page) number and [`position`](/docs/reference/introspection/location/#definitions-position) (page, x, y) for that element.
## Examples
Locating a specific element:
```typst
#context [
Introduction is at: \
#locate(<intro>).position()
]
= Introduction <intro>
```
```typst
#locate(
selector
) -> location
```
## Parameters
- selector:
- description: A selector that should match exactly one element. This element will be located. Especially useful in combination with - [`here`](/docs/reference/introspection/here/) to locate the current context, - a [`location`](/docs/reference/introspection/location/) retrieved from some queried element via the [`location()`](/docs/reference/foundations/content/#definitions-location) method on content.
- type: label | selector | location | function
- default: None
docs/reference/introspection/location.md
# Location
Identifies an element in the document.
A location uniquely identifies an element in the document and lets you access its absolute position on the pages. You can retrieve the current location with the [`here`](/docs/reference/introspection/here/) function and the location of a queried or shown element with the [`location()`](/docs/reference/foundations/content/#definitions-location) method on content.
## Locatable elements
Elements that are automatically assigned a location are called _locatable._ For efficiency reasons, not all elements are locatable.
- In the [Model category](/docs/reference/model/), most elements are locatable. This is because semantic elements like [headings](/docs/reference/model/heading/) and [figures](/docs/reference/model/figure/) are often used with introspection.
- In the [Text category](/docs/reference/text/), the [`raw`](/docs/reference/text/raw/) element, and the decoration elements [`underline`](/docs/reference/text/underline/), [`overline`](/docs/reference/text/overline/), [`strike`](/docs/reference/text/strike/), and [`highlight`](/docs/reference/text/highlight/) are locatable as these are also quite semantic in nature.
- In the [Introspection category](/docs/reference/introspection/), the [`metadata`](/docs/reference/introspection/metadata/) element is locatable as being queried for is its primary purpose.
- In the other categories, most elements are not locatable. Exceptions are [`math.equation`](/docs/reference/math/equation/) and [`image`](/docs/reference/visualize/image/).
To find out whether a specific element is locatable, you can try to [`query`](/docs/reference/introspection/query/) for it.
Note that you can still observe elements that are not locatable in queries through other means, for instance, when they have a label attached to them.
## Methods
## location.page
Returns the page number for this location.
Note that this does not return the value of the [page counter](/docs/reference/introspection/counter/) at this location, but the true page number (starting from one).
If you want to know the value of the page counter, use `counter(page).at(loc)` instead.
Can be used with [`here`](/docs/reference/introspection/here/) to retrieve the physical page position of the current context:
```typst
#context [
I am located on
page #here().page()
]
```
## location.position
Returns a dictionary with the page number and the x, y position for this location. The page number starts at one and the coordinates are measured from the top-left of the page.
If you only need the page number, use `page()` instead as it allows Typst to skip unnecessary work.
## location.page-numbering
Returns the page numbering pattern of the page at this location. This can be used when displaying the page counter in order to obtain the local numbering. This is useful if you are building custom indices or outlines.
If the page numbering is set to `none` at that location, this function returns `none`.
docs/reference/introspection/metadata.md
# Metadata
# metadata
Exposes a value to the query system without producing visible content.
This element can be retrieved with the [`query`](/docs/reference/introspection/query/) function and from the command line with [`typst query`](/docs/reference/introspection/query/#command-line-queries). Its purpose is to expose an arbitrary value to the introspection system. To identify a metadata value among others, you can attach a [`label`](/docs/reference/foundations/label/) to it and query for that label.
The `metadata` element is especially useful for command line queries because it allows you to expose arbitrary values to the outside world.
```typst
// Put metadata somewhere.
#metadata("This is a note") <note>
// And find it from anywhere else.
#context {
query(<note>).first().value
}
```
```typst
#metadata(
value
) -> content
```
## Parameters
- value:
- description: The value to embed into the document.
- type: any
- default: None
docs/reference/introspection/query.md
# Query
# query
Finds elements in the document.
The `query` function lets you search your document for elements of a particular type or with a particular label. To use it, you first need to ensure that [context](/docs/reference/context/) is available.
## Finding elements
In the example below, we manually create a table of contents instead of using the [`outline`](/docs/reference/model/outline/) function.
To do this, we first query for all headings in the document at level 1 and where `outlined` is true. Querying only for headings at level 1 ensures that, for the purpose of this example, sub-headings are not included in the table of contents. The `outlined` field is used to exclude the "Table of Contents" heading itself.
Note that we open a `context` to be able to use the `query` function.
```typst
#set page(numbering: "1")
#heading(outlined: false)[
Table of Contents
]
#context {
let chapters = query(
heading.where(
level: 1,
outlined: true,
)
)
for chapter in chapters {
let loc = chapter.location()
let nr = numbering(
loc.page-numbering(),
..counter(page).at(loc),
)
[#chapter.body #h(1fr) #nr \ ]
}
}
= Introduction
#lorem(10)
#pagebreak()
== Sub-Heading
#lorem(8)
= Discussion
#lorem(18)
```
To get the page numbers, we first get the location of the elements returned by `query` with [`location`](/docs/reference/foundations/content/#definitions-location). We then also retrieve the [page numbering](/docs/reference/introspection/location/#definitions-page-numbering) and [page counter](/docs/reference/introspection/counter/#page-counter) at that location and apply the numbering to the counter.
## A word of caution
To resolve all your queries, Typst evaluates and layouts parts of the document multiple times. However, there is no guarantee that your queries can actually be completely resolved. If you aren't careful a query can affect itself—leading to a result that never stabilizes.
In the example below, we query for all headings in the document. We then generate as many headings. In the beginning, there's just one heading, titled `Real`. Thus, `count` is `1` and one `Fake` heading is generated. Typst sees that the query's result has changed and processes it again. This time, `count` is `2` and two `Fake` headings are generated. This goes on and on. As we can see, the output has a finite amount of headings. This is because Typst simply gives up after a few attempts.
In general, you should try not to write queries that affect themselves. The same words of caution also apply to other introspection features like [counters](/docs/reference/introspection/counter/) and [state](/docs/reference/introspection/state/).
```typst
= Real
#context {
let elems = query(heading)
let count = elems.len()
count * [= Fake]
}
```
## Command line queries
You can also perform queries from the command line with the `typst query` command. This command executes an arbitrary query on the document and returns the resulting elements in serialized form. Consider the following `example.typ` file which contains some invisible [metadata](/docs/reference/introspection/metadata/):
```typst
#metadata("This is a note") <note>
```
You can execute a query on it as follows using Typst's CLI:
```typst
$ typst query example.typ "<note>"
[
{
"func": "metadata",
"value": "This is a note",
"label": "<note>"
}
]
```
### Retrieving a specific field
Frequently, you're interested in only one specific field of the resulting elements. In the case of the `metadata` element, the `value` field is the interesting one. You can extract just this field with the `--field` argument.
```typst
$ typst query example.typ "<note>" --field value
["This is a note"]
```
If you are interested in just a single element, you can use the `--one` flag to extract just it.
```typst
$ typst query example.typ "<note>" --field value --one
"This is a note"
```
### Querying for a specific export target
In case you need to query a document when exporting for a specific target, you can use the `--target` argument. Valid values are `paged`, and `html` (if the [`html`](/docs/reference/html/) feature is enabled).
```typst
#query(
target
) -> array
```
## Parameters
- target:
- description: Can be - an element function like a `heading` or `figure`, - a `<label>`, - a more complex selector like `heading.where(level: 1)`, - or `selector(heading).before(here())`. Only [locatable](/docs/reference/introspection/location/#locatable) element functions are supported.
- type: label | selector | location | function
- default: None
docs/reference/introspection/state.md
# State
Manages stateful parts of your document.
Let's say you have some computations in your document and want to remember the result of your last computation to use it in the next one. You might try something similar to the code below and expect it to output 10, 13, 26, and 21. However this **does not work** in Typst. If you test this code, you will see that Typst complains with the following error message: _Variables from
outside the function are read-only and cannot be modified._
```typst
// This doesn't work!
#let star = 0
#let compute(expr) = {
star = eval(
expr.replace("⭐", str(star))
)
[New value is #star.]
}
#compute("10") \
#compute("⭐ + 3") \
#compute("⭐ * 2") \
#compute("⭐ - 5")
```
## State and document markup
Why does it do that? Because, in general, this kind of computation with side effects is problematic in document markup and Typst is upfront about that. For the results to make sense, the computation must proceed in the same order in which the results will be laid out in the document. In our simple example, that's the case, but in general it might not be.
Let's look at a slightly different, but similar kind of state: The heading numbering. We want to increase the heading counter at each heading. Easy enough, right? Just add one. Well, it's not that simple. Consider the following example:
```typst
#set heading(numbering: "1.")
#let template(body) = [
= Outline
...
#body
]
#show: template
= Introduction
...
```
Here, Typst first processes the body of the document after the show rule, sees the `Introduction` heading, then passes the resulting content to the `template` function and only then sees the `Outline`. Just counting up would number the `Introduction` with `1` and the `Outline` with `2`.
## Managing state in Typst
So what do we do instead? We use Typst's state management system. Calling the `state` function with an identifying string key and an optional initial value gives you a state value which exposes a few functions. The two most important ones are `get` and `update`:
- The [`get`](/docs/reference/introspection/state/#definitions-get) function retrieves the current value of the state. Because the value can vary over the course of the document, it is a _contextual_ function that can only be used when [context](/docs/reference/context/) is available.
- The [`update`](/docs/reference/introspection/state/#definitions-update) function modifies the state. You can give it any value. If given a non-function value, it sets the state to that value. If given a function, that function receives the previous state and has to return the new state.
Our initial example would now look like this:
```typst
#let star = state("star", 0)
#let compute(expr) = {
star.update(old =>
eval(expr.replace("⭐", str(old)))
)
[New value is #context star.get().]
}
#compute("10") \
#compute("⭐ + 3") \
#compute("⭐ * 2") \
#compute("⭐ - 5")
```
State managed by Typst is always updated in layout order, not in evaluation order. The `update` method returns content and its effect occurs at the position where the returned content is inserted into the document.
As a result, we can now also store some of the computations in variables, but they still show the correct results:
```typst
...
#let more = [
#compute("⭐ * 2") \
#compute("⭐ - 5")
]
#compute("10") \
#compute("⭐ + 3") \
#more
```
This example is of course a bit silly, but in practice this is often exactly what you want! A good example are heading counters, which is why Typst's [counting system](/docs/reference/introspection/counter/) is very similar to its state system.
## Time Travel
By using Typst's state management system you also get time travel capabilities! We can find out what the value of the state will be at any position in the document from anywhere else. In particular, the `at` method gives us the value of the state at any particular location and the `final` methods gives us the value of the state at the end of the document.
```typst
...
Value at `<here>` is
#context star.at(<here>)
#compute("10") \
#compute("⭐ + 3") \
*Here.* <here> \
#compute("⭐ * 2") \
#compute("⭐ - 5")
```
## A word of caution
To resolve the values of all states, Typst evaluates parts of your code multiple times. However, there is no guarantee that your state manipulation can actually be completely resolved.
For instance, if you generate state updates depending on the final value of a state, the results might never converge. The example below illustrates this. We initialize our state with `1` and then update it to its own final value plus 1. So it should be `2`, but then its final value is `2`, so it should be `3`, and so on. This example displays a finite value because Typst simply gives up after a few attempts.
```typst
// This is bad!
#let x = state("key", 1)
#context x.update(x.final() + 1)
#context x.get()
```
In general, you should try not to generate state updates from within context expressions. If possible, try to express your updates as non-contextual values or functions that compute the new value from the previous value. Sometimes, it cannot be helped, but in those cases it is up to you to ensure that the result converges.
## Constructor
## state
Create a new state identified by a key.
```typst
#state(
key,
init
) -> state
```
### Parameters
- key:
- description: The key that identifies this state. Any [updates](/docs/reference/introspection/state/#definitions-update) to the state will be identified with the string key. If you construct multiple states with the same `key`, then updating any one will affect all of them.
- type: str
- default: None
- init:
- description: The initial value of the state. If you construct multiple states with the same `key` but different `init` values, they will each use their own initial value but share updates. Specifically, the value of a state at some location in the document will be computed from that state\'s initial value and all preceding updates for the state\'s key. ```typst #let banana = state("key", "🍌") #let broccoli = state("key", "🥦") #banana.update(it => it + "😋") #context [ - #state("key", "🍎").get() - #banana.get() - #broccoli.get() ] ```
- type: any
- default: none
## Methods
## state.get
Retrieves the value of the state at the current location.
This is equivalent to `state.at(here())`.
## state.at
Retrieves the value of the state at the given selector's unique match.
The `selector` must match exactly one element in the document. The most useful kinds of selectors for this are [labels](/docs/reference/foundations/label/) and [locations](/docs/reference/introspection/location/).
```typst
#state.at(
selector
) -> any
```
### Parameters
- selector:
- description: The place at which the state\'s value should be retrieved.
- type: label | selector | location | function
- default: None
## state.final
Retrieves the value of the state at the end of the document.
## state.update
Updates the value of the state.
Returns an invisible piece of [content](/docs/reference/foundations/content/) that must be inserted into the document to take effect. This invisible content tells Typst that the specified update should take place wherever the content is inserted into the document.
State is a part of your document and runs like a thread embedded in the document content. The value of a state is the result of all state updates that happened in the document up until that point.
That's why `state.update` returns an invisible sliver of content that you need to return and include in the document — a state update that is not "placed" in the document does not happen, and "when" it happens is determined by where you place it. That's also why you need [context](/docs/reference/context/) to read state: You need to use the current document position to know where on the state's "thread" you are.
Storing a state update in a variable (e.g. `let my-update = state("key").update(c => c * 2)`) will have no effect by itself. Only once you insert the variable `#my-update` somewhere into the document content, the update will take effect — at the position where it was inserted. You can also use `#my-update` multiple times at different positions. Then, the update will take effect multiple times as well.
In contrast to [`get`](/docs/reference/introspection/state/#definitions-get), [`at`](/docs/reference/introspection/state/#definitions-at), and [`final`](/docs/reference/introspection/state/#definitions-final), this function does not require [context](/docs/reference/context/). This is because, to create the state update, we do not need to know where in the document we are. We only need this information to resolve the state's value.
```typst
#state.update(
update
) -> content
```
### Parameters
- update:
- description: A value to update to or a function to update with. - If given a non-function value, sets the state to that value. - If given a function, that function receives the state\'s previous value and has to return the state\'s new value. When updating the state based on its previous value, you should prefer the function form instead of retrieving the previous value from the [context](/docs/reference/context/). This allows the compiler to resolve the final state efficiently, minimizing the number of [layout iterations](/docs/reference/context/#compiler-iterations) required. In the following example, `fill.update(f => not f)` will paint odd [items in the bullet list](/docs/reference/model/list/#definitions-item) as expected. However, if it\'s replaced with `context fill.update(not fill.get())`, then layout will not converge within 5 attempts, as each update will take one additional iteration to propagate. ```typst #let fill = state("fill", false) #show list.item: it => { fill.update(f => not f) context { set text(fill: fuchsia) if fill.get() it } } #lorem(5).split().map(list.item).join() ```
- type: any | function
- default: None
docs/reference/layout/align.md
# Align
# align
Aligns content horizontally and vertically.
## Example
Let's start with centering our content horizontally:
```typst
#set page(height: 120pt)
#set align(center)
Centered text, a sight to see \
In perfect balance, visually \
Not left nor right, it stands alone \
A work of art, a visual throne
```
To center something vertically, use _horizon_ alignment:
```typst
#set page(height: 120pt)
#set align(horizon)
Vertically centered, \
the stage had entered, \
a new paragraph.
```
## Combining alignments
You can combine two alignments with the `+` operator. Let's also only apply this to one piece of content by using the function form instead of a set rule:
```typst
#set page(height: 120pt)
Though left in the beginning ...
#align(right + bottom)[
... they were right in the end, \
and with addition had gotten, \
the paragraph to the bottom!
]
```
## Nested alignment
You can use varying alignments for layout containers and the elements within them. This way, you can create intricate layouts:
```typst
#align(center, block[
#set align(left)
Though centered together \
alone \
we \
are \
left.
])
```
## Alignment within the same line
The `align` function performs block-level alignment and thus always interrupts the current paragraph. To have different alignment for parts of the same line, you should use [fractional spacing](/docs/reference/layout/h/) instead:
```typst
Start #h(1fr) End
```
```typst
#align(
alignment,
body
) -> content
```
## Parameters
- alignment:
- description: The [alignment](/docs/reference/layout/alignment/) along both axes. ```typst #set page(height: 6cm) #set text(lang: "ar") مثال #align( end + horizon, rect(inset: 12pt)[ركن] ) ```
- type: alignment
- default: start + top
- body:
- description: The content to align.
- type: content
- default: None
docs/reference/layout/alignment.md
# Alignment
Where to align something along an axis.
Possible values are:
- `start`: Aligns at the [start](/docs/reference/layout/direction/#definitions-start) of the [text direction](/docs/reference/text/text/#parameters-dir).
- `end`: Aligns at the [end](/docs/reference/layout/direction/#definitions-end) of the [text direction](/docs/reference/text/text/#parameters-dir).
- `left`: Align at the left.
- `center`: Aligns in the middle, horizontally.
- `right`: Aligns at the right.
- `top`: Aligns at the top.
- `horizon`: Aligns in the middle, vertically.
- `bottom`: Align at the bottom.
These values are available globally and also in the alignment type's scope, so you can write either of the following two:
```typst
#align(center)[Hi]
#align(alignment.center)[Hi]
```
## 2D alignments
To align along both axes at the same time, add the two alignments using the `+` operator. For example, `top + right` aligns the content to the top right corner.
```typst
#set page(height: 3cm)
#align(center + bottom)[Hi]
```
## Fields
The `x` and `y` fields hold the alignment's horizontal and vertical components, respectively (as yet another `alignment`). They may be `none`.
```typst
#(top + right).x \
#left.x \
#left.y (none)
```
## Methods
## alignment.axis
The axis this alignment belongs to.
- `"horizontal"` for `start`, `left`, `center`, `right`, and `end`
- `"vertical"` for `top`, `horizon`, and `bottom`
- `none` for 2-dimensional alignments
```typst
#left.axis() \
#bottom.axis()
```
## alignment.inv
The inverse alignment.
```typst
#top.inv() \
#left.inv() \
#center.inv() \
#(left + bottom).inv()
```
docs/reference/layout/angle.md
# Angle
An angle describing a rotation.
Typst supports the following angular units:
- Degrees: `180deg`
- Radians: `3.14rad`
## Example
```typst
#rotate(10deg)[Hello there!]
```
## Methods
## angle.rad
Converts this angle to radians.
## angle.deg
Converts this angle to degrees.
docs/reference/layout/block.md
# Block
# block
A block-level container.
Such a container can be used to separate content, size it, and give it a background or border.
Blocks are also the primary way to control whether text becomes part of a paragraph or not. See [the paragraph documentation](/docs/reference/model/par/#what-becomes-a-paragraph) for more details.
## Examples
With a block, you can give a background to content while still allowing it to break across multiple pages.
```typst
#set page(height: 100pt)
#block(
fill: luma(230),
inset: 8pt,
radius: 4pt,
lorem(30),
)
```
Blocks are also useful to force elements that would otherwise be inline to become block-level, especially when writing show rules.
```typst
#show heading: it => it.body
= Blockless
More text.
#show heading: it => block(it.body)
= Blocky
More text.
```
```typst
#block(
width: auto | relative,
height: auto | relative | fraction,
breakable: bool,
fill: none | color | gradient | tiling,
stroke: none | length | color | gradient | stroke | tiling | dictionary,
radius: relative | dictionary,
inset: relative | dictionary,
outset: relative | dictionary,
spacing: relative | fraction,
above: auto | relative | fraction,
below: auto | relative | fraction,
clip: bool,
sticky: bool,
body
) -> content
```
## Parameters
- width:
- description: The block\'s width. ```typst #set align(center) #block( width: 60%, inset: 8pt, fill: silver, lorem(10), ) ```
- type: auto | relative
- default: auto
- height:
- description: The block\'s height. When the height is larger than the remaining space on a page and [`breakable`](/docs/reference/layout/block/#parameters-breakable) is `true`, the block will continue on the next page with the remaining height. ```typst #set page(height: 80pt) #set align(center) #block( width: 80%, height: 150%, fill: aqua, ) ```
- type: auto | relative | fraction
- default: auto
- breakable:
- description: Whether the block can be broken and continue on the next page. ```typst #set page(height: 80pt) The following block will jump to its own page. #block( breakable: false, lorem(15), ) ```
- type: bool
- default: true
- fill:
- description: The block\'s background color. See the [rectangle\'s documentation](/docs/reference/visualize/rect/#parameters-fill) for more details.
- type: none | color | gradient | tiling
- default: none
- stroke:
- description: The block\'s border color. See the [rectangle\'s documentation](/docs/reference/visualize/rect/#parameters-stroke) for more details.
- type: none | length | color | gradient | stroke | tiling | dictionary
- default: (:)
- radius:
- description: How much to round the block\'s corners. See the [rectangle\'s documentation](/docs/reference/visualize/rect/#parameters-radius) for more details.
- type: relative | dictionary
- default: (:)
- inset:
- description: How much to pad the block\'s content. See the [box\'s documentation](/docs/reference/layout/box/#parameters-inset) for more details.
- type: relative | dictionary
- default: (:)
- outset:
- description: How much to expand the block\'s size without affecting the layout. See the [box\'s documentation](/docs/reference/layout/box/#parameters-outset) for more details.
- type: relative | dictionary
- default: (:)
- spacing:
- description: The spacing around the block. When `auto`, inherits the paragraph [`spacing`](/docs/reference/model/par/#parameters-spacing). For two adjacent blocks, the larger of the first block\'s `above` and the second block\'s `below` spacing wins. Moreover, block spacing takes precedence over paragraph [`spacing`](/docs/reference/model/par/#parameters-spacing). Note that this is only a shorthand to set `above` and `below` to the same value. Since the values for `above` and `below` might differ, a [context](/docs/reference/context/) block only provides access to `block.above` and `block.below`, not to `block.spacing` directly. This property can be used in combination with a show rule to adjust the spacing around arbitrary block-level elements. ```typst #set align(center) #show math.equation: set block(above: 8pt, below: 16pt) This sum of $x$ and $y$: $ x + y = z $ A second paragraph. ```
- type: relative | fraction
- default: 1.2em
- above:
- description: The spacing between this block and its predecessor.
- type: auto | relative | fraction
- default: auto
- below:
- description: The spacing between this block and its successor.
- type: auto | relative | fraction
- default: auto
- clip:
- description: Whether to clip the content inside the block. Clipping is useful when the block\'s content is larger than the block itself, as any content that exceeds the block\'s bounds will be hidden. ```typst #block( width: 50pt, height: 50pt, clip: true, image("tiger.jpg", width: 100pt, height: 100pt) ) ```
- type: bool
- default: false
- sticky:
- description: Whether this block must stick to the following one, with no break in between. This is, by default, set on heading blocks to prevent orphaned headings at the bottom of the page. ```typst // Disable stickiness of headings. #show heading: set block(sticky: false) #lorem(20) = Chapter #lorem(10) ```
- type: bool
- default: false
- body:
- description: The contents of the block.
- type: none | content
- default: none
docs/reference/layout/box.md
# Box
# box
An inline-level container that sizes content.
All elements except inline math, text, and boxes are block-level and cannot occur inside of a [paragraph](/docs/reference/model/par/). The box function can be used to integrate such elements into a paragraph. Boxes take the size of their contents by default but can also be sized explicitly.
## Example
```typst
Refer to the docs
#box(
height: 9pt,
image("docs.svg")
)
for more information.
```
```typst
#box(
width: auto | relative | fraction,
height: auto | relative,
baseline: relative,
fill: none | color | gradient | tiling,
stroke: none | length | color | gradient | stroke | tiling | dictionary,
radius: relative | dictionary,
inset: relative | dictionary,
outset: relative | dictionary,
clip: bool,
body
) -> content
```
## Parameters
- width:
- description: The width of the box. Boxes can have [fractional](/docs/reference/layout/fraction/) widths, as the example below demonstrates. _Note:_ Currently, only boxes and only their widths might be fractionally sized within paragraphs. Support for fractionally sized images, shapes, and more might be added in the future. ```typst Line in #box(width: 1fr, line(length: 100%)) between. ```
- type: auto | relative | fraction
- default: auto
- height:
- description: The height of the box.
- type: auto | relative
- default: auto
- baseline:
- description: An amount to shift the box\'s baseline by. ```typst Image: #box(baseline: 40%, image("tiger.jpg", width: 2cm)). ```
- type: relative
- default: 0 % + 0pt
- fill:
- description: The box\'s background color. See the [rectangle\'s documentation](/docs/reference/visualize/rect/#parameters-fill) for more details.
- type: none | color | gradient | tiling
- default: none
- stroke:
- description: The box\'s border color. See the [rectangle\'s documentation](/docs/reference/visualize/rect/#parameters-stroke) for more details.
- type: none | length | color | gradient | stroke | tiling | dictionary
- default: (:)
- radius:
- description: How much to round the box\'s corners. See the [rectangle\'s documentation](/docs/reference/visualize/rect/#parameters-radius) for more details.
- type: relative | dictionary
- default: (:)
- inset:
- description: How much to pad the box\'s content. This can be a single length for all sides or a dictionary of lengths for individual sides. When passing a dictionary, it can contain the following keys in order of precedence: `top`, `right`, `bottom`, `left` (controlling the respective cell sides), `x`, `y` (controlling vertical and horizontal insets), and `rest` (covers all insets not styled by other dictionary entries). All keys are optional; omitted keys will use their previously set value, or the default value if never set. [Relative lengths](/docs/reference/layout/relative/) for this parameter are relative to the box size excluding [outset](/docs/reference/layout/box/#parameters-outset). Note that relative insets and outsets are different from relative [widths](/docs/reference/layout/box/#parameters-width) and [heights](/docs/reference/layout/box/#parameters-height), which are relative to the container. _Note:_ When the box contains text, its exact size depends on the current [text edges](/docs/reference/text/text/#parameters-top-edge). ```typst #rect(inset: 0pt)[Tight] ```
- type: relative | dictionary
- default: (:)
- outset:
- description: How much to expand the box\'s size without affecting the layout. This can be a single length for all sides or a dictionary of lengths for individual sides. [Relative lengths](/docs/reference/layout/relative/) for this parameter are relative to the box size excluding outset. See the documentation for [inset](/docs/reference/layout/box/#parameters-inset) above for further details. This is useful to prevent padding from affecting line layout. For a generalized version of the example below, see the documentation for the [raw text\'s block parameter](/docs/reference/text/raw/#parameters-block). ```typst An inline #box( fill: luma(235), inset: (x: 3pt, y: 0pt), outset: (y: 3pt), radius: 2pt, )[rectangle]. ```
- type: relative | dictionary
- default: (:)
- clip:
- description: Whether to clip the content inside the box. Clipping is useful when the box\'s content is larger than the box itself, as any content that exceeds the box\'s bounds will be hidden. ```typst #box( width: 50pt, height: 50pt, clip: true, image("tiger.jpg", width: 100pt, height: 100pt) ) ```
- type: bool
- default: false
- body:
- description: The contents of the box.
- type: none | content
- default: none
docs/reference/layout/colbreak.md
# Column Break
# colbreak
Forces a column break.
The function will behave like a [page break](/docs/reference/layout/pagebreak/) when used in a single column layout or the last column on a page. Otherwise, content after the column break will be placed in the next column.
## Example
```typst
#set page(columns: 2)
Preliminary findings from our
ongoing research project have
revealed a hitherto unknown
phenomenon of extraordinary
significance.
#colbreak()
Through rigorous experimentation
and analysis, we have discovered
a hitherto uncharacterized process
that defies our current
understanding of the fundamental
laws of nature.
```
```typst
#colbreak(
weak: bool
) -> content
```
## Parameters
- weak:
- description: If `true`, the column break is skipped if the current column is already empty.
- type: bool
- default: false
docs/reference/layout/columns.md
# Columns
# columns
Separates a region into multiple equally sized columns.
The `column` function lets you separate the interior of any container into multiple columns. It will currently not balance the height of the columns. Instead, the columns will take up the height of their container or the remaining height on the page. Support for balanced columns is planned for the future.
When arranging content across multiple columns, use [`colbreak`](/docs/reference/layout/colbreak/) to explicitly continue in the next column.
## Example
```typst
#columns(2, gutter: 8pt)[
This text is in the
first column.
#colbreak()
This text is in the
second column.
]
```
## Page-level columns
If you need to insert columns across your whole document, use the `page` function's [`columns` parameter](/docs/reference/layout/page/#parameters-columns) instead. This will create the columns directly at the page-level rather than wrapping all of your content in a layout container. As a result, things like [pagebreaks](/docs/reference/layout/pagebreak/), [footnotes](/docs/reference/model/footnote/), and [line numbers](/docs/reference/model/par/#definitions-line) will continue to work as expected. For more information, also read the [relevant part of the page setup guide](/docs/guides/page-setup/#columns).
## Breaking out of columns
To temporarily break out of columns (e.g. for a paper's title), use parent-scoped floating placement:
```typst
#set page(columns: 2, height: 150pt)
#place(
top + center,
scope: "parent",
float: true,
text(1.4em, weight: "bold")[
My document
],
)
#lorem(40)
```
```typst
#columns(
count,
gutter: relative,
body
) -> content
```
## Parameters
- count:
- description: The number of columns.
- type: int
- default: 2
- gutter:
- description: The size of the gutter space between each column.
- type: relative
- default: 4 % + 0pt
- body:
- description: The content that should be layouted into the columns.
- type: content
- default: None
docs/reference/layout/direction.md
# Direction
The four directions into which content can be laid out.
Possible values are:
- `ltr`: Left to right.
- `rtl`: Right to left.
- `ttb`: Top to bottom.
- `btt`: Bottom to top.
These values are available globally and also in the direction type's scope, so you can write either of the following two:
```typst
#stack(dir: rtl)[A][B][C]
#stack(dir: direction.rtl)[A][B][C]
```
## Methods
## direction.from
Returns a direction from a starting point.
```typst
#direction.from(left) \
#direction.from(right) \
#direction.from(top) \
#direction.from(bottom)
```
```typst
#direction.from(
side
) -> direction
```
### Parameters
- side:
- description:
- type: alignment
- default: None
## direction.to
Returns a direction from an end point.
```typst
#direction.to(left) \
#direction.to(right) \
#direction.to(top) \
#direction.to(bottom)
```
```typst
#direction.to(
side
) -> direction
```
### Parameters
- side:
- description:
- type: alignment
- default: None
## direction.axis
The axis this direction belongs to, either `"horizontal"` or `"vertical"`.
```typst
#ltr.axis() \
#ttb.axis()
```
## direction.sign
The corresponding sign, for use in calculations.
```typst
#ltr.sign() \
#rtl.sign() \
#ttb.sign() \
#btt.sign()
```
## direction.start
The start point of this direction, as an alignment.
```typst
#ltr.start() \
#rtl.start() \
#ttb.start() \
#btt.start()
```
## direction.end
The end point of this direction, as an alignment.
```typst
#ltr.end() \
#rtl.end() \
#ttb.end() \
#btt.end()
```
## direction.inv
The inverse direction.
```typst
#ltr.inv() \
#rtl.inv() \
#ttb.inv() \
#btt.inv()
```
docs/reference/layout/fraction.md
# Fraction
Defines how the remaining space in a layout is distributed.
Each fractionally sized element gets space based on the ratio of its fraction to the sum of all fractions.
For more details, also see the [h](/docs/reference/layout/h/) and [v](/docs/reference/layout/v/) functions and the [grid function](/docs/reference/layout/grid/).
## Example
```typst
Left #h(1fr) Left-ish #h(2fr) Right
```
docs/reference/layout/grid.md
# Grid
# grid
Arranges content in a grid.
The grid element allows you to arrange content in a grid. You can define the number of rows and columns, as well as the size of the gutters between them. There are multiple sizing modes for columns and rows that can be used to create complex layouts.
While the grid and table elements work very similarly, they are intended for different use cases and carry different semantics. The grid element is intended for presentational and layout purposes, while the [`table`](/docs/reference/model/table/) element is intended for, in broad terms, presenting multiple related data points. Set and show rules on one of these elements do not affect the other. Refer to the [Accessibility Section](/docs/reference/layout/grid/#accessibility) to learn how grids and tables are presented to users of Assistive Technology (AT) like screen readers.
## Sizing the tracks
A grid's sizing is determined by the track sizes specified in the arguments. There are multiple sizing parameters: [`columns`](/docs/reference/layout/grid/#parameters-columns), [`rows`](/docs/reference/layout/grid/#parameters-rows) and [`gutter`](/docs/reference/layout/grid/#parameters-gutter). Because each of the sizing parameters accepts the same values, we will explain them just once, here. Each sizing argument accepts an array of individual track sizes. A track size is either:
- `auto`: The track will be sized to fit its contents. It will be at most as large as the remaining space. If there is more than one `auto` track width, and together they claim more than the available space, the `auto` tracks will fairly distribute the available space among themselves.
- A fixed or relative length (e.g. `10pt` or `20% - 1cm`): The track will be exactly of this size.
- A fractional length (e.g. `1fr`): Once all other tracks have been sized, the remaining space will be divided among the fractional tracks according to their fractions. For example, if there are two fractional tracks, each with a fraction of `1fr`, they will each take up half of the remaining space.
To specify a single track, the array can be omitted in favor of a single value. To specify multiple `auto` tracks, enter the number of tracks instead of an array. For example, `columns:` `3` is equivalent to `columns:` `(auto, auto, auto)`.
## Examples
The example below demonstrates the different track sizing options. It also shows how you can use [`grid.cell`](/docs/reference/layout/grid/#definitions-cell) to make an individual cell span two grid tracks.
```typst
// We use `rect` to emphasize the
// area of cells.
#set rect(
inset: 8pt,
fill: rgb("e4e5ea"),
width: 100%,
)
#grid(
columns: (60pt, 1fr, 2fr),
rows: (auto, 60pt),
gutter: 3pt,
rect[Fixed width, auto height],
rect[1/3 of the remains],
rect[2/3 of the remains],
rect(height: 100%)[Fixed height],
grid.cell(
colspan: 2,
image("tiger.jpg", width: 100%),
),
)
```
You can also [spread](/docs/reference/foundations/arguments/#spreading) an array of strings or content into a grid to populate its cells.
```typst
#grid(
columns: 5,
gutter: 5pt,
..range(25).map(str)
)
```
## Styling the grid
The grid and table elements work similarly. For a hands-on explanation, refer to the [Table Guide](/docs/guides/tables/#fills); for a quick overview, continue reading.
The grid's appearance can be customized through different parameters. These are the most important ones:
- [`align`](/docs/reference/layout/grid/#parameters-align) to change how cells are aligned
- [`inset`](/docs/reference/layout/grid/#parameters-inset) to optionally add internal padding to cells
- [`fill`](/docs/reference/layout/grid/#parameters-fill) to give cells a background
- [`stroke`](/docs/reference/layout/grid/#parameters-stroke) to optionally enable grid lines with a certain stroke
To meet different needs, there are various ways to set them.
If you need to override the above options for individual cells, you can use the [`grid.cell`](/docs/reference/layout/grid/#definitions-cell) element. Likewise, you can override individual grid lines with the [`grid.hline`](/docs/reference/layout/grid/#definitions-hline) and [`grid.vline`](/docs/reference/layout/grid/#definitions-vline) elements.
To configure an overall style for a grid, you may instead specify the option in any of the following fashions:
- As a single value that applies to all cells.
- As an array of values corresponding to each column. The array will be cycled if there are more columns than the array has items.
- As a function in the form of `(x, y) => value`. It receives the cell's column and row indices (both starting from zero) and should return the value to apply to that cell.
```typst
#grid(
columns: 5,
// By a single value
align: center,
// By a single but more complicated value
inset: (x: 2pt, y: 3pt),
// By an array of values (cycling)
fill: (rgb("#239dad50"), none),
// By a function that returns a value
stroke: (x, y) => if calc.rem(x + y, 3) == 0 { 0.5pt },
..range(5 * 3).map(n => numbering("A", n + 1))
)
```
On top of that, you may [apply styling rules](/docs/reference/styling/) to [`grid`](/docs/reference/layout/grid/) and [`grid.cell`](/docs/reference/layout/grid/#definitions-cell). Especially, the [`x`](/docs/reference/layout/grid/#definitions-cell-x) and [`y`](/docs/reference/layout/grid/#definitions-cell-y) fields of `grid.cell` can be used in a [`where`](/docs/reference/foundations/function/#definitions-where) selector, making it possible to style cells at specific columns or rows, or individual positions.
### Stroke styling precedence
As explained above, there are three ways to set the stroke of a grid cell: through [`grid.cell`'s `stroke` field](/docs/reference/layout/grid/#definitions-cell-stroke), by using [`grid.hline`](/docs/reference/layout/grid/#definitions-hline) and [`grid.vline`](/docs/reference/layout/grid/#definitions-vline), or by setting the [`grid`'s `stroke` field](/docs/reference/layout/grid/#parameters-stroke). When multiple of these settings are present and conflict, the `hline` and `vline` settings take the highest precedence, followed by the `cell` settings, and finally the `grid` settings.
Furthermore, strokes of a repeated grid header or footer will take precedence over regular cell strokes.
## Accessibility
Grids do not carry any special semantics. Assistive Technology (AT) does not offer the ability to navigate two-dimensionally by cell in grids. If you want to present tabular data, use the [`table`](/docs/reference/model/table/) element instead.
AT will read the grid cells in their semantic order. Usually, this is the order in which you passed them to the grid. However, if you manually positioned them using [`grid.cell`'s `x` and `y` arguments](/docs/reference/layout/grid/#definitions-cell-x), cells will be read row by row, from left to right (in left-to-right documents). A cell will be read when its position is first reached.
```typst
#grid(
columns: auto | int | relative | fraction | array,
rows: auto | int | relative | fraction | array,
gutter: auto | int | relative | fraction | array,
column-gutter: auto | int | relative | fraction | array,
row-gutter: auto | int | relative | fraction | array,
inset: relative | array | dictionary | function,
align: auto | array | alignment | function,
fill: none | color | gradient | array | tiling | function,
stroke: none | length | color | gradient | array | stroke | tiling | dictionary | function,
children
) -> content
```
## Parameters
- columns:
- description: The column sizes. Either specify a track size array or provide an integer to create a grid with that many `auto`-sized columns. Note that opposed to rows and gutters, providing a single track size will only ever create a single column. See the [track size section](#track-size) above for more details.
- type: auto | int | relative | fraction | array
- default: ()
- rows:
- description: The row sizes. If there are more cells than fit the defined rows, the last row is repeated until there are no more cells. See the [track size section](#track-size) above for more details.
- type: auto | int | relative | fraction | array
- default: ()
- gutter:
- description: The gaps between rows and columns. This is a shorthand to set [`column-gutter`](/docs/reference/layout/grid/#parameters-column-gutter) and [`row-gutter`](/docs/reference/layout/grid/#parameters-row-gutter) to the same value. If there are more gutters than defined sizes, the last gutter is repeated. See the [track size section](#track-size) above for more details.
- type: auto | int | relative | fraction | array
- default: ()
- column-gutter:
- description: The gaps between columns.
- type: auto | int | relative | fraction | array
- default: ()
- row-gutter:
- description: The gaps between rows.
- type: auto | int | relative | fraction | array
- default: ()
- inset:
- description: How much to pad the cells\' content. To specify a uniform inset for all cells, you can use a single length for all sides, or a dictionary of lengths for individual sides. See the [box\'s documentation](/docs/reference/layout/box/#parameters-inset) for more details. To specify varying inset for different cells, you can: - use a single inset for all cells - use an array of insets corresponding to each column - use a function that maps a cell\'s position to its inset See the [styling section](#styling) above for more details. In addition, you can find an example at the [`table.inset`](/docs/reference/model/table/#parameters-inset) parameter.
- type: relative | array | dictionary | function
- default: (:)
- align:
- description: How to align the cells\' content. If set to `auto`, the outer alignment is used. You can specify the alignment in any of the following fashions: - use a single alignment for all cells - use an array of alignments corresponding to each column - use a function that maps a cell\'s position to its alignment See the [styling section](#styling) above for details. In addition, you can find an example at the [`table.align`](/docs/reference/model/table/#parameters-align) parameter.
- type: auto | array | alignment | function
- default: auto
- fill:
- description: How to fill the cells. This can be: - a single color for all cells - an array of colors corresponding to each column - a function that maps a cell\'s position to its color Most notably, arrays and functions are useful for creating striped grids. See the [styling section](#styling) above for more details. ```typst #grid( fill: (x, y) => if calc.even(x + y) { luma(230) } else { white }, align: center + horizon, columns: 4, inset: 2pt, [X], [O], [X], [O], [O], [X], [O], [X], [X], [O], [X], [O], [O], [X], [O], [X], ) ```
- type: none | color | gradient | array | tiling | function
- default: none
- stroke:
- description: How to [stroke](/docs/reference/visualize/stroke/) the cells. Grids have no strokes by default, which can be changed by setting this option to the desired stroke. If it is necessary to place lines which can cross spacing between cells produced by the [`gutter`](/docs/reference/layout/grid/#parameters-gutter) option, or to override the stroke between multiple specific cells, consider specifying one or more of [`grid.hline`](/docs/reference/layout/grid/#definitions-hline) and [`grid.vline`](/docs/reference/layout/grid/#definitions-vline) alongside your grid cells. To specify the same stroke for all cells, you can use a single [stroke](/docs/reference/visualize/stroke/) for all sides, or a dictionary of [strokes](/docs/reference/visualize/stroke/) for individual sides. See the [rectangle\'s documentation](/docs/reference/visualize/rect/#parameters-stroke) for more details. To specify varying strokes for different cells, you can: - use a single stroke for all cells - use an array of strokes corresponding to each column - use a function that maps a cell\'s position to its stroke See the [styling section](#styling) above for more details. ```typst #set page(width: 420pt) #set text(number-type: "old-style") #show grid.cell.where(y: 0): set text(size: 1.3em) #grid( columns: (1fr, 2fr, 2fr), row-gutter: 1.5em, inset: (left: 0.5em), stroke: (x, y) => if x > 0 { (left: 0.5pt + gray) }, align: horizon, [Winter \\ 2007 \\ Season], [Aaron Copland \\ *The Tender Land* \\ January 2007], [Eric Satie \\ *Gymnopedie 1, 2* \\ February 2007], [], [Jan 12 \\ *Middlebury College \\ Center for the Arts* \\ 20:00], [Feb 2 \\ *Johnson State College Dibden Center for the Arts* \\ 19:30], [], [Skip a week \\ #text(0.8em)[_Prepare your exams!_]], [Feb 9 \\ *Castleton State College \\ Fine Arts Center* \\ 19:30], [], [Jan 26, 27 \\ *Lyndon State College Alexander Twilight Theater* \\ 20:00], [ Feb 17 --- #smallcaps[Anniversary] \\ *Middlebury College \\ Center for the Arts* \\ 19:00 #text(0.7em)[(for a special guest)] ], ) ``` ```typst #set page(height: 13em, width: 26em) #let cv(..jobs) = grid( columns: 2, inset: 5pt, stroke: (x, y) => if x == 0 and y > 0 { (right: ( paint: luma(180), thickness: 1.5pt, dash: "dotted", )) }, grid.header(grid.cell(colspan: 2)[ *Professional Experience* #box(width: 1fr, line(length: 100%, stroke: luma(180))) ]), ..{ let last = none for job in jobs.pos() { ( if job.year != last [*#job.year*], [ *#job.company* - #job.role _(#job.timeframe)_ \\ #job.details ] ) last = job.year } } ) #cv( ( year: 2012, company: [Pear Seed & Co.], role: [Lead Engineer], timeframe: [Jul - Dec], details: [ - Raised engineers from 3x to 10x - Did a great job ], ), ( year: 2012, company: [Mega Corp.], role: [VP of Sales], timeframe: [Mar - Jun], details: [- Closed tons of customers], ), ( year: 2013, company: [Tiny Co.], role: [CEO], timeframe: [Jan - Dec], details: [- Delivered 4x more shareholder value], ), ( year: 2014, company: [Glorbocorp Ltd], role: [CTO], timeframe: [Jan - Mar], details: [- Drove containerization forward], ), ) ```
- type: none | length | color | gradient | array | stroke | tiling | dictionary | function
- default: (:)
- children:
- description: The contents of the grid cells, plus any extra grid lines specified with the [`grid.hline`](/docs/reference/layout/grid/#definitions-hline) and [`grid.vline`](/docs/reference/layout/grid/#definitions-vline) elements. The cells are populated in row-major order.
- type: content
- default: None
## Definitions
### grid.cell
A cell in the grid. You can use this function in the argument list of a grid to override grid style properties for an individual cell or manually positioning it within the grid. You can also use this function in show rules to apply certain styles to multiple cells at once.
For example, you can override the position and stroke for a single cell:
```typst
#set text(15pt, font: "Noto Sans Symbols 2")
#show regex("[♚-♟︎]"): set text(fill: rgb("21212A"))
#show regex("[♔-♙]"): set text(fill: rgb("111015"))
#grid(
fill: (x, y) => rgb(
if calc.odd(x + y) { "7F8396" }
else { "EFF0F3" }
),
columns: (1em,) * 8,
rows: 1em,
align: center + horizon,
[♖], [♘], [♗], [♕], [♔], [♗], [♘], [♖],
[♙], [♙], [♙], [♙], [], [♙], [♙], [♙],
grid.cell(
x: 4, y: 3,
stroke: blue.transparentize(60%)
)[♙],
..(grid.cell(y: 6)[♟],) * 8,
..([♜], [♞], [♝], [♛], [♚], [♝], [♞], [♜])
.map(grid.cell.with(y: 7)),
)
```
You may also apply a show rule on `grid.cell` to style all cells at once, which allows you, for example, to apply styles based on a cell's position. Refer to the examples of the [`table.cell`](/docs/reference/model/table/#definitions-cell) element to learn more about this.
```typst
#grid.cell(
body,
x: auto | int,
y: auto | int,
colspan: int,
rowspan: int,
inset: auto | relative | dictionary,
align: auto | alignment,
fill: none | auto | color | gradient | tiling,
stroke: none | length | color | gradient | stroke | tiling | dictionary,
breakable: auto | bool
) -> content
```
#### Parameters
- body:
- description: The cell\'s body.
- type: content
- default: None
- x:
- description: The cell\'s column (zero-indexed). This field may be used in show rules to style a cell depending on its column. You may override this field to pick in which column the cell must be placed. If no row (`y`) is chosen, the cell will be placed in the first row (starting at row 0) with that column available (or a new row if none). If both `x` and `y` are chosen, however, the cell will be placed in that exact position. An error is raised if that position is not available (thus, it is usually wise to specify cells with a custom position before cells with automatic positions). ```typst #let circ(c) = circle( fill: c, width: 5mm ) #grid( columns: 4, rows: 7mm, stroke: .5pt + blue, align: center + horizon, inset: 1mm, grid.cell(x: 2, y: 2, circ(aqua)), circ(yellow), grid.cell(x: 3, circ(green)), circ(black), ) ```
- type: auto | int
- default: auto
- y:
- description: The cell\'s row (zero-indexed). This field may be used in show rules to style a cell depending on its row. You may override this field to pick in which row the cell must be placed. If no column (`x`) is chosen, the cell will be placed in the first column (starting at column 0) available in the chosen row. If all columns in the chosen row are already occupied, an error is raised. ```typst #let tri(c) = polygon.regular( fill: c, size: 5mm, vertices: 3, ) #grid( columns: 2, stroke: blue, inset: 1mm, tri(black), grid.cell(y: 1, tri(teal)), grid.cell(y: 1, tri(red)), grid.cell(y: 2, tri(orange)) ) ```
- type: auto | int
- default: auto
- colspan:
- description: The amount of columns spanned by this cell.
- type: int
- default: 1
- rowspan:
- description: The amount of rows spanned by this cell.
- type: int
- default: 1
- inset:
- description: The cell\'s [inset](/docs/reference/layout/grid/#parameters-inset) override.
- type: auto | relative | dictionary
- default: auto
- align:
- description: The cell\'s [alignment](/docs/reference/layout/grid/#parameters-align) override.
- type: auto | alignment
- default: auto
- fill:
- description: The cell\'s [fill](/docs/reference/layout/grid/#parameters-fill) override.
- type: none | auto | color | gradient | tiling
- default: auto
- stroke:
- description: The cell\'s [stroke](/docs/reference/layout/grid/#parameters-stroke) override.
- type: none | length | color | gradient | stroke | tiling | dictionary
- default: (:)
- breakable:
- description: Whether rows spanned by this cell can be placed in different pages. When equal to `auto`, a cell spanning only fixed-size rows is unbreakable, while a cell spanning at least one `auto`-sized row is breakable.
- type: auto | bool
- default: auto
### grid.hline
A horizontal line in the grid.
Overrides any per-cell stroke, including stroke specified through the grid's `stroke` field. Can cross spacing between cells created through the grid's `column-gutter` option.
An example for this function can be found at the [`table.hline`](/docs/reference/model/table/#definitions-hline) element.
```typst
#grid.hline(
y: auto | int,
start: int,
end: none | int,
stroke: none | length | color | gradient | stroke | tiling | dictionary,
position: alignment
) -> content
```
#### Parameters
- y:
- description: The row above which the horizontal line is placed (zero-indexed). If the `position` field is set to `bottom`, the line is placed below the row with the given index instead (see [`grid.hline.position`](/docs/reference/layout/grid/#definitions-hline-position) for details). Specifying `auto` causes the line to be placed at the row below the last automatically positioned cell (that is, cell without coordinate overrides) before the line among the grid\'s children. If there is no such cell before the line, it is placed at the top of the grid (row 0). Note that specifying for this option exactly the total amount of rows in the grid causes this horizontal line to override the bottom border of the grid, while a value of 0 overrides the top border.
- type: auto | int
- default: auto
- start:
- description: The column at which the horizontal line starts (zero-indexed, inclusive).
- type: int
- default: 0
- end:
- description: The column before which the horizontal line ends (zero-indexed, exclusive). Therefore, the horizontal line will be drawn up to and across column `end - 1`. A value equal to `none` or to the amount of columns causes it to extend all the way towards the end of the grid.
- type: none | int
- default: none
- stroke:
- description: The line\'s stroke. Specifying `none` removes any lines previously placed across this line\'s range, including hlines or per-cell stroke below it.
- type: none | length | color | gradient | stroke | tiling | dictionary
- default: 1pt + black
- position:
- description: The position at which the line is placed, given its row (`y`) - either `top` to draw above it or `bottom` to draw below it. This setting is only relevant when row gutter is enabled (and shouldn\'t be used otherwise - prefer just increasing the `y` field by one instead), since then the position below a row becomes different from the position above the next row due to the spacing between both.
- type: alignment
- default: top
### grid.vline
A vertical line in the grid.
Overrides any per-cell stroke, including stroke specified through the grid's `stroke` field. Can cross spacing between cells created through the grid's `row-gutter` option.
```typst
#grid.vline(
x: auto | int,
start: int,
end: none | int,
stroke: none | length | color | gradient | stroke | tiling | dictionary,
position: alignment
) -> content
```
#### Parameters
- x:
- description: The column before which the vertical line is placed (zero-indexed). If the `position` field is set to `end`, the line is placed after the column with the given index instead (see [`grid.vline.position`](/docs/reference/layout/grid/#definitions-vline-position) for details). Specifying `auto` causes the line to be placed at the column after the last automatically positioned cell (that is, cell without coordinate overrides) before the line among the grid\'s children. If there is no such cell before the line, it is placed before the grid\'s first column (column 0). Note that specifying for this option exactly the total amount of columns in the grid causes this vertical line to override the end border of the grid (right in LTR, left in RTL), while a value of 0 overrides the start border (left in LTR, right in RTL).
- type: auto | int
- default: auto
- start:
- description: The row at which the vertical line starts (zero-indexed, inclusive).
- type: int
- default: 0
- end:
- description: The row on top of which the vertical line ends (zero-indexed, exclusive). Therefore, the vertical line will be drawn up to and across row `end - 1`. A value equal to `none` or to the amount of rows causes it to extend all the way towards the bottom of the grid.
- type: none | int
- default: none
- stroke:
- description: The line\'s stroke. Specifying `none` removes any lines previously placed across this line\'s range, including vlines or per-cell stroke below it.
- type: none | length | color | gradient | stroke | tiling | dictionary
- default: 1pt + black
- position:
- description: The position at which the line is placed, given its column (`x`) - either `start` to draw before it or `end` to draw after it. The values `left` and `right` are also accepted, but discouraged as they cause your grid to be inconsistent between left-to-right and right-to-left documents. This setting is only relevant when column gutter is enabled (and shouldn\'t be used otherwise - prefer just increasing the `x` field by one instead), since then the position after a column becomes different from the position before the next column due to the spacing between both.
- type: alignment
- default: start
### grid.header
A repeatable grid header.
If `repeat` is set to `true`, the header will be repeated across pages. For an example, refer to the [`table.header`](/docs/reference/model/table/#definitions-header) element and the [`grid.stroke`](/docs/reference/layout/grid/#parameters-stroke) parameter.
```typst
#grid.header(
repeat: bool,
level: int,
children
) -> content
```
#### Parameters
- repeat:
- description: Whether this header should be repeated across pages.
- type: bool
- default: true
- level:
- description: The level of the header. Must not be zero. This allows repeating multiple headers at once. Headers with different levels can repeat together, as long as they have ascending levels. Notably, when a header with a lower level starts repeating, all higher or equal level headers stop repeating (they are "replaced" by the new header).
- type: int
- default: 1
- children:
- description: The cells and lines within the header.
- type: content
- default: None
### grid.footer
A repeatable grid footer.
Just like the [`grid.header`](/docs/reference/layout/grid/#definitions-header) element, the footer can repeat itself on every page of the grid.
No other grid cells may be placed after the footer.
```typst
#grid.footer(
repeat: bool,
children
) -> content
```
#### Parameters
- repeat:
- description: Whether this footer should be repeated across pages.
- type: bool
- default: true
- children:
- description: The cells and lines within the footer.
- type: content
- default: None
docs/reference/layout/h.md
# Spacing (H)
# h
Inserts horizontal spacing into a paragraph.
The spacing can be absolute, relative, or fractional. In the last case, the remaining space on the line is distributed among all fractional spacings according to their relative fractions.
## Example
```typst
First #h(1cm) Second \
First #h(30%) Second
```
## Fractional spacing
With fractional spacing, you can align things within a line without forcing a paragraph break (like [`align`](/docs/reference/layout/align/) would). Each fractionally sized element gets space based on the ratio of its fraction to the sum of all fractions.
```typst
First #h(1fr) Second \
First #h(1fr) Second #h(1fr) Third \
First #h(2fr) Second #h(1fr) Third
```
## Mathematical Spacing
In [mathematical formulas](/docs/reference/math/), you can additionally use these constants to add spacing between elements: `thin` (1/6 em), `med` (2/9 em), `thick` (5/18 em), `quad` (1 em), `wide` (2 em).
```typst
#h(
amount,
weak: bool
) -> content
```
## Parameters
- amount:
- description: How much spacing to insert.
- type: relative | fraction
- default: None
- weak:
- description: If `true`, the spacing collapses at the start or end of a paragraph. Moreover, from multiple adjacent weak spacings all but the largest one collapse. Weak spacing in markup also causes all adjacent markup spaces to be removed, regardless of the amount of spacing inserted. To force a space next to weak spacing, you can explicitly write `#" "` (for a normal space) or `~` (for a non-breaking space). The latter can be useful to create a construct that always attaches to the preceding word with one non-breaking space, independently of whether a markup space existed in front or not. ```typst #h(1cm, weak: true) We identified a group of _weak_ specimens that fail to manifest in most cases. However, when #h(8pt, weak: true) supported #h(8pt, weak: true) on both sides, they do show up. Further #h(0pt, weak: true) more, even the smallest of them swallow adjacent markup spaces. ```
- type: bool
- default: false
docs/reference/layout/hide.md
# Hide
# hide
Hides content without affecting layout.
The `hide` function allows you to hide content while the layout still "sees" it. This is useful for creating blank space that is exactly as large as some content.
## Example
```typst
Hello Jane \
#hide[Hello] Joe
```
## Redaction
This function may also be useful for redacting content as its arguments are neither present visually nor accessible to Assistive Technology. That said, there can be _some_ traces of the hidden content (such as a bookmarked heading in the PDF's Document Outline).
Note that, depending on the circumstances, it may be possible for content to be reverse engineered based on its size in the layout. We thus do not recommend using this function to hide highly sensitive information.
```typst
#hide(
body
) -> content
```
## Parameters
- body:
- description: The content to hide.
- type: content
- default: None
docs/reference/layout/index.md
# Layout
Arranging elements on the page in different ways.
By combining layout functions, you can create complex and automatic layouts.
## Definitions
| Name | Description |
| --- | --- |
| [`align`](/reference/layout/align/) | Aligns content horizontally and vertically. |
| [`alignment`](/reference/layout/alignment/) | Where to align something along an axis. |
| [`angle`](/reference/layout/angle/) | An angle describing a rotation. |
| [`block`](/reference/layout/block/) | A block-level container. |
| [`box`](/reference/layout/box/) | An inline-level container that sizes content. |
| [`colbreak`](/reference/layout/colbreak/) | Forces a column break. |
| [`columns`](/reference/layout/columns/) | Separates a region into multiple equally sized columns. |
| [`direction`](/reference/layout/direction/) | The four directions into which content can be laid out. |
| [`fraction`](/reference/layout/fraction/) | Defines how the remaining space in a layout is distributed. |
| [`grid`](/reference/layout/grid/) | Arranges content in a grid. |
| [`h`](/reference/layout/h/) | Inserts horizontal spacing into a paragraph. |
| [`hide`](/reference/layout/hide/) | Hides content without affecting layout. |
| [`layout`](/reference/layout/layout/) | Provides access to the current outer container's (or page's, if none) dimensions (width and height). |
| [`length`](/reference/layout/length/) | A size or distance, possibly expressed with contextual units. |
| [`measure`](/reference/layout/measure/) | Measures the layouted size of content. |
| [`move`](/reference/layout/move/) | Moves content without affecting layout. |
| [`pad`](/reference/layout/pad/) | Adds spacing around content. |
| [`page`](/reference/layout/page/) | Layouts its child onto one or multiple pages. |
| [`pagebreak`](/reference/layout/pagebreak/) | A manual page break. |
| [`place`](/reference/layout/place/) | Places content relatively to its parent container. |
| [`ratio`](/reference/layout/ratio/) | A ratio of a whole. |
| [`relative`](/reference/layout/relative/) | A length in relation to some known length. |
| [`repeat`](/reference/layout/repeat/) | Repeats content to the available space. |
| [`rotate`](/reference/layout/rotate/) | Rotates content without affecting layout. |
| [`scale`](/reference/layout/scale/) | Scales content without affecting layout. |
| [`skew`](/reference/layout/skew/) | Skews content. |
| [`stack`](/reference/layout/stack/) | Arranges content and spacing horizontally or vertically. |
| [`v`](/reference/layout/v/) | Inserts vertical spacing into a flow of blocks. |
docs/reference/layout/layout.md
# Layout
# layout
Provides access to the current outer container's (or page's, if none) dimensions (width and height).
Accepts a function that receives a single parameter, which is a dictionary with keys `width` and `height`, both of type [`length`](/docs/reference/layout/length/). The function is provided [context](/docs/reference/context/), meaning you don't need to use it in combination with the `context` keyword. This is why [`measure`](/docs/reference/layout/measure/) can be called in the example below.
```typst
#let text = lorem(30)
#layout(size => [
#let (height,) = measure(
width: size.width,
text,
)
This text is #height high with
the current page width: \
#text
])
```
Note that the `layout` function forces its contents into a [block](/docs/reference/layout/block/)-level container, so placement relative to the page or pagebreaks are not possible within it.
If the `layout` call is placed inside a box with a width of `800pt` and a height of `400pt`, then the specified function will be given the argument `(width: 800pt, height: 400pt)`. If it is placed directly into the page, it receives the page's dimensions minus its margins. This is mostly useful in combination with [measurement](/docs/reference/layout/measure/).
To retrieve the _remaining_ height of the page rather than its full size, you can wrap your `layout` call in a `block(height: 1fr)`. This works because the block automatically grows to fill the remaining space (see the [fraction](/docs/reference/layout/fraction/) documentation for more details).
```typst
#set page(height: 150pt)
#lorem(20)
#block(height: 1fr, layout(size => [
Remaining height: #size.height
]))
```
You can also use this function to resolve a [`ratio`](/docs/reference/layout/ratio/) to a fixed length. This might come in handy if you're building your own layout abstractions.
```typst
#layout(size => {
let half = 50% * size.width
[Half a page is #half wide.]
})
```
Note that the width or height provided by `layout` will be infinite if the corresponding page dimension is set to `auto`.
```typst
#layout(
func
) -> content
```
## Parameters
- func:
- description: A function to call with the outer container\'s size. Its return value is displayed in the document. The container\'s size is given as a [dictionary](/docs/reference/foundations/dictionary/) with the keys `width` and `height`, both of type [`length`](/docs/reference/layout/length/). This function is called once for each time the content returned by `layout` appears in the document. This makes it possible to generate content that depends on the dimensions of its container.
- type: function
- default: None
docs/reference/layout/length.md
# Length
A size or distance, possibly expressed with contextual units.
Typst supports the following length units:
- Points: `72pt`
- Millimeters: `254mm`
- Centimeters: `2.54cm`
- Inches: `1in`
- Relative to font size: `2.5em`
You can multiply lengths with and divide them by integers and floats.
## Example
```typst
#rect(width: 20pt)
#rect(width: 2em)
#rect(width: 1in)
#(3em + 5pt).em \
#(20pt).em \
#(40em + 2pt).abs \
#(5em).abs
```
## Fields
- `abs`: A length with just the absolute component of the current length (that is, excluding the `em` component).
- `em`: The amount of `em` units in this length, as a [float](/docs/reference/foundations/float/).
## Methods
## length.pt
Converts this length to points.
Fails with an error if this length has non-zero `em` units (such as `5em + 2pt` instead of just `2pt`). Use the `abs` field (such as in `(5em + 2pt).abs.pt()`) to ignore the `em` component of the length (thus converting only its absolute component).
## length.mm
Converts this length to millimeters.
Fails with an error if this length has non-zero `em` units. See the [`pt`](/docs/reference/layout/length/#definitions-pt) method for more details.
## length.cm
Converts this length to centimeters.
Fails with an error if this length has non-zero `em` units. See the [`pt`](/docs/reference/layout/length/#definitions-pt) method for more details.
## length.inches
Converts this length to inches.
Fails with an error if this length has non-zero `em` units. See the [`pt`](/docs/reference/layout/length/#definitions-pt) method for more details.
## length.to-absolute
Resolve this length to an absolute length.
```typst
#set text(size: 12pt)
#context [
#(6pt).to-absolute() \
#(6pt + 10em).to-absolute() \
#(10em).to-absolute()
]
#set text(size: 6pt)
#context [
#(6pt).to-absolute() \
#(6pt + 10em).to-absolute() \
#(10em).to-absolute()
]
```
docs/reference/layout/measure.md
# Measure
# measure
Measures the layouted size of content.
The `measure` function lets you determine the layouted size of content. By default an infinite space is assumed, so the measured dimensions may not necessarily match the final dimensions of the content. If you want to measure in the current layout dimensions, you can combine `measure` and [`layout`](/docs/reference/layout/layout/).
## Example
The same content can have a different size depending on the [context](/docs/reference/context/) that it is placed into. In the example below, the `#content` is of course bigger when we increase the font size.
```typst
#let content = [Hello!]
#content
#set text(14pt)
#content
```
For this reason, you can only measure when context is available.
```typst
#let thing(body) = context {
let size = measure(body)
[Width of "#body" is #size.width]
}
#thing[Hey] \
#thing[Welcome]
```
The measure function returns a dictionary with the entries `width` and `height`, both of type [`length`](/docs/reference/layout/length/).
```typst
#measure(
width: auto | length,
height: auto | length,
content
) -> dictionary
```
## Parameters
- width:
- description: The width available to layout the content. Setting this to `auto` indicates infinite available width. Note that using the `width` and `height` parameters of this function is different from measuring a sized [`block`](/docs/reference/layout/block/) containing the content. In the following example, the former will get the dimensions of the inner content instead of the dimensions of the block. ```typst #context measure(lorem(100), width: 400pt) #context measure(block(lorem(100), width: 400pt)) ```
- type: auto | length
- default: auto
- height:
- description: The height available to layout the content. Setting this to `auto` indicates infinite available height.
- type: auto | length
- default: auto
- content:
- description: The content whose size to measure.
- type: content
- default: None
docs/reference/layout/move.md
# Move
# move
Moves content without affecting layout.
The `move` function allows you to move content while the layout still 'sees' it at the original positions. Containers will still be sized as if the content was not moved.
## Example
```typst
#rect(inset: 0pt, fill: gray, move(
dx: 4pt, dy: 6pt,
rect(
inset: 8pt,
fill: white,
stroke: black,
[Abra cadabra]
)
))
```
## Accessibility
Moving is transparent to Assistive Technology (AT). Your content will be read in the order it appears in the source, regardless of any visual movement. If you need to hide content from AT altogether in PDF export, consider using [`pdf.artifact`](/docs/reference/pdf/artifact/).
```typst
#move(
dx: relative,
dy: relative,
body
) -> content
```
## Parameters
- dx:
- description: The horizontal displacement of the content.
- type: relative
- default: 0 % + 0pt
- dy:
- description: The vertical displacement of the content.
- type: relative
- default: 0 % + 0pt
- body:
- description: The content to move.
- type: content
- default: None
docs/reference/layout/pad.md
# Padding
# pad
Adds spacing around content.
The spacing can be specified for each side individually, or for all sides at once by specifying a positional argument.
## Example
```typst
#set align(center)
#pad(x: 16pt, image("typing.jpg"))
_Typing speeds can be
measured in words per minute._
```
```typst
#pad(
left: relative,
top: relative,
right: relative,
bottom: relative,
x: relative,
y: relative,
rest: relative,
body
) -> content
```
## Parameters
- left:
- description: The padding at the left side.
- type: relative
- default: 0 % + 0pt
- top:
- description: The padding at the top side.
- type: relative
- default: 0 % + 0pt
- right:
- description: The padding at the right side.
- type: relative
- default: 0 % + 0pt
- bottom:
- description: The padding at the bottom side.
- type: relative
- default: 0 % + 0pt
- x:
- description: A shorthand to set `left` and `right` to the same value.
- type: relative
- default: 0 % + 0pt
- y:
- description: A shorthand to set `top` and `bottom` to the same value.
- type: relative
- default: 0 % + 0pt
- rest:
- description: A shorthand to set all four sides to the same value.
- type: relative
- default: 0 % + 0pt
- body:
- description: The content to pad at the sides.
- type: content
- default: None
docs/reference/layout/page.md
# Page
# page
Layouts its child onto one or multiple pages.
Although this function is primarily used in set rules to affect page properties, it can also be used to explicitly render its argument onto a set of pages of its own.
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 [Guide for Page Setup](/docs/guides/page-setup/) explains how to use this and related functions to set up a document with many examples.
## Example
```typst
#set page("us-letter")
There you go, US friends!
```
## Accessibility
The contents of the page's header, footer, foreground, and background are invisible to Assistive Technology (AT) like screen readers. Only the body of the page is read by AT. Do not include vital information not included elsewhere in the document in these areas.
```typst
#page(
paper: str,
width: auto | length,
height: auto | length,
flipped: bool,
margin: auto | relative | dictionary,
binding: auto | alignment,
columns: int,
fill: none | auto | color | gradient | tiling,
numbering: none | str | function,
supplement: none | auto | content,
number-align: alignment,
header: none | auto | content,
header-ascent: relative,
footer: none | auto | content,
footer-descent: relative,
background: none | content,
foreground: none | content,
body: content
) -> content
```
## Parameters
- paper:
- description: A standard paper size to set width and height. This is just a shorthand for setting `width` and `height` and, as such, cannot be retrieved in a context expression.
- type: str
- default: "a4"
- width:
- description: The width of the page. ```typst #set page( width: 3cm, margin: (x: 0cm), ) #for i in range(3) { box(square(width: 1cm)) } ```
- type: auto | length
- default: 595.28pt
- height:
- description: The height of the page. If this is set to `auto`, page breaks can only be triggered manually by inserting a [page break](/docs/reference/layout/pagebreak/) or by adding another non-empty page set rule. Most examples throughout this documentation use `auto` for the height of the page to dynamically grow and shrink to fit their content.
- type: auto | length
- default: 841.89pt
- flipped:
- description: Whether the page is flipped into landscape orientation. ```typst #set page( "us-business-card", flipped: true, fill: rgb("f2e5dd"), ) #set align(bottom + end) #text(14pt)[*Sam H. Richards*] \\ _Procurement Manager_ #set text(10pt) 17 Main Street \\ New York, NY 10001 \\ +1 555 555 5555 ```
- type: bool
- default: false
- margin:
- description: The page\'s margins. - `auto`: The margins are set automatically to 2.5/21 times the smaller dimension of the page. This results in 2.5 cm margins for an A4 page. - A single length: The same margin on all sides. - A dictionary: With a dictionary, the margins can be set individually. The dictionary can contain the following keys in order of precedence: - `top`: The top margin. - `right`: The right margin. - `bottom`: The bottom margin. - `left`: The left margin. - `inside`: The margin at the inner side of the page (where the [binding](/docs/reference/layout/page/#parameters-binding) is). - `outside`: The margin at the outer side of the page (opposite to the [binding](/docs/reference/layout/page/#parameters-binding)). - `x`: The horizontal margins. - `y`: The vertical margins. - `rest`: The margins on all sides except those for which the dictionary explicitly sets a size. All keys are optional; omitted keys will use their previously set value, or the default margin if never set. In addition, the values for `left` and `right` are mutually exclusive with the values for `inside` and `outside`. ```typst #set page( width: 3cm, height: 4cm, margin: (x: 8pt, y: 4pt), ) #rect( width: 100%, height: 100%, fill: aqua, ) ```
- type: auto | relative | dictionary
- default: auto
- binding:
- description: On which side the pages will be bound. - `auto`: Equivalent to `left` if the [text direction](/docs/reference/text/text/#parameters-dir) is left-to-right and `right` if it is right-to-left. - `left`: Bound on the left side. - `right`: Bound on the right side. This affects the meaning of the `inside` and `outside` options for margins.
- type: auto | alignment
- default: auto
- columns:
- description: How many columns the page has. If you need to insert columns into a page or other container, you can also use the [`columns` function](/docs/reference/layout/columns/). ```typst #set page(columns: 2, height: 4.8cm) Climate change is one of the most pressing issues of our time, with the potential to devastate communities, ecosystems, and economies around the world. It\'s clear that we need to take urgent action to reduce our carbon emissions and mitigate the impacts of a rapidly changing climate. ```
- type: int
- default: 1
- fill:
- description: The page\'s background fill. Setting this to something non-transparent instructs the printer to color the complete page. If you are considering larger production runs, it may be more environmentally friendly and cost-effective to source pre-dyed pages and not set this property. When set to `none`, the background becomes transparent. Note that PDF pages will still appear with a (usually white) background in viewers, but they are actually transparent. (If you print them, no color is used for the background.) The default of `auto` results in `none` for PDF output, and `white` for PNG and SVG. ```typst #set page(fill: rgb("444352")) #set text(fill: rgb("fdfdfd")) *Dark mode enabled.* ```
- type: none | auto | color | gradient | tiling
- default: auto
- numbering:
- description: How to number the pages. You can refer to the Page Setup Guide for [customizing page numbers](/docs/guides/page-setup/#page-numbers). Accepts a [numbering pattern or function](/docs/reference/model/numbering/) taking one or two numbers: 1. The first number is the current page number. 2. The second number is the total number of pages. In a numbering pattern, the second number can be omitted. If a function is passed, it will receive one argument in the context of links or references, and two arguments when producing the visible page numbers. These are logical numbers controlled by the page counter, and may thus not match the physical numbers. Specifically, they are the [current](/docs/reference/introspection/counter/#definitions-get) and the [final](/docs/reference/introspection/counter/#definitions-final) value of `counter(page)`. See the [`counter`](/docs/reference/introspection/counter/#page-counter) documentation for more details. If an explicit [`footer`](/docs/reference/layout/page/#parameters-footer) (or [`header`](/docs/reference/layout/page/#parameters-header) for [top-aligned](/docs/reference/layout/page/#parameters-number-align) numbering) is given, the numbering is ignored. ```typst #set page( height: 100pt, margin: (top: 16pt, bottom: 24pt), numbering: "1 / 1", ) #lorem(48) ```
- type: none | str | function
- default: none
- supplement:
- description: A supplement for the pages. For page references, this is added before the page number. ```typst #set page(numbering: "1.", supplement: [p.]) = Introduction <intro> We are on #ref(<intro>, form: "page")! ```
- type: none | auto | content
- default: auto
- number-align:
- description: The alignment of the page numbering. If the vertical component is `top`, the numbering is placed into the header and if it is `bottom`, it is placed in the footer. Horizon alignment is forbidden. If an explicit matching `header` or `footer` is given, the numbering is ignored. ```typst #set page( margin: (top: 16pt, bottom: 24pt), numbering: "1", number-align: right, ) #lorem(30) ```
- type: alignment
- default: center + bottom
- header:
- description: The page\'s header. Fills the top margin of each page. - Content: Shows the content as the header. - `auto`: Shows the page number if a [`numbering`](/docs/reference/layout/page/#parameters-numbering) is set and [`number-align`](/docs/reference/layout/page/#parameters-number-align) is `top`. - `none`: Suppresses the header. ```typst #set par(justify: true) #set page( margin: (top: 32pt, bottom: 20pt), header: [ #set text(8pt) #smallcaps[Typst Academy] #h(1fr) _Exercise Sheet 3_ ], ) #lorem(19) ```
- type: none | auto | content
- default: auto
- header-ascent:
- description: The amount the header is raised into the top margin.
- type: relative
- default: 30 % + 0pt
- footer:
- description: The page\'s footer. Fills the bottom margin of each page. - Content: Shows the content as the footer. - `auto`: Shows the page number if a [`numbering`](/docs/reference/layout/page/#parameters-numbering) is set and [`number-align`](/docs/reference/layout/page/#parameters-number-align) is `bottom`. - `none`: Suppresses the footer. For just a page number, the `numbering` property typically suffices. If you want to create a custom footer but still display the page number, you can directly access the [page counter](/docs/reference/introspection/counter/). ```typst #set par(justify: true) #set page( height: 100pt, margin: 20pt, footer: context [ #set align(right) #set text(8pt) #counter(page).display( "1 of I", both: true, ) ] ) #lorem(48) ```
- type: none | auto | content
- default: auto
- footer-descent:
- description: The amount the footer is lowered into the bottom margin.
- type: relative
- default: 30 % + 0pt
- background:
- description: Content in the page\'s background. This content will be placed behind the page\'s body. It can be used to place a background image or a watermark. ```typst #set page(background: rotate(24deg, text(18pt, fill: rgb("FFCBC4"))[ *CONFIDENTIAL* ] )) = Typst\'s secret plans In the year 2023, we plan to take over the world (of typesetting). ```
- type: none | content
- default: none
- foreground:
- description: Content in the page\'s foreground. This content will overlay the page\'s body. ```typst #set page(foreground: text(24pt)[🤓]) Reviewer 2 has marked our paper "Weak Reject" because they did not understand our approach... ```
- type: none | content
- default: none
- body:
- description: The contents of the page(s). Multiple pages will be created if the content does not fit on a single page. A new page with the page properties prior to the function invocation will be created after the body has been typeset.
- type: content
- default: []
docs/reference/layout/pagebreak.md
# Page Break
# pagebreak
A manual page break.
Must not be used inside any containers.
## Example
```typst
The next page contains
more details on compound theory.
#pagebreak()
== Compound Theory
In 1984, the first ...
```
Even without manual page breaks, content will be automatically paginated based on the configured page size. You can set [the page height](/docs/reference/layout/page/#parameters-height) to `auto` to let the page grow dynamically until a manual page break occurs.
Pagination tries to avoid single lines of text at the top or bottom of a page (these are called _widows_ and _orphans_). You can adjust the [`text.costs`](/docs/reference/text/text/#parameters-costs) parameter to disable this behavior.
```typst
#pagebreak(
weak: bool,
to: none | str
) -> content
```
## Parameters
- weak:
- description: If `true`, the page break is skipped if the current page is already empty.
- type: bool
- default: false
- to:
- description: If given, ensures that the next page will be an even/odd page, with an empty page in between if necessary. ```typst #set page(height: 30pt) First. #pagebreak(to: "odd") Third. ```
- type: none | str
- default: none
docs/reference/layout/place.md
# Place
# place
Places content relatively to its parent container.
Placed content can be either overlaid (the default) or floating. Overlaid content is aligned with the parent container according to the given [`alignment`](/docs/reference/layout/place/#parameters-alignment), and shown over any other content added so far in the container. Floating content is placed at the top or bottom of the container, displacing other content down or up respectively. In both cases, the content position can be adjusted with [`dx`](/docs/reference/layout/place/#parameters-dx) and [`dy`](/docs/reference/layout/place/#parameters-dy) offsets without affecting the layout.
The parent can be any container such as a [`block`](/docs/reference/layout/block/), [`box`](/docs/reference/layout/box/), [`rect`](/docs/reference/visualize/rect/), etc. A top level `place` call will place content directly in the text area of the current page. This can be used for absolute positioning on the page: with a `top + left` [`alignment`](/docs/reference/layout/place/#parameters-alignment), the offsets `dx` and `dy` will set the position of the element's top left corner relatively to the top left corner of the text area. For absolute positioning on the full page including margins, you can use `place` in [`page.foreground`](/docs/reference/layout/page/#parameters-foreground) or [`page.background`](/docs/reference/layout/page/#parameters-background).
## Examples
```typst
#set page(height: 120pt)
Hello, world!
#rect(
width: 100%,
height: 2cm,
place(horizon + right, square()),
)
#place(
top + left,
dx: -5pt,
square(size: 5pt, fill: red),
)
```
## Effect on the position of other elements
Overlaid elements don't take space in the flow of content, but a `place` call inserts an invisible block-level element in the flow. This can affect the layout by breaking the current paragraph. To avoid this, you can wrap the `place` call in a [`box`](/docs/reference/layout/box/) when the call is made in the middle of a paragraph. The alignment and offsets will then be relative to this zero-size box. To make sure it doesn't interfere with spacing, the box should be attached to a word using a word joiner.
For example, the following defines a function for attaching an annotation to the following word:
```typst
#let annotate(..args) = {
box(place(..args))
sym.wj
h(0pt, weak: true)
}
A placed #annotate(square(), dy: 2pt)
square in my text.
```
The zero-width weak spacing serves to discard spaces between the function call and the next word.
## Accessibility
Assistive Technology (AT) will always read the placed element at the point where it logically appears in the document, regardless of where this function physically moved it. Put its markup where it would make the most sense in the reading order.
```typst
#place(
alignment,
scope: str,
float: bool,
clearance: length,
dx: relative,
dy: relative,
body
) -> content
```
## Parameters
- alignment:
- description: Relative to which position in the parent container to place the content. - If `float` is `false`, then this can be any alignment other than `auto`. - If `float` is `true`, then this must be `auto`, `top`, or `bottom`. When `float` is `false` and no vertical alignment is specified, the content is placed at the current position on the vertical axis.
- type: auto | alignment
- default: start
- scope:
- description: Relative to which containing scope something is placed. The parent scope is primarily used with figures and, for this reason, the figure function has a mirrored [`scope` parameter](/docs/reference/model/figure/#parameters-scope). Nonetheless, it can also be more generally useful to break out of the columns. A typical example would be to [create a single-column title section](/docs/guides/page-setup/#columns) in a two-column document. Note that parent-scoped placement is currently only supported if `float` is `true`. This may change in the future. ```typst #set page(height: 150pt, columns: 2) #place( top + center, scope: "parent", float: true, rect(width: 80%, fill: aqua), ) #lorem(25) ```
- type: str
- default: "column"
- float:
- description: Whether the placed element has floating layout. Floating elements are positioned at the top or bottom of the parent container, displacing in-flow content. They are always placed in the in-flow order relative to each other, as well as before any content following a later [`place.flush`](/docs/reference/layout/place/#definitions-flush) element. ```typst #set page(height: 150pt) #let note(where, body) = place( center + where, float: true, clearance: 6pt, rect(body), ) #lorem(10) #note(bottom)[Bottom 1] #note(bottom)[Bottom 2] #lorem(40) #note(top)[Top] #lorem(10) ```
- type: bool
- default: false
- clearance:
- description: The spacing between the placed element and other elements in a floating layout. Has no effect if `float` is `false`.
- type: length
- default: 1.5em
- dx:
- description: The horizontal displacement of the placed content. ```typst #set page(height: 100pt) #for x in range(-8, 8) { place(center + horizon, dx: x * 8pt, dy: x * 4pt, text( size: calc.root(x + 10, 3) * 6pt, fill: color.mix((green, 8 - x), (blue, 8 + x)), )[T] ) } ``` This does not affect the layout of in-flow content. In other words, the placed content is treated as if it were wrapped in a [`move`](/docs/reference/layout/move/) element.
- type: relative
- default: 0 % + 0pt
- dy:
- description: The vertical displacement of the placed content. This does not affect the layout of in-flow content. In other words, the placed content is treated as if it were wrapped in a [`move`](/docs/reference/layout/move/) element.
- type: relative
- default: 0 % + 0pt
- body:
- description: The content to place.
- type: content
- default: None
## Definitions
### place.flush
Asks the layout algorithm to place pending floating elements before continuing with the content.
This is useful for preventing floating figures from spilling into the next section.
```typst
#lorem(15)
#figure(
rect(width: 100%, height: 50pt),
placement: auto,
caption: [A rectangle],
)
#place.flush()
This text appears after the figure.
```
docs/reference/layout/ratio.md
# Ratio
A ratio of a whole.
A ratio is written as a number, followed by a percent sign. Ratios most often appear as part of a [relative length](/docs/reference/layout/relative/), to specify the size of some layout element relative to the page or some container.
```typst
#rect(width: 25%)
```
However, they can also describe any other property that is relative to some base, e.g. an amount of [horizontal scaling](/docs/reference/layout/scale/#parameters-x) or the [height of parentheses](/docs/reference/math/lr/#functions-lr-size) relative to the height of the content they enclose.
## Scripting
Within your own code, you can use ratios as you like. You can multiply them with various other types as shown below:
| Multiply by | Example | Result |
| --- | --- | --- |
| [`ratio`](/docs/reference/layout/ratio/) | `27% * 10%` | `2.7%` |
| [`length`](/docs/reference/layout/length/) | `27% * 100pt` | `27pt` |
| [`relative`](/docs/reference/layout/relative/) | `27% * (10% + 100pt)` | `2.7% + 27pt` |
| [`angle`](/docs/reference/layout/angle/) | `27% * 100deg` | `27deg` |
| [`int`](/docs/reference/foundations/int/) | `27% * 2` | `54%` |
| [`float`](/docs/reference/foundations/float/) | `27% * 0.37037` | `10%` |
| [`fraction`](/docs/reference/layout/fraction/) | `27% * 3fr` | `0.81fr` |
When ratios are [displayed](/docs/reference/foundations/repr/) in the document, they are rounded to two significant digits for readability.
docs/reference/layout/relative.md
# Relative Length
A length in relation to some known length.
This type is a combination of a [length](/docs/reference/layout/length/) with a [ratio](/docs/reference/layout/ratio/). It results from addition and subtraction of a length and a ratio. Wherever a relative length is expected, you can also use a bare length or ratio.
## Relative to the page
A common use case is setting the width or height of a layout element (e.g., [block](/docs/reference/layout/block/), [rect](/docs/reference/visualize/rect/), etc.) as a certain percentage of the width of the page. Here, the rectangle's width is set to `25%`, so it takes up one fourth of the page's _inner_ width (the width minus margins).
```typst
#rect(width: 25%)
```
Bare lengths or ratios are always valid where relative lengths are expected, but the two can also be freely mixed:
```typst
#rect(width: 25% + 1cm)
```
If you're trying to size an element so that it takes up the page's _full_ width, you have a few options (this highly depends on your exact use case):
1. Set page margins to `0pt` (`#set page(margin: 0pt)`)
2. Multiply the ratio by the known full page width (`21cm * 69%`)
3. Use padding which will negate the margins (`#pad(x: -2.5cm, ...)`)
4. Use the page [background](/docs/reference/layout/page/#parameters-background) or [foreground](/docs/reference/layout/page/#parameters-foreground) field as those don't take margins into account (note that it will render the content outside of the document flow, see [place](/docs/reference/layout/place/) to control the content position)
## Relative to a container
When a layout element (e.g. a [rect](/docs/reference/visualize/rect/)) is nested in another layout container (e.g. a [block](/docs/reference/layout/block/)) instead of being a direct descendant of the page, relative widths become relative to the container:
```typst
#block(
width: 100pt,
fill: aqua,
rect(width: 50%),
)
```
## Scripting
You can multiply relative lengths by [ratios](/docs/reference/layout/ratio/), [integers](/docs/reference/foundations/int/), and [floats](/docs/reference/foundations/float/).
A relative length has the following fields:
- `length`: Its [length](/docs/reference/layout/length/) component.
- `ratio`: Its [ratio](/docs/reference/layout/ratio/) component.
```typst
#(100% - 50pt).length \
#(100% - 50pt).ratio
```
docs/reference/layout/repeat.md
# Repeat
# repeat
Repeats content to the available space.
This can be useful when implementing a custom index, reference, or outline.
Space may be inserted between the instances of the body parameter, so be sure to adjust the [`justify`](/docs/reference/layout/repeat/#parameters-justify) parameter accordingly.
Errors if there are no bounds on the available space, as it would create infinite content.
## Example
```typst
Sign on the dotted line:
#box(width: 1fr, repeat[.])
#set text(10pt)
#v(8pt, weak: true)
#align(right)[
Berlin, the 22nd of December, 2022
]
```
## Accessibility
Repeated content is automatically marked as an [artifact](/docs/reference/pdf/artifact/) and hidden from Assistive Technology (AT). Do not use this function to create content that contributes to the meaning of your document.
```typst
#repeat(
body,
gap: length,
justify: bool
) -> content
```
## Parameters
- body:
- description: The content to repeat.
- type: content
- default: None
- gap:
- description: The gap between each instance of the body.
- type: length
- default: 0pt
- justify:
- description: Whether to increase the gap between instances to completely fill the available space.
- type: bool
- default: true
docs/reference/layout/rotate.md
# Rotate
# rotate
Rotates content without affecting layout.
Rotates an element by a given angle. The layout will act as if the element was not rotated unless you specify `reflow: true`.
## Example
```typst
#stack(
dir: ltr,
spacing: 1fr,
..range(16)
.map(i => rotate(24deg * i)[X]),
)
```
```typst
#rotate(
angle,
origin: alignment,
reflow: bool,
body
) -> content
```
## Parameters
- angle:
- description: The amount of rotation. ```typst #rotate(-1.571rad)[Space!] ```
- type: angle
- default: 0deg
- origin:
- description: The origin of the rotation. If, for instance, you wanted the bottom left corner of the rotated element to stay aligned with the baseline, you would set it to `bottom + left` instead. ```typst #set text(spacing: 8pt) #let square = square.with(width: 8pt) #box(square()) #box(rotate(30deg, origin: center, square())) #box(rotate(30deg, origin: top + left, square())) #box(rotate(30deg, origin: bottom + right, square())) ```
- type: alignment
- default: center + horizon
- reflow:
- description: Whether the rotation impacts the layout. If set to `false`, the rotated content will retain the bounding box of the original content. If set to `true`, the bounding box will take the rotation of the content into account and adjust the layout accordingly. ```typst Hello #rotate(90deg, reflow: true)[World]! ```
- type: bool
- default: false
- body:
- description: The content to rotate.
- type: content
- default: None
docs/reference/layout/scale.md
# Scale
# scale
Scales content without affecting layout.
Lets you mirror content by specifying a negative scale on a single axis.
## Example
```typst
#set align(center)
#scale(x: -100%)[This is mirrored.]
#scale(x: -100%, reflow: true)[This is mirrored.]
```
```typst
#scale(
factor: auto | length | ratio,
x: auto | length | ratio,
y: auto | length | ratio,
origin: alignment,
reflow: bool,
body
) -> content
```
## Parameters
- factor:
- description: The scaling factor for both axes, as a positional argument. This is just an optional shorthand notation for setting `x` and `y` to the same value.
- type: auto | length | ratio
- default: 100 %
- x:
- description: The horizontal scaling factor. The body will be mirrored horizontally if the parameter is negative.
- type: auto | length | ratio
- default: 100 %
- y:
- description: The vertical scaling factor. The body will be mirrored vertically if the parameter is negative.
- type: auto | length | ratio
- default: 100 %
- origin:
- description: The origin of the transformation. ```typst A#box(scale(75%)[A])A \\ B#box(scale(75%, origin: bottom + left)[B])B ```
- type: alignment
- default: center + horizon
- reflow:
- description: Whether the scaling impacts the layout. If set to `false`, the scaled content will be allowed to overlap other content. If set to `true`, it will compute the new size of the scaled content and adjust the layout accordingly. ```typst Hello #scale(x: 20%, y: 40%, reflow: true)[World]! ```
- type: bool
- default: false
- body:
- description: The content to scale.
- type: content
- default: None
docs/reference/layout/skew.md
# Skew
# skew
Skews content.
Skews an element in horizontal and/or vertical direction. The layout will act as if the element was not skewed unless you specify `reflow: true`.
## Example
```typst
#skew(ax: -12deg)[
This is some fake italic text.
]
```
```typst
#skew(
ax: angle,
ay: angle,
origin: alignment,
reflow: bool,
body
) -> content
```
## Parameters
- ax:
- description: The horizontal skewing angle. ```typst #skew(ax: 30deg)[Skewed] ```
- type: angle
- default: 0deg
- ay:
- description: The vertical skewing angle. ```typst #skew(ay: 30deg)[Skewed] ```
- type: angle
- default: 0deg
- origin:
- description: The origin of the skew transformation. The origin will stay fixed during the operation. ```typst X #box(skew(ax: -30deg, origin: center + horizon)[X]) X \\ X #box(skew(ax: -30deg, origin: bottom + left)[X]) X \\ X #box(skew(ax: -30deg, origin: top + right)[X]) X ```
- type: alignment
- default: center + horizon
- reflow:
- description: Whether the skew transformation impacts the layout. If set to `false`, the skewed content will retain the bounding box of the original content. If set to `true`, the bounding box will take the transformation of the content into account and adjust the layout accordingly. ```typst Hello #skew(ay: 30deg, reflow: true, "World")! ```
- type: bool
- default: false
- body:
- description: The content to skew.
- type: content
- default: None
docs/reference/layout/stack.md
# Stack
# stack
Arranges content and spacing horizontally or vertically.
The stack places a list of items along an axis, with optional spacing between each item.
## Example
```typst
#stack(
dir: ttb,
rect(width: 40pt),
rect(width: 120pt),
rect(width: 90pt),
)
```
## Accessibility
Stacks do not carry any special semantics. The contents of the stack are read by Assistive Technology (AT) in the order in which they have been passed to this function.
```typst
#stack(
dir: direction,
spacing: none | relative | fraction,
children
) -> content
```
## Parameters
- dir:
- description: The direction along which the items are stacked. Possible values are: - `ltr`: Left to right. - `rtl`: Right to left. - `ttb`: Top to bottom. - `btt`: Bottom to top. You can use the `start` and `end` methods to obtain the initial and final points (respectively) of a direction, as `alignment`. You can also use the `axis` method to determine whether a direction is `"horizontal"` or `"vertical"`. The `inv` method returns a direction\'s inverse direction. For example, `ttb.start()` is `top`, `ttb.end()` is `bottom`, `ttb.axis()` is `"vertical"` and `ttb.inv()` is equal to `btt`.
- type: direction
- default: ttb
- spacing:
- description: Spacing to insert between items where no explicit spacing was provided.
- type: none | relative | fraction
- default: none
- children:
- description: The children to stack along the axis.
- type: relative | fraction | content
- default: None
docs/reference/layout/v.md
# Spacing (V)
# v
Inserts vertical spacing into a flow of blocks.
The spacing can be absolute, relative, or fractional. In the last case, the remaining space on the page is distributed among all fractional spacings according to their relative fractions.
## Example
```typst
#grid(
rows: 3cm,
columns: 6,
gutter: 1fr,
[A #parbreak() B],
[A #v(0pt) B],
[A #v(10pt) B],
[A #v(0pt, weak: true) B],
[A #v(40%, weak: true) B],
[A #v(1fr) B],
)
```
```typst
#v(
amount,
weak: bool
) -> content
```
## Parameters
- amount:
- description: How much spacing to insert.
- type: relative | fraction
- default: None
- weak:
- description: 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. Weak spacings will always collapse adjacent paragraph spacing, even if the paragraph spacing is larger. ```typst The following theorem is foundational to the field: #v(4pt, weak: true) $ x^2 + y^2 = r^2 $ #v(4pt, weak: true) The proof is simple: ```
- type: bool
- default: false
docs/reference/math/accent.md
# Accent
# math.accent
Attaches an accent to a base.
## Example
```typst
$grave(a) = accent(a, `)$ \
$arrow(a) = accent(a, arrow)$ \
$tilde(a) = accent(a, \u{0303})$
```
```typst
#math.accent(
base,
accent,
size: relative,
dotless: bool
) -> content
```
## Parameters
- base:
- description: The base to which the accent is applied. May consist of multiple letters. ```typst $arrow(A B C)$ ```
- type: content
- default: None
- accent:
- description: The accent to apply to the base. Supported accents include: | Accent | Name | Codepoint | | --- | --- | --- | | Grave | `grave` | ``` | | Acute | `acute` | `´` | | Circumflex | `hat` | `^` | | Tilde | `tilde` | `~` | | Macron | `macron` | `¯` | | Dash | `dash` | `‾` | | Breve | `breve` | `˘` | | Dot | `dot` | `.` | | Double dot, Diaeresis | `dot.double`, `diaer` | `¨` | | Triple dot | `dot.triple` | `⃛` | | Quadruple dot | `dot.quad` | `⃜` | | Circle | `circle` | `∘` | | Double acute | `acute.double` | `˝` | | Caron | `caron` | `ˇ` | | Right arrow | `arrow`, `->` | `→` | | Left arrow | `arrow.l`, `<-` | `←` | | Left/Right arrow | `arrow.l.r` | `↔` | | Right harpoon | `harpoon` | `⇀` | | Left harpoon | `harpoon.lt` | `↼` |
- type: str | content
- default: None
- size:
- description: The size of the accent, relative to the width of the base. ```typst $dash(A, size: #150%)$ ```
- type: relative
- default: 100 % + 0pt
- dotless:
- description: Whether to remove the dot on top of lowercase i and j when adding a top accent. This enables the `dtls` OpenType feature. ```typst $hat(dotless: #false, i)$ ```
- type: bool
- default: true
docs/reference/math/attach.md
# Attach
Subscript, superscripts, and limits.
Attachments can be displayed either as sub/superscripts, or limits. Typst automatically decides which is more suitable depending on the base, but you can also control this manually with the `scripts` and `limits` functions.
If you want the base to stretch to fit long top and bottom attachments (for example, an arrow with text above it), use the [`stretch`](/docs/reference/math/stretch/) function.
## Example
```typst
$ sum_(i=0)^n a_i = 2^(1+i) $
```
## 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.
# math.attach
A base with optional attachments.
```typst
$ attach(
Pi, t: alpha, b: beta,
tl: 1, tr: 2+3, bl: 4+5, br: 6,
) $
```
```typst
#math.attach(
base,
t: none | content,
b: none | content,
tl: none | content,
bl: none | content,
tr: none | content,
br: none | content
) -> content
```
## Parameters
- base:
- description: The base to which things are attached.
- type: content
- default: None
- t:
- description: The top attachment, smartly positioned at top-right or above the base. You can wrap the base in `limits()` or `scripts()` to override the smart positioning.
- type: none | content
- default: none
- b:
- description: 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.
- type: none | content
- default: none
- tl:
- description: The top-left attachment (before the base).
- type: none | content
- default: none
- bl:
- description: The bottom-left attachment (before base).
- type: none | content
- default: none
- tr:
- description: The top-right attachment (after the base).
- type: none | content
- default: none
- br:
- description: The bottom-right attachment (after the base).
- type: none | content
- default: none
# math.scripts
Forces a base to display attachments as scripts.
```typst
$ scripts(sum)_1^2 != sum_1^2 $
```
```typst
#math.scripts(
body
) -> content
```
## Parameters
- body:
- description: The base to attach the scripts to.
- type: content
- default: None
# math.limits
Forces a base to display attachments as limits.
```typst
$ limits(A)_1^2 != A_1^2 $
```
```typst
#math.limits(
body,
inline: bool
) -> content
```
## Parameters
- body:
- description: The base to attach the limits to.
- type: content
- default: None
- inline:
- description: Whether to also force limits in inline equations. When applying limits globally (e.g., through a show rule), it is typically a good idea to disable this.
- type: bool
- default: true
docs/reference/math/binom.md
# Binomial
# math.binom
A binomial expression.
## Example
```typst
$ binom(n, k) $
$ binom(n, k_1, k_2, k_3, ..., k_m) $
```
```typst
#math.binom(
upper,
lower
) -> content
```
## Parameters
- upper:
- description: The binomial\'s upper index.
- type: content
- default: None
- lower:
- description: The binomial\'s lower index.
- type: content
- default: None
docs/reference/math/cancel.md
# Cancel
# math.cancel
Displays a diagonal line over a part of an equation.
This is commonly used to show the elimination of a term.
## Example
```typst
Here, we can simplify:
$ (a dot b dot cancel(x)) /
cancel(x) $
```
```typst
#math.cancel(
body,
length: relative,
inverted: bool,
cross: bool,
angle: auto | angle | function,
stroke: length | color | gradient | stroke | tiling | dictionary
) -> content
```
## Parameters
- body:
- description: The content over which the line should be placed.
- type: content
- default: None
- length:
- description: The length of the line, relative to the length of the diagonal spanning the whole element being "cancelled". A value of `100%` would then have the line span precisely the element\'s diagonal. ```typst $ a + cancel(x, length: #200%) - cancel(x, length: #200%) $ ```
- type: relative
- default: 100 % + 3pt
- inverted:
- description: Whether the cancel line should be inverted (flipped along the y-axis). For the default angle setting, inverted means the cancel line points to the top left instead of top right. ```typst $ (a cancel((b + c), inverted: #true)) / cancel(b + c, inverted: #true) $ ```
- type: bool
- default: false
- cross:
- description: Whether two opposing cancel lines should be drawn, forming a cross over the element. Overrides `inverted`. ```typst $ cancel(Pi, cross: #true) $ ```
- type: bool
- default: false
- angle:
- description: How much to rotate the cancel line. - If given an angle, the line is rotated by that angle clockwise with respect to the y-axis. - If `auto`, the line assumes the default angle; that is, along the rising diagonal of the content box. - If given a function `angle => angle`, the line is rotated, with respect to the y-axis, by the angle returned by that function. The function receives the default angle as its input. ```typst $ cancel(Pi) cancel(Pi, angle: #0deg) cancel(Pi, angle: #45deg) cancel(Pi, angle: #90deg) cancel(1/(1+x), angle: #(a => a + 45deg)) cancel(1/(1+x), angle: #(a => a + 90deg)) $ ```
- type: auto | angle | function
- default: auto
- stroke:
- description: How to [stroke](/docs/reference/visualize/stroke/) the cancel line. ```typst $ cancel( sum x, stroke: #( paint: red, thickness: 1.5pt, dash: "dashed", ), ) $ ```
- type: length | color | gradient | stroke | tiling | dictionary
- default: 0.5pt
docs/reference/math/cases.md
# Cases
# math.cases
A case distinction.
Content across different branches can be aligned with the `&` symbol.
## Example
```typst
$ f(x, y) := cases(
1 "if" (x dot y)/2 <= 0,
2 "if" x "is even",
3 "if" x in NN,
4 "else",
) $
```
```typst
#math.cases(
delim: none | str | array | symbol,
reverse: bool,
gap: relative,
children
) -> content
```
## Parameters
- delim:
- description: The delimiter to use. Can be a single character specifying the left delimiter, in which case the right delimiter is inferred. Otherwise, can be an array containing a left and a right delimiter. ```typst #set math.cases(delim: "[") $ x = cases(1, 2) $ ```
- type: none | str | array | symbol
- default: ("{", "}")
- reverse:
- description: Whether the direction of cases should be reversed. ```typst #set math.cases(reverse: true) $ cases(1, 2) = x $ ```
- type: bool
- default: false
- gap:
- description: The gap between branches. ```typst #set math.cases(gap: 1em) $ x = cases(1, 2) $ ```
- type: relative
- default: 0 % + 0.2em
- children:
- description: The branches of the case distinction.
- type: content
- default: None
docs/reference/math/class.md
# Class
# math.class
Forced use of a certain math class.
This is useful to treat certain symbols as if they were of a different class, e.g. to make a symbol behave like a relation. The class of a symbol defines the way it is laid out, including spacing around it, and how its scripts are attached by default. Note that the latter can always be overridden using [`limits`](/docs/reference/math/attach/#functions-limits) and [`scripts`](/docs/reference/math/attach/#functions-scripts).
## Example
```typst
#let loves = math.class(
"relation",
sym.suit.heart,
)
$x loves y and y loves 5$
```
```typst
#math.class(
class,
body
) -> content
```
## Parameters
- class:
- description: The class to apply to the content.
- type: str
- default: None
- body:
- description: The content to which the class is applied.
- type: content
- default: None
docs/reference/math/equation.md
# Equation
# math.equation
A mathematical equation.
Can be displayed inline with text or as a separate block. An equation becomes block-level through the presence of whitespace after the opening dollar sign and whitespace before the closing dollar sign.
## Example
```typst
#set text(font: "New Computer Modern")
Let $a$, $b$, and $c$ be the side
lengths of right-angled triangle.
Then, we know that:
$ a^2 + b^2 = c^2 $
Prove by induction:
$ sum_(k=1)^n k = (n(n+1)) / 2 $
```
By default, block-level equations will not break across pages. This can be changed through `show math.equation: set block(breakable: true)`.
## Syntax
This function also has dedicated syntax: Write mathematical markup within dollar signs to create an equation. Starting and ending the equation with whitespace lifts it into a separate block that is centered horizontally. For more details about math syntax, see the [main math page](/docs/reference/math/).
```typst
#math.equation(
block: bool,
numbering: none | str | function,
number-align: alignment,
supplement: none | auto | content | function,
alt: none | str,
body
) -> content
```
## Parameters
- block:
- description: Whether the equation is displayed as a separate block.
- type: bool
- default: false
- numbering:
- description: How to number block-level equations. Accepts a [numbering pattern or function](/docs/reference/model/numbering/) taking a single number. ```typst #set math.equation(numbering: "(1)") We define: $ phi.alt := (1 + sqrt(5)) / 2 $ <ratio> With @ratio, we get: $ F_n = floor(1 / sqrt(5) phi.alt^n) $ ```
- type: none | str | function
- default: none
- number-align:
- description: The alignment of the equation numbering. By default, the alignment is `end + horizon`. For the horizontal component, you can use `right`, `left`, or `start` and `end` of the text direction; for the vertical component, you can use `top`, `horizon`, or `bottom`. ```typst #set math.equation(numbering: "(1)", number-align: bottom) We can calculate: $ E &= sqrt(m_0^2 + p^2) \\ &approx 125 "GeV" $ ```
- type: alignment
- default: end + horizon
- supplement:
- description: A supplement for the equation. For references to equations, this is added before the referenced number. If a function is specified, it is passed the referenced equation and should return content. ```typst #set math.equation(numbering: "(1)", supplement: [Eq.]) We define: $ phi.alt := (1 + sqrt(5)) / 2 $ <ratio> With @ratio, we get: $ F_n = floor(1 / sqrt(5) phi.alt^n) $ ```
- type: none | auto | content | function
- default: auto
- alt:
- description: An alternative description of the mathematical equation. This should describe the full equation in natural language and will be made available to Assistive Technology. You can learn more in the [Textual Representations section of the Accessibility Guide](/docs/guides/accessibility/#textual-representations). ```typst #math.equation( alt: "integral from 1 to infinity of a x squared plus b with respect to x", block: true, $ integral_1^oo a x^2 + b dif x $, ) ```
- type: none | str
- default: none
- body:
- description: The contents of the equation.
- type: content
- default: None
docs/reference/math/frac.md
# Fraction
# math.frac
A mathematical fraction.
## Example
```typst
$ 1/2 < (x+1)/2 $
$ ((x+1)) / 2 = frac(a, b) $
```
## Syntax
This function also has dedicated syntax: Use a slash to turn neighbouring expressions into a fraction. Multiple atoms can be grouped into a single expression using round grouping parentheses. Such parentheses are removed from the output, but you can nest multiple to force them.
```typst
#math.frac(
num,
denom,
style: str
) -> content
```
## Parameters
- num:
- description: The fraction\'s numerator.
- type: content
- default: None
- denom:
- description: The fraction\'s denominator.
- type: content
- default: None
- style:
- description: How the fraction should be laid out. ```typst $ frac(x, y, style: "vertical") $ $ frac(x, y, style: "skewed") $ $ frac(x, y, style: "horizontal") $ ``` ```typst #set math.frac(style: "skewed") $ a / b $ ``` ```typst // Grouping parentheses are removed. #set math.frac(style: "vertical") $ (a + b) / b $ // Grouping parentheses are removed. #set math.frac(style: "skewed") $ (a + b) / b $ // Grouping parentheses are retained. #set math.frac(style: "horizontal") $ (a + b) / b $ ``` ```typst // This changes the style for inline equations only. #show math.equation.where(block: false): set math.frac(style: "horizontal") This $(x-y)/z = 3$ is inline math, and this is block math: $ (x-y)/z = 3 $ ```
- type: str
- default: "vertical"
docs/reference/math/index.md
# Math
Typst has special [syntax](/docs/reference/syntax/#math) and library functions to typeset mathematical formulas. Math formulas can be displayed inline with text or as separate blocks. They will be typeset into their own block if they start and end with at least one space (e.g. `$ x^2 $`).
## Variables
In math, single letters are always displayed as is. Multiple letters, however, are interpreted as variables and functions. To display multiple letters verbatim, you can place them into quotes and to access single letter variables, you can use the [hash syntax](/docs/reference/scripting/#expressions).
```typst
$ A = pi r^2 $
$ "area" = pi dot "radius"^2 $
$ cal(A) :=
{ x in RR | x "is natural" } $
#let x = 5
$ #x < 17 $
```
## Symbols
Math mode makes a wide selection of [symbols](/docs/reference/symbols/sym/) like `pi`, `dot`, or `RR` available. Many mathematical symbols are available in different variants. You can select between different variants by applying [modifiers](/docs/reference/foundations/symbol/) to the symbol. Typst further recognizes a number of shorthand sequences like `=>` that approximate a symbol. When such a shorthand exists, the symbol's documentation lists it.
```typst
$ x < y => x gt.eq.not y $
```
## Line Breaks
Formulas can also contain line breaks. Each line can contain one or multiple _alignment points_ (`&`) which are then aligned.
```typst
$ sum_(k=0)^n k
&= 1 + ... + n \
&= (n(n+1)) / 2 $
```
## Function calls
Math mode supports special function calls without the hash prefix. In these "math calls", the argument list works a little differently than in code:
- Within them, Typst is still in "math mode". Thus, you can write math directly into them, but need to use hash syntax to pass code expressions (except for strings, which are available in the math syntax).
- They support positional and named arguments, as well as argument spreading.
- They don't support trailing content blocks.
- They provide additional syntax for 2-dimensional argument lists. The semicolon (`;`) merges preceding arguments separated by commas into an array argument.
```typst
$ frac(a^2, 2) $
$ vec(1, 2, delim: "[") $
$ mat(1, 2; 3, 4) $
$ mat(..#range(1, 5).chunks(2)) $
$ lim_x =
op("lim", limits: #true)_x $
```
To write a verbatim comma or semicolon in a math call, escape it with a backslash. The colon on the other hand is only recognized in a special way if directly preceded by an identifier, so to display it verbatim in those cases, you can just insert a space before it.
Functions calls preceded by a hash are normal code function calls and not affected by these rules.
## Alignment
When equations include multiple _alignment points_ (`&`), this creates blocks of alternatingly right- and left-aligned columns. In the example below, the expression `(3x + y) / 7` is right-aligned and `= 9` is left-aligned. The word "given" is also left-aligned because `&&` creates two alignment points in a row, alternating the alignment twice. `& &` and `&&` behave exactly the same way. Meanwhile, "multiply by 7" is right-aligned because just one `&` precedes it. Each alignment point simply alternates between right-aligned/left-aligned.
```typst
$ (3x + y) / 7 &= 9 && "given" \
3x + y &= 63 & "multiply by 7" \
3x &= 63 - y && "subtract y" \
x &= 21 - y/3 & "divide by 3" $
```
## Math fonts
You can set the math font by with a [show-set rule](/docs/reference/styling/#show-rules) as demonstrated below. Note that only special OpenType math fonts are suitable for typesetting maths.
```typst
#show math.equation: set text(font: "Fira Math")
$ sum_(i in NN) 1 + i $
```
## Math module
All math functions are part of the `math` [module](/docs/reference/scripting/#modules), which is available by default in equations. Outside of equations, they can be accessed with the `math.` prefix.
## Accessibility
To make math accessible, you must provide alternative descriptions of equations in natural language using the [`alt` parameter of `math.equation`](/docs/reference/math/equation/#parameters-alt). For more information, see the [Textual Representations section of the Accessibility Guide](/docs/guides/accessibility/#textual-representations).
```typst
#math.equation(
alt: "d S equals delta q divided by T",
block: true,
$ dif S = (delta q) / T $,
)
```
In the future, Typst will automatically make equations without alternative descriptions accessible in HTML and PDF 2.0 export.
## Definitions
| Name | Description |
| --- | --- |
| [`accent`](/reference/math/accent/) | Attaches an accent to a base. |
| [`attach`](/reference/math/attach/) | Subscript, superscripts, and limits. |
| [`binom`](/reference/math/binom/) | A binomial expression. |
| [`cancel`](/reference/math/cancel/) | Displays a diagonal line over a part of an equation. |
| [`cases`](/reference/math/cases/) | A case distinction. |
| [`class`](/reference/math/class/) | Forced use of a certain math class. |
| [`equation`](/reference/math/equation/) | A mathematical equation. |
| [`frac`](/reference/math/frac/) | A mathematical fraction. |
| [`lr`](/reference/math/lr/) | Delimiter matching. |
| [`mat`](/reference/math/mat/) | A matrix. |
| [`op`](/reference/math/op/) | A text operator in an equation. |
| [`primes`](/reference/math/primes/) | Grouped primes. |
| [`roots`](/reference/math/roots/) | Square and non-square roots. |
| [`sizes`](/reference/math/sizes/) | Forced size styles for expressions within formulas. |
| [`stretch`](/reference/math/stretch/) | Stretches a glyph. |
| [`styles`](/reference/math/styles/) | Alternate letterforms within formulas. |
| [`underover`](/reference/math/underover/) | Delimiters above or below parts of an equation. |
| [`variants`](/reference/math/variants/) | Alternate typefaces within formulas. |
| [`vec`](/reference/math/vec/) | A column vector. |
docs/reference/math/lr.md
# Left/Right
Delimiter matching.
The `lr` function allows you to match two delimiters and scale them with the content they contain. While this also happens automatically for delimiters that match syntactically, `lr` allows you to match two arbitrary delimiters and control their size exactly. Apart from the `lr` function, Typst provides a few more functions that create delimiter pairings for absolute, ceiled, and floored values as well as norms.
To prevent a delimiter from being matched by Typst, and thus auto-scaled, escape it with a backslash. To instead disable auto-scaling completely, use `set math.lr(size: 1em)`.
## Example
```typst
$ [a, b/2] $
$ lr(]sum_(x=1)^n], size: #50%) x $
$ abs((x + y) / 2) $
$ \{ (x / y) \} $
#set math.lr(size: 1em)
$ { (a / b), a, b in (0; 1/2] } $
```
# math.lr
Scales delimiters.
While matched delimiters scale by default, this can be used to scale unmatched delimiters and to control the delimiter scaling more precisely.
```typst
#math.lr(
size: relative,
body
) -> content
```
## Parameters
- size:
- description: The size of the brackets, relative to the height of the wrapped content.
- type: relative
- default: 100 % + 0pt
- body:
- description: The delimited content, including the delimiters.
- type: content
- default: None
# math.mid
Scales delimiters vertically to the nearest surrounding `lr()` group.
```typst
$ { x mid(|) sum_(i=1)^n w_i|f_i (x)| < 1 } $
```
```typst
#math.mid(
body
) -> content
```
## Parameters
- body:
- description: The content to be scaled.
- type: content
- default: None
# math.abs
Takes the absolute value of an expression.
```typst
$ abs(x/2) $
```
```typst
#math.abs(
size: relative,
body
) -> content
```
## Parameters
- size:
- description: The size of the brackets, relative to the height of the wrapped content.
- type: relative
- default: None
- body:
- description: The expression to take the absolute value of.
- type: content
- default: None
# math.norm
Takes the norm of an expression.
```typst
$ norm(x/2) $
```
```typst
#math.norm(
size: relative,
body
) -> content
```
## Parameters
- size:
- description: The size of the brackets, relative to the height of the wrapped content.
- type: relative
- default: None
- body:
- description: The expression to take the norm of.
- type: content
- default: None
# math.floor
Floors an expression.
```typst
$ floor(x/2) $
```
```typst
#math.floor(
size: relative,
body
) -> content
```
## Parameters
- size:
- description: The size of the brackets, relative to the height of the wrapped content.
- type: relative
- default: None
- body:
- description: The expression to floor.
- type: content
- default: None
# math.ceil
Ceils an expression.
```typst
$ ceil(x/2) $
```
```typst
#math.ceil(
size: relative,
body
) -> content
```
## Parameters
- size:
- description: The size of the brackets, relative to the height of the wrapped content.
- type: relative
- default: None
- body:
- description: The expression to ceil.
- type: content
- default: None
# math.round
Rounds an expression.
```typst
$ round(x/2) $
```
```typst
#math.round(
size: relative,
body
) -> content
```
## Parameters
- size:
- description: The size of the brackets, relative to the height of the wrapped content.
- type: relative
- default: None
- body:
- description: The expression to round.
- type: content
- default: None
docs/reference/math/mat.md
# Matrix
# math.mat
A matrix.
The elements of a row should be separated by commas, while the rows themselves should be separated by semicolons. The semicolon syntax merges preceding arguments separated by commas into an array. You can also use this special syntax of math function calls to define custom functions that take 2D data.
Content in cells can be aligned with the [`align`](/docs/reference/math/mat/#parameters-align) parameter, or content in cells that are in the same row can be aligned with the `&` symbol.
## Example
```typst
$ mat(
1, 2, ..., 10;
2, 2, ..., 10;
dots.v, dots.v, dots.down, dots.v;
10, 10, ..., 10;
) $
```
```typst
#math.mat(
delim: none | str | array | symbol,
align: alignment,
augment: none | int | dictionary,
gap: relative,
row-gap: relative,
column-gap: relative,
rows
) -> content
```
## Parameters
- delim:
- description: The delimiter to use. Can be a single character specifying the left delimiter, in which case the right delimiter is inferred. Otherwise, can be an array containing a left and a right delimiter. ```typst #set math.mat(delim: "[") $ mat(1, 2; 3, 4) $ ```
- type: none | str | array | symbol
- default: ("(", ")")
- align:
- description: The horizontal alignment that each cell should have. ```typst #set math.mat(align: right) $ mat(-1, 1, 1; 1, -1, 1; 1, 1, -1) $ ```
- type: alignment
- default: center
- augment:
- description: Draws augmentation lines in a matrix. - `none`: No lines are drawn. - A single number: A vertical augmentation line is drawn after the specified column number. Negative numbers start from the end. - A dictionary: With a dictionary, multiple augmentation lines can be drawn both horizontally and vertically. Additionally, the style of the lines can be set. The dictionary can contain the following keys: - `hline`: The offsets at which horizontal lines should be drawn. For example, an offset of `2` would result in a horizontal line being drawn after the second row of the matrix. Accepts either an integer for a single line, or an array of integers for multiple lines. Like for a single number, negative numbers start from the end. - `vline`: The offsets at which vertical lines should be drawn. For example, an offset of `2` would result in a vertical line being drawn after the second column of the matrix. Accepts either an integer for a single line, or an array of integers for multiple lines. Like for a single number, negative numbers start from the end. - `stroke`: How to [stroke](/docs/reference/visualize/stroke/) the line. If set to `auto`, takes on a thickness of 0.05 em and square line caps. ```typst $ mat(1, 0, 1; 0, 1, 2; augment: #2) $ // Equivalent to: $ mat(1, 0, 1; 0, 1, 2; augment: #(-1)) $ ``` ```typst $ mat(0, 0, 0; 1, 1, 1; augment: #(hline: 1, stroke: 2pt + green)) $ ```
- type: none | int | dictionary
- default: none
- gap:
- description: The gap between rows and columns. This is a shorthand to set `row-gap` and `column-gap` to the same value. ```typst #set math.mat(gap: 1em) $ mat(1, 2; 3, 4) $ ```
- type: relative
- default: 0 % + 0pt
- row-gap:
- description: The gap between rows. ```typst #set math.mat(row-gap: 1em) $ mat(1, 2; 3, 4) $ ```
- type: relative
- default: 0 % + 0.2em
- column-gap:
- description: The gap between columns. ```typst #set math.mat(column-gap: 1em) $ mat(1, 2; 3, 4) $ ```
- type: relative
- default: 0 % + 0.5em
- rows:
- description: An array of arrays with the rows of the matrix. ```typst #let data = ((1, 2, 3), (4, 5, 6)) #let matrix = math.mat(..data) $ v := matrix $ ```
- type: array
- default: None
docs/reference/math/op.md
# Text Operator
# math.op
A text operator in an equation.
## Example
```typst
$ tan x = (sin x)/(cos x) $
$ op("custom",
limits: #true)_(n->oo) n $
```
## Predefined Operators
Typst predefines the operators `arccos`, `arcsin`, `arctan`, `arg`, `cos`, `cosh`, `cot`, `coth`, `csc`, `csch`, `ctg`, `deg`, `det`, `dim`, `exp`, `gcd`, `lcm`, `hom`, `id`, `im`, `inf`, `ker`, `lg`, `lim`, `liminf`, `limsup`, `ln`, `log`, `max`, `min`, `mod`, `Pr`, `sec`, `sech`, `sin`, `sinc`, `sinh`, `sup`, `tan`, `tanh`, `tg` and `tr`.
```typst
#math.op(
text,
limits: bool
) -> content
```
## Parameters
- text:
- description: The operator\'s text.
- type: content
- default: None
- limits:
- description: Whether the operator should show attachments as limits in display mode.
- type: bool
- default: false
docs/reference/math/primes.md
# Primes
# math.primes
Grouped primes.
```typst
$ a'''_b = a^'''_b $
```
## Syntax
This function has dedicated syntax: use apostrophes instead of primes. They will automatically attach to the previous element, moving superscripts to the next level.
```typst
#math.primes(
count
) -> content
```
## Parameters
- count:
- description: The number of grouped primes.
- type: int
- default: None
docs/reference/math/roots.md
# Roots
Square and non-square roots.
## Example
```typst
$ sqrt(3 - 2 sqrt(2)) = sqrt(2) - 1 $
$ root(3, x) $
```
# math.root
A general root.
```typst
$ root(3, x) $
```
```typst
#math.root(
index,
radicand
) -> content
```
## Parameters
- index:
- description: Which root of the radicand to take.
- type: none | content
- default: none
- radicand:
- description: The expression to take the root of.
- type: content
- default: None
# math.sqrt
A square root.
```typst
$ sqrt(3 - 2 sqrt(2)) = sqrt(2) - 1 $
```
```typst
#math.sqrt(
radicand
) -> content
```
## Parameters
- radicand:
- description: The expression to take the square root of.
- type: content
- default: None
docs/reference/math/sizes.md
# Sizes
Forced size styles for expressions within formulas.
These functions allow manual configuration of the size of equation elements to make them look as in a display/inline equation or as if used in a root or sub/superscripts.
# math.display
Forced display style in math.
This is the normal size for block equations.
```typst
$sum_i x_i/2 = display(sum_i x_i/2)$
```
```typst
#math.display(
body,
cramped: bool
) -> content
```
## Parameters
- body:
- description: The content to size.
- type: content
- default: None
- cramped:
- description: Whether to impose a height restriction for exponents, like regular sub- and superscripts do.
- type: bool
- default: false
# math.inline
Forced inline (text) style in math.
This is the normal size for inline equations.
```typst
$ sum_i x_i/2
= inline(sum_i x_i/2) $
```
```typst
#math.inline(
body,
cramped: bool
) -> content
```
## Parameters
- body:
- description: The content to size.
- type: content
- default: None
- cramped:
- description: Whether to impose a height restriction for exponents, like regular sub- and superscripts do.
- type: bool
- default: false
# math.script
Forced script style in math.
This is the smaller size used in powers or sub- or superscripts.
```typst
$sum_i x_i/2 = script(sum_i x_i/2)$
```
```typst
#math.script(
body,
cramped: bool
) -> content
```
## Parameters
- body:
- description: The content to size.
- type: content
- default: None
- cramped:
- description: Whether to impose a height restriction for exponents, like regular sub- and superscripts do.
- type: bool
- default: true
# math.sscript
Forced second script style in math.
This is the smallest size, used in second-level sub- and superscripts (script of the script).
```typst
$sum_i x_i/2 = sscript(sum_i x_i/2)$
```
```typst
#math.sscript(
body,
cramped: bool
) -> content
```
## Parameters
- body:
- description: The content to size.
- type: content
- default: None
- cramped:
- description: Whether to impose a height restriction for exponents, like regular sub- and superscripts do.
- type: bool
- default: true
docs/reference/math/stretch.md
# Stretch
# math.stretch
Stretches a glyph.
This function can also be used to automatically stretch the base of an attachment, so that it fits the top and bottom attachments.
Note that only some glyphs can be stretched, and which ones can depend on the math font being used. However, most math fonts are the same in this regard.
```typst
$ H stretch(=)^"define" U + p V $
$ f : X stretch(->>, size: #150%)_"surjective" Y $
$ x stretch(harpoons.ltrb, size: #3em) y
stretch(\[, size: #150%) z $
```
```typst
#math.stretch(
body,
size: relative
) -> content
```
## Parameters
- body:
- description: The glyph to stretch.
- type: content
- default: None
- size:
- description: The size to stretch to, relative to the maximum size of the glyph and its attachments.
- type: relative
- default: 100 % + 0pt
docs/reference/math/styles.md
# Styles
Alternate letterforms within formulas.
These functions are distinct from the [`text`](/docs/reference/text/text/) function because math fonts contain multiple variants of each letter.
# math.upright
Upright (non-italic) font style in math.
```typst
$ upright(A) != A $
```
```typst
#math.upright(
body
) -> content
```
## Parameters
- body:
- description: The content to style.
- type: content
- default: None
# math.italic
Italic font style in math.
For roman letters and greek lowercase letters, this is already the default.
```typst
#math.italic(
body
) -> content
```
## Parameters
- body:
- description: The content to style.
- type: content
- default: None
# math.bold
Bold font style in math.
```typst
$ bold(A) := B^+ $
```
```typst
#math.bold(
body
) -> content
```
## Parameters
- body:
- description: The content to style.
- type: content
- default: None
docs/reference/math/underover.md
# Under/Over
Delimiters above or below parts of an equation.
The braces and brackets further allow you to add an optional annotation below or above themselves.
# math.underline
A horizontal line under content.
```typst
$ underline(1 + 2 + ... + 5) $
```
```typst
#math.underline(
body
) -> content
```
## Parameters
- body:
- description: The content above the line.
- type: content
- default: None
# math.overline
A horizontal line over content.
```typst
$ overline(1 + 2 + ... + 5) $
```
```typst
#math.overline(
body
) -> content
```
## Parameters
- body:
- description: The content below the line.
- type: content
- default: None
# math.underbrace
A horizontal brace under content, with an optional annotation below.
```typst
$ underbrace(0 + 1 + dots.c + n, n + 1 "numbers") $
```
```typst
#math.underbrace(
body,
annotation
) -> content
```
## Parameters
- body:
- description: The content above the brace.
- type: content
- default: None
- annotation:
- description: The optional content below the brace.
- type: none | content
- default: none
# math.overbrace
A horizontal brace over content, with an optional annotation above.
```typst
$ overbrace(0 + 1 + dots.c + n, n + 1 "numbers") $
```
```typst
#math.overbrace(
body,
annotation
) -> content
```
## Parameters
- body:
- description: The content below the brace.
- type: content
- default: None
- annotation:
- description: The optional content above the brace.
- type: none | content
- default: none
# math.underbracket
A horizontal bracket under content, with an optional annotation below.
```typst
$ underbracket(0 + 1 + dots.c + n, n + 1 "numbers") $
```
```typst
#math.underbracket(
body,
annotation
) -> content
```
## Parameters
- body:
- description: The content above the bracket.
- type: content
- default: None
- annotation:
- description: The optional content below the bracket.
- type: none | content
- default: none
# math.overbracket
A horizontal bracket over content, with an optional annotation above.
```typst
$ overbracket(0 + 1 + dots.c + n, n + 1 "numbers") $
```
```typst
#math.overbracket(
body,
annotation
) -> content
```
## Parameters
- body:
- description: The content below the bracket.
- type: content
- default: None
- annotation:
- description: The optional content above the bracket.
- type: none | content
- default: none
# math.underparen
A horizontal parenthesis under content, with an optional annotation below.
```typst
$ underparen(0 + 1 + dots.c + n, n + 1 "numbers") $
```
```typst
#math.underparen(
body,
annotation
) -> content
```
## Parameters
- body:
- description: The content above the parenthesis.
- type: content
- default: None
- annotation:
- description: The optional content below the parenthesis.
- type: none | content
- default: none
# math.overparen
A horizontal parenthesis over content, with an optional annotation above.
```typst
$ overparen(0 + 1 + dots.c + n, n + 1 "numbers") $
```
```typst
#math.overparen(
body,
annotation
) -> content
```
## Parameters
- body:
- description: The content below the parenthesis.
- type: content
- default: None
- annotation:
- description: The optional content above the parenthesis.
- type: none | content
- default: none
# math.undershell
A horizontal tortoise shell bracket under content, with an optional annotation below.
```typst
$ undershell(0 + 1 + dots.c + n, n + 1 "numbers") $
```
```typst
#math.undershell(
body,
annotation
) -> content
```
## Parameters
- body:
- description: The content above the tortoise shell bracket.
- type: content
- default: None
- annotation:
- description: The optional content below the tortoise shell bracket.
- type: none | content
- default: none
# math.overshell
A horizontal tortoise shell bracket over content, with an optional annotation above.
```typst
$ overshell(0 + 1 + dots.c + n, n + 1 "numbers") $
```
```typst
#math.overshell(
body,
annotation
) -> content
```
## Parameters
- body:
- description: The content below the tortoise shell bracket.
- type: content
- default: None
- annotation:
- description: The optional content above the tortoise shell bracket.
- type: none | content
- default: none
docs/reference/math/variants.md
# Variants
Alternate typefaces within formulas.
These functions are distinct from the [`text`](/docs/reference/text/text/) function because math fonts contain multiple variants of each letter.
# math.serif
Serif (roman) font style in math.
This is already the default.
```typst
#math.serif(
body
) -> content
```
## Parameters
- body:
- description: The content to style.
- type: content
- default: None
# math.sans
Sans-serif font style in math.
```typst
$ sans(A B C) $
```
```typst
#math.sans(
body
) -> content
```
## Parameters
- body:
- description: The content to style.
- type: content
- default: None
# math.frak
Fraktur font style in math.
```typst
$ frak(P) $
```
```typst
#math.frak(
body
) -> content
```
## Parameters
- body:
- description: The content to style.
- type: content
- default: None
# math.mono
Monospace font style in math.
```typst
$ mono(x + y = z) $
```
```typst
#math.mono(
body
) -> content
```
## Parameters
- body:
- description: The content to style.
- type: content
- default: None
# math.bb
Blackboard bold (double-struck) font style in math.
For uppercase latin letters, blackboard bold is additionally available through [symbols](/docs/reference/symbols/sym/) of the form `NN` and `RR`.
```typst
$ bb(b) $
$ bb(N) = NN $
$ f: NN -> RR $
```
```typst
#math.bb(
body
) -> content
```
## Parameters
- body:
- description: The content to style.
- type: content
- default: None
# math.cal
Calligraphic (chancery) font style in math.
```typst
Let $cal(P)$ be the set of ...
```
This is the default calligraphic/script style for most math fonts. See [`scr`](/docs/reference/math/variants/#functions-scr) for more on how to get the other style (roundhand).
```typst
#math.cal(
body
) -> content
```
## Parameters
- body:
- description: The content to style.
- type: content
- default: None
# math.scr
Script (roundhand) font style in math.
```typst
$scr(L)$ is not the set of linear
maps $cal(L)$.
```
There are two ways that fonts can support differentiating `cal` and `scr`. The first is using Unicode variation sequences. This works out of the box in Typst, however only a few math fonts currently support this.
The other way is using [font features](/docs/reference/text/text/#parameters-features). For example, the roundhand style might be available in a font through the _stylistic set 1_ (`ss01`) feature. To use it in Typst, you could then define your own version of `scr` like in the example below.
```typst
#let scr(it) = text(
stylistic-set: 1,
$cal(it)$,
)
We establish $cal(P) != scr(P)$.
```
```typst
#math.scr(
body
) -> content
```
## Parameters
- body:
- description: The content to style.
- type: content
- default: None
docs/reference/math/vec.md
# Vector
# math.vec
A column vector.
Content in the vector's elements can be aligned with the [`align`](/docs/reference/math/vec/#parameters-align) parameter, or the `&` symbol.
This function is for typesetting vector components. To typeset a symbol that represents a vector, [`arrow`](/docs/reference/math/accent/) and [`bold`](/docs/reference/math/styles/#functions-bold) are commonly used.
## Example
```typst
$ vec(a, b, c) dot vec(1, 2, 3)
= a + 2b + 3c $
```
```typst
#math.vec(
delim: none | str | array | symbol,
align: alignment,
gap: relative,
children
) -> content
```
## Parameters
- delim:
- description: The delimiter to use. Can be a single character specifying the left delimiter, in which case the right delimiter is inferred. Otherwise, can be an array containing a left and a right delimiter. ```typst #set math.vec(delim: "[") $ vec(1, 2) $ ```
- type: none | str | array | symbol
- default: ("(", ")")
- align:
- description: The horizontal alignment that each element should have. ```typst #set math.vec(align: right) $ vec(-1, 1, -1) $ ```
- type: alignment
- default: center
- gap:
- description: The gap between elements. ```typst #set math.vec(gap: 1em) $ vec(1, 2) $ ```
- type: relative
- default: 0 % + 0.2em
- children:
- description: The elements of the vector.
- type: content
- default: None
docs/reference/model/bibliography.md
# Bibliography
# bibliography
A bibliography / reference listing.
You can create a new bibliography by calling this function with a path to a bibliography file in either one of two formats:
- A Hayagriva `.yaml`/`.yml` file. Hayagriva is a new bibliography file format designed for use with Typst. Visit its [documentation](https://github.com/typst/hayagriva/blob/main/docs/file-format.md) for more details.
- A BibLaTeX `.bib` file.
As soon as you add a bibliography somewhere in your document, you can start citing things with reference syntax (`@key`) or explicit calls to the [citation](/docs/reference/model/cite/) function (`#cite(<key>)`). The bibliography will only show entries for works that were referenced in the document.
## Styles
Typst offers a wide selection of built-in [citation and bibliography styles](/docs/reference/model/bibliography/#parameters-style). Beyond those, you can add and use custom [CSL](https://citationstyles.org/) (Citation Style Language) files. Wondering which style to use? Here are some good defaults based on what discipline you're working in:
| Fields | Typical Styles |
| --- | --- |
| Engineering, IT | `"ieee"` |
| Psychology, Life Sciences | `"apa"` |
| Social sciences | `"chicago-author-date"` |
| Humanities | `"mla"`, `"chicago-notes"`, `"harvard-cite-them-right"` |
| Economics | `"harvard-cite-them-right"` |
| Physics | `"american-physics-society"` |
## Example
```typst
This was already noted by
pirates long ago. @arrgh
Multiple sources say ...
@arrgh @netwok.
#bibliography("works.bib")
```
```typst
#bibliography(
sources,
title: none | auto | content,
full: bool,
style: str | bytes
) -> content
```
## Parameters
- sources:
- description: One or multiple paths to or raw bytes for Hayagriva `.yaml` and/or BibLaTeX `.bib` files. This can be a: - A path string to load a bibliography file from the given path. For more details about paths, see the [Paths section](/docs/reference/syntax/#paths). - Raw bytes from which the bibliography should be decoded. - An array where each item is one of the above.
- type: str | bytes | array
- default: None
- title:
- description: The title of the bibliography. - When set to `auto`, an appropriate title for the [text language](/docs/reference/text/text/#parameters-lang) will be used. This is the default. - When set to `none`, the bibliography will not have a title. - A custom title can be set by passing content. The bibliography\'s heading will not be numbered by default, but you can force it to be with a show-set rule: `show bibliography: set heading(numbering: "1.")`
- type: none | auto | content
- default: auto
- full:
- description: Whether to include all works from the given bibliography files, even those that weren\'t cited in the document. To selectively add individual cited works without showing them, you can also use the `cite` function with [`form`](/docs/reference/model/cite/#parameters-form) set to `none`.
- type: bool
- default: false
- style:
- description: The bibliography style. This can be: - A string with the name of one of the built-in styles (see below). Some of the styles listed below appear twice, once with their full name and once with a short alias. - A path string to a [CSL file](https://citationstyles.org/). For more details about paths, see the [Paths section](/docs/reference/syntax/#paths). - Raw bytes from which a CSL style should be decoded.
- type: str | bytes
- default: "ieee"
docs/reference/model/cite.md
# Cite
# cite
Cite a work from the bibliography.
Before you starting citing, you need to add a [bibliography](/docs/reference/model/bibliography/) somewhere in your document.
## Example
```typst
This was already noted by
pirates long ago. @arrgh
Multiple sources say ...
@arrgh @netwok.
You can also call `cite`
explicitly. #cite(<arrgh>)
#bibliography("works.bib")
```
If your source name contains certain characters such as slashes, which are not recognized by the `<>` syntax, you can explicitly call `label` instead.
```typst
Computer Modern is an example of a modernist serif typeface.
#cite(label("DBLP:books/lib/Knuth86a")).
```
## Syntax
This function indirectly has dedicated syntax. [References](/docs/reference/model/ref/) can be used to cite works from the bibliography. The label then corresponds to the citation key.
```typst
#cite(
key,
supplement: none | content,
form: none | str,
style: auto | str | bytes
) -> content
```
## Parameters
- key:
- description: The citation key that identifies the entry in the bibliography that shall be cited, as a label. ```typst // All the same @netwok \\ #cite(<netwok>) \\ #cite(label("netwok")) ```
- type: label
- default: None
- supplement:
- description: A supplement for the citation such as page or chapter number. In reference syntax, the supplement can be added in square brackets: ```typst This has been proven. @distress[p.~7] #bibliography("works.bib") ```
- type: none | content
- default: none
- form:
- description: The kind of citation to produce. Different forms are useful in different scenarios: A normal citation is useful as a source at the end of a sentence, while a "prose" citation is more suitable for inclusion in the flow of text. If set to `none`, the cited work is included in the bibliography, but nothing will be displayed. ```typst #cite(<netwok>, form: "prose") show the outsized effects of pirate life on the human psyche. ```
- type: none | str
- default: "normal"
- style:
- description: The citation style. This can be: - `auto` to automatically use the [bibliography\'s style](/docs/reference/model/bibliography/#parameters-style) for citations. - A string with the name of one of the built-in styles (see below). Some of the styles listed below appear twice, once with their full name and once with a short alias. - A path string to a [CSL file](https://citationstyles.org/). For more details about paths, see the [Paths section](/docs/reference/syntax/#paths). - Raw bytes from which a CSL style should be decoded.
- type: auto | str | bytes
- default: auto
docs/reference/model/document.md
# Document
# document
The root element of a document and its metadata.
All documents are automatically wrapped in a `document` element. You cannot create a document element yourself. This function is only used with [set rules](/docs/reference/styling/#set-rules) to specify document metadata. Such a set rule must not occur inside of any layout container.
```typst
#set document(title: [Hello])
This has no visible output, but
embeds metadata into the PDF!
```
Note that metadata set with this function is not rendered within the document. Instead, it is embedded in the compiled PDF file.
```typst
#document(
title: none | content,
author: str | array,
description: none | content,
keywords: str | array,
date: none | auto | datetime
) -> content
```
## Parameters
- title:
- description: The document\'s title. This is rendered as the title of the PDF viewer window or the browser tab of the page. Adding a title is important for accessibility, as it makes it easier to navigate to your document and identify it among other open documents. When exporting to PDF/UA, a title is required. While this can be arbitrary content, PDF viewers only support plain text titles, so the conversion might be lossy.
- type: none | content
- default: none
- author:
- description: The document\'s authors.
- type: str | array
- default: ()
- description:
- description: The document\'s description.
- type: none | content
- default: none
- keywords:
- description: The document\'s keywords.
- type: str | array
- default: ()
- date:
- description: The document\'s creation date. If this is `auto` (default), Typst uses the current date and time. Setting it to `none` prevents Typst from embedding any creation date into the PDF metadata. The year component must be at least zero in order to be embedded into a PDF. If you want to create byte-by-byte reproducible PDFs, set this to something other than `auto`.
- type: none | auto | datetime
- default: auto
docs/reference/model/emph.md
# Emphasis
# emph
Emphasizes content by toggling italics.
- If the current [text style](/docs/reference/text/text/#parameters-style) is `"normal"`, this turns it into `"italic"`.
- If it is already `"italic"` or `"oblique"`, it turns it back to `"normal"`.
## Example
```typst
This is _emphasized._ \
This is #emph[too.]
#show emph: it => {
text(blue, it.body)
}
This is _emphasized_ differently.
```
## Syntax
This function also has dedicated syntax: To emphasize content, simply enclose it in underscores (`_`). Note that this only works at word boundaries. To emphasize part of a word, you have to use the function.
```typst
#emph(
body
) -> content
```
## Parameters
- body:
- description: The content to emphasize.
- type: content
- default: None
docs/reference/model/enum.md
# Numbered List
# enum
A numbered list.
Displays a sequence of items vertically and numbers them consecutively.
## Example
```typst
Automatically numbered:
+ Preparations
+ Analysis
+ Conclusions
Manually numbered:
2. What is the first step?
5. I am confused.
+ Moving on ...
Multiple lines:
+ This enum item has multiple
lines because the next line
is indented.
Function call.
#enum[First][Second]
```
You can easily switch all your enumerations to a different numbering style with a set rule.
```typst
#set enum(numbering: "a)")
+ Starting off ...
+ Don't forget step two
```
You can also use [`enum.item`](/docs/reference/model/enum/#definitions-item) to programmatically customize the number of each item in the enumeration:
```typst
#enum(
enum.item(1)[First step],
enum.item(5)[Fifth step],
enum.item(10)[Tenth step]
)
```
## Syntax
This functions also has dedicated syntax:
- Starting a line with a plus sign creates an automatically numbered enumeration item.
- Starting a line with a number followed by a dot creates an explicitly numbered enumeration item.
Enumeration items can contain multiple paragraphs and other block-level content. All content that is indented more than an item's marker becomes part of that item.
```typst
#enum(
tight: bool,
numbering: str | function,
start: auto | int,
full: bool,
reversed: bool,
indent: length,
body-indent: length,
spacing: auto | length,
number-align: alignment,
children
) -> content
```
## Parameters
- tight:
- description: Defines the default [spacing](/docs/reference/model/enum/#parameters-spacing) of the enumeration. If it is `false`, the items are spaced apart with [paragraph spacing](/docs/reference/model/par/#parameters-spacing). If it is `true`, they use [paragraph leading](/docs/reference/model/par/#parameters-leading) instead. This makes the list more compact, which can look better if the items are short. In markup mode, the value of this parameter is determined based on whether items are separated with a blank line. If items directly follow each other, this is set to `true`; if items are separated by a blank line, this is set to `false`. The markup-defined tightness cannot be overridden with set rules. ```typst + 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. ```
- type: bool
- default: true
- numbering:
- description: How to number the enumeration. Accepts a [numbering pattern or function](/docs/reference/model/numbering/). If the numbering pattern contains multiple counting symbols, they apply to nested enums. If given a function, the function receives one argument if `full` is `false` and multiple arguments if `full` is `true`. ```typst #set enum(numbering: "1.a)") + Different + Numbering + Nested + Items + Style #set enum(numbering: n => super[#n]) + Superscript + Numbering! ```
- type: str | function
- default: "1."
- start:
- description: Which number to start the enumeration with. ```typst #enum( start: 3, [Skipping], [Ahead], ) ```
- type: auto | int
- default: auto
- full:
- description: Whether to display the full numbering, including the numbers of all parent enumerations. ```typst #set enum(numbering: "1.a)", full: true) + Cook + Heat water + Add ingredients + Eat ```
- type: bool
- default: false
- reversed:
- description: Whether to reverse the numbering for this enumeration. ```typst #set enum(reversed: true) + Coffee + Tea + Milk ```
- type: bool
- default: false
- indent:
- description: The indentation of each item.
- type: length
- default: 0pt
- body-indent:
- description: The space between the numbering and the body of each item.
- type: length
- default: 0.5em
- spacing:
- description: The spacing between the items of the enumeration. If set to `auto`, uses paragraph [`leading`](/docs/reference/model/par/#parameters-leading) for tight enumerations and paragraph [`spacing`](/docs/reference/model/par/#parameters-spacing) for wide (non-tight) enumerations.
- type: auto | length
- default: auto
- number-align:
- description: The alignment that enum numbers should have. By default, this is set to `end + top`, which aligns enum numbers towards end of the current text direction (in left-to-right script, for example, this is the same as `right`) and at the top of the line. The choice of `end` for horizontal alignment of enum numbers is usually preferred over `start`, as numbers then grow away from the text instead of towards it, avoiding certain visual issues. This option lets you override this behaviour, however. (Also to note is that the [unordered list](/docs/reference/model/list/) uses a different method for this, by giving the `marker` content an alignment directly.). ```typst #set enum(number-align: start + bottom) Here are some powers of two: 1. One 2. Two 4. Four 8. Eight 16. Sixteen 32. Thirty two ```
- type: alignment
- default: end + top
- children:
- description: The numbered list\'s items. When using the enum syntax, adjacent items are automatically collected into enumerations, even through constructs like for loops. ```typst #for phase in ( "Launch", "Orbit", "Descent", ) [+ #phase] ```
- type: content | array
- default: None
## Definitions
### enum.item
An enumeration item.
```typst
#enum.item(
number,
body
) -> content
```
#### Parameters
- number:
- description: The item\'s number.
- type: auto | int
- default: auto
- body:
- description: The item\'s body.
- type: content
- default: None
docs/reference/model/figure.md
# Figure
# figure
A figure with an optional caption.
Automatically detects its kind to select the correct counting track. For example, figures containing images will be numbered separately from figures containing tables.
## Examples
The example below shows a basic figure with an image:
```typst
@glacier shows a glacier. Glaciers
are complex systems.
#figure(
image("glacier.jpg", width: 80%),
caption: [A curious figure.],
) <glacier>
```
You can also insert [tables](/docs/reference/model/table/) into figures to give them a caption. The figure will detect this and automatically use a separate counter.
```typst
#figure(
table(
columns: 4,
[t], [1], [2], [3],
[y], [0.3s], [0.4s], [0.8s],
),
caption: [Timing results],
)
```
This behaviour can be overridden by explicitly specifying the figure's `kind`. All figures of the same kind share a common counter.
## Figure behaviour
By default, figures are placed within the flow of content. To make them float to the top or bottom of the page, you can use the [`placement`](/docs/reference/model/figure/#parameters-placement) argument.
If your figure is too large and its contents are breakable across pages (e.g. if it contains a large table), then you can make the figure itself breakable across pages as well with this show rule:
```typst
#show figure: set block(breakable: true)
```
See the [block](/docs/reference/layout/block/#parameters-breakable) documentation for more information about breakable and non-breakable blocks.
## Caption customization
You can modify the appearance of the figure's caption with its associated [`caption`](/docs/reference/model/figure/#definitions-caption) function. In the example below, we emphasize all captions:
```typst
#show figure.caption: emph
#figure(
rect[Hello],
caption: [I am emphasized!],
)
```
By using a [`where`](/docs/reference/foundations/function/#definitions-where) selector, we can scope such rules to specific kinds of figures. For example, to position the caption above tables, but keep it below for all other kinds of figures, we could write the following show-set rule:
```typst
#show figure.where(
kind: table
): set figure.caption(position: top)
#figure(
table(columns: 2)[A][B][C][D],
caption: [I'm up here],
)
```
## Accessibility
You can use the [`alt`](/docs/reference/model/figure/#parameters-alt) parameter to provide an [alternative description](/docs/guides/accessibility/#textual-representations) of the figure for screen readers and other Assistive Technology (AT). Refer to [its documentation](/docs/reference/model/figure/#parameters-alt) to learn more.
You can use figures to add alternative descriptions to paths, shapes, or visualizations that do not have their own `alt` parameter. If your graphic is purely decorative and does not have a semantic meaning, consider wrapping it in [`pdf.artifact`](/docs/reference/pdf/artifact/) instead, which will hide it from AT when exporting to PDF.
AT will always read the figure at the point where it appears in the document, regardless of its [`placement`](/docs/reference/model/figure/#parameters-placement). Put its markup where it would make the most sense in the reading order.
```typst
#figure(
body,
alt: none | str,
placement: none | auto | alignment,
scope: str,
caption: none | content,
kind: auto | str | function,
supplement: none | auto | content | function,
numbering: none | str | function,
gap: length,
outlined: bool
) -> content
```
## Parameters
- body:
- description: The content of the figure. Often, an [image](/docs/reference/visualize/image/).
- type: content
- default: None
- alt:
- description: An alternative description of the figure. When you add an alternative description, AT will read both it and the caption (if any). However, the content of the figure itself will be skipped. When the body of your figure is an [image](/docs/reference/visualize/image/) with its own `alt` text set, this parameter should not be used on the figure element. Likewise, do not use this parameter when the figure contains a table, code, or other content that is already accessible. In such cases, the content of the figure will be read by AT, and adding an alternative description would lead to a loss of information. You can learn how to write good alternative descriptions in the [Accessibility Guide](/docs/guides/accessibility/#textual-representations).
- type: none | str
- default: none
- placement:
- description: The figure\'s placement on the page. - `none`: The figure stays in-flow exactly where it was specified like other content. - `auto`: The figure picks `top` or `bottom` depending on which is closer. - `top`: The figure floats to the top of the page. - `bottom`: The figure floats to the bottom of the page. The gap between the main flow content and the floating figure is controlled by the [`clearance`](/docs/reference/layout/place/#parameters-clearance) argument on the `place` function. ```typst #set page(height: 200pt) #show figure: set place( clearance: 1em, ) = Introduction #figure( placement: bottom, caption: [A glacier], image("glacier.jpg", width: 60%), ) #lorem(60) ```
- type: none | auto | alignment
- default: none
- scope:
- description: Relative to which containing scope the figure is placed. Set this to `"parent"` to create a full-width figure in a two-column document. Has no effect if `placement` is `none`. ```typst #set page(height: 250pt, columns: 2) = Introduction #figure( placement: bottom, scope: "parent", caption: [A glacier], image("glacier.jpg", width: 60%), ) #lorem(60) ```
- type: str
- default: "column"
- caption:
- description: The figure\'s caption.
- type: none | content
- default: none
- kind:
- description: The kind of figure this is. All figures of the same kind share a common counter. If set to `auto`, the figure will try to automatically determine its kind based on the type of its body. Automatically detected kinds are [tables](/docs/reference/model/table/) and [code](/docs/reference/text/raw/). In other cases, the inferred kind is that of an [image](/docs/reference/visualize/image/). Setting this to something other than `auto` will override the automatic detection. This can be useful if - you wish to create a custom figure type that is not an [image](/docs/reference/visualize/image/), a [table](/docs/reference/model/table/) or [code](/docs/reference/text/raw/), - you want to force the figure to use a specific counter regardless of its content. You can set the kind to be an element function or a string. If you set it to an element function other than [`table`](/docs/reference/model/table/), [`raw`](/docs/reference/text/raw/), or [`image`](/docs/reference/visualize/image/), you will need to manually specify the figure\'s supplement. ```typst #figure( circle(radius: 10pt), caption: [A curious atom.], kind: "atom", supplement: [Atom], ) ``` If you want to modify a counter to skip a number or reset the counter, you can access the [counter](/docs/reference/introspection/counter/) of each kind of figure with a [`where`](/docs/reference/foundations/function/#definitions-where) selector: - For [tables](/docs/reference/model/table/): `counter(figure.where(kind: table))` - For [images](/docs/reference/visualize/image/): `counter(figure.where(kind: image))` - For a custom kind: `counter(figure.where(kind: kind))` ```typst #figure( table(columns: 2, $n$, $1$), caption: [The first table.], ) #counter( figure.where(kind: table) ).update(41) #figure( table(columns: 2, $n$, $42$), caption: [The 42nd table], ) #figure( rect[Image], caption: [Does not affect images], ) ``` To conveniently use the correct counter in a show rule, you can access the `counter` field. There is an example of this in the documentation [of the `figure.caption` element\'s `body` field](/docs/reference/model/figure/#definitions-caption-body).
- type: auto | str | function
- default: auto
- supplement:
- description: The figure\'s supplement. If set to `auto`, the figure will try to automatically determine the correct supplement based on the `kind` and the active [text language](/docs/reference/text/text/#parameters-lang). If you are using a custom figure type, you will need to manually specify the supplement. If a function is specified, it is passed the first descendant of the specified `kind` (typically, the figure\'s body) and should return content. ```typst #figure( [The contents of my figure!], caption: [My custom figure], supplement: [Bar], kind: "foo", ) ```
- type: none | auto | content | function
- default: auto
- numbering:
- description: How to number the figure. Accepts a [numbering pattern or function](/docs/reference/model/numbering/) taking a single number.
- type: none | str | function
- default: "1"
- gap:
- description: The vertical gap between the body and caption.
- type: length
- default: 0.65em
- outlined:
- description: Whether the figure should appear in an [`outline`](/docs/reference/model/outline/) of figures.
- type: bool
- default: true
## Definitions
### figure.caption
The caption of a figure. This element can be used in set and show rules to customize the appearance of captions for all figures or figures of a specific kind.
In addition to its `position` and `body`, the `caption` also provides the figure's `kind`, `supplement`, `counter`, and `numbering` as fields. These parts can be used in [`where`](/docs/reference/foundations/function/#definitions-where) selectors and show rules to build a completely custom caption.
```typst
#show figure.caption: emph
#figure(
rect[Hello],
caption: [A rectangle],
)
```
```typst
#figure.caption(
position: alignment,
separator: auto | content,
body
) -> content
```
#### Parameters
- position:
- description: The caption\'s position in the figure. Either `top` or `bottom`. ```typst #show figure.where( kind: table ): set figure.caption(position: top) #figure( table(columns: 2)[A][B], caption: [I\'m up here], ) #figure( rect[Hi], caption: [I\'m down here], ) #figure( table(columns: 2)[A][B], caption: figure.caption( position: bottom, [I\'m down here too!] ) ) ```
- type: alignment
- default: bottom
- separator:
- description: The separator which will appear between the number and body. If set to `auto`, the separator will be adapted to the current [language](/docs/reference/text/text/#parameters-lang) and [region](/docs/reference/text/text/#parameters-region). ```typst #set figure.caption(separator: [ --- ]) #figure( rect[Hello], caption: [A rectangle], ) ```
- type: auto | content
- default: auto
- body:
- description: The caption\'s body. Can be used alongside `kind`, `supplement`, `counter`, `numbering`, and `location` to completely customize the caption. ```typst #show figure.caption: it => [ #underline(it.body) | #it.supplement #context it.counter.display(it.numbering) ] #figure( rect[Hello], caption: [A rectangle], ) ```
- type: content
- default: None
docs/reference/model/footnote.md
# Footnote
# footnote
A footnote.
Includes additional remarks and references on the same page with footnotes. A footnote will insert a superscript number that links to the note at the bottom of the page. Notes are numbered sequentially throughout your document and can break across multiple pages.
To customize the appearance of the entry in the footnote listing, see [`footnote.entry`](/docs/reference/model/footnote/#definitions-entry). The footnote itself is realized as a normal superscript, so you can use a set rule on the [`super`](/docs/reference/text/super/) function to customize it. You can also apply a show rule to customize only the footnote marker (superscript number) in the running text.
## Example
```typst
Check the docs for more details.
#footnote[https://typst.app/docs]
```
The footnote automatically attaches itself to the preceding word, even if there is a space before it in the markup. To force space, you can use the string `#" "` or explicit [horizontal spacing](/docs/reference/layout/h/).
By giving a label to a footnote, you can have multiple references to it.
```typst
You can edit Typst documents online.
#footnote[https://typst.app/app] <fn>
Checkout Typst's website. @fn
And the online app. #footnote(<fn>)
```
_Note:_ Set and show rules in the scope where `footnote` is called may not apply to the footnote's content. See [here](https://github.com/typst/typst/issues/1467#issuecomment-1588799440) for more information.
## Accessibility
Footnotes will be read by Assistive Technology (AT) immediately after the spot in the text where they are referenced, just like how they appear in markup.
```typst
#footnote(
numbering: str | function,
body
) -> content
```
## Parameters
- numbering:
- description: How to number footnotes. Accepts a [numbering pattern or function](/docs/reference/model/numbering/) taking a single number. By default, the footnote numbering continues throughout your document. If you prefer per-page footnote numbering, you can reset the footnote [counter](/docs/reference/introspection/counter/) in the page [header](/docs/reference/layout/page/#parameters-header). In the future, there might be a simpler way to achieve this. ```typst #set footnote(numbering: "*") Footnotes: #footnote[Star], #footnote[Dagger] ```
- type: str | function
- default: "1"
- body:
- description: The content to put into the footnote. Can also be the label of another footnote this one should point to.
- type: label | content
- default: None
## Definitions
### footnote.entry
An entry in a footnote list.
This function is not intended to be called directly. Instead, it is used in set and show rules to customize footnote listings.
```typst
#show footnote.entry: set text(red)
My footnote listing
#footnote[It's down here]
has red text!
```
_Note:_ Footnote entry properties must be uniform across each page run (a page run is a sequence of pages without an explicit pagebreak in between). For this reason, set and show rules for footnote entries should be defined before any page content, typically at the very start of the document.
```typst
#footnote.entry(
note,
separator: content,
clearance: length,
gap: length,
indent: length
) -> content
```
#### Parameters
- note:
- description: The footnote for this entry. Its location can be used to determine the footnote counter state. ```typst #show footnote.entry: it => { let loc = it.note.location() numbering( "1: ", ..counter(footnote).at(loc), ) it.note.body } Customized #footnote[Hello] listing #footnote[World! 🌏] ```
- type: content
- default: None
- separator:
- description: The separator between the document body and the footnote listing. ```typst #set footnote.entry( separator: repeat[.] ) Testing a different separator. #footnote[ Unconventional, but maybe not that bad? ] ```
- type: content
- default: line (length : 30 % + 0pt, stroke : 0.5pt)
- clearance:
- description: The amount of clearance between the document body and the separator. ```typst #set footnote.entry(clearance: 3em) Footnotes also need ... #footnote[ ... some space to breathe. ] ```
- type: length
- default: 1em
- gap:
- description: The gap between footnote entries. ```typst #set footnote.entry(gap: 0.8em) Footnotes: #footnote[Spaced], #footnote[Apart] ```
- type: length
- default: 0.5em
- indent:
- description: The indent of each footnote entry. ```typst #set footnote.entry(indent: 0em) Footnotes: #footnote[No], #footnote[Indent] ```
- type: length
- default: 1em
docs/reference/model/heading.md
# Heading
# heading
A section heading.
With headings, you can structure your document into sections. Each heading has a _level,_ which starts at one and is unbounded upwards. This level indicates the logical role of the following content (section, subsection, etc.) A top-level heading indicates a top-level section of the document (not the document's title). To insert a title, use the [`title`](/docs/reference/model/title/) element instead.
Typst can automatically number your headings for you. To enable numbering, specify how you want your headings to be numbered with a [numbering pattern or function](/docs/reference/model/numbering/).
Independently of the numbering, Typst can also automatically generate an [outline](/docs/reference/model/outline/) of all headings for you. To exclude one or more headings from this outline, you can set the `outlined` parameter to `false`.
When writing a [show rule](/docs/reference/styling/#show-rules) that accesses the [`body` field](/docs/reference/model/heading/#parameters-body) to create a completely custom look for headings, make sure to wrap the content in a [`block`](/docs/reference/layout/block/) (which is implicitly [sticky](/docs/reference/layout/block/#parameters-sticky) for headings through a built-in show-set rule). This prevents headings from becoming "orphans", i.e. remaining at the end of the page with the following content being on the next page.
## Example
```typst
#set heading(numbering: "1.a)")
= Introduction
In recent years, ...
== Preliminaries
To start, ...
```
## Syntax
Headings have dedicated syntax: They can be created by starting a line with one or multiple equals signs, followed by a space. The number of equals signs determines the heading's logical nesting depth. The `offset` field can be set to configure the starting depth.
## Accessibility
Headings are important for accessibility, as they help users of Assistive Technologies (AT) like screen readers to navigate within your document. Screen reader users will be able to skip from heading to heading, or get an overview of all headings in the document.
To make your headings accessible, you should not skip heading levels. This means that you should start with a first-level heading. Also, when the previous heading was of level 3, the next heading should be of level 3 (staying at the same depth), level 4 (going exactly one level deeper), or level 1 or 2 (new hierarchically higher headings).
## HTML export
As mentioned above, a top-level heading indicates a top-level section of the document rather than its title. This is in contrast to the HTML `<h1>` element of which there should be only one per document.
For this reason, in HTML export, a [`title`](/docs/reference/model/title/) element will turn into an `<h1>` and headings turn into `<h2>` and lower (a level 1 heading thus turns into `<h2>`, a level 2 heading into `<h3>`, etc).
```typst
#heading(
level: auto | int,
depth: int,
offset: int,
numbering: none | str | function,
supplement: none | auto | content | function,
outlined: bool,
bookmarked: auto | bool,
hanging-indent: auto | length,
body
) -> content
```
## Parameters
- level:
- description: The absolute nesting depth of the heading, starting from one. If set to `auto`, it is computed from `offset + depth`. This is primarily useful for usage in [show rules](/docs/reference/styling/#show-rules) (either with [`where`](/docs/reference/foundations/function/#definitions-where) selectors or by accessing the level directly on a shown heading). ```typst #show heading.where(level: 2): set text(red) = Level 1 == Level 2 #set heading(offset: 1) = Also level 2 == Level 3 ```
- type: auto | int
- default: auto
- depth:
- description: The relative nesting depth of the heading, starting from one. This is combined with `offset` to compute the actual `level`. This is set by the heading syntax, such that `== Heading` creates a heading with logical depth of 2, but actual level `offset + 2`. If you construct a heading manually, you should typically prefer this over setting the absolute level.
- type: int
- default: 1
- offset:
- description: The starting offset of each heading\'s `level`, used to turn its relative `depth` into its absolute `level`. ```typst = Level 1 #set heading(offset: 1, numbering: "1.1") = Level 2 #heading(offset: 2, depth: 2)[ I\'m level 4 ] ```
- type: int
- default: 0
- numbering:
- description: How to number the heading. Accepts a [numbering pattern or function](/docs/reference/model/numbering/) taking multiple numbers. ```typst #set heading(numbering: "1.a.") = A section == A subsection === A sub-subsection ```
- type: none | str | function
- default: none
- supplement:
- description: A supplement for the heading. For references to headings, this is added before the referenced number. If a function is specified, it is passed the referenced heading and should return content. ```typst #set heading(numbering: "1.", supplement: [Chapter]) = Introduction <intro> In @intro, we see how to turn Sections into Chapters. And in @intro[Part], it is done manually. ```
- type: none | auto | content | function
- default: auto
- outlined:
- description: Whether the heading should appear in the [outline](/docs/reference/model/outline/). Note that this property, if set to `true`, ensures the heading is also shown as a bookmark in the exported PDF\'s outline (when exporting to PDF). To change that behavior, use the `bookmarked` property. ```typst #outline() #heading[Normal] This is a normal heading. #heading(outlined: false)[Hidden] This heading does not appear in the outline. ```
- type: bool
- default: true
- bookmarked:
- description: Whether the heading should appear as a bookmark in the exported PDF\'s outline. Doesn\'t affect other export formats, such as PNG. The default value of `auto` indicates that the heading will only appear in the exported PDF\'s outline if its `outlined` property is set to `true`, that is, if it would also be listed in Typst\'s [outline](/docs/reference/model/outline/). Setting this property to either `true` (bookmark) or `false` (don\'t bookmark) bypasses that behavior. ```typst #heading[Normal heading] This heading will be shown in the PDF\'s bookmark outline. #heading(bookmarked: false)[Not bookmarked] This heading won\'t be bookmarked in the resulting PDF. ```
- type: auto | bool
- default: auto
- hanging-indent:
- description: The indent all but the first line of a heading should have. The default value of `auto` uses the width of the numbering as indent if the heading is aligned at the [start](/docs/reference/layout/direction/#definitions-start) of the [text direction](/docs/reference/text/text/#parameters-dir), and no indent for center and other alignments. ```typst #set heading(numbering: "1.") = A very, very, very, very, very, very long heading #show heading: set align(center) == A very long heading\\ with center alignment ```
- type: auto | length
- default: auto
- body:
- description: The heading\'s title.
- type: content
- default: None
docs/reference/model/index.md
# Model
Document structuring.
Here, you can find functions to structure your document and interact with that structure. This includes section headings, figures, bibliography management, cross-referencing and more.
## Definitions
| Name | Description |
| --- | --- |
| [`bibliography`](/reference/model/bibliography/) | A bibliography / reference listing. |
| [`cite`](/reference/model/cite/) | Cite a work from the bibliography. |
| [`document`](/reference/model/document/) | The root element of a document and its metadata. |
| [`emph`](/reference/model/emph/) | Emphasizes content by toggling italics. |
| [`enum`](/reference/model/enum/) | A numbered list. |
| [`figure`](/reference/model/figure/) | A figure with an optional caption. |
| [`footnote`](/reference/model/footnote/) | A footnote. |
| [`heading`](/reference/model/heading/) | A section heading. |
| [`link`](/reference/model/link/) | Links to a URL or a location in the document. |
| [`list`](/reference/model/list/) | A bullet list. |
| [`numbering`](/reference/model/numbering/) | Applies a numbering to a sequence of numbers. |
| [`outline`](/reference/model/outline/) | A table of contents, figures, or other elements. |
| [`par`](/reference/model/par/) | A logical subdivison of textual content. |
| [`parbreak`](/reference/model/parbreak/) | A paragraph break. |
| [`quote`](/reference/model/quote/) | Displays a quote alongside an optional attribution. |
| [`ref`](/reference/model/ref/) | A reference to a label or bibliography. |
| [`strong`](/reference/model/strong/) | Strongly emphasizes content by increasing the font weight. |
| [`table`](/reference/model/table/) | A table of items. |
| [`terms`](/reference/model/terms/) | A list of terms and their descriptions. |
| [`title`](/reference/model/title/) | A document title. |
docs/reference/model/link.md
# Link
# link
Links to a URL or a location in the document.
By default, links do not look any different from normal text. However, you can easily apply a style of your choice with a show rule.
## Example
```typst
#show link: underline
https://example.com \
#link("https://example.com") \
#link("https://example.com")[
See example.com
]
```
## Syntax
This function also has dedicated syntax: Text that starts with `http://` or `https://` is automatically turned into a link.
## Hyphenation
If you enable hyphenation or justification, by default, it will not apply to links to prevent unwanted hyphenation in URLs. You can opt out of this default via `show link: set text(hyphenate: true)`.
## Accessibility
The destination of a link should be clear from the link text itself, or at least from the text immediately surrounding it. In PDF export, Typst will automatically generate a tooltip description for links based on their destination. For links to URLs, the URL itself will be used as the tooltip.
## Links in HTML export
In HTML export, a link to a [label](/docs/reference/foundations/label/) or [location](/docs/reference/introspection/location/) will be turned into a fragment link to a named anchor point. To support this, targets without an existing ID will automatically receive an ID in the DOM. How this works varies by which kind of HTML node(s) the link target turned into:
- If the link target turned into a single HTML element, that element will receive the ID. This is, for instance, typically the case when linking to a top-level heading (which turns into a single `<h2>` element).
- If the link target turned into a single text node, the node will be wrapped in a `<span>`, which will then receive the ID.
- If the link target turned into multiple nodes, the first node will receive the ID.
- If the link target turned into no nodes at all, an empty span will be generated to serve as a link target.
If you rely on a specific DOM structure, you should ensure that the link target turns into one or multiple elements, as the compiler makes no guarantees on the precise segmentation of text into text nodes.
If present, the automatic ID generation tries to reuse the link target's label to create a human-readable ID. A label can be reused if:
- All characters are alphabetic or numeric according to Unicode, or a hyphen, or an underscore.
- The label does not start with a digit or hyphen.
These rules ensure that the label is both a valid CSS identifier and a valid URL fragment for linking.
As IDs must be unique in the DOM, duplicate labels might need disambiguation when reusing them as IDs. The precise rules for this are as follows:
- If a label can be reused and is unique in the document, it will directly be used as the ID.
- If it's reusable, but not unique, a suffix consisting of a hyphen and an integer will be added. For instance, if the label `<mylabel>` exists twice, it would turn into `mylabel-1` and `mylabel-2`.
- Otherwise, a unique ID of the form `loc-` followed by an integer will be generated.
```typst
#link(
dest,
body
) -> content
```
## Parameters
- dest:
- description: 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` can take one of three forms: - A [label](/docs/reference/foundations/label/) attached to an element. If you also want automatic text for the link based on the element, consider using a [reference](/docs/reference/model/ref/) instead. - A [`location`](/docs/reference/introspection/location/) (typically retrieved from [`here`](/docs/reference/introspection/here/), [`locate`](/docs/reference/introspection/locate/) or [`query`](/docs/reference/introspection/query/)). - A dictionary with a `page` key of type [integer](/docs/reference/foundations/int/) and `x` and `y` coordinates of type [length](/docs/reference/layout/length/). Pages are counted from one, and the coordinates are relative to the page\'s top left corner. ```typst = Introduction <intro> #link("mailto:hello@typst.app") \\ #link(<intro>)[Go to intro] \\ #link((page: 1, x: 0pt, y: 0pt))[ Go to top ] ```
- type: str | label | location | dictionary
- default: None
- body:
- description: 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.
- type: content
- default: None
docs/reference/model/list.md
# Bullet List
# list
A bullet list.
Displays a sequence of items vertically, with each item introduced by a marker.
## Example
```typst
Normal list.
- Text
- Math
- Layout
- ...
Multiple lines.
- This list item spans multiple
lines because it is indented.
Function call.
#list(
[Foundations],
[Calculate],
[Construct],
[Data Loading],
)
```
## Syntax
This functions also has dedicated syntax: Start a line with a hyphen, followed by a space to create a list item. A list item can contain multiple paragraphs and other block-level content. All content that is indented more than an item's marker becomes part of that item.
```typst
#list(
tight: bool,
marker: content | array | function,
indent: length,
body-indent: length,
spacing: auto | length,
children
) -> content
```
## Parameters
- tight:
- description: Defines the default [spacing](/docs/reference/model/list/#parameters-spacing) of the list. If it is `false`, the items are spaced apart with [paragraph spacing](/docs/reference/model/par/#parameters-spacing). If it is `true`, they use [paragraph leading](/docs/reference/model/par/#parameters-leading) instead. This makes the list more compact, which can look better if the items are short. In markup mode, the value of this parameter is determined based on whether items are separated with a blank line. If items directly follow each other, this is set to `true`; if items are separated by a blank line, this is set to `false`. The markup-defined tightness cannot be overridden with set rules. ```typst - If a list has a lot of text, and maybe other inline content, it should not be tight anymore. - To make a list wide, simply insert a blank line between the items. ```
- type: bool
- default: true
- marker:
- description: The marker which introduces each item. Instead of plain content, you can also pass an array with multiple markers that should be used for nested lists. If the list nesting depth exceeds the number of markers, the markers are cycled. For total control, you may pass a function that maps the list\'s nesting depth (starting from `0`) to a desired marker. ```typst #set list(marker: [--]) - A more classic list - With en-dashes #set list(marker: ([•], [--])) - Top-level - Nested - Items - Items ```
- type: content | array | function
- default: ([•], [‣], [–])
- indent:
- description: The indent of each item.
- type: length
- default: 0pt
- body-indent:
- description: The spacing between the marker and the body of each item.
- type: length
- default: 0.5em
- spacing:
- description: The spacing between the items of the list. If set to `auto`, uses paragraph [`leading`](/docs/reference/model/par/#parameters-leading) for tight lists and paragraph [`spacing`](/docs/reference/model/par/#parameters-spacing) for wide (non-tight) lists.
- type: auto | length
- default: auto
- children:
- description: The bullet list\'s children. When using the list syntax, adjacent items are automatically collected into lists, even through constructs like for loops. ```typst #for letter in "ABC" [ - Letter #letter ] ```
- type: content
- default: None
## Definitions
### list.item
A bullet list item.
```typst
#list.item(
body
) -> content
```
#### Parameters
- body:
- description: The item\'s body.
- type: content
- default: None
docs/reference/model/numbering.md
# Numbering
# numbering
Applies a numbering to a sequence of numbers.
A numbering defines how a sequence of numbers should be displayed as content. It is defined either through a pattern string or an arbitrary function.
A numbering pattern consists of counting symbols, for which the actual number is substituted, their prefixes, and one suffix. The prefixes and the suffix are displayed as-is.
## Example
```typst
#numbering("1.1)", 1, 2, 3) \
#numbering("1.a.i", 1, 2) \
#numbering("I – 1", 12, 2) \
#numbering(
(..nums) => nums
.pos()
.map(str)
.join(".") + ")",
1, 2, 3,
)
```
## Numbering patterns and numbering functions
There are multiple instances where you can provide a numbering pattern or function in Typst. For example, when defining how to number [headings](/docs/reference/model/heading/) or [figures](/docs/reference/model/figure/). Every time, the expected format is the same as the one described below for the [`numbering`](/docs/reference/model/numbering/#parameters-numbering) parameter.
The following example illustrates that a numbering function is just a regular [function](/docs/reference/foundations/function/) that accepts numbers and returns [`content`](/docs/reference/foundations/content/).
```typst
#let unary(.., last) = "|" * last
#set heading(numbering: unary)
= First heading
= Second heading
= Third heading
```
```typst
#numbering(
numbering,
numbers
) -> any
```
## Parameters
- numbering:
- description: Defines how the numbering works. **Counting symbols** are `1`, `a`, `A`, `i`, `I`, `α`, `Α`, `一`, `壹`, `あ`, `い`, `ア`, `イ`, `א`, `가`, `ㄱ`, `*`, `١`, `۱`, `१`, `১`, `ক`, `①`, and `⓵`. They are replaced by the number in the sequence, preserving the original case. The `*` character means that symbols should be used to count, in the order of `*`, `†`, `‡`, `§`, `¶`, `‖`. If there are more than six items, the number is represented using repeated symbols. **Suffixes** are all characters after the last counting symbol. They are displayed as-is at the end of any rendered number. **Prefixes** are all characters that are neither counting symbols nor suffixes. They are displayed as-is at in front of their rendered equivalent of their counting symbol. This parameter can also be an arbitrary function that gets each number as an individual argument. When given a function, the `numbering` function just forwards the arguments to that function. While this is not particularly useful in itself, it means that you can just give arbitrary numberings to the `numbering` function without caring whether they are defined as a pattern or function.
- type: str | function
- default: None
- numbers:
- description: The numbers to apply the numbering to. Must be non-negative. In general, numbers are counted from one. A number of zero indicates that the first element has not yet appeared. If `numbering` is a pattern and more numbers than counting symbols are given, the last counting symbol with its prefix is repeated.
- type: int
- default: None
docs/reference/model/outline.md
# Outline
# outline
A table of contents, figures, or other elements.
This function generates a list of all occurrences of an element in the document, up to a given [`depth`](/docs/reference/model/outline/#parameters-depth). The element's numbering and page number will be displayed in the outline alongside its title or caption.
## Example
```typst
#set heading(numbering: "1.")
#outline()
= Introduction
#lorem(5)
= Methods
== Setup
#lorem(10)
```
## Alternative outlines
In its default configuration, this function generates a table of contents. By setting the `target` parameter, the outline can be used to generate a list of other kinds of elements than headings.
In the example below, we list all figures containing images by setting `target` to `figure.where(kind: image)`. Just the same, we could have set it to `figure.where(kind: table)` to generate a list of tables.
We could also set it to just `figure`, without using a [`where`](/docs/reference/foundations/function/#definitions-where) selector, but then the list would contain _all_ figures, be it ones containing images, tables, or other material.
```typst
#outline(
title: [List of Figures],
target: figure.where(kind: image),
)
#figure(
image("tiger.jpg"),
caption: [A nice figure!],
)
```
## Styling the outline
At the most basic level, you can style the outline by setting properties on it and its entries. This way, you can customize the outline's [title](/docs/reference/model/outline/#parameters-title), how outline entries are [indented](/docs/reference/model/outline/#parameters-indent), and how the space between an entry's text and its page number should be [filled](/docs/reference/model/outline/#definitions-entry-fill).
Richer customization is possible through configuration of the outline's [entries](/docs/reference/model/outline/#definitions-entry). The outline generates one entry for each outlined element.
### Spacing the entries
Outline entries are [blocks](/docs/reference/layout/block/), so you can adjust the spacing between them with normal block-spacing rules:
```typst
#show outline.entry.where(
level: 1
): set block(above: 1.2em)
#outline()
= About ACME Corp.
== History
=== Origins
= Products
== ACME Tools
```
### Building an outline entry from its parts
For full control, you can also write a transformational show rule on `outline.entry`. However, the logic for properly formatting and indenting outline entries is quite complex and the outline entry itself only contains two fields: The level and the outlined element.
For this reason, various helper functions are provided. You can mix and match these to compose an entry from just the parts you like.
The default show rule for an outline entry looks like this[1](#1):
```typst
#show outline.entry: it => link(
it.element.location(),
it.indented(it.prefix(), it.inner()),
)
```
- The [`indented`](/docs/reference/model/outline/#definitions-entry-definitions-indented) function takes an optional prefix and inner content and automatically applies the proper indentation to it, such that different entries align nicely and long headings wrap properly.
- The [`prefix`](/docs/reference/model/outline/#definitions-entry-definitions-prefix) function formats the element's numbering (if any). It also appends a supplement for certain elements.
- The [`inner`](/docs/reference/model/outline/#definitions-entry-definitions-inner) function combines the element's [`body`](/docs/reference/model/outline/#definitions-entry-definitions-body), the filler, and the [`page` number](/docs/reference/model/outline/#definitions-entry-definitions-page).
You can use these individual functions to format the outline entry in different ways. Let's say, you'd like to fully remove the filler and page numbers. To achieve this, you could write a show rule like this:
```typst
#show outline.entry: it => link(
it.element.location(),
// Keep just the body, dropping
// the fill and the page.
it.indented(it.prefix(), it.body()),
)
#outline()
= About ACME Corp.
== History
```
[^1]: The outline of equations is the exception to this rule as it does not have a body and thus does not use indented layout.
```typst
#outline(
title: none | auto | content,
target: label | selector | location | function,
depth: none | int,
indent: auto | relative | function
) -> content
```
## Parameters
- title:
- description: The title of the outline. - When set to `auto`, an appropriate title for the [text language](/docs/reference/text/text/#parameters-lang) will be used. - When set to `none`, the outline will not have a title. - A custom title can be set by passing content. The outline\'s heading will not be numbered by default, but you can force it to be with a show-set rule: `show outline: set heading(numbering: "1.")`
- type: none | auto | content
- default: auto
- target:
- description: The type of element to include in the outline. To list figures containing a specific kind of element, like an image or a table, you can specify the desired kind in a [`where`](/docs/reference/foundations/function/#definitions-where) selector. See the section on [alternative outlines](/docs/reference/model/outline/#alternative-outlines) for more details. ```typst #outline( title: [List of Tables], target: figure.where(kind: table), ) #figure( table( columns: 4, [t], [1], [2], [3], [y], [0.3], [0.7], [0.5], ), caption: [Experiment results], ) ```
- type: label | selector | location | function
- default: heading
- depth:
- description: The maximum level up to which elements are included in the outline. When this argument is `none`, all elements are included. ```typst #set heading(numbering: "1.") #outline(depth: 2) = Yes Top-level section. == Still Subsection. === Nope Not included. ```
- type: none | int
- default: none
- indent:
- description: How to indent the outline\'s entries. - `auto`: Indents the numbering/prefix of a nested entry with the title of its parent entry. If the entries are not numbered (e.g., via [heading numbering](/docs/reference/model/heading/#parameters-numbering)), this instead simply inserts a fixed amount of `1.2em` indent per level. - [Relative length](/docs/reference/layout/relative/): Indents the entry by the specified length per nesting level. Specifying `2em`, for instance, would indent top-level headings by `0em` (not nested), second level headings by `2em` (nested once), third-level headings by `4em` (nested twice) and so on. - [Function](/docs/reference/foundations/function/): You can further customize this setting with a function. That function receives the nesting level as a parameter (starting at 0 for top-level headings/elements) and should return a (relative) length. For example, `n => n * 2em` would be equivalent to just specifying `2em`. ```typst #set heading(numbering: "I-I.") #set outline(title: none) #outline() #line(length: 100%) #outline(indent: 3em) = Software engineering technologies == Requirements == Tools and technologies === Code editors == Analyzing alternatives = Designing software components = Testing and integration ```
- type: auto | relative | function
- default: auto
## Definitions
### outline.entry
Represents an entry line in an outline.
With show-set and show rules on outline entries, you can richly customize the outline's appearance. See the [section on styling the outline](/docs/reference/model/outline/#styling-the-outline) for details.
```typst
#outline.entry(
level,
element,
fill: none | content
) -> content
```
#### Parameters
- level:
- description: The nesting level of this outline entry. Starts at `1` for top-level entries.
- type: int
- default: None
- element:
- description: The element this entry refers to. Its location will be available through the [`location`](/docs/reference/foundations/content/#definitions-location) method on the content and can be [linked](/docs/reference/model/link/) to.
- type: content
- default: None
- fill:
- description: Content to fill the space between the title and the page number. Can be set to `none` to disable filling. The `fill` will be placed into a fractionally sized box that spans the space between the entry\'s body and the page number. When using show rules to override outline entries, it is thus recommended to wrap the fill in a [`box`](/docs/reference/layout/box/) with fractional width, i.e. `box(width: 1fr, it.fill)`. When using [`repeat`](/docs/reference/layout/repeat/), the [`gap`](/docs/reference/layout/repeat/#parameters-gap) property can be useful to tweak the visual weight of the fill. ```typst #set outline.entry(fill: line(length: 100%)) #outline() = A New Beginning ```
- type: none | content
- default: repeat (body : [.], gap : 0.15em)
#### Definitions
##### entry.indented
A helper function for producing an indented entry layout: Lays out a prefix and the rest of the entry in an indent-aware way.
If the parent outline's [`indent`](/docs/reference/model/outline/#parameters-indent) is `auto`, the inner content of all entries at level `N` is aligned with the prefix of all entries at level `N + 1`, leaving at least `gap` space between the prefix and inner parts. Furthermore, the `inner` contents of all entries at the same level are aligned.
If the outline's indent is a fixed value or a function, the prefixes are indented, but the inner contents are simply offset from the prefix by the specified `gap`, rather than aligning outline-wide. For a visual explanation, see [`outline.indent`](/docs/reference/model/outline/#parameters-indent).
```typst
#entry.indented(
prefix,
inner,
gap: length
) -> content
```
###### Parameters
- prefix:
- description: The `prefix` is aligned with the `inner` content of entries that have level one less. In the default show rule, this is just `it.prefix()`, but it can be freely customized.
- type: none | content
- default: None
- inner:
- description: The formatted inner content of the entry. In the default show rule, this is just `it.inner()`, but it can be freely customized.
- type: content
- default: None
- gap:
- description: The gap between the prefix and the inner content.
- type: length
- default: 0.5em
##### entry.prefix
Formats the element's numbering (if any).
This also appends the element's supplement in case of figures or equations. For instance, it would output `1.1` for a heading, but `Figure 1` for a figure, as is usual for outlines.
##### entry.inner
Creates the default inner content of the entry.
This includes the body, the fill, and page number.
##### entry.body
The content which is displayed in place of the referred element at its entry in the outline. For a heading, this is its [`body`](/docs/reference/model/heading/#parameters-body); for a figure a caption and for equations, it is empty.
##### entry.page
The page number of this entry's element, formatted with the numbering set for the referenced page.
docs/reference/model/par.md
# Paragraph
# par
A logical subdivison of textual content.
Typst automatically collects _inline-level_ elements into paragraphs. Inline-level elements include [text](/docs/reference/text/text/), [horizontal spacing](/docs/reference/layout/h/), [boxes](/docs/reference/layout/box/), and [inline equations](/docs/reference/math/equation/).
To separate paragraphs, use a blank line (or an explicit [`parbreak`](/docs/reference/model/parbreak/)). Paragraphs are also automatically interrupted by any block-level element (like [`block`](/docs/reference/layout/block/), [`place`](/docs/reference/layout/place/), or anything that shows itself as one of these).
The `par` element is primarily used in set rules to affect paragraph properties, but it can also be used to explicitly display its argument as a paragraph of its own. Then, the paragraph's body may not contain any block-level content.
## Boxes and blocks
As explained above, usually paragraphs only contain inline-level content. However, you can integrate any kind of block-level content into a paragraph by wrapping it in a [`box`](/docs/reference/layout/box/).
Conversely, you can separate inline-level content from a paragraph by wrapping it in a [`block`](/docs/reference/layout/block/). In this case, it will not become part of any paragraph at all. Read the following section for an explanation of why that matters and how it differs from just adding paragraph breaks around the content.
## What becomes a paragraph?
When you add inline-level content to your document, Typst will automatically wrap it in paragraphs. However, a typical document also contains some text that is not semantically part of a paragraph, for example in a heading or caption.
The rules for when Typst wraps inline-level content in a paragraph are as follows:
- All text at the root of a document is wrapped in paragraphs.
- Text in a container (like a `block`) is only wrapped in a paragraph if the container holds any block-level content. If all of the contents are inline-level, no paragraph is created.
In the laid-out document, it's not immediately visible whether text became part of a paragraph. However, it is still important for various reasons:
- Certain paragraph styling like `first-line-indent` will only apply to proper paragraphs, not any text. Similarly, `par` show rules of course only trigger on paragraphs.
- A proper distinction between paragraphs and other text helps people who rely on Assistive Technology (AT) (such as screen readers) navigate and understand the document properly.
- PDF export will generate a `P` tag only for paragraphs.
- HTML export will generate a `<p>` tag only for paragraphs.
When creating custom reusable components, you can and should take charge over whether Typst creates paragraphs. By wrapping text in a [`block`](/docs/reference/layout/block/) instead of just adding paragraph breaks around it, you can force the absence of a paragraph. Conversely, by adding a [`parbreak`](/docs/reference/model/parbreak/) after some content in a container, you can force it to become a paragraph even if it's just one word. This is, for example, what [non-`tight`](/docs/reference/model/list/#parameters-tight) lists do to force their items to become paragraphs.
## Example
```typst
#set par(
first-line-indent: 1em,
spacing: 0.65em,
justify: true,
)
We proceed by contradiction.
Suppose that there exists a set
of positive integers $a$, $b$, and
$c$ that satisfies the equation
$a^n + b^n = c^n$ for some
integer value of $n > 2$.
Without loss of generality,
let $a$ be the smallest of the
three integers. Then, we ...
```
```typst
#par(
leading: length,
spacing: length,
justify: bool,
justification-limits: dictionary,
linebreaks: auto | str,
first-line-indent: length | dictionary,
hanging-indent: length,
body
) -> content
```
## Parameters
- leading:
- description: The spacing between lines. Leading defines the spacing between the [bottom edge](/docs/reference/text/text/#parameters-bottom-edge) of one line and the [top edge](/docs/reference/text/text/#parameters-top-edge) of the following line. By default, these two properties are up to the font, but they can also be configured manually with a text set rule. By setting top edge, bottom edge, and leading, you can also configure a consistent baseline-to-baseline distance. You could, for instance, set the leading to `1em`, the top-edge to `0.8em`, and the bottom-edge to `-0.2em` to get a baseline gap of exactly `2em`. The exact distribution of the top- and bottom-edge values affects the bounds of the first and last line.
- type: length
- default: 0.65em
- spacing:
- description: The spacing between paragraphs. Just like leading, this defines the spacing between the bottom edge of a paragraph\'s last line and the top edge of the next paragraph\'s first line. When a paragraph is adjacent to a [`block`](/docs/reference/layout/block/) that is not a paragraph, that block\'s [`above`](/docs/reference/layout/block/#parameters-above) or [`below`](/docs/reference/layout/block/#parameters-below) property takes precedence over the paragraph spacing. Headings, for instance, reduce the spacing below them by default for a better look.
- type: length
- default: 1.2em
- justify:
- description: Whether to justify text in its line. Hyphenation will be enabled for justified paragraphs if the [text function\'s `hyphenate` property](/docs/reference/text/text/#parameters-hyphenate) is set to `auto` and the current language is known. Note that the current [alignment](/docs/reference/layout/align/#parameters-alignment) still has an effect on the placement of the last line except if it ends with a [justified line break](/docs/reference/text/linebreak/#parameters-justify). By default, Typst only changes the spacing between words to achieve justification. However, you can also allow it to adjust the spacing between individual characters using the [`justification-limits` property](/docs/reference/model/par/#parameters-justification-limits).
- type: bool
- default: false
- justification-limits:
- description: How much the spacing between words and characters may be adjusted during justification. When justifying text, Typst needs to stretch or shrink a line to the full width of the measure. To achieve this, by default, it adjusts the spacing between words. Additionally, it can also adjust the spacing between individual characters. This property allows you to configure lower and upper bounds for these adjustments. The property accepts a dictionary with two entries, `spacing` and `tracking`, each containing a dictionary with the keys `min` and `max`. The `min` keys define down to which lower bound gaps may be shrunk while the `max` keys define up to which upper bound they may be stretched. - The `spacing` entry defines how much the width of spaces between words may be adjusted. It is closely related to [`text.spacing`](/docs/reference/text/text/#parameters-spacing) and its `min` and `max` keys accept [relative lengths](/docs/reference/layout/relative/), just like the `spacing` property. A `min` value of `100%` means that spaces should retain their normal size (i.e. not be shrunk), while a value of `90% - 0.01em` would indicate that a space can be shrunk to a width of 90% of its normal width minus 0.01× the current font size. Similarly, a `max` value of `100% + 0.02em` means that a space\'s width can be increased by 0.02× the current font size. The ratio part must always be positive. The length part, meanwhile, must not be positive for `min` and not be negative for `max`. Note that spaces may still be expanded beyond the `max` value if there is no way to justify the line otherwise. However, other means of justification (e.g. spacing apart characters if the `tracking` entry is configured accordingly) are first used to their maximum. - The `tracking` entry defines how much the spacing between letters may be adjusted. It is closely related to [`text.tracking`](/docs/reference/text/text/#parameters-tracking) and its `min` and `max` keys accept [lengths](/docs/reference/layout/length/), just like the `tracking` property. Unlike `spacing`, it does not accept relative lengths because the base of the relative length would vary for each character, leading to an uneven visual appearance. The behavior compared to `spacing` is as if the base was `100%`. Otherwise, the `min` and `max` values work just like for `spacing`. A `max` value of `0.01em` means that additional spacing amounting to 0.01× of the current font size may be inserted between every pair of characters. Note that this also includes the gaps between spaces and characters, so for spaces the values of `tracking` act in addition to the values for `spacing`. If you only specify one of `spacing` or `tracking`, the other retains its previously set value (or the default if it was not previously set). If you want to enable character-level justification, a good value for the `min` and `max` keys is around `0.01em` to `0.02em` (negated for `min`). Using the same value for both gives a good baseline, but tweaking the two values individually may produce more balanced results, as demonstrated in the example below. Be careful not to set the bounds too wide, as it quickly looks unnatural. Using character-level justification is an impactful microtypographical technique that can improve the appearance of justified text, especially in narrow columns. Note though that character-level justification does not work with every font or language. For example, cursive fonts connect letters. Using character-level justification would lead to jagged connections. ```typst #let example(name) = columns(2, gutter: 10pt)[ #place(top, float: true, scope: "parent", strong(name)) /* Text from https://en.wikipedia.org/wiki/Anne_Bayley */ ] #set page(width: 440pt, height: 21em, margin: 15pt) #set par(justify: true) #set text(size: 0.8em) #grid( columns: (1fr, 1fr), gutter: 20pt, { // These are Typst\'s default limits. set par(justification-limits: ( spacing: (min: 100% * 2 / 3, max: 150%), tracking: (min: 0em, max: 0em), )) example[Word-level justification] }, { // These are our custom character-level limits. set par(justification-limits: ( tracking: (min: -0.01em, max: 0.02em), )) example[Character-level justification] }, ) ```
- type: dictionary
- default: (spacing : (min : 66.67 % + 0pt, max : 150 % + 0pt), tracking : (min : 0pt, max : 0pt),)
- linebreaks:
- description: How to determine line breaks. When this property is set to `auto`, its default value, optimized line breaks will be used for justified paragraphs. Enabling optimized line breaks for ragged paragraphs may also be worthwhile to improve the appearance of the text. ```typst #set page(width: 207pt) #set par(linebreaks: "simple") Some texts feature many longer words. Those are often exceedingly challenging to break in a visually pleasing way. #set par(linebreaks: "optimized") Some texts feature many longer words. Those are often exceedingly challenging to break in a visually pleasing way. ```
- type: auto | str
- default: auto
- first-line-indent:
- description: The indent the first line of a paragraph should have. By default, only the first line of a consecutive paragraph will be indented (not the first one in the document or container, and not paragraphs immediately following other block-level elements). If you want to indent all paragraphs instead, you can pass a dictionary containing the `amount` of indent as a length and the pair `all: true`. When `all` is omitted from the dictionary, it defaults to `false`. By typographic convention, paragraph breaks are indicated either by some space between paragraphs or by indented first lines. Consider - reducing the [paragraph `spacing`](/docs/reference/model/par/#parameters-spacing) to the [`leading`](/docs/reference/model/par/#parameters-leading) using `set par(spacing: 0.65em)` - increasing the [block `spacing`](/docs/reference/layout/block/#parameters-spacing) (which inherits the paragraph spacing by default) to the original paragraph spacing using `set block(spacing: 1.2em)` ```typst #set block(spacing: 1.2em) #set par( first-line-indent: 1.5em, spacing: 0.65em, ) The first paragraph is not affected by the indent. But the second paragraph is. #line(length: 100%) #set par(first-line-indent: ( amount: 1.5em, all: true, )) Now all paragraphs are affected by the first line indent. Even the first one. ```
- type: length | dictionary
- default: (amount : 0pt, all : false)
- hanging-indent:
- description: The indent that all but the first line of a paragraph should have. ```typst #set par(hanging-indent: 1em) #lorem(15) ```
- type: length
- default: 0pt
- body:
- description: The contents of the paragraph.
- type: content
- default: None
## Definitions
### par.line
A paragraph line.
This element is exclusively used for line number configuration through set rules and cannot be placed.
The [`numbering`](/docs/reference/model/par/#definitions-line-numbering) option is used to enable line numbers by specifying a numbering format.
```typst
#set par.line(numbering: "1")
Roses are red. \
Violets are blue. \
Typst is there for you.
```
The `numbering` option takes either a predefined [numbering pattern](/docs/reference/model/numbering/) or a function returning styled content. You can disable line numbers for text inside certain elements by setting the numbering to `none` using show-set rules.
```typst
// Styled red line numbers.
#set par.line(
numbering: n => text(red)[#n]
)
// Disable numbers inside figures.
#show figure: set par.line(
numbering: none
)
Roses are red. \
Violets are blue.
#figure(
caption: [Without line numbers.]
)[
Lorem ipsum \
dolor sit amet
]
The text above is a sample \
originating from distant times.
```
This element exposes further options which may be used to control other aspects of line numbering, such as its [alignment](/docs/reference/model/par/#definitions-line-number-align) or [margin](/docs/reference/model/par/#definitions-line-number-margin). In addition, you can control whether the numbering is reset on each page through the [`numbering-scope`](/docs/reference/model/par/#definitions-line-numbering-scope) option.
```typst
#par.line(
numbering: none | str | function,
number-align: auto | alignment,
number-margin: alignment,
number-clearance: auto | length,
numbering-scope: str
) -> content
```
#### Parameters
- numbering:
- description: How to number each line. Accepts a [numbering pattern or function](/docs/reference/model/numbering/) taking a single number. ```typst #set par.line(numbering: "I") Roses are red. \\ Violets are blue. \\ Typst is there for you. ``` ```typst #set par.line( numbering: i => if calc.rem(i, 5) == 0 or i == 1 { i }, ) #lorem(60) ```
- type: none | str | function
- default: none
- number-align:
- description: The alignment of line numbers associated with each line. The default of `auto` indicates a smart default where numbers grow horizontally away from the text, considering the margin they\'re in and the current text direction. ```typst #set par.line( numbering: "I", number-align: left, ) Hello world! \\ Today is a beautiful day \\ For exploring the world. ```
- type: auto | alignment
- default: auto
- number-margin:
- description: The margin at which line numbers appear. _Note:_ In a multi-column document, the line numbers for paragraphs inside the last column will always appear on the `end` margin (right margin for left-to-right text and left margin for right-to-left), regardless of this configuration. That behavior cannot be changed at this moment. ```typst #set par.line( numbering: "1", number-margin: right, ) = Report - Brightness: Dark, yet darker - Readings: Negative ```
- type: alignment
- default: start
- number-clearance:
- description: The distance between line numbers and text. The default value of `auto` results in a clearance that is adaptive to the page width and yields reasonable results in most cases. ```typst #set par.line( numbering: "1", number-clearance: 4pt, ) Typesetting \\ Styling \\ Layout ```
- type: auto | length
- default: auto
- numbering-scope:
- description: Controls when to reset line numbering. _Note:_ The line numbering scope must be uniform across each page run (a page run is a sequence of pages without an explicit pagebreak in between). For this reason, set rules for it should be defined before any page content, typically at the very start of the document. ```typst #set par.line( numbering: "1", numbering-scope: "page", ) First line \\ Second line #pagebreak() First line again \\ Second line again ```
- type: str
- default: "document"
docs/reference/model/parbreak.md
# Paragraph Break
# parbreak
A paragraph break.
This starts a new paragraph. Especially useful when used within code like [for loops](/docs/reference/scripting/#loops). Multiple consecutive paragraph breaks collapse into a single one.
## Example
```typst
#for i in range(3) {
[Blind text #i: ]
lorem(5)
parbreak()
}
```
## Syntax
Instead of calling this function, you can insert a blank line into your markup to create a paragraph break.
docs/reference/model/quote.md
# Quote
# quote
Displays a quote alongside an optional attribution.
## Example
```typst
Plato is often misquoted as the author of #quote[I know that I know
nothing], however, this is a derivation form his original quote:
#set quote(block: true)
#quote(attribution: [Plato])[
... ἔοικα γοῦν τούτου γε σμικρῷ τινι αὐτῷ τούτῳ σοφώτερος εἶναι, ὅτι
ἃ μὴ οἶδα οὐδὲ οἴομαι εἰδέναι.
]
#quote(attribution: [from the Henry Cary literal translation of 1897])[
... I seem, then, in just this little thing to be wiser than this man at
any rate, that what I do not know I do not think I know either.
]
```
By default block quotes are padded left and right by `1em`, alignment and padding can be controlled with show rules:
```typst
#set quote(block: true)
#show quote: set align(center)
#show quote: set pad(x: 5em)
#quote[
You cannot pass... I am a servant of the Secret Fire, wielder of the
flame of Anor. You cannot pass. The dark fire will not avail you,
flame of Udûn. Go back to the Shadow! You cannot pass.
]
```
```typst
#quote(
block: bool,
quotes: auto | bool,
attribution: none | label | content,
body
) -> content
```
## Parameters
- block:
- description: Whether this is a block quote. ```typst An inline citation would look like this: #quote( attribution: [René Descartes] )[ cogito, ergo sum ], and a block equation like this: #quote( block: true, attribution: [JFK] )[ Ich bin ein Berliner. ] ```
- type: bool
- default: false
- quotes:
- description: Whether double quotes should be added around this quote. The double quotes used are inferred from the `quotes` property on [smartquote](/docs/reference/text/smartquote/), which is affected by the `lang` property on [text](/docs/reference/text/text/). - `true`: Wrap this quote in double quotes. - `false`: Do not wrap this quote in double quotes. - `auto`: Infer whether to wrap this quote in double quotes based on the `block` property. If `block` is `false`, double quotes are automatically added. ```typst #set text(lang: "de") Ein deutsch-sprechender Author zitiert unter umständen JFK: #quote[Ich bin ein Berliner.] #set text(lang: "en") And an english speaking one may translate the quote: #quote[I am a Berliner.] ```
- type: auto | bool
- default: auto
- attribution:
- description: The attribution of this quote, usually the author or source. Can be a label pointing to a bibliography entry or any content. By default only displayed for block quotes, but can be changed using a `show` rule. ```typst #quote(attribution: [René Descartes])[ cogito, ergo sum ] #show quote.where(block: false): it => { ["] + h(0pt, weak: true) + it.body + h(0pt, weak: true) + ["] if it.attribution != none [ (#it.attribution)] } #quote( attribution: link("https://typst.app/home")[typst.app] )[ Compose papers faster ] #set quote(block: true) #quote(attribution: <tolkien54>)[ You cannot pass... I am a servant of the Secret Fire, wielder of the flame of Anor. You cannot pass. The dark fire will not avail you, flame of Udûn. Go back to the Shadow! You cannot pass. ] #bibliography("works.bib", style: "apa") ```
- type: none | label | content
- default: none
- body:
- description: The quote.
- type: content
- default: None
docs/reference/model/ref.md
# Reference
# ref
A reference to a label or bibliography.
Takes a label and cross-references it. There are two kind of references, determined by its [`form`](/docs/reference/model/ref/#parameters-form): `"normal"` and `"page"`.
The default, a `"normal"` reference, produces a textual reference to a label. For example, a reference to a heading will yield an appropriate string such as "Section 1" for a reference to the first heading. The word "Section" depends on the [`lang`](/docs/reference/text/text/#parameters-lang) setting and is localized accordingly. The references are also links to the respective element. Reference syntax can also be used to [cite](/docs/reference/model/cite/) from a bibliography.
As the default form requires a supplement and numbering, the label must be attached to a _referenceable element_. Referenceable elements include [headings](/docs/reference/model/heading/), [figures](/docs/reference/model/figure/), [equations](/docs/reference/math/equation/), and [footnotes](/docs/reference/model/footnote/). To create a custom referenceable element like a theorem, you can create a figure of a custom [`kind`](/docs/reference/model/figure/#parameters-kind) and write a show rule for it. In the future, there might be a more direct way to define a custom referenceable element.
If you just want to link to a labelled element and not get an automatic textual reference, consider using the [`link`](/docs/reference/model/link/) function instead.
A `"page"` reference produces a page reference to a label, displaying the page number at its location. You can use the [page's supplement](/docs/reference/layout/page/#parameters-supplement) to modify the text before the page number. Unlike a `"normal"` reference, the label can be attached to any element.
## Example
```typst
#set page(numbering: "1")
#set heading(numbering: "1.")
#set math.equation(numbering: "(1)")
= Introduction <intro>
Recent developments in
typesetting software have
rekindled hope in previously
frustrated researchers. @distress
As shown in @results (see
#ref(<results>, form: "page")),
we ...
= Results <results>
We discuss our approach in
comparison with others.
== Performance <perf>
@slow demonstrates what slow
software looks like.
$ T(n) = O(2^n) $ <slow>
#bibliography("works.bib")
```
## Syntax
This function also has dedicated syntax: A `"normal"` reference to a label can be created by typing an `@` followed by the name of the label (e.g. `= Introduction <intro>` can be referenced by typing `@intro`).
To customize the supplement, add content in square brackets after the reference: `@intro[Chapter]`.
## Customization
When you only ever need to reference pages of a figure/table/heading/etc. in a document, the default `form` field value can be changed to `"page"` with a set rule. If you prefer a short "p." supplement over "page", the [`page.supplement`](/docs/reference/layout/page/#parameters-supplement) field can be used for changing this:
```typst
#set page(
numbering: "1",
supplement: "p.",
)
#set ref(form: "page")
#figure(
stack(
dir: ltr,
spacing: 1em,
circle(),
square(),
),
caption: [Shapes],
) <shapes>
#pagebreak()
See @shapes for examples
of different shapes.
```
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.
```typst
#set heading(numbering: "1.")
#set math.equation(numbering: "(1)")
#show ref: it => {
let eq = math.equation
let el = it.element
// Skip all other references.
if el == none or el.func() != eq { return it }
// Override equation references.
link(el.location(), numbering(
el.numbering,
..counter(eq).at(el.location())
))
}
= Beginnings <beginning>
In @beginning we prove @pythagoras.
$ a^2 + b^2 = c^2 $ <pythagoras>
```
```typst
#ref(
target,
supplement: none | auto | content | function,
form: str
) -> content
```
## Parameters
- target:
- description: The target label that should be referenced. Can be a label that is defined in the document or, if the [`form`](/docs/reference/model/ref/#parameters-form) is set to `"normal"`, an entry from the [`bibliography`](/docs/reference/model/bibliography/).
- type: label
- default: None
- supplement:
- description: A supplement for the reference. If the [`form`](/docs/reference/model/ref/#parameters-form) is set to `"normal"`: - For references to headings or figures, this is added before the referenced number. - For citations, this can be used to add a page number. If the [`form`](/docs/reference/model/ref/#parameters-form) is set to `"page"`, then this is added before the page number of the label referenced. If a function is specified, it is passed the referenced element and should return content. ```typst #set heading(numbering: "1.") #show ref.where( form: "normal" ): set ref(supplement: it => { if it.func() == heading { "Chapter" } else { "Thing" } }) = Introduction <intro> In @intro, we see how to turn Sections into Chapters. And in @intro[Part], it is done manually. ```
- type: none | auto | content | function
- default: auto
- form:
- description: The kind of reference to produce. ```typst #set page(numbering: "1") Here <here> we are on #ref(<here>, form: "page"). ```
- type: str
- default: "normal"
docs/reference/model/strong.md
# Strong Emphasis
# strong
Strongly emphasizes content by increasing the font weight.
Increases the current font weight by a given `delta`.
## Example
```typst
This is *strong.* \
This is #strong[too.] \
#show strong: set text(red)
And this is *evermore.*
```
## Syntax
This function also has dedicated syntax: To strongly emphasize content, simply enclose it in stars/asterisks (`*`). Note that this only works at word boundaries. To strongly emphasize part of a word, you have to use the function.
```typst
#strong(
delta: int,
body
) -> content
```
## Parameters
- delta:
- description: The delta to apply on the font weight. ```typst #set strong(delta: 0) No *effect!* ```
- type: int
- default: 300
- body:
- description: The content to strongly emphasize.
- type: content
- default: None
docs/reference/model/table.md
# Table
# table
A table of items.
Tables are used to arrange content in cells. Cells can contain arbitrary content, including multiple paragraphs and are specified in row-major order. For a hands-on explanation of all the ways you can use and customize tables in Typst, check out the [Table Guide](/docs/guides/tables/).
Because tables are just grids with different defaults for some cell properties (notably `stroke` and `inset`), refer to the [grid documentation](/docs/reference/layout/grid/#track-size) for more information on how to size the table tracks and specify the cell appearance properties.
If you are unsure whether you should be using a table or a grid, consider whether the content you are arranging semantically belongs together as a set of related data points or similar or whether you are just want to enhance your presentation by arranging unrelated content in a grid. In the former case, a table is the right choice, while in the latter case, a grid is more appropriate. Furthermore, Assistive Technology (AT) like screen readers will announce content in a `table` as tabular while a grid's content will be announced no different than multiple content blocks in the document flow. AT users will be able to navigate tables two-dimensionally by cell.
Note that, to override a particular cell's properties or apply show rules on table cells, you can use the [`table.cell`](/docs/reference/model/table/#definitions-cell) element. See its documentation for more information.
Although the `table` and the `grid` share most properties, set and show rules on one of them do not affect the other. Locating most of your styling in set and show rules is recommended, as it keeps the table's actual usages clean and easy to read. It also allows you to easily change the appearance of all tables in one place.
To give a table a caption and make it [referenceable](/docs/reference/model/ref/), put it into a [figure](/docs/reference/model/figure/).
## Example
The example below demonstrates some of the most common table options.
```typst
#table(
columns: (1fr, auto, auto),
inset: 10pt,
align: horizon,
table.header(
[], [*Volume*], [*Parameters*],
),
image("cylinder.svg"),
$ pi h (D^2 - d^2) / 4 $,
[
$h$: height \
$D$: outer radius \
$d$: inner radius
],
image("tetrahedron.svg"),
$ sqrt(2) / 12 a^3 $,
[$a$: edge length]
)
```
Much like with grids, you can use [`table.cell`](/docs/reference/model/table/#definitions-cell) to customize the appearance and the position of each cell.
```typst
#set table(
stroke: none,
gutter: 0.2em,
fill: (x, y) =>
if x == 0 or y == 0 { gray },
inset: (right: 1.5em),
)
#show table.cell: it => {
if it.x == 0 or it.y == 0 {
set text(white)
strong(it)
} else if it.body == [] {
// Replace empty cells with 'N/A'
pad(..it.inset)[_N/A_]
} else {
it
}
}
#let a = table.cell(
fill: green.lighten(60%),
)[A]
#let b = table.cell(
fill: aqua.lighten(60%),
)[B]
#table(
columns: 4,
[], [Exam 1], [Exam 2], [Exam 3],
[John], [], a, [],
[Mary], [], a, a,
[Robert], b, a, b,
)
```
## Accessibility
Tables are challenging to consume for users of Assistive Technology (AT). To make the life of AT users easier, we strongly recommend that you use [`table.header`](/docs/reference/model/table/#definitions-header) and [`table.footer`](/docs/reference/model/table/#definitions-footer) to mark the header and footer sections of your table. This will allow AT to announce the column labels for each cell.
Because navigating a table by cell is more cumbersome than reading it visually, you should consider making the core information in your table available as text as well. You can do this by wrapping your table in a [figure](/docs/reference/model/figure/) and using its caption to summarize the table's content.
```typst
#table(
columns: auto | int | relative | fraction | array,
rows: auto | int | relative | fraction | array,
gutter: auto | int | relative | fraction | array,
column-gutter: auto | int | relative | fraction | array,
row-gutter: auto | int | relative | fraction | array,
inset: relative | array | dictionary | function,
align: auto | array | alignment | function,
fill: none | color | gradient | array | tiling | function,
stroke: none | length | color | gradient | array | stroke | tiling | dictionary | function,
children
) -> content
```
## Parameters
- columns:
- description: The column sizes. See the [grid documentation](/docs/reference/layout/grid/#track-size) for more information on track sizing.
- type: auto | int | relative | fraction | array
- default: ()
- rows:
- description: The row sizes. See the [grid documentation](/docs/reference/layout/grid/#track-size) for more information on track sizing.
- type: auto | int | relative | fraction | array
- default: ()
- gutter:
- description: The gaps between rows and columns. This is a shorthand for setting `column-gutter` and `row-gutter` to the same value. See the [grid documentation](/docs/reference/layout/grid/#parameters-gutter) for more information on gutters.
- type: auto | int | relative | fraction | array
- default: ()
- column-gutter:
- description: The gaps between columns. Takes precedence over `gutter`. See the [grid documentation](/docs/reference/layout/grid/#parameters-gutter) for more information on gutters.
- type: auto | int | relative | fraction | array
- default: ()
- row-gutter:
- description: The gaps between rows. Takes precedence over `gutter`. See the [grid documentation](/docs/reference/layout/grid/#parameters-gutter) for more information on gutters.
- type: auto | int | relative | fraction | array
- default: ()
- inset:
- description: How much to pad the cells\' content. To specify the same inset for all cells, use a single length for all sides, or a dictionary of lengths for individual sides. See the [box\'s documentation](/docs/reference/layout/box/#parameters-inset) for more details. To specify a varying inset for different cells, you can: - use a single, uniform inset for all cells - use an array of insets for each column - use a function that maps a cell\'s X/Y position (both starting from zero) to its inset See the [grid documentation](/docs/reference/layout/grid/#styling) for more details. ```typst #table( columns: 2, inset: 10pt, [Hello], [World], ) #table( columns: 2, inset: (x: 20pt, y: 10pt), [Hello], [World], ) ```
- type: relative | array | dictionary | function
- default: 0 % + 5pt
- align:
- description: How to align the cells\' content. If set to `auto`, the outer alignment is used. You can specify the alignment in any of the following fashions: - use a single alignment for all cells - use an array of alignments corresponding to each column - use a function that maps a cell\'s X/Y position (both starting from zero) to its alignment See the [Table Guide](/docs/guides/tables/#alignment) for details. ```typst #table( columns: 3, align: (left, center, right), [Hello], [Hello], [Hello], [A], [B], [C], ) ```
- type: auto | array | alignment | function
- default: auto
- fill:
- description: How to fill the cells. This can be: - a single fill for all cells - an array of fill corresponding to each column - a function that maps a cell\'s position to its fill Most notably, arrays and functions are useful for creating striped tables. See the [Table Guide](/docs/guides/tables/#fills) for more details. ```typst #table( fill: (x, _) => if calc.odd(x) { luma(240) } else { white }, align: (x, y) => if y == 0 { center } else if x == 0 { left } else { right }, columns: 4, [], [*Q1*], [*Q2*], [*Q3*], [Revenue:], [1000 €], [2000 €], [3000 €], [Expenses:], [500 €], [1000 €], [1500 €], [Profit:], [500 €], [1000 €], [1500 €], ) ```
- type: none | color | gradient | array | tiling | function
- default: none
- stroke:
- description: How to [stroke](/docs/reference/visualize/stroke/) the cells. Strokes can be disabled by setting this to `none`. If it is necessary to place lines which can cross spacing between cells produced by the [`gutter`](/docs/reference/model/table/#parameters-gutter) option, or to override the stroke between multiple specific cells, consider specifying one or more of [`table.hline`](/docs/reference/model/table/#definitions-hline) and [`table.vline`](/docs/reference/model/table/#definitions-vline) alongside your table cells. To specify the same stroke for all cells, use a single [stroke](/docs/reference/visualize/stroke/) for all sides, or a dictionary of [strokes](/docs/reference/visualize/stroke/) for individual sides. See the [rectangle\'s documentation](/docs/reference/visualize/rect/#parameters-stroke) for more details. To specify varying strokes for different cells, you can: - use a single stroke for all cells - use an array of strokes corresponding to each column - use a function that maps a cell\'s position to its stroke See the [Table Guide](/docs/guides/tables/#strokes) for more details.
- type: none | length | color | gradient | array | stroke | tiling | dictionary | function
- default: 1pt + black
- children:
- description: The contents of the table cells, plus any extra table lines specified with the [`table.hline`](/docs/reference/model/table/#definitions-hline) and [`table.vline`](/docs/reference/model/table/#definitions-vline) elements.
- type: content
- default: None
## Definitions
### table.cell
A cell in the table. Use this to position a cell manually or to apply styling. To do the latter, you can either use the function to override the properties for a particular cell, or use it in show rules to apply certain styles to multiple cells at once.
Perhaps the most important use case of `table.cell` is to make a cell span multiple columns and/or rows with the `colspan` and `rowspan` fields.
```typst
#show table.cell.where(y: 0): strong
#set table(
stroke: (x, y) => if y == 0 {
(bottom: 0.7pt + black)
},
align: (x, y) => (
if x > 0 { center }
else { left }
)
)
#table(
columns: 3,
table.header(
[Substance],
[Subcritical °C],
[Supercritical °C],
),
[Hydrochloric Acid],
[12.0], [92.1],
[Sodium Myreth Sulfate],
[16.6], [104],
[Potassium Hydroxide],
table.cell(colspan: 2)[24.7],
)
```
For example, you can override the fill, alignment or inset for a single cell:
```typst
// You can also import those.
#import table: cell, header
#table(
columns: 2,
align: center,
header(
[*Trip progress*],
[*Itinerary*],
),
cell(
align: right,
fill: fuchsia.lighten(80%),
[🚗],
),
[Get in, folks!],
[🚗], [Eat curbside hotdog],
cell(align: left)[🌴🚗],
cell(
inset: 0.06em,
text(1.62em)[🏝️🌅🌊],
),
)
```
You may also apply a show rule on `table.cell` to style all cells at once. Combined with selectors, this allows you to apply styles based on a cell's position:
```typst
#show table.cell.where(x: 0): strong
#table(
columns: 3,
gutter: 3pt,
[Name], [Age], [Strength],
[Hannes], [36], [Grace],
[Irma], [50], [Resourcefulness],
[Vikram], [49], [Perseverance],
)
```
```typst
#table.cell(
body,
x: auto | int,
y: auto | int,
colspan: int,
rowspan: int,
inset: auto | relative | dictionary,
align: auto | alignment,
fill: none | auto | color | gradient | tiling,
stroke: none | length | color | gradient | stroke | tiling | dictionary,
breakable: auto | bool
) -> content
```
#### Parameters
- body:
- description: The cell\'s body.
- type: content
- default: None
- x:
- description: The cell\'s column (zero-indexed). Functions identically to the `x` field in [`grid.cell`](/docs/reference/layout/grid/#definitions-cell).
- type: auto | int
- default: auto
- y:
- description: The cell\'s row (zero-indexed). Functions identically to the `y` field in [`grid.cell`](/docs/reference/layout/grid/#definitions-cell).
- type: auto | int
- default: auto
- colspan:
- description: The amount of columns spanned by this cell.
- type: int
- default: 1
- rowspan:
- description: The amount of rows spanned by this cell.
- type: int
- default: 1
- inset:
- description: The cell\'s [inset](/docs/reference/model/table/#parameters-inset) override.
- type: auto | relative | dictionary
- default: auto
- align:
- description: The cell\'s [alignment](/docs/reference/model/table/#parameters-align) override.
- type: auto | alignment
- default: auto
- fill:
- description: The cell\'s [fill](/docs/reference/model/table/#parameters-fill) override.
- type: none | auto | color | gradient | tiling
- default: auto
- stroke:
- description: The cell\'s [stroke](/docs/reference/model/table/#parameters-stroke) override.
- type: none | length | color | gradient | stroke | tiling | dictionary
- default: (:)
- breakable:
- description: Whether rows spanned by this cell can be placed in different pages. When equal to `auto`, a cell spanning only fixed-size rows is unbreakable, while a cell spanning at least one `auto`-sized row is breakable.
- type: auto | bool
- default: auto
### table.hline
A horizontal line in the table.
Overrides any per-cell stroke, including stroke specified through the table's `stroke` field. Can cross spacing between cells created through the table's [`column-gutter`](/docs/reference/model/table/#parameters-column-gutter) option.
Use this function instead of the table's `stroke` field if you want to manually place a horizontal line at a specific position in a single table. Consider using [table's `stroke`](/docs/reference/model/table/#parameters-stroke) field or [`table.cell`'s `stroke`](/docs/reference/model/table/#definitions-cell-stroke) field instead if the line you want to place is part of all your tables' designs.
```typst
#set table.hline(stroke: .6pt)
#table(
stroke: none,
columns: (auto, 1fr),
[09:00], [Badge pick up],
[09:45], [Opening Keynote],
[10:30], [Talk: Typst's Future],
[11:15], [Session: Good PRs],
table.hline(start: 1),
[Noon], [_Lunch break_],
table.hline(start: 1),
[14:00], [Talk: Tracked Layout],
[15:00], [Talk: Automations],
[16:00], [Workshop: Tables],
table.hline(),
[19:00], [Day 1 Attendee Mixer],
)
```
```typst
#table.hline(
y: auto | int,
start: int,
end: none | int,
stroke: none | length | color | gradient | stroke | tiling | dictionary,
position: alignment
) -> content
```
#### Parameters
- y:
- description: The row above which the horizontal line is placed (zero-indexed). Functions identically to the `y` field in [`grid.hline`](/docs/reference/layout/grid/#definitions-hline-y).
- type: auto | int
- default: auto
- start:
- description: The column at which the horizontal line starts (zero-indexed, inclusive).
- type: int
- default: 0
- end:
- description: The column before which the horizontal line ends (zero-indexed, exclusive).
- type: none | int
- default: none
- stroke:
- description: The line\'s stroke. Specifying `none` removes any lines previously placed across this line\'s range, including hlines or per-cell stroke below it.
- type: none | length | color | gradient | stroke | tiling | dictionary
- default: 1pt + black
- position:
- description: The position at which the line is placed, given its row (`y`) - either `top` to draw above it or `bottom` to draw below it. This setting is only relevant when row gutter is enabled (and shouldn\'t be used otherwise - prefer just increasing the `y` field by one instead), since then the position below a row becomes different from the position above the next row due to the spacing between both.
- type: alignment
- default: top
### table.vline
A vertical line in the table. See the docs for [`grid.vline`](/docs/reference/layout/grid/#definitions-vline) for more information regarding how to use this element's fields.
Overrides any per-cell stroke, including stroke specified through the table's `stroke` field. Can cross spacing between cells created through the table's [`row-gutter`](/docs/reference/model/table/#parameters-row-gutter) option.
Similar to [`table.hline`](/docs/reference/model/table/#definitions-hline), use this function if you want to manually place a vertical line at a specific position in a single table and use the [table's `stroke`](/docs/reference/model/table/#parameters-stroke) field or [`table.cell`'s `stroke`](/docs/reference/model/table/#definitions-cell-stroke) field instead if the line you want to place is part of all your tables' designs.
```typst
#table.vline(
x: auto | int,
start: int,
end: none | int,
stroke: none | length | color | gradient | stroke | tiling | dictionary,
position: alignment
) -> content
```
#### Parameters
- x:
- description: The column before which the vertical line is placed (zero-indexed). Functions identically to the `x` field in [`grid.vline`](/docs/reference/layout/grid/#definitions-vline).
- type: auto | int
- default: auto
- start:
- description: The row at which the vertical line starts (zero-indexed, inclusive).
- type: int
- default: 0
- end:
- description: The row on top of which the vertical line ends (zero-indexed, exclusive).
- type: none | int
- default: none
- stroke:
- description: The line\'s stroke. Specifying `none` removes any lines previously placed across this line\'s range, including vlines or per-cell stroke below it.
- type: none | length | color | gradient | stroke | tiling | dictionary
- default: 1pt + black
- position:
- description: The position at which the line is placed, given its column (`x`) - either `start` to draw before it or `end` to draw after it. The values `left` and `right` are also accepted, but discouraged as they cause your table to be inconsistent between left-to-right and right-to-left documents. This setting is only relevant when column gutter is enabled (and shouldn\'t be used otherwise - prefer just increasing the `x` field by one instead), since then the position after a column becomes different from the position before the next column due to the spacing between both.
- type: alignment
- default: start
### table.header
A repeatable table header.
You should wrap your tables' heading rows in this function even if you do not plan to wrap your table across pages because Typst uses this function to attach accessibility metadata to tables and ensure [Universal Access](/docs/guides/accessibility/#basics) to your document.
You can use the `repeat` parameter to control whether your table's header will be repeated across pages.
Currently, this function is unsuitable for creating a header column or single header cells. Either use regular cells, or, if you are exporting a PDF, you can also use the [`pdf.header-cell`](/docs/reference/pdf/header-cell/) function to mark a cell as a header cell. Likewise, you can use [`pdf.data-cell`](/docs/reference/pdf/data-cell/) to mark cells in this function as data cells. Note that these functions are not final and thus only available when you enable the `a11y-extras` feature (see the [PDF module documentation](/docs/reference/pdf/) for details).
```typst
#set page(height: 11.5em)
#set table(
fill: (x, y) =>
if x == 0 or y == 0 {
gray.lighten(40%)
},
align: right,
)
#show table.cell.where(x: 0): strong
#show table.cell.where(y: 0): strong
#table(
columns: 4,
table.header(
[], [Blue chip],
[Fresh IPO], [Penny st'k],
),
table.cell(
rowspan: 6,
align: horizon,
rotate(-90deg, reflow: true)[
*USD / day*
],
),
[0.20], [104], [5],
[3.17], [108], [4],
[1.59], [84], [1],
[0.26], [98], [15],
[0.01], [195], [4],
[7.34], [57], [2],
)
```
```typst
#table.header(
repeat: bool,
level: int,
children
) -> content
```
#### Parameters
- repeat:
- description: Whether this header should be repeated across pages.
- type: bool
- default: true
- level:
- description: The level of the header. Must not be zero. This allows repeating multiple headers at once. Headers with different levels can repeat together, as long as they have ascending levels. Notably, when a header with a lower level starts repeating, all higher or equal level headers stop repeating (they are "replaced" by the new header).
- type: int
- default: 1
- children:
- description: The cells and lines within the header.
- type: content
- default: None
### table.footer
A repeatable table footer.
Just like the [`table.header`](/docs/reference/model/table/#definitions-header) element, the footer can repeat itself on every page of the table. This is useful for improving legibility by adding the column labels in both the header and footer of a large table, totals, or other information that should be visible on every page.
No other table cells may be placed after the footer.
```typst
#table.footer(
repeat: bool,
children
) -> content
```
#### Parameters
- repeat:
- description: Whether this footer should be repeated across pages.
- type: bool
- default: true
- children:
- description: The cells and lines within the footer.
- type: content
- default: None
docs/reference/model/terms.md
# Term List
# terms
A list of terms and their descriptions.
Displays a sequence of terms and their descriptions vertically. When the descriptions span over multiple lines, they use hanging indent to communicate the visual hierarchy.
## Example
```typst
/ Ligature: A merged glyph.
/ Kerning: A spacing adjustment
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.
```typst
#terms(
tight: bool,
separator: content,
indent: length,
hanging-indent: length,
spacing: auto | length,
children
) -> content
```
## Parameters
- tight:
- description: Defines the default [spacing](/docs/reference/model/terms/#parameters-spacing) of the term list. If it is `false`, the items are spaced apart with [paragraph spacing](/docs/reference/model/par/#parameters-spacing). If it is `true`, they use [paragraph leading](/docs/reference/model/par/#parameters-leading) instead. This makes the list more compact, which can look better if the items are short. In markup mode, the value of this parameter is determined based on whether items are separated with a blank line. If items directly follow each other, this is set to `true`; if items are separated by a blank line, this is set to `false`. The markup-defined tightness cannot be overridden with set rules. ```typst / Fact: If a term list has a lot of text, and maybe other inline content, it should not be tight anymore. / Tip: To make it wide, simply insert a blank line between the items. ```
- type: bool
- default: true
- separator:
- description: The separator between the item and the description. If you want to just separate them with a certain amount of space, use `h(2cm, weak: true)` as the separator and replace `2cm` with your desired amount of space. ```typst #set terms(separator: [: ]) / Colon: A nice separator symbol. ```
- type: content
- default: h (amount : 0.6em, weak : true)
- indent:
- description: The indentation of each item.
- type: length
- default: 0pt
- hanging-indent:
- description: The hanging indent of the description. This is in addition to the whole item\'s `indent`. ```typst #set terms(hanging-indent: 0pt) / Term: This term list does not make use of hanging indents. ```
- type: length
- default: 2em
- spacing:
- description: The spacing between the items of the term list. If set to `auto`, uses paragraph [`leading`](/docs/reference/model/par/#parameters-leading) for tight term lists and paragraph [`spacing`](/docs/reference/model/par/#parameters-spacing) for wide (non-tight) term lists.
- type: auto | length
- default: auto
- children:
- description: The term list\'s children. When using the term list syntax, adjacent items are automatically collected into term lists, even through constructs like for loops. ```typst #for (year, product) in ( "1978": "TeX", "1984": "LaTeX", "2019": "Typst", ) [/ #product: Born in #year.] ```
- type: content | array
- default: None
## Definitions
### terms.item
A term list item.
```typst
#terms.item(
term,
description
) -> content
```
#### Parameters
- term:
- description: The term described by the list item.
- type: content
- default: None
- description:
- description: The description of the term.
- type: content
- default: None
docs/reference/model/title.md
# Title
# title
A document title.
This should be used to display the main title of the whole document and should occur only once per document. In contrast, level 1 [headings](/docs/reference/model/heading/) are intended to be used for the top-level sections of the document.
Note that additional frontmatter (like an author list) that should appear together with the title does not belong in its body.
In HTML export, this shows as a `h1` element while level 1 headings show as `h2` elements.
## Example
```typst
#set document(
title: [Interstellar Mail Delivery]
)
#title()
= Introduction
In recent years, ...
```
```typst
#title(
body
) -> content
```
## Parameters
- body:
- description: The content of the title. When omitted (or `auto`), this will default to [`document.title`](/docs/reference/model/document/#parameters-title). In this case, a document title must have been previously set with `set document(title: [..])`. ```typst #set document(title: "Course ABC, Homework 1") #title[Homework 1] ... ```
- type: auto | content
- default: auto
docs/reference/pdf/artifact.md
# Artifact
# pdf.artifact
Marks content as a PDF artifact.
Artifacts are parts of the document that are not meant to be read by Assistive Technology (AT), such as screen readers. Typical examples include purely decorative images that do not contribute to the meaning of the document, watermarks, or repeated content such as page numbers.
Typst will automatically mark certain content, such as page headers, footers, backgrounds, and foregrounds, as artifacts. Likewise, paths and shapes are automatically marked as artifacts, but their content is not. Repetitions of table headers and footers are also marked as artifacts.
Once something is marked as an artifact, you cannot make any of its contents accessible again. If you need to mark only part of something as an artifact, you may need to use this function multiple times.
If you are unsure what constitutes an artifact, check the [Accessibility Guide](/docs/guides/accessibility/#artifacts).
In the future, this function may be moved out of the `pdf` module, making it possible to hide content in HTML export from AT.
```typst
#pdf.artifact(
kind: str,
body
) -> content
```
## Parameters
- kind:
- description: The artifact kind. This will govern how the PDF reader treats the artifact during reflow and content extraction (e.g. copy and paste).
- type: str
- default: "other"
- body:
- description: The content that is an artifact.
- type: content
- default: None
docs/reference/pdf/attach.md
# Attach
# pdf.attach
A file that will be attached to the output PDF.
This can be used to distribute additional files associated with the PDF within it. PDF readers will display the files in a file listing.
Some international standards use this mechanism to attach machine-readable data (e.g., ZUGFeRD/Factur-X for invoices) that mirrors the visual content of the PDF.
## Example
```typst
#pdf.attach(
"experiment.csv",
relationship: "supplement",
mime-type: "text/csv",
description: "Raw Oxygen readings from the Arctic experiment",
)
```
## Notes
- This element is ignored if exporting to a format other than PDF.
- File attachments are not currently supported for PDF/A-2, even if the attached file conforms to PDF/A-1 or PDF/A-2.
```typst
#pdf.attach(
path,
data,
relationship: none | str,
mime-type: none | str,
description: none | str
) -> content
```
## Parameters
- path:
- description: The [path](/docs/reference/syntax/#paths) of the file to be attached. Must always be specified, but is only read from if no data is provided in the following argument.
- type: str
- default: None
- data:
- description: Raw file data, optionally. If omitted, the data is read from the specified path.
- type: bytes
- default: None
- relationship:
- description: The relationship of the attached file to the document. Ignored if export doesn\'t target PDF/A-3.
- type: none | str
- default: none
- mime-type:
- description: The MIME type of the attached file.
- type: none | str
- default: none
- description:
- description: A description for the attached file.
- type: none | str
- default: none
docs/reference/pdf/data-cell.md
# Data Cell
# pdf.data-cell
Explicitly defines this cell as a data cell.
Each cell in a table is either a header cell or a data cell. By default, all cells in [`table.header`](/docs/reference/model/table/#definitions-header) are header cells, and all other cells data cells.
If your header contains a cell that is not a header cell, you can use this function to mark it as a data cell.
The API of this feature is temporary. Hence, calling this function requires enabling the `a11y-extras` feature flag at the moment. In a future Typst release, this functionality may move out of the `pdf` module so that tables in other export targets can contain the same information.
```typst
#show table.cell.where(x: 0): set text(weight: "bold")
#show table.cell.where(x: 1): set text(style: "italic")
#show table.cell.where(x: 1, y: 0): set text(style: "normal")
#table(
columns: 3,
align: (left, left, center),
table.header[Objective][Key Result][Status],
table.header(
level: 2,
table.cell(colspan: 2)[Improve Customer Satisfaction],
// Status is data for this objective, not a header
pdf.data-cell[✓ On Track],
),
[], [Increase NPS to 50+], [45],
[], [Reduce churn to \<5%], [4.2%],
table.header(
level: 2,
table.cell(colspan: 2)[Grow Revenue],
pdf.data-cell[⚠ At Risk],
),
[], [Achieve \$2M ARR], [\$1.8M],
[], [Close 50 enterprise deals], [38],
)
```
```typst
#pdf.data-cell(
cell
) -> content
```
## Parameters
- cell:
- description: The table cell. This can be content or a call to [`table.cell`](/docs/reference/model/table/#definitions-cell).
- type: content
- default: None
docs/reference/pdf/header-cell.md
# Header Cell
# pdf.header-cell
Explicitly defines a cell as a header cell.
Header cells help users of Assistive Technology (AT) understand and navigate complex tables. When your table is correctly marked up with header cells, AT can announce the relevant header information on-demand when entering a cell.
By default, Typst will automatically mark all cells within [`table.header`](/docs/reference/model/table/#definitions-header) as header cells. They will apply to the columns below them. You can use that function's [`level`](/docs/reference/model/table/#definitions-header-level) parameter to make header cells labelled by other header cells.
The `pdf.header-cell` function allows you to indicate that a cell is a header cell in the following additional situations:
- You have a **header column** in which each cell applies to its row. In that case, you pass `"row"` as an argument to the [`scope` parameter](/docs/reference/pdf/header-cell/#parameters-scope) to indicate that the header cell applies to the row.
- You have a cell in [`table.header`](/docs/reference/model/table/#definitions-header), for example at the very start, that labels both its row and column. In that case, you pass `"both"` as an argument to the [`scope`](/docs/reference/pdf/header-cell/#parameters-scope) parameter.
- You have a header cell in a row not containing other header cells. In that case, you can use this function to mark it as a header cell.
The API of this feature is temporary. Hence, calling this function requires enabling the `a11y-extras` feature flag at the moment. In a future Typst release, this functionality may move out of the `pdf` module so that tables in other export targets can contain the same information.
```typst
#show table.cell.where(x: 0): set text(weight: "medium")
#show table.cell.where(y: 0): set text(weight: "bold")
#table(
columns: 3,
align: (start, end, end),
table.header(
// Top-left cell: Labels both the nutrient rows
// and the serving size columns.
pdf.header-cell(scope: "both")[Nutrient],
[Per 100g],
[Per Serving],
),
// First column cells are row headers
pdf.header-cell(scope: "row")[Calories],
[250 kcal], [375 kcal],
pdf.header-cell(scope: "row")[Protein],
[8g], [12g],
pdf.header-cell(scope: "row")[Fat],
[12g], [18g],
pdf.header-cell(scope: "row")[Carbs],
[30g], [45g],
)
```
```typst
#pdf.header-cell(
level: int,
scope: str,
cell
) -> content
```
## Parameters
- level:
- description: The nesting level of this header cell.
- type: int
- default: 1
- scope:
- description: What track of the table this header cell applies to.
- type: str
- default: "column"
- cell:
- description: The table cell. This can be content or a call to [`table.cell`](/docs/reference/model/table/#definitions-cell).
- type: content
- default: None
docs/reference/pdf/index.md
# PDF
PDF files focus on accurately describing documents visually, but also have facilities for annotating their structure. This hybrid approach makes them a good fit for document exchange: They render exactly the same on every device, but also support extraction of a document's content and structure (at least to an extent). Unlike PNG files, PDFs are not bound to a specific resolution. Hence, you can view them at any size without incurring a loss of quality.
## Exporting as PDF
### Command Line
PDF is Typst's default export format. Running the `compile` or `watch` subcommand without specifying a format will create a PDF. When exporting to PDF, you have the following configuration options:
- Which [PDF standards](#pdf-standards) Typst should enforce conformance with by specifying `--pdf-standard` followed by one or multiple comma-separated standards. Valid standards are `1.4`, `1.5`, `1.6`, `1.7`, `2.0`, `a-1b`, `a-1a`, `a-2b`, `a-2u`, `a-2a`, `a-3b`, `a-3u`, `a-3a`, `a-4`, `a-4f`, `a-4e`, and `ua-1`. By default, Typst outputs PDF-1.7-compliant files.
- You can disable PDF tagging completely with `--no-pdf-tags`. By default, Typst will always write _Tagged PDF_ to provide a baseline level of accessibility. Using this flag, you can turn tags off. This will make your file inaccessible and prevent conformance with accessible conformance levels of PDF/A and all parts of PDF/UA.
- Which pages to export by specifying `--pages` followed by a comma-separated list of numbers or dash-separated number ranges. Ranges can be half-open. Example: `2,3,7-9,11-`.
### Web App
Click the quick download button at the top right to export a PDF with default settings. For further configuration, click "File" \> "Export as" \> "PDF" or click the downwards-facing arrow next to the quick download button and select "Export as PDF". When exporting to PDF, you have the following configuration options:
- Which PDF standards Typst should enforce conformance with. By default, Typst outputs PDF-1.7-compliant files. You can choose the PDF version freely between 1.4 and 2.0. Valid additional standards are `A-1b`, `A-1a`, `A-2b`, `A-2u`, `A-2a`, `A-3b`. `A-3u`, `A-3a`, `A-4`, `A-4f`, `A-4e`, and `UA-1`.
- Which pages to export. Valid options are "All pages", "Current page", and "Custom ranges". Custom ranges are a comma-separated list of numbers or dash-separated number ranges. Ranges can be half-open. Example: `2,3,7-9,11-`.
## PDF standards
The International Standards Organization (ISO) has published the base PDF standard and various standards that extend it to make PDFs more suitable for specific use-cases. By default, Typst exports PDF 1.7 files. Adobe Acrobat 8 and later as well as all other commonly used PDF viewers are compatible with this PDF version.
Some features of Typst may not be available depending on the PDF standard you choose. You currently cannot choose both PDF/A and PDF/UA at the same time.
### PDF versions
Typst supports five different PDF versions: 1.4, 1.5, 1.6, 1.7 (default), and 2.0. You can choose each of these versions for your document export. However, based on the features you used there may be a minimum version. Likewise, the standards you target can limit which versions you can choose (see below for more).
Here is a list on how each new version improves over PDF 1.4 for Typst documents:
- **PDF 1.5** (2003): Improved color management, text extraction, table accessibility, reflow, and emoji fonts
- **PDF 1.6** (2004): More flexible links
- **PDF 1.7** (2006): Allows [attachments](/docs/reference/pdf/attach/), improved reflow
- **PDF 2.0** (2017): Improved both metadata and tag semantics for accessibility
The software used to read your file must support your PDF version. Under normal circumstances, this poses no problem, but it can be a source of errors when working with older hardware. For general exchange, we recommend keeping the default PDF 1.7 setting or choosing PDF 2.0.
When using PDF files as [images](/docs/reference/visualize/image/) in your document, the export PDF version must equal or exceed the image file versions.
### PDF/UA
Typst supports writing PDF/UA-conformant files. PDF/UA files are designed for _Universal Access._ When you choose this PDF standard, Typst will run additional checks when exporting your document. These checks will make sure that you are following accessibility best practices. For example, it will make sure that all your images come with alternative descriptions.
Note that there are some rules in PDF/UA that are crucial for accessibility but cannot be automatically checked. Hence, when exporting a PDF/UA-1 document, make sure you did the following:
- If your document is written in a different language than English, make sure [set the text language](/docs/reference/text/text/#parameters-lang) before any content.
- Make sure to use Typst's semantic elements (like [headings](/docs/reference/model/heading/), [figures](/docs/reference/model/figure/), and [lists](/docs/reference/model/list/)) when appropriate instead of defining custom constructs. This lets Typst know (and export) the role a construct plays in the document. See [the Accessibility guide](/docs/guides/accessibility/) for more details.
- Do not exclusively use contrast, color, format, or layout to communicate an idea. Use text or alternative descriptions instead of or in addition to these elements.
- Wrap all decorative elements without a semantic meaning in [`pdf.artifact`](/docs/reference/pdf/artifact/).
- Do not use images of text. Instead, insert the text directly into your markup.
Typst currently only supports part one (PDF/UA-1) which is based on PDF 1.7 (2006). When exporting to PDF/UA-1, be aware that you will need to manually provide [alternative descriptions of mathematics](/docs/reference/math/#accessibility) in natural language.
New accessibility features were added to PDF 2.0 (2017). When set to PDF 2.0 export, Typst will leverage some of these features. PDF 2.0 and PDF/UA-1, however, are mutually incompatible. For accessible documents, we currently recommend exporting to PDF/UA-1 instead of PDF 2.0 for the additional checks and greater compatibility. The second part of PDF/UA is designed for PDF 2.0, but not yet supported by Typst.
### PDF/A
Typst optionally supports emitting PDF/A-conformant files. PDF/A files are geared towards maximum compatibility with current and future PDF tooling. They do not rely on difficult-to-implement or proprietary features and contain exhaustive metadata. This makes them suitable for long-term archival.
The PDF/A Standard has multiple versions (_parts_ in ISO terminology) and most parts have multiple profiles that indicate the file's conformance level. You can target one part and conformance level at a time. Currently, Typst supports these PDF/A output profiles:
- **PDF/A-1b:** The _basic_ conformance level of ISO 19005-1. This version of PDF/A is based on PDF 1.4 (2001) and results in self-contained, archivable PDF files. As opposed to later parts of the PDF/A standard, transparency is not allowed in PDF/A-1 files.
- **PDF/A-1a:** This is the _accessible_ conformance level that builds on the basic level PDF/A-1b. To conform to this level, your file must be an accessible _Tagged PDF_ file. Note that accessibility is improved with later parts as not all PDF accessibility features are available for PDF 1.4 files. Furthermore, all text in the file must consist of known Unicode code points.
- **PDF/A-2b:** The _basic_ conformance level of ISO 19005-2. This version of PDF/A is based on PDF 1.7 (2006) and results in self-contained, archivable PDF files.
- **PDF/A-2u:** This is the _Unicode-mappable_ conformance level that builds on the basic level A-2b. It also adds rules that all text in the document must consist of known Unicode code points. If possible, always prefer this standard over PDF/A-2b.
- **PDF/A-2a:** This is the _accessible_ conformance level that builds on the Unicode-mappable level A-2u. This conformance level also adds two requirements: Your file must be an accessible _Tagged PDF_ file. Typst automatically adds tags to help you reach this conformance level. Also pay attention to the Accessibility Sections throughout the reference and the [Accessibility Guide](/docs/guides/accessibility/) when targeting this conformance level. Finally, PDF/A-2a forbids you from using code points in the [Unicode Private Use area](https://en.wikipedia.org/wiki/Private_Use_Areas). If you want to build an accessible file, also consider additionally targeting PDF/UA-1, which enables more automatic accessibility checks.
- **PDF/A-3b:** The _basic_ conformance level of ISO 19005-3. This version of PDF/A is based on PDF 1.7 (2006) and results in archivable PDF files that can contain arbitrary other related files as [attachments](/docs/reference/pdf/attach/). The only difference between it and PDF/A-2b is the capability to attach non-PDF/A-conformant files.
- **PDF/A-3u:** This is the _Unicode-mappable_ conformance level that builds on the basic level A-3b. Just like PDF/A-2b, this requires all text to consist of known Unicode code points. These rules do not apply to attachments. If possible, always prefer this standard over PDF/A-3b.
- **PDF/A-3a:** This is the _accessible_ conformance level that builds on the Unicode-mappable level A-3u. Just like PDF/A-2a, this requires files to be accessible _Tagged PDF_ and to not use characters from the Unicode Private Use area. Just like before, these rules do not apply to attachments.
- **PDF/A-4:** The basic conformance level of ISO 19005-4. This version of PDF/A is based on PDF 2.0 (2017) and results in self-contained, archivable PDF files. PDF/A-4 has no parts relating to accessibility. Instead, the topic has been elaborated on more in the dedicated PDF/UA standard. PDF/A-4 files can conform to PDF/UA-2 (currently not supported in Typst).
- **PDF/A-4f:** The _embedded files_ conformance level that builds on the basic level A-4. Files conforming to this level can contain arbitrary other related files as [attachments](/docs/reference/pdf/attach/), just as files conforming to part 3 of ISO 19005. The only difference between it and PDF/A-4 is the capability to attach non-PDF/A-conformant files.
- **PDF/A-4e:** The _engineering_ conformance level that builds on the embedded files level A-4f. Files conforming to this level can contain 3D objects. Typst does not support 3D content, so this is functionally equivalent to PDF/A-4f from a Typst perspective.
If you want to target PDF/A but are unsure about which particular setting to use, there are some good rules of thumb. First, you must determine your **part,** that's the "version number" of the standard. Ask yourself these questions:
1. **Does pre-2006 software or equipment need to be able to read my file?** If so, choose part one (PDF/A-1).
2. **If not, does my file need attachments?** If so, you must choose part three (PDF/A-3) or the embedded files level of part four (PDF/A-4f).
3. **Does your file need to use features introduced in PDF 2.0?** Currently, use of PDF 2.0 features in Typst is limited to minor improvements in accessibility, e.g. for the [title element](/docs/reference/model/title/). If you can do without these improvements, maximize compatibility by choosing part two (when you don't need attachments) or part three (when you do need attachments). If you rely on PDF 2.0 features, use part four.
Now, you only need to choose a **conformance level** (the lowercase letter at the end).
- **If you decided on part one, two, or three,** you should typically choose the accessible conformance level of your part, indicated by a lowercase `a` at the end. If your document is inherently inaccessible, e.g. an artist's portfolio that cannot be boiled down to alternative descriptions, choose conformance level `u` instead. Only if this results in a compiler error, e.g. because you used code points from the Unicode Private Use Area, use the basic level `b`.
- **If you have chosen part four,** you should choose the basic conformance level (PDF/A-4) except when needing to embed files.
When choosing between exporting PDF/A and regular PDF, keep in mind that PDF/A files contain additional metadata, and that some readers will prevent the user from modifying a PDF/A file.
## PDF-specific functionality
Typst exposes PDF-specific functionality in the global `pdf` module. See below for the definitions it contains.
This module contains some functions without a final API. They are designed to enhance accessibility for documents with complex tables. This includes [`table-summary`](/docs/reference/pdf/table-summary/), [`header-cell`](/docs/reference/pdf/header-cell/), and [`data-cell`](/docs/reference/pdf/data-cell/). All of these functions will be removed in a future Typst release, either through integration into table functions or through full removal. You can enable these functions by passing `--features a11y-extras` or setting the `TYPST_FEATURES` environment variable to `a11y-extras`. In the web app, these features are not available at this time.
## Definitions
| Name | Description |
| --- | --- |
| [`artifact`](/reference/pdf/artifact/) | Marks content as a PDF artifact. |
| [`attach`](/reference/pdf/attach/) | A file that will be attached to the output PDF. |
| [`data-cell`](/reference/pdf/data-cell/) | Explicitly defines this cell as a data cell. |
| [`header-cell`](/reference/pdf/header-cell/) | Explicitly defines a cell as a header cell. |
| [`table-summary`](/reference/pdf/table-summary/) | A summary of the purpose and structure of a complex table. |
docs/reference/pdf/table-summary.md
# Table Summary
# pdf.table-summary
A summary of the purpose and structure of a complex table.
This will be available for Assistive Technology (AT), such as screen readers, when exporting to PDF, but not for sighted readers of your file.
This field is intended for instructions that help the user navigate the table using AT. It is not an alternative description, so do not duplicate the contents of the table within. Likewise, do not use this for the core takeaway of the table. Instead, include that in the text around the table or, even better, in a [figure caption](/docs/reference/model/figure/#definitions-caption).
If in doubt whether your table is complex enough to warrant a summary, err on the side of not including one. If you are certain that your table is complex enough, consider whether a sighted user might find it challenging. They might benefit from the instructions you put here, so consider printing them visibly in the document instead.
The API of this feature is temporary. Hence, calling this function requires enabling the `a11y-extras` feature flag at the moment. Even if this functionality should be available without a feature flag in the future, the summary will remain exclusive to PDF export.
```typst
#figure(
pdf.table-summary(
// The summary just provides orientation and structural
// information for AT users.
summary: "The first two columns list the names of each participant. The last column contains cells spanning multiple rows for their assigned group.",
table(
columns: 3,
table.header[First Name][Given Name][Group],
[Mike], [Davis], table.cell(rowspan: 3)[Sales],
[Anna], [Smith],
[John], [Johnson],
[Sara], [Wilkins], table.cell(rowspan: 2)[Operations],
[Tom], [Brown],
),
),
// This is the key takeaway of the table, so we put it in the caption.
caption: [The Sales org now has a new member],
)
```
```typst
#pdf.table-summary(
summary: str,
table
) -> content
```
## Parameters
- summary:
- description:
- type: str
- default: None
- table:
- description: The table.
- type: content
- default: None
docs/reference/png.md
# PNG
Instead of creating a PDF, Typst can also directly render pages to PNG raster graphics. PNGs are losslessly compressed images that can contain one page at a time. When exporting a multi-page document, Typst will emit multiple PNGs. PNGs are a good choice when you want to use Typst's output in an image editing software or when you can use none of Typst's other export formats.
In contrast to Typst's other export formats, PNGs are bound to a specific resolution. When exporting to PNG, you can configure the resolution as pixels per inch (PPI). If the medium you view the PNG on has a finer resolution than the PNG you exported, you will notice a loss of quality. Typst calculates the resolution of your PNGs based on each page's physical dimensions and the PPI. If you need guidance for choosing a PPI value, consider the following:
- A value of 300 or 600 is typical for desktop printing.
- Professional prints of detailed graphics can go up to 1200 PPI.
- If your document is only viewed at a distance, e.g. a poster, you may choose a smaller value than 300.
- If your document is viewed on screens, a typical PPI value for a smartphone is 400-500.
Because PNGs only contain a pixel raster, the text within cannot be extracted automatically (without OCR), for example by copy/paste or a screen reader. If you need the text to be accessible, export a PDF or HTML file instead.
PNGs can have transparent backgrounds. By default, Typst will output a PNG with an opaque white background. You can make the background transparent using `#set page(fill: none)`. Learn more on the [`page` function's reference page](/docs/reference/layout/page/#parameters-fill).
## Exporting as PNG
### Command Line
Pass `--format png` to the `compile` or `watch` subcommand or provide an output file name that ends with `.png`.
If your document has more than one page, Typst will create multiple image files. The output file name must then be a template string containing at least one of
- `\{p\}`, which will be replaced by the page number
- `\{0p\}`, which will be replaced by the zero-padded page number (so that all numbers have the same length)
- `\{t\}`, which will be replaced by the total number of pages
When exporting to PNG, you have the following configuration options:
- Which resolution to render at by specifying `--ppi` followed by a number of pixels per inch. The default is `144`.
- Which pages to export by specifying `--pages` followed by a comma-separated list of numbers or dash-separated number ranges. Ranges can be half-open. Example: `2,3,7-9,11-`.
### Web App
Click "File" \> "Export as" \> "PNG" or click the downwards-facing arrow next to the quick download button and select "Export as PNG". When exporting to PNG, you have the following configuration options:
- The resolution at which the pages should be rendered, as a number of pixels per inch. The default is `144`.
- Which pages to export. Valid options are "All pages", "Current page", and "Custom ranges". Custom ranges are a comma-separated list of numbers or dash-separated number ranges. Ranges can be half-open. Example: `2,3,7-9,11-`.
docs/reference/scripting.md
# Scripting
Typst embeds a powerful scripting language. You can automate your documents and create more sophisticated styles with code. Below is an overview over the scripting concepts.
## Expressions
In Typst, markup and code are fused into one. All but the most common elements are created with _functions._ To make this as convenient as possible, Typst provides compact syntax to embed a code expression into markup: An expression is introduced with a hash (`#`) and normal markup parsing resumes after the expression is finished. If a character would continue the expression but should be interpreted as text, the expression can forcibly be ended with a semicolon (`;`). You can [escape a literal `#` or `;` with a backslash](/docs/reference/syntax/#escapes).
```typst
#emph[Hello] \
#emoji.face \
#"hello".len()
```
The example above shows a few of the available expressions, including [function calls](/docs/reference/foundations/function/), [field accesses](/docs/reference/scripting/#fields), and [method calls](/docs/reference/scripting/#methods). More kinds of expressions are discussed in the remainder of this chapter. A few kinds of expressions are not compatible with the hash syntax (e.g. binary operator expressions). To embed these into markup, you can use parentheses, as in `#(1 + 2)`.
## Blocks
To structure your code and embed markup into it, Typst provides two kinds of _blocks:_
- **Code block:** `\{ let x = 1; x + 2 \}` When writing code, you'll probably want to split up your computation into multiple statements, create some intermediate variables and so on. Code blocks let you write multiple expressions where one is expected. The individual expressions in a code block should be separated by line breaks or semicolons. The output values of the individual expressions in a code block are joined to determine the block's value. Expressions without useful output, like `let` bindings yield `none`, which can be joined with any value without effect.
- **Content block:** `[*Hey* there!]` With content blocks, you can handle markup/content as a programmatic value, store it in variables and pass it to [functions](/docs/reference/foundations/function/). Content blocks are delimited by square brackets and can contain arbitrary markup. A content block results in a value of type [content](/docs/reference/foundations/content/). An arbitrary number of content blocks can be passed as trailing arguments to functions. That is, `list([A], [B])` is equivalent to `list[A][B]`.
Content and code blocks can be nested arbitrarily. In the example below, `[hello ]` is joined with the output of `a + [ the ] + b` yielding `[hello from the *world*]`.
```typst
#{
let a = [from]
let b = [*world*]
[hello ]
a + [ the ] + b
}
```
## Bindings and Destructuring
As already demonstrated above, variables can be defined with `let` bindings. The variable is assigned the value of the expression that follows the `=` sign. A [valid variable name](#identifiers) may contain `-`, but cannot start with `-`. The assignment of a value is optional, if no value is assigned, the variable will be initialized as `none`. The `let` keyword can also be used to create a [custom named function](/docs/reference/foundations/function/#defining-functions). Variables can be accessed for the rest of the containing block (or the rest of the file if there is no containing block).
```typst
#let name = "Typst"
This is #name's documentation.
It explains #name.
#let my-add(x, y) = x + y
Sum is #my-add(2, 3).
```
Let bindings can also be used to destructure [arrays](/docs/reference/foundations/array/) and [dictionaries](/docs/reference/foundations/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.
```typst
#let (x, y) = (1, 2)
The coordinates are #x, #y.
#let (a, .., b) = (1, 2, 3, 4)
The first element is #a.
The last element is #b.
#let books = (
Shakespeare: "Hamlet",
Homer: "The Odyssey",
Austen: "Persuasion",
)
#let (Austen,) = books
Austen wrote #Austen.
#let (Homer: h) = books
Homer wrote #h.
#let (Homer, ..other) = books
#for (author, title) in other [
#author wrote #title.
]
```
You can use the underscore to discard elements in a destructuring pattern:
```typst
#let (_, y, _) = (1, 2, 3)
The y coordinate is #y.
```
Destructuring also works in argument lists of functions ...
```typst
#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.
```typst
#{
let a = 1
let b = 2
(a, b) = (b, a)
[a = #a, b = #b]
}
```
## Conditionals
With a conditional, you can display or compute different things depending on whether some condition is fulfilled. Typst supports `if`, `else if` and `else` expressions. When the condition evaluates to `true`, the conditional yields the value resulting from the if's body, otherwise yields the value resulting from the else's body.
```typst
#if 1 < 2 [
This is shown
] else [
This is not.
]
```
Each branch can have a code or content block as its body.
- `if condition \{..\}`
- `if condition [..]`
- `if condition [..] else \{..\}`
- `if condition [..] else if condition \{..\} else [..]`
## Loops
With loops, you can repeat content or compute something iteratively. Typst supports two types of loops: `for` and `while` loops. The former iterate over a specified collection whereas the latter iterate as long as a condition stays fulfilled. Just like blocks, loops _join_ the results from each iteration into one value.
In the example below, the three sentences created by the for loop join together into a single content value and the length-1 arrays in the while loop join together into one larger array.
```typst
#for c in "ABC" [
#c is a letter.
]
#let n = 2
#while n < 10 {
n = (n * 2) - 1
(n,)
}
```
For loops can iterate over a variety of collections:
- `for value in array \{..\}` Iterates over the items in the [array](/docs/reference/foundations/array/). The destructuring syntax described in [Let binding](/docs/reference/scripting/#bindings) can also be used here.
- `for pair in dict \{..\}` Iterates over the key-value pairs of the [dictionary](/docs/reference/foundations/dictionary/). The pairs can also be destructured by using `for (key, value) in dict \{..\}`. It is more efficient than `for pair in dict.pairs() \{..\}` because it doesn't create a temporary array of all key-value pairs.
- `for letter in "abc" \{..\}` Iterates over the characters of the [string](/docs/reference/foundations/str/). Technically, it iterates over the grapheme clusters of the string. Most of the time, a grapheme cluster is just a single codepoint. However, a grapheme cluster could contain multiple codepoints, like a flag emoji.
- `for byte in bytes("😀") \{..\}` Iterates over the [bytes](/docs/reference/foundations/bytes/), which can be converted from a [string](/docs/reference/foundations/str/) or [read](/docs/reference/data-loading/read/) from a file without encoding. Each byte value is an [integer](/docs/reference/foundations/int/) between `0` and `255`.
To control the execution of the loop, Typst provides the `break` and `continue` statements. The former performs an early exit from the loop while the latter skips ahead to the next iteration of the loop.
```typst
#for letter in "abc nope" {
if letter == " " {
break
}
letter
}
```
The body of a loop can be a code or content block:
- `for .. in collection \{..\}`
- `for .. in collection [..]`
- `while condition \{..\}`
- `while condition [..]`
## Fields
You can use _dot notation_ to access fields on a value. For values of type [`content`](/docs/reference/foundations/content/), you can also use the [`fields`](/docs/reference/foundations/content/#definitions-fields) function to list the fields.
The value in question can be either:
- a [dictionary](/docs/reference/foundations/dictionary/) that has the specified key,
- a [symbol](/docs/reference/foundations/symbol/) that has the specified modifier,
- a [module](/docs/reference/foundations/module/) containing the specified definition,
- [content](/docs/reference/foundations/content/) consisting of an element that has the specified field. The available fields match the arguments of the [element function](/docs/reference/foundations/function/#element-functions) that were given when the element was constructed.
```typst
#let it = [= Heading]
#it.body \
#it.depth \
#it.fields()
#let dict = (greet: "Hello")
#dict.greet \
#emoji.face
```
## Methods
A _method call_ is a convenient way to call a function that is scoped to a value's [type](/docs/reference/foundations/type/). For example, we can call the [`str.len`](/docs/reference/foundations/str/#definitions-len) function in the following two equivalent ways:
```typst
#str.len("abc") is the same as
#"abc".len()
```
The structure of a method call is `value.method(..args)` and its equivalent full function call is `type(value).method(value, ..args)`. The documentation of each type lists its scoped functions. You cannot currently define your own methods.
```typst
#let values = (1, 2, 3, 4)
#values.pop() \
#values.len() \
#("a, b, c"
.split(", ")
.join[ --- ])
#"abc".len() is the same as
#str.len("abc")
```
There are a few special functions that modify the value they are called on (e.g. [`array.push`](/docs/reference/foundations/array/#definitions-push)). These functions _must_ be called in method form. In some cases, when the method is only called for its side effect, its return value should be ignored (and not participate in joining). The canonical way to discard a value is with a let binding: `let _ = array.remove(1)`.
## Modules
You can split up your Typst projects into multiple files called _modules._ A module can refer to the content and definitions of another module in multiple ways:
- **Including:** `include "bar.typ"` Evaluates the file at the path `bar.typ` and returns the resulting [content](/docs/reference/foundations/content/).
- **Import:** `import "bar.typ"` Evaluates the file at the path `bar.typ` and inserts the resulting [module](/docs/reference/foundations/module/) into the current scope as `bar` (filename without extension). You can use the `as` keyword to rename the imported module: `import "bar.typ" as baz`. You can import nested items using dot notation: `import "bar.typ": baz.a`.
- **Import items:** `import "bar.typ": a, b` Evaluates the file at the path `bar.typ`, extracts the values of the variables `a` and `b` (that need to be defined in `bar.typ`, e.g. through `let` bindings) and defines them in the current file. Replacing `a, b` with `*` loads all variables defined in a module. You can use the `as` keyword to rename the individual items: `import "bar.typ": a as one, b as two`
Instead of a path, you can also use a [module value](/docs/reference/foundations/module/), as shown in the following example:
```typst
#import emoji: face
#face.grin
```
## Packages
To reuse building blocks across projects, you can also create and import Typst _packages._ A package import is specified as a triple of a namespace, a name, and a version.
```typst
#import "@preview/example:0.1.0": add
#add(2, 7)
```
The `preview` namespace contains packages shared by the community. You can find all available community packages on [Typst Universe](https://typst.app/universe/).
If you are using Typst locally, you can also create your own system-local packages. For more details on this, see the [package repository](https://github.com/typst/packages).
## Operators
The following table lists all available unary and binary operators with effect, arity (unary, binary) and precedence level (higher binds stronger). Some operations, such as [modulus](/docs/reference/foundations/calc/#functions-rem-euclid), do not have a special syntax and can be achieved using functions from the [`calc`](/docs/reference/foundations/calc/) module.
| Operator | Effect | Arity | Precedence |
| --- | --- | --- | --- |
| `-` | Negation | Unary | 7 |
| `+` | No effect (exists for symmetry) | Unary | 7 |
| `*` | Multiplication | Binary | 6 |
| `/` | Division | Binary | 6 |
| `+` | Addition | Binary | 5 |
| `-` | Subtraction | Binary | 5 |
| `==` | Check equality | Binary | 4 |
| `!=` | Check inequality | Binary | 4 |
| `<` | Check less-than | Binary | 4 |
| `<=` | Check less-than or equal | Binary | 4 |
| `>` | Check greater-than | Binary | 4 |
| `>=` | Check greater-than or equal | Binary | 4 |
| `in` | Check if in collection | Binary | 4 |
| `not in` | Check if not in collection | Binary | 4 |
| `not` | Logical "not" | Unary | 3 |
| `and` | Short-circuiting logical "and" | Binary | 3 |
| `or` | Short-circuiting logical "or" | Binary | 2 |
| `=` | Assignment | Binary | 1 |
| `+=` | Add-Assignment | Binary | 1 |
| `-=` | Subtraction-Assignment | Binary | 1 |
| `*=` | Multiplication-Assignment | Binary | 1 |
| `/=` | Division-Assignment | Binary | 1 |
docs/reference/styling.md
# Styling
Typst includes a flexible styling system that automatically applies styling of your choice to your document. With _set rules,_ you can configure basic properties of elements. This way, you create most common styles. However, there might not be a built-in property for everything you wish to do. For this reason, Typst further supports _show rules_ that can completely redefine the appearance of elements.
## Set rules
With set rules, you can customize the appearance of elements. They are written as a [function call](/docs/reference/foundations/function/) to an [element function](/docs/reference/foundations/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](/docs/reference/text/text/#parameters-font) and [heading numbering](/docs/reference/model/heading/#parameters-numbering).
```typst
#set heading(numbering: "I.")
#set text(
font: "New Computer Modern"
)
= Introduction
With set rules, you can style
your document.
```
A top level set rule stays in effect until the end of the file. When nested inside of a block, it is only in effect until the end of that block. With a block, you can thus restrict the effect of a rule to a particular segment of your document. Below, we use a content block to scope the list styling to one particular list.
```typst
This list is affected: #[
#set list(marker: [--])
- Dash
]
This one is not:
- Bullet
```
Sometimes, you'll want to apply a set rule conditionally. For this, you can use a _set-if_ rule.
```typst
#let task(body, critical: false) = {
set text(red) if critical
[- #body]
}
#task(critical: true)[Food today?]
#task(critical: false)[Work deadline]
```
## 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 [selector](/docs/reference/foundations/selector/), a colon and then a set rule. The most basic form of selector is an [element function](/docs/reference/foundations/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.
```typst
#show heading: set text(navy)
= This is navy-blue
But this stays black.
```
With show-set rules you can mix and match properties from different functions to achieve many different effects. But they still limit you to what is predefined in Typst. For maximum flexibility, you can instead write a _transformational_ show rule that defines how to format an element from scratch. To write such a show rule, replace the set rule after the colon with an arbitrary [function](/docs/reference/foundations/function/). This function receives the element in question and can return arbitrary content. The function is often defined inline as `it => ..` using the [unnamed function syntax](/docs/reference/foundations/function/#unnamed). The function's parameter is typically named `it` by convention.
The available [fields](/docs/reference/scripting/#fields) on the element passed to the function match the parameters of the respective element function. Below, we define a show rule that formats headings for a fantasy encyclopedia.
The show rule itself adds tilde characters around the title (these must be escaped with a backslash because otherwise they would indicate a non-breaking space), emphasizes the title with italics, and then displays the heading counter after the title.
For this example, we also wanted center alignment and a different font. While we could've added these set rules into the existing show rule, we instead added them as separate show-set rules. This is good practice because now these rules can still be overridden by later show-set rules in the document, keeping styling composable. In contrast, set rules within a transformational show rule would not be overridable anymore.
```typst
#set heading(numbering: "(I)")
#show heading: set align(center)
#show heading: set text(font: "Inria Serif")
#show heading: it => block[
\~
#emph(it.body)
#counter(heading).display(it.numbering)
\~
]
= Dragon
With a base health of 15, the dragon is the most
powerful creature.
= Manticore
While less powerful than the dragon, the manticore
gets extra style points.
```
Like set rules, show rules are in effect until the end of the current block or file.
Instead of a function, the right-hand side of a show rule can also take a literal string or content block that should be directly substituted for the element. And apart from a function, the left-hand side of a show rule can also take a number of other _selectors_ that define what to apply the transformation to:
- **Everything:** `show: rest => ..` Transform everything after the show rule. This is useful to apply a more complex layout to your whole document without wrapping everything in a giant function call.
- **Text:** `show "Text": ..` Style, transform or replace text.
- **Regex:** `show regex("\w+"): ..` Select and transform text with a regular expression for even more flexibility. See the documentation of the [`regex` type](/docs/reference/foundations/regex/) for details.
- **Function with fields:** `show heading.where(level: 1): ..` Transform only elements that have the specified fields. For example, you might want to only change the style of level-1 headings.
- **Label:** `show <intro>: ..` Select and transform elements that have the specified label. See the documentation of the [`label` type](/docs/reference/foundations/label/) for more details.
```typst
#show "Project": smallcaps
#show "badly": "great"
We started Project in 2019
and are still working on it.
Project is progressing badly.
```
docs/reference/svg.md
# SVG
Instead of creating a PDF, Typst can also directly render pages to scalable vector graphics (SVGs), which are the preferred format for embedding vector graphics in web pages. Like PDF files, SVGs display your document exactly how you have laid it out in Typst. Likewise, they share the benefit of not being bound to a specific resolution. Hence, you can print or view SVG files on any device without incurring a loss of quality. (Note that font printing quality may be better with a PDF.) In contrast to a PDF, an SVG cannot contain multiple pages. When exporting a multi-page document, Typst will emit multiple SVGs.
SVGs can represent text in two ways: By embedding the text itself and rendering it with the fonts available on the viewer's computer or by embedding the shapes of each glyph in the font used to create the document. To ensure that the SVG file looks the same across all devices it is viewed on, Typst chooses the latter method. This means that the text in the SVG cannot be extracted automatically, for example by copy/paste or a screen reader. If you need the text to be accessible, export a PDF or HTML file instead.
SVGs can have transparent backgrounds. By default, Typst will output an SVG with an opaque white background. You can make the background transparent using `#set page(fill: none)`. Learn more on the [`page` function's reference page](/docs/reference/layout/page/#parameters-fill).
## Exporting as SVG
### Command Line
Pass `--format svg` to the `compile` or `watch` subcommand or provide an output file name that ends with `.svg`.
If your document has more than one page, Typst will create multiple image files. The output file name must then be a template string containing at least one of
- `\{p\}`, which will be replaced by the page number
- `\{0p\}`, which will be replaced by the zero-padded page number (so that all numbers have the same length)
- `\{t\}`, which will be replaced by the total number of pages
When exporting to SVG, you have the following configuration options:
- Which pages to export by specifying `--pages` followed by a comma-separated list of numbers or dash-separated number ranges. Ranges can be half-open. Example: `2,3,7-9,11-`.
### Web App
Click "File" \> "Export as" \> "SVG" or click the downwards-facing arrow next to the quick download button and select "Export as SVG". When exporting to SVG, you have the following configuration options:
- Which pages to export. Valid options are "All pages", "Current page", and "Custom ranges". Custom ranges are a comma-separated list of numbers or dash-separated number ranges. Ranges can be half-open. Example: `2,3,7-9,11-`.
docs/reference/symbols/emoji.md
# Emoji
Named emojis.
For example, `#emoji.face` produces the 😀 emoji. If you frequently use certain emojis, you can also import them from the `emoji` module (`#import emoji: face`) to use them without the `emoji.` prefix.
| Symbol | Name | Math Class |
| ----- | ----- | ----- |
| 🔠 | ABCD | None |
| 🅰️ | a | None |
| 🆎 | ab | None |
| 🧮 | abacus | None |
| 🔤 | abc | None |
| 🔡 | abcd | None |
| 🪗 | accordion | None |
| ⚕️ | aesculapius | None |
| ✈️ | airplane | None |
| 🛬 | airplane.landing | None |
| 🛩️ | airplane.small | None |
| 🛫 | airplane.takeoff | None |
| ⚗️ | alembic | None |
| 👽️ | alien | None |
| 👾 | alien.monster | None |
| 🚑️ | ambulance | None |
| 🏺 | amphora | None |
| ⚓️ | anchor | None |
| 💢 | anger | None |
| 🐜 | ant | None |
| 🍏 | apple.green | None |
| 🍎 | apple.red | None |
| 🦾 | arm.mech | None |
| 💪 | arm.muscle | None |
| 🤳 | arm.selfie | None |
| ➡️ | arrow.r.filled | None |
| ↪️ | arrow.r.hook | Relation |
| 🔜 | arrow.r.soon | None |
| ⬅️ | arrow.l.filled | Relation |
| ↩️ | arrow.l.hook | Relation |
| 🔙 | arrow.l.back | None |
| 🔚 | arrow.l.end | None |
| ⬆️ | arrow.t.filled | Relation |
| ⤴️ | arrow.t.curve | Relation |
| 🔝 | arrow.t.top | None |
| ⬇️ | arrow.b.filled | Relation |
| ⤵️ | arrow.b.curve | Relation |
| ↔️ | arrow.l.r | Relation |
| 🔛 | arrow.l.r.on | None |
| ↕️ | arrow.t.b | Relation |
| ↙️ | arrow.bl | Relation |
| ↘️ | arrow.br | Relation |
| ↖️ | arrow.tl | Relation |
| ↗️ | arrow.tr | Relation |
| 🔄 | arrows.cycle | None |
| *️ | ast | Normal |
| ✳️ | ast.box | None |
| 🏧 | atm | None |
| ⚛️ | atom | None |
| 🍆 | aubergine | None |
| 🥑 | avocado | None |
| 🪓 | axe | None |
| 🅱️ | b | None |
| 👶 | baby | None |
| 👼 | baby.angel | None |
| 🚼️ | baby.box | None |
| 🍼 | babybottle | None |
| 🎒 | backpack | None |
| 🥓 | bacon | None |
| 🦡 | badger | None |
| 🏸 | badminton | None |
| 🥯 | bagel | None |
| 🛄 | baggageclaim | None |
| 🥖 | baguette | None |
| 🎈 | balloon | None |
| ☑️ | ballot.check | None |
| 🗳️ | ballotbox | None |
| 🍌 | banana | None |
| 🪕 | banjo | None |
| 🏦 | bank | None |
| 💈 | barberpole | None |
| ⚾️ | baseball | None |
| 🧢 | basecap | None |
| 🧺 | basket | None |
| ⛹️ | basketball | None |
| 🏀 | basketball.ball | None |
| 🦇 | bat | None |
| 🛀 | bathtub | None |
| 🛁 | bathtub.foam | None |
| 🔋 | battery | None |
| 🪫 | battery.low | None |
| 🏝️ | beach.palm | None |
| 🏖️ | beach.umbrella | None |
| 📿 | beads | None |
| 🫘 | beans | None |
| 🐻 | bear | None |
| 🦫 | beaver | None |
| 🛏️ | bed | None |
| 🛌 | bed.person | None |
| 🐝 | bee | None |
| 🍺 | beer | None |
| 🍻 | beer.clink | None |
| | beet | None |
| 🪲 | beetle | None |
| 🐞 | beetle.lady | None |
| 🔔 | bell | None |
| 🛎️ | bell.ding | None |
| 🔕 | bell.not | None |
| 🍱 | bento | None |
| 🚴 | bicyclist | None |
| 🚵 | bicyclist.mountain | None |
| 🚲️ | bike | None |
| 🚳 | bike.not | None |
| 👙 | bikini | None |
| 🎱 | billiards | None |
| 🗑️ | bin | None |
| ☣️ | biohazard | None |
| 🐦️ | bird | None |
| 🦬 | bison | None |
| 🩸 | blood | None |
| 👚 | blouse | None |
| 🐡 | blowfish | None |
| 🫐 | blueberries | None |
| 🐗 | boar | None |
| ⛵️ | boat.sail | None |
| 🚣 | boat.row | None |
| 🛥️ | boat.motor | None |
| 🚤 | boat.speed | None |
| 🛶 | boat.canoe | None |
| 🔩 | bolt | None |
| 💣️ | bomb | None |
| 🦴 | bone | None |
| 📕 | book.red | None |
| 📘 | book.blue | None |
| 📗 | book.green | None |
| 📙 | book.orange | None |
| 📒 | book.spiral | None |
| 📖 | book.open | None |
| 🔖 | bookmark | None |
| 📚️ | books | None |
| 🪃 | boomerang | None |
| 🛂 | bordercontrol | None |
| 💐 | bouquet | None |
| 🏹 | bow | None |
| 🥣 | bowl.spoon | None |
| 🍜 | bowl.steam | None |
| 🎳 | bowling | None |
| 🥊 | boxing | None |
| 👦 | boy | None |
| 🧠 | brain | None |
| 🍞 | bread | None |
| 🧱 | brick | None |
| 👰 | bride | None |
| 🌁 | bridge.fog | None |
| 🌉 | bridge.night | None |
| 💼 | briefcase | None |
| 🩲 | briefs | None |
| 🔆 | brightness.high | None |
| 🔅 | brightness.low | None |
| 🥦 | broccoli | None |
| 🧹 | broom | None |
| 🖌️ | brush | None |
| 💬 | bubble.speech.r | None |
| 🗨️ | bubble.speech.l | None |
| 💭 | bubble.thought | None |
| 🗯️ | bubble.anger.r | None |
| 🫧 | bubbles | None |
| 🧋 | bubbletea | None |
| 🪣 | bucket | None |
| 🐃 | buffalo.water | None |
| 🐛 | bug | None |
| 👷 | builder | None |
| 🍔 | burger | None |
| 🌯 | burrito | None |
| 🚌 | bus | None |
| 🚍️ | bus.front | None |
| 🚐 | bus.small | None |
| 🚏 | bus.stop | None |
| 🚎 | bus.trolley | None |
| 🧈 | butter | None |
| 🦋 | butterfly | None |
| 🔲 | button | None |
| 🔳 | button.alt | None |
| 🔘 | button.radio | None |
| 🗄️ | cabinet.file | None |
| 🚠 | cablecar | None |
| 🚡 | cablecar.small | None |
| 🌵 | cactus | None |
| 🎂 | cake | None |
| 🍥 | cake.fish | None |
| 🥮 | cake.moon | None |
| 🍰 | cake.slice | None |
| 📅 | calendar | None |
| 🗓️ | calendar.spiral | None |
| 📆 | calendar.tearoff | None |
| 🐫 | camel | None |
| 🐪 | camel.dromedar | None |
| 📷️ | camera | None |
| 📸 | camera.flash | None |
| 🎥 | camera.movie | None |
| 🎦 | camera.movie.box | None |
| 📹️ | camera.video | None |
| 🏕️ | camping | None |
| 🥫 | can | None |
| 🕯️ | candle | None |
| 🍬 | candy | None |
| 🦯 | cane | None |
| 🚗 | car | None |
| 🚘️ | car.front | None |
| 🛻 | car.pickup | None |
| 🚓 | car.police | None |
| 🚔️ | car.police.front | None |
| 🏎️ | car.racing | None |
| 🛺 | car.rickshaw | None |
| 🚙 | car.suv | None |
| 💳️ | card.credit | None |
| 🪪 | card.id | None |
| 📇 | cardindex | None |
| 🥕 | carrot | None |
| 🛒 | cart | None |
| 📼 | cassette | None |
| 🏰 | castle.eu | None |
| 🏯 | castle.jp | None |
| 🐈️ | cat | None |
| 🐱 | cat.face | None |
| 😾 | cat.face.angry | None |
| 😿 | cat.face.cry | None |
| 😻 | cat.face.heart | None |
| 😹 | cat.face.joy | None |
| 😽 | cat.face.kiss | None |
| 😸 | cat.face.laugh | None |
| 🙀 | cat.face.shock | None |
| 😺 | cat.face.smile | None |
| 😼 | cat.face.smirk | None |
| 🔗 | chain | None |
| ⛓️ | chains | None |
| 🪑 | chair | None |
| 🍾 | champagne | None |
| 📊 | chart.bar | None |
| 📈 | chart.up | None |
| 📉 | chart.down | None |
| 💹 | chart.yen.up | None |
| ✔️ | checkmark.heavy | None |
| ✅️ | checkmark.box | None |
| 🧀 | cheese | None |
| 🍒 | cherries | None |
| ♟️ | chess | None |
| 🌰 | chestnut | None |
| 🐔 | chicken | None |
| 🐥 | chicken.baby | None |
| 🐣 | chicken.baby.egg | None |
| 🐤 | chicken.baby.head | None |
| 🍗 | chicken.leg | None |
| 🐓 | chicken.male | None |
| 🧒 | child | None |
| 🐿️ | chipmunk | None |
| 🍫 | chocolate | None |
| 🥢 | chopsticks | None |
| ⛪️ | church | None |
| 💒 | church.love | None |
| 🚬 | cigarette | None |
| 🚭️ | cigarette.not | None |
| ⚫️ | circle.black | Normal |
| 🔵 | circle.blue | None |
| 🟤 | circle.brown | None |
| 🟢 | circle.green | None |
| 🟠 | circle.orange | None |
| 🟣 | circle.purple | None |
| ⚪️ | circle.white | Normal |
| 🔴 | circle.red | None |
| 🟡 | circle.yellow | None |
| ⭕️ | circle.stroked | None |
| 🎪 | circus | None |
| 🏙️ | city | None |
| 🌆 | city.dusk | None |
| 🌃 | city.night | None |
| 🌇 | city.sunset | None |
| 🆑 | cl | None |
| 🗜️ | clamp | None |
| 🎬️ | clapperboard | None |
| 🧗 | climbing | None |
| 📎 | clip | None |
| 📋️ | clipboard | None |
| 🖇️ | clips | None |
| 🕐️ | clock.one | None |
| 🕜️ | clock.one.thirty | None |
| 🕑️ | clock.two | None |
| 🕝️ | clock.two.thirty | None |
| 🕒️ | clock.three | None |
| 🕞️ | clock.three.thirty | None |
| 🕓️ | clock.four | None |
| 🕟️ | clock.four.thirty | None |
| 🕔️ | clock.five | None |
| 🕠️ | clock.five.thirty | None |
| 🕕️ | clock.six | None |
| 🕡️ | clock.six.thirty | None |
| 🕖️ | clock.seven | None |
| 🕢️ | clock.seven.thirty | None |
| 🕗️ | clock.eight | None |
| 🕣️ | clock.eight.thirty | None |
| 🕘️ | clock.nine | None |
| 🕤️ | clock.nine.thirty | None |
| 🕙️ | clock.ten | None |
| 🕥️ | clock.ten.thirty | None |
| 🕚️ | clock.eleven | None |
| 🕦️ | clock.eleven.thirty | None |
| 🕛️ | clock.twelve | None |
| 🕧️ | clock.twelve.thirty | None |
| ⏰️ | clock.alarm | None |
| 🕰️ | clock.old | None |
| ⏲️ | clock.timer | None |
| ☁️ | cloud | None |
| 💨 | cloud.dust | None |
| 🌧️ | cloud.rain | None |
| 🌨️ | cloud.snow | None |
| ⛈️ | cloud.storm | None |
| ⛅️ | cloud.sun | None |
| 🌥️ | cloud.sun.hidden | None |
| 🌦️ | cloud.sun.rain | None |
| 🌩️ | cloud.thunder | None |
| 🧥 | coat | None |
| 🥼 | coat.lab | None |
| 🪳 | cockroach | None |
| 🍸️ | cocktail.martini | None |
| 🍹 | cocktail.tropical | None |
| 🥥 | coconut | None |
| ☕️ | coffee | None |
| ⚰️ | coffin | None |
| 🪙 | coin | None |
| ☄️ | comet | None |
| 🧭 | compass | None |
| 🖥️ | computer | None |
| 🖱️ | computermouse | None |
| 🎊 | confetti | None |
| 🚧 | construction | None |
| 🎮️ | controller | None |
| 🍪 | cookie | None |
| 🥠 | cookie.fortune | None |
| 🍳 | cooking | None |
| 🆒 | cool | None |
| ©️ | copyright | None |
| 🪸 | coral | None |
| 🌽 | corn | None |
| 🛋️ | couch | None |
| 💑 | couple | None |
| 🐄 | cow | None |
| 🐮 | cow.face | None |
| 🦀 | crab | None |
| 🏗️ | crane | None |
| 🖍️ | crayon | None |
| 🦗 | cricket | None |
| 🏏 | cricketbat | None |
| 🐊 | crocodile | None |
| 🥐 | croissant | None |
| ❌️ | crossmark | None |
| ❎️ | crossmark.box | None |
| 👑 | crown | None |
| 🩼 | crutch | None |
| 🔮 | crystal | None |
| 🥒 | cucumber | None |
| 🥤 | cup.straw | None |
| 🧁 | cupcake | None |
| 🥌 | curling | None |
| 🍛 | curry | None |
| 🍮 | custard | None |
| 🛃 | customs | None |
| 🍴 | cutlery | None |
| 🌀 | cyclone | None |
| 🕺 | dancing.man | None |
| 💃 | dancing.woman | None |
| 👯 | dancing.bunny | None |
| 👯♂ | dancing.bunny.men | None |
| 👯♀ | dancing.bunny.women | None |
| 🎯 | darts | None |
| 〰️ | dash.wave.double | None |
| 🦌 | deer | None |
| 🏜️ | desert | None |
| 🕵️ | detective | None |
| 🔷 | diamond.blue | None |
| 🔹 | diamond.blue.small | None |
| 🔶 | diamond.orange | None |
| 🔸 | diamond.orange.small | None |
| 💠 | diamond.dot | None |
| 🎲 | die | None |
| 🦕 | dino.pod | None |
| 🦖 | dino.rex | None |
| 💿️ | disc.cd | None |
| 📀 | disc.dvd | None |
| 💽 | disc.mini | None |
| 🪩 | discoball | None |
| 🤿 | diving | None |
| 🦤 | dodo | None |
| 🐕️ | dog | None |
| 🐶 | dog.face | None |
| 🦮 | dog.guide | None |
| 🐩 | dog.poodle | None |
| 💲 | dollar | None |
| 🐬 | dolphin | None |
| 🫏 | donkey | None |
| 🍩 | donut | None |
| 🚪 | door | None |
| 🕊️ | dove.peace | None |
| 🐉 | dragon | None |
| 🐲 | dragon.face | None |
| 👗 | dress | None |
| 👘 | dress.kimono | None |
| 🥻 | dress.sari | None |
| 💧 | drop | None |
| 💦 | drops | None |
| 🥁 | drum | None |
| 🪘 | drum.big | None |
| 🦆 | duck | None |
| 🥟 | dumpling | None |
| 🦅 | eagle | None |
| 👂️ | ear | None |
| 🦻 | ear.aid | None |
| 🥚 | egg | None |
| 🔞 | eighteen.not | None |
| 🐘 | elephant | None |
| 🛗 | elevator | None |
| 🧝 | elf | None |
| 📧 | email | None |
| ❗️ | excl | None |
| ❕️ | excl.white | None |
| ‼️ | excl.double | Normal |
| ⁉️ | excl.quest | None |
| 💥 | explosion | None |
| 🧯 | extinguisher | None |
| 👁️ | eye | None |
| 👀 | eyes | None |
| 😀 | face.grin | None |
| 😠 | face.angry | None |
| 😡 | face.angry.red | None |
| 😧 | face.anguish | None |
| 😲 | face.astonish | None |
| 🤕 | face.bandage | None |
| 😁 | face.beam | None |
| 😶 | face.blank | None |
| 🤡 | face.clown | None |
| 🥶 | face.cold | None |
| 😦 | face.concern | None |
| 😎 | face.cool | None |
| 🤭 | face.cover | None |
| 🤠 | face.cowboy | None |
| 😭 | face.cry | None |
| 😈 | face.devil.smile | None |
| 👿 | face.devil.frown | None |
| 🫤 | face.diagonal | None |
| 🥸 | face.disguise | None |
| 😫 | face.distress | None |
| 😵 | face.dizzy | None |
| 🫥 | face.dotted | None |
| 😞 | face.down | None |
| 😓 | face.down.sweat | None |
| 🤤 | face.drool | None |
| 🤯 | face.explode | None |
| 🙄 | face.eyeroll | None |
| ☺️ | face.friendly | None |
| 😨 | face.fear | None |
| 😰 | face.fear.sweat | None |
| 🤒 | face.fever | None |
| 😳 | face.flush | None |
| ☹️ | face.frown | None |
| 🙁 | face.frown.slight | None |
| 😣 | face.frust | None |
| 🤪 | face.goofy | None |
| 😇 | face.halo | None |
| 😊 | face.happy | None |
| 😍 | face.heart | None |
| 🥰 | face.hearts | None |
| 🥵 | face.heat | None |
| 🤗 | face.hug | None |
| 🙃 | face.inv | None |
| 😂 | face.joy | None |
| 😗 | face.kiss | None |
| 😙 | face.kiss.smile | None |
| 😘 | face.kiss.heart | None |
| 😚 | face.kiss.blush | None |
| 😋 | face.lick | None |
| 🤥 | face.lie | None |
| 😷 | face.mask | None |
| 😒 | face.meh | None |
| 🫠 | face.melt | None |
| 🤑 | face.money | None |
| 🧐 | face.monocle | None |
| 🤢 | face.nausea | None |
| 🤓 | face.nerd | None |
| 😐️ | face.neutral | None |
| 😃 | face.open | None |
| 🥳 | face.party | None |
| 🫣 | face.peek | None |
| 🥺 | face.plead | None |
| 😌 | face.relief | None |
| 🤣 | face.rofl | None |
| 😔 | face.sad | None |
| 🫡 | face.salute | None |
| 🫨 | face.shaking | None |
| 😱 | face.shock | None |
| 🤫 | face.shush | None |
| 🤨 | face.skeptic | None |
| 😴 | face.sleep | None |
| 😪 | face.sleepy | None |
| 😄 | face.smile | None |
| 🙂 | face.smile.slight | None |
| 😅 | face.smile.sweat | None |
| 🥲 | face.smile.tear | None |
| 😏 | face.smirk | None |
| 🤧 | face.sneeze | None |
| 🫢 | face.speak.not | None |
| 😆 | face.squint | None |
| 🤩 | face.stars | None |
| 😑 | face.straight | None |
| 😖 | face.suffer | None |
| 😯 | face.surprise | None |
| 🤬 | face.symbols | None |
| 😢 | face.tear | None |
| 😥 | face.tear.relief | None |
| 🥹 | face.tear.withheld | None |
| 😬 | face.teeth | None |
| 🤔 | face.think | None |
| | face.tired | None |
| 😛 | face.tongue | None |
| 😝 | face.tongue.squint | None |
| 😜 | face.tongue.wink | None |
| 😤 | face.triumph | None |
| 😕 | face.unhappy | None |
| 🤮 | face.vomit | None |
| 😩 | face.weary | None |
| 😉 | face.wink | None |
| 🥴 | face.woozy | None |
| 😟 | face.worry | None |
| 😮 | face.wow | None |
| 🥱 | face.yawn | None |
| 🤐 | face.zip | None |
| 🏭️ | factory | None |
| 🧚 | fairy | None |
| ✝️ | faith.christ | None |
| ☸️ | faith.dharma | None |
| 🪯 | faith.khanda | None |
| ☪️ | faith.islam | None |
| ✡️ | faith.judaism | None |
| 🕎 | faith.menorah | None |
| 🕉️ | faith.om | None |
| ☦️ | faith.orthodox | None |
| ☮️ | faith.peace | None |
| 🔯 | faith.star.dot | None |
| 🛐 | faith.worship | None |
| ☯️ | faith.yinyang | None |
| 🧆 | falafel | None |
| 👪️ | family | None |
| 📠 | fax | None |
| 🪶 | feather | None |
| 🤱 | feeding.breast | None |
| 🤺 | fencing | None |
| 🎡 | ferriswheel | None |
| 🗃️ | filebox | None |
| 🗂️ | filedividers | None |
| 🎞️ | film | None |
| 👉️ | finger.r | None |
| 👈️ | finger.l | None |
| 👆️ | finger.t | None |
| ☝️ | finger.t.alt | None |
| 👇️ | finger.b | None |
| 🫵 | finger.front | None |
| 🖕 | finger.m | None |
| | fingerprint | None |
| 🤞 | fingers.cross | None |
| 🤌 | fingers.pinch | None |
| 🫰 | fingers.snap | None |
| 🔥 | fire | None |
| 🧨 | firecracker | None |
| 🚒 | fireengine | None |
| 🎆 | fireworks | None |
| 🐟️ | fish | None |
| 🐠 | fish.tropical | None |
| 🎣 | fishing | None |
| 👊 | fist.front | None |
| 🤜 | fist.r | None |
| 🤛 | fist.l | None |
| ✊️ | fist.raised | None |
| 🏴 | flag.black | None |
| 🏳️ | flag.white | None |
| 🏁 | flag.goal | None |
| ⛳️ | flag.golf | None |
| 🚩 | flag.red | None |
| 🎌 | flags.jp.crossed | None |
| 🦩 | flamingo | None |
| 🔦 | flashlight | None |
| 🫓 | flatbread | None |
| ⚜️ | fleur | None |
| 💾 | floppy | None |
| 🌺 | flower.hibiscus | None |
| 🪻 | flower.hyacinth | None |
| 🪷 | flower.lotus | None |
| 🌸 | flower.pink | None |
| 🌹 | flower.rose | None |
| 🌻 | flower.sun | None |
| 🌷 | flower.tulip | None |
| 💮 | flower.white | None |
| 🥀 | flower.wilted | None |
| 🌼 | flower.yellow | None |
| 🪈 | flute | None |
| 🪰 | fly | None |
| 🌫️ | fog | None |
| 📁 | folder | None |
| 📂 | folder.open | None |
| 🫕 | fondue | None |
| 🦶 | foot | None |
| ⚽️ | football | None |
| 🏈 | football.am | None |
| 💱 | forex | None |
| ⛲️ | fountain | None |
| 🦊 | fox | None |
| 🆓 | free | None |
| 🍟 | fries | None |
| 🥏 | frisbee | None |
| 🐸 | frog.face | None |
| ⛽️ | fuelpump | None |
| 🈷️ | gachi | None |
| 🧄 | garlic | None |
| ⚙️ | gear | None |
| 💎 | gem | None |
| 🧞 | genie | None |
| 👻 | ghost | None |
| 🫚 | ginger | None |
| 🦒 | giraffe | None |
| 👧 | girl | None |
| 🥂 | glass.clink | None |
| 🥛 | glass.milk | None |
| 🫗 | glass.pour | None |
| 🥃 | glass.tumbler | None |
| 👓️ | glasses | None |
| 🕶️ | glasses.sun | None |
| 🌎️ | globe.am | None |
| 🌏️ | globe.as.au | None |
| 🌍️ | globe.eu.af | None |
| 🌐 | globe.meridian | None |
| 🧤 | gloves | None |
| 🈴 | go | None |
| 🥅 | goal | None |
| 🐐 | goat | None |
| 🥽 | goggles | None |
| 🏌️ | golfing | None |
| 🪿 | goose | None |
| 🦍 | gorilla | None |
| 🍇 | grapes | None |
| 💂 | guard.man | None |
| 🎸 | guitar | None |
| 🤸 | gymnastics | None |
| 💇 | haircut | None |
| 🪮 | hairpick | None |
| 🔨 | hammer | None |
| ⚒️ | hammer.pick | None |
| 🛠️ | hammer.wrench | None |
| 🪬 | hamsa | None |
| 🐹 | hamster.face | None |
| ✋️ | hand.raised | None |
| 🤚 | hand.raised.alt | None |
| 🫱 | hand.r | None |
| 🫲 | hand.l | None |
| 🫴 | hand.t | None |
| 🫳 | hand.b | None |
| 👌 | hand.ok | None |
| 🤙 | hand.call | None |
| 🤟 | hand.love | None |
| 🖖 | hand.part | None |
| ✌️ | hand.peace | None |
| 🤏 | hand.pinch | None |
| 🫷 | hand.pushing.l | None |
| 🫸 | hand.pushing.r | None |
| 🤘 | hand.rock | None |
| 🖐️ | hand.splay | None |
| 👋 | hand.wave | None |
| ✍️ | hand.write | None |
| 👜 | handbag | None |
| 🤾 | handball | None |
| 🪭 | handfan | None |
| 🧑🤝🧑 | handholding | None |
| 👬 | handholding.man.man | None |
| 👫 | handholding.woman.man | None |
| 👭 | handholding.woman.woman | None |
| 🙏 | hands.folded | None |
| 🤲 | hands.palms | None |
| 👏 | hands.clap | None |
| 🫶 | hands.heart | None |
| 👐 | hands.open | None |
| 🙌 | hands.raised | None |
| 🤝 | hands.shake | None |
| | harp | None |
| #️ | hash | Normal |
| 👒 | hat.ribbon | None |
| 🎩 | hat.top | None |
| 🎧️ | headphone | None |
| ❤️ | heart | None |
| 💘 | heart.arrow | None |
| 💓 | heart.beat | None |
| 🖤 | heart.black | None |
| 💙 | heart.blue | None |
| 💟 | heart.box | None |
| 💔 | heart.broken | None |
| 🤎 | heart.brown | None |
| 💕 | heart.double | None |
| ❣️ | heart.excl | None |
| 🩶 | heart.gray | None |
| 💚 | heart.green | None |
| 💗 | heart.grow | None |
| 🩵 | heart.lightblue | None |
| 🧡 | heart.orange | None |
| 🩷 | heart.pink | None |
| 💜 | heart.purple | None |
| 🫀 | heart.real | None |
| 💞 | heart.revolve | None |
| 💝 | heart.ribbon | None |
| 💖 | heart.spark | None |
| 🤍 | heart.white | None |
| 💛 | heart.yellow | None |
| 🦔 | hedgehog | None |
| 🚁 | helicopter | None |
| 🧬 | helix | None |
| ⛑️ | helmet.cross | None |
| 🪖 | helmet.military | None |
| ㊙️ | hi | None |
| 🦛 | hippo | None |
| 🏑 | hockey | None |
| 🕳️ | hole | None |
| 🍯 | honey | None |
| 🧧 | hongbao | None |
| 🪝 | hook | None |
| 📯 | horn.postal | None |
| 🐎 | horse | None |
| 🎠 | horse.carousel | None |
| 🐴 | horse.face | None |
| 🏇 | horse.race | None |
| 🏥 | hospital | None |
| 🌭 | hotdog | None |
| 🏨 | hotel | None |
| 🏩 | hotel.love | None |
| ♨️ | hotspring | None |
| ⌛️ | hourglass | None |
| ⏳️ | hourglass.flow | None |
| 🏠️ | house | None |
| 🏚️ | house.derelict | None |
| 🏡 | house.garden | None |
| 🏘️ | house.multiple | None |
| 💯 | hundred | None |
| 🛖 | hut | None |
| 🧊 | ice | None |
| 🍨 | icecream | None |
| 🍧 | icecream.shaved | None |
| 🍦 | icecream.soft | None |
| 🏒 | icehockey | None |
| 🆔 | id | None |
| ℹ️ | info | None |
| 🏮 | izakaya | None |
| 🫙 | jar | None |
| 👖 | jeans | None |
| 🪼 | jellyfish | None |
| 🧩 | jigsaw | None |
| 🕹️ | joystick | None |
| 🤹 | juggling | None |
| 🧃 | juice | None |
| 🉑 | ka | None |
| 🕋 | kaaba | None |
| 🈹 | kachi | None |
| 🎍 | kadomatsu | None |
| 🦘 | kangaroo | None |
| 🈳 | kara | None |
| 🥙 | kebab | None |
| 🔑 | key | None |
| 🗝️ | key.old | None |
| ⌨️ | keyboard | None |
| 💏 | kiss | None |
| 💋 | kissmark | None |
| 🪁 | kite | None |
| 🥝 | kiwi | None |
| 🔪 | knife | None |
| 🗡️ | knife.dagger | None |
| 🪢 | knot | None |
| 🐨 | koala | None |
| 🎏 | koinobori | None |
| 🈁 | koko | None |
| 🈲 | kon | None |
| 🏷️ | label | None |
| 🥍 | lacrosse | None |
| 🪜 | ladder | None |
| 🪔 | lamp.diya | None |
| 💻️ | laptop | None |
| ☘️ | leaf.clover.three | None |
| 🍀 | leaf.clover.four | None |
| 🍂 | leaf.fall | None |
| 🌿 | leaf.herb | None |
| 🍁 | leaf.maple | None |
| 🍃 | leaf.wind | None |
| 🛅 | leftluggage | None |
| 🦵 | leg | None |
| 🦿 | leg.mech | None |
| 🍋 | lemon | None |
| 🐆 | leopard | None |
| 💌 | letter.love | None |
| 🗽 | liberty | None |
| 💡 | lightbulb | None |
| ⚡️ | lightning | None |
| 🦁 | lion | None |
| 💄 | lipstick | None |
| 🚮 | litter | None |
| 🚯 | litter.not | None |
| 🦎 | lizard | None |
| 🦙 | llama | None |
| 🦞 | lobster | None |
| 🔒️ | lock | None |
| 🔐 | lock.key | None |
| 🔓️ | lock.open | None |
| 🔏 | lock.pen | None |
| 🍭 | lollipop | None |
| 🧴 | lotion | None |
| 🧳 | luggage | None |
| 🫁 | lungs | None |
| 🧙 | mage | None |
| 🧲 | magnet | None |
| 🔎 | magnify.r | None |
| 🔍️ | magnify.l | None |
| 🀄️ | mahjong.dragon.red | None |
| ✉️ | mail | None |
| 📩 | mail.arrow | None |
| 📪️ | mailbox.closed.empty | None |
| 📫️ | mailbox.closed.full | None |
| 📭️ | mailbox.open.empty | None |
| 📬️ | mailbox.open.full | None |
| 🦣 | mammoth | None |
| 👨 | man | None |
| 🚹️ | man.box | None |
| 🤴 | man.crown | None |
| 👲 | man.guapimao | None |
| 🕴️ | man.levitate | None |
| 👴 | man.old | None |
| 🫃 | man.pregnant | None |
| 👳 | man.turban | None |
| 🤵 | man.tuxedo | None |
| 🥭 | mango | None |
| 🗺️ | map.world | None |
| 🗾 | map.jp | None |
| 🪇 | maracas | None |
| 🥋 | martialarts | None |
| 🎭️ | masks | None |
| 🧉 | mate | None |
| 🪆 | matryoshka | None |
| 🥩 | meat | None |
| 🍖 | meat.bone | None |
| 🥇 | medal.first | None |
| 🥈 | medal.second | None |
| 🥉 | medal.third | None |
| 🏅 | medal.sports | None |
| 🎖️ | medal.military | None |
| 📢 | megaphone | None |
| 📣 | megaphone.simple | None |
| 🍈 | melon | None |
| 🧜 | merperson | None |
| Ⓜ️ | metro | None |
| 🦠 | microbe | None |
| 🎤 | microphone | None |
| 🎙️ | microphone.studio | None |
| 🔬 | microscope | None |
| 🌌 | milkyway | None |
| 🪞 | mirror | None |
| 🎛️ | mixer | None |
| 💰️ | money.bag | None |
| 💵 | money.dollar | None |
| 💶 | money.euro | None |
| 💷 | money.pound | None |
| 💴 | money.yen | None |
| 💸 | money.wings | None |
| 🐒 | monkey | None |
| 🐵 | monkey.face | None |
| 🙉 | monkey.hear.not | None |
| 🙈 | monkey.see.not | None |
| 🙊 | monkey.speak.not | None |
| 🌙 | moon.crescent | None |
| 🌕️ | moon.full | None |
| 🌝 | moon.full.face | None |
| 🌑 | moon.new | None |
| 🌚 | moon.new.face | None |
| 🌖 | moon.wane.one | None |
| 🌗 | moon.wane.two | None |
| 🌜️ | moon.wane.three.face | None |
| 🌘 | moon.wane.three | None |
| 🌒 | moon.wax.one | None |
| 🌓 | moon.wax.two | None |
| 🌛 | moon.wax.two.face | None |
| 🌔 | moon.wax.three | None |
| 🫎 | moose | None |
| 🎓️ | mortarboard | None |
| 🕌 | mosque | None |
| 🦟 | mosquito | None |
| 🏍️ | motorcycle | None |
| 🛣️ | motorway | None |
| ⛰️ | mountain | None |
| 🗻 | mountain.fuji | None |
| 🏔️ | mountain.snow | None |
| 🌄 | mountain.sunrise | None |
| 🐁 | mouse | None |
| 🐭 | mouse.face | None |
| 🪤 | mousetrap | None |
| 👄 | mouth | None |
| 🫦 | mouth.bite | None |
| 🗿 | moyai | None |
| 🈚️ | muryo | None |
| 🏛️ | museum | None |
| 🍄 | mushroom | None |
| 🎼 | musicalscore | None |
| 💅 | nails.polish | None |
| 📛 | namebadge | None |
| 🧿 | nazar | None |
| 👔 | necktie | None |
| 🪡 | needle | None |
| 🪹 | nest.empty | None |
| 🪺 | nest.eggs | None |
| 🆕 | new | None |
| 📰 | newspaper | None |
| 🗞️ | newspaper.rolled | None |
| 🆖 | ng | None |
| 🎎 | ningyo | None |
| 🥷 | ninja | None |
| ⛔️ | noentry | None |
| 👃 | nose | None |
| 📓 | notebook | None |
| 📔 | notebook.deco | None |
| 🗒️ | notepad | None |
| 🎵 | notes | None |
| 🎶 | notes.triple | None |
| 🔢 | numbers | None |
| 🅾️ | o | None |
| 🐙 | octopus | None |
| 🏢 | office | None |
| 🛢️ | oil | None |
| 🆗 | ok | None |
| 🫒 | olive | None |
| 👹 | oni | None |
| 🧅 | onion | None |
| 🦧 | orangutan | None |
| 🦦 | otter | None |
| 🦉 | owl | None |
| 🐂 | ox | None |
| 🦪 | oyster | None |
| 📦️ | package | None |
| 🥘 | paella | None |
| 📄 | page | None |
| 📃 | page.curl | None |
| 📝 | page.pencil | None |
| 📟️ | pager | None |
| 📑 | pages.tabs | None |
| 🖼️ | painting | None |
| 🎨 | palette | None |
| 🥞 | pancakes | None |
| 🐼 | panda | None |
| 🪂 | parachute | None |
| 🏞️ | park | None |
| 🅿️ | parking | None |
| 🦜 | parrot | None |
| 〽️ | partalteration | None |
| 🎉 | party | None |
| 🍑 | peach | None |
| 🦚 | peacock | None |
| 🥜 | peanuts | None |
| 🫛 | peapod | None |
| 🍐 | pear | None |
| 🚶 | pedestrian | None |
| 🚷 | pedestrian.not | None |
| 🖊️ | pen.ball | None |
| 🖋️ | pen.fountain | None |
| ✏️ | pencil | None |
| 🐧 | penguin | None |
| 🫑 | pepper | None |
| 🌶️ | pepper.hot | None |
| 🧑 | person | None |
| 🙎 | person.angry | None |
| 🧔 | person.beard | None |
| 👱 | person.blonde | None |
| 🙇 | person.bow | None |
| 🫅 | person.crown | None |
| 🧏 | person.deaf | None |
| 🤦 | person.facepalm | None |
| 🙍 | person.frown | None |
| 🧕 | person.hijab | None |
| 🧎 | person.kneel | None |
| 🧘 | person.lotus | None |
| 💆 | person.massage | None |
| 🙅 | person.no | None |
| 🙆 | person.ok | None |
| 🧓 | person.old | None |
| 🫄 | person.pregnant | None |
| 🙋 | person.raise | None |
| 💁 | person.sassy | None |
| 🤷 | person.shrug | None |
| 🧍 | person.stand | None |
| 🧖 | person.steam | None |
| 🧫 | petri | None |
| 📱 | phone | None |
| 📲 | phone.arrow | None |
| ☎️ | phone.classic | None |
| 📵 | phone.not | None |
| 📴 | phone.off | None |
| 📞 | phone.receiver | None |
| 📶 | phone.signal | None |
| 📳 | phone.vibrate | None |
| 🎹 | piano | None |
| ⛏️ | pick | None |
| 🥧 | pie | None |
| 🐖 | pig | None |
| 🐷 | pig.face | None |
| 🐽 | pig.nose | None |
| 💊 | pill | None |
| 📌 | pin | None |
| 📍 | pin.round | None |
| 🪅 | pinata | None |
| 🍍 | pineapple | None |
| 🏓 | pingpong | None |
| 🔫 | pistol | None |
| 🍕 | pizza | None |
| 🪧 | placard | None |
| 🪐 | planet | None |
| 🪴 | plant | None |
| 🩹 | plaster | None |
| 🍽️ | plate.cutlery | None |
| ⏬️ | playback.down | None |
| ⏏️ | playback.eject | None |
| ⏩️ | playback.forward | None |
| ⏸️ | playback.pause | None |
| ⏺️ | playback.record | None |
| 🔁 | playback.repeat | None |
| 🔂 | playback.repeat.once | None |
| 🔃 | playback.repeat.v | None |
| ⏮️ | playback.restart | None |
| ⏪️ | playback.rewind | None |
| 🔀 | playback.shuffle | None |
| ⏭️ | playback.skip | None |
| ⏹️ | playback.stop | None |
| ⏯️ | playback.toggle | None |
| ⏫️ | playback.up | None |
| 🎴 | playingcard.flower | None |
| 🃏 | playingcard.joker | None |
| 🪠 | plunger | None |
| 👮 | policeofficer | None |
| 💩 | poo | None |
| 🍿 | popcorn | None |
| 🏤 | post.eu | None |
| 🏣 | post.jp | None |
| 📮 | postbox | None |
| 🥔 | potato | None |
| 🍠 | potato.sweet | None |
| 👝 | pouch | None |
| 🔌 | powerplug | None |
| 🎁 | present | None |
| 🥨 | pretzel | None |
| 🖨️ | printer | None |
| 👣 | prints.foot | None |
| 🐾 | prints.paw | None |
| 🚫 | prohibited | None |
| 📽️ | projector | None |
| 🎃 | pumpkin.lantern | None |
| 👛 | purse | None |
| ❓️ | quest | None |
| ❔️ | quest.white | None |
| 🐇 | rabbit | None |
| 🐰 | rabbit.face | None |
| 🦝 | raccoon | None |
| 📻️ | radio | None |
| ☢️ | radioactive | None |
| 🛤️ | railway | None |
| 🌈 | rainbow | None |
| 🐏 | ram | None |
| 🐀 | rat | None |
| 🪒 | razor | None |
| 🧾 | receipt | None |
| ♻️ | recycling | None |
| ®️ | reg | None |
| 🚻 | restroom | None |
| 🦏 | rhino | None |
| 🎀 | ribbon | None |
| 🎗️ | ribbon.remind | None |
| 🍚 | rice | None |
| 🍘 | rice.cracker | None |
| 🌾 | rice.ear | None |
| 🍙 | rice.onigiri | None |
| 💍 | ring | None |
| 🛟 | ringbuoy | None |
| 🤖 | robot | None |
| 🪨 | rock | None |
| 🚀 | rocket | None |
| 🎢 | rollercoaster | None |
| 🏵️ | rosette | None |
| 🏉 | rugby | None |
| 📏 | ruler | None |
| 📐 | ruler.triangle | None |
| 🏃 | running | None |
| 🈂️ | sa | None |
| 🧷 | safetypin | None |
| 🦺 | safetyvest | None |
| 🍶 | sake | None |
| 🥗 | salad | None |
| 🧂 | salt | None |
| 🥪 | sandwich | None |
| 🎅 | santa.man | None |
| 🤶 | santa.woman | None |
| 📡 | satdish | None |
| 🛰️ | satellite | None |
| 🪚 | saw | None |
| 🎷 | saxophone | None |
| ⚖️ | scales | None |
| 🧣 | scarf | None |
| 🏫 | school | None |
| ✂️ | scissors | None |
| 🛴 | scooter | None |
| 🛵 | scooter.motor | None |
| 🦂 | scorpion | None |
| 🪛 | screwdriver | None |
| 📜 | scroll | None |
| 🦭 | seal | None |
| 💺 | seat | None |
| 🌱 | seedling | None |
| 🦈 | shark | None |
| 🐑 | sheep | None |
| 🐚 | shell.spiral | None |
| 🛡️ | shield | None |
| 🈸 | shin | None |
| 🚢 | ship | None |
| 🛳️ | ship.cruise | None |
| ⛴️ | ship.ferry | None |
| 🎽 | shirt.sports | None |
| 👕 | shirt.t | None |
| 👞 | shoe | None |
| 🩰 | shoe.ballet | None |
| 🥿 | shoe.flat | None |
| 👠 | shoe.heel | None |
| 🥾 | shoe.hike | None |
| ⛸️ | shoe.ice | None |
| 🛼 | shoe.roller | None |
| 👡 | shoe.sandal.heel | None |
| 🎿 | shoe.ski | None |
| 👟 | shoe.sneaker | None |
| 👢 | shoe.tall | None |
| 🩴 | shoe.thong | None |
| 🛍️ | shopping | None |
| 🩳 | shorts | None |
| 🔰 | shoshinsha | None |
| | shovel | None |
| 🚿 | shower | None |
| 🦐 | shrimp | None |
| 🍤 | shrimp.fried | None |
| ⛩️ | shrine | None |
| ㊗️ | shuku | None |
| 🚸 | sign.crossing | None |
| 🛑 | sign.stop | None |
| 👤 | silhouette | None |
| 👥 | silhouette.double | None |
| 🫂 | silhouette.hug | None |
| 🗣️ | silhouette.speak | None |
| 🚨 | siren | None |
| 🛹 | skateboard | None |
| 🍡 | skewer.dango | None |
| 🍢 | skewer.oden | None |
| ⛷️ | skiing | None |
| 💀 | skull | None |
| ☠️ | skull.bones | None |
| 🦨 | skunk | None |
| 🛷 | sled | None |
| 🛝 | slide | None |
| 🎚️ | slider | None |
| 🦥 | sloth | None |
| 🎰 | slots | None |
| 🐌 | snail | None |
| 🐍 | snake | None |
| 🏂️ | snowboarding | None |
| ❄️ | snowflake | None |
| ⛄️ | snowman | None |
| ☃️ | snowman.snow | None |
| 🧼 | soap | None |
| 🧦 | socks | None |
| 🥎 | softball | None |
| 🆘 | sos | None |
| 🍲 | soup | None |
| 🍝 | spaghetti | None |
| ❇️ | sparkle.box | None |
| 🎇 | sparkler | None |
| ✨️ | sparkles | None |
| 🔈️ | speaker | None |
| 🔇 | speaker.not | None |
| 🔉 | speaker.wave | None |
| 🔊 | speaker.waves | None |
| 🕷️ | spider | None |
| 🕸️ | spiderweb | None |
| 🥬 | spinach | None |
| | splatter | None |
| 🧽 | sponge | None |
| 🥄 | spoon | None |
| ⬛️ | square.black | Normal |
| ▪️ | square.black.tiny | Normal |
| ◾️ | square.black.small | Binary |
| ◼️ | square.black.medium | Binary |
| ⬜️ | square.white | Normal |
| ▫️ | square.white.tiny | Normal |
| ◽️ | square.white.small | Binary |
| ◻️ | square.white.medium | Binary |
| 🟦 | square.blue | None |
| 🟫 | square.brown | None |
| 🟩 | square.green | None |
| 🟧 | square.orange | None |
| 🟪 | square.purple | None |
| 🟥 | square.red | None |
| 🟨 | square.yellow | None |
| 🦑 | squid | None |
| 🏟️ | stadium | None |
| ⭐️ | star | Normal |
| 💫 | star.arc | None |
| ✴️ | star.box | None |
| 🌟 | star.glow | None |
| 🌠 | star.shoot | None |
| 🩺 | stethoscope | None |
| 🏬 | store.big | None |
| 🏪 | store.small | None |
| 🍓 | strawberry | None |
| ♣️ | suit.club | Normal |
| ♦️ | suit.diamond | Normal |
| ♥️ | suit.heart | Normal |
| ♠️ | suit.spade | Normal |
| ☀️ | sun | None |
| 🌤️ | sun.cloud | None |
| 🌞 | sun.face | None |
| 🌅 | sunrise | None |
| 🦸 | superhero | None |
| 🦹 | supervillain | None |
| 🏄️ | surfing | None |
| 🍣 | sushi | None |
| 🦢 | swan | None |
| 🏊️ | swimming | None |
| 🩱 | swimsuit | None |
| ⚔️ | swords | None |
| 🔣 | symbols | None |
| 🕍 | synagogue | None |
| 💉 | syringe | None |
| 🌮 | taco | None |
| 🥡 | takeout | None |
| 🫔 | tamale | None |
| 🎋 | tanabata | None |
| 🍊 | tangerine | None |
| 🚰 | tap | None |
| 🚱 | tap.not | None |
| 🚕 | taxi | None |
| 🚖 | taxi.front | None |
| 🍵 | teacup | None |
| 🫖 | teapot | None |
| 🧸 | teddy | None |
| 🔭 | telescope | None |
| 🛕 | temple | None |
| 🔟 | ten | None |
| 👺 | tengu | None |
| 🎾 | tennis | None |
| ⛺️ | tent | None |
| 🧪 | testtube | None |
| 🌡️ | thermometer | None |
| 🧵 | thread | None |
| 👍️ | thumb.up | None |
| 👎️ | thumb.down | None |
| 🎟️ | ticket.event | None |
| 🎫 | ticket.travel | None |
| 🐅 | tiger | None |
| 🐯 | tiger.face | None |
| ™️ | tm | None |
| 🚽 | toilet | None |
| 🧻 | toiletpaper | None |
| 🉐 | toku | None |
| 🍅 | tomato | None |
| 🪦 | tombstone | None |
| 👅 | tongue | None |
| 🧰 | toolbox | None |
| 🦷 | tooth | None |
| 🪥 | toothbrush | None |
| 🌪️ | tornado | None |
| 🗼 | tower.tokyo | None |
| 🖲️ | trackball | None |
| 🚜 | tractor | None |
| 🚦 | trafficlight.v | None |
| 🚥 | trafficlight.h | None |
| 🚆 | train | None |
| 🚃 | train.car | None |
| 🚈 | train.light | None |
| 🚇️ | train.metro | None |
| 🚝 | train.mono | None |
| 🚞 | train.mountain | None |
| 🚄 | train.speed | None |
| 🚅 | train.speed.bullet | None |
| 🚂 | train.steam | None |
| 🚉 | train.stop | None |
| 🚟 | train.suspend | None |
| 🚊 | train.tram | None |
| 🚋 | train.tram.car | None |
| ⚧️ | transgender | None |
| 📥️ | tray.inbox | None |
| 📨 | tray.mail | None |
| 📤️ | tray.outbox | None |
| 🌳 | tree.deciduous | None |
| 🌲 | tree.evergreen | None |
| | tree.leafless | None |
| 🌴 | tree.palm | None |
| 🎄 | tree.xmas | None |
| ▶️ | triangle.r | Binary |
| ◀️ | triangle.l | Binary |
| 🔼 | triangle.t | None |
| 🔽 | triangle.b | None |
| 🔺 | triangle.t.red | None |
| 🔻 | triangle.b.red | None |
| 🔱 | trident | None |
| 🧌 | troll | None |
| 🏆️ | trophy | None |
| 🚚 | truck | None |
| 🚛 | truck.trailer | None |
| 🎺 | trumpet | None |
| 🎑 | tsukimi | None |
| 🦃 | turkey | None |
| 🐢 | turtle | None |
| 📺️ | tv | None |
| 🛸 | ufo | None |
| ☂️ | umbrella.open | None |
| 🌂 | umbrella.closed | None |
| ☔️ | umbrella.rain | None |
| ⛱️ | umbrella.sun | None |
| 🦄 | unicorn | None |
| 🦳 | unknown | None |
| 🆙 | up | None |
| ⚱️ | urn | None |
| 🧛 | vampire | None |
| 🎻 | violin | None |
| 🌋 | volcano | None |
| 🏐 | volleyball | None |
| 🆚 | vs | None |
| 🧇 | waffle | None |
| 🪄 | wand | None |
| ⚠️ | warning | None |
| ⌚️ | watch | None |
| ⏱️ | watch.stop | None |
| 🍉 | watermelon | None |
| 🤽 | waterpolo | None |
| 🌊 | wave | None |
| 🚾 | wc | None |
| 🏋️ | weightlifting | None |
| 🐋 | whale | None |
| 🐳 | whale.spout | None |
| 🛞 | wheel | None |
| 🦽 | wheelchair | None |
| ♿️ | wheelchair.box | None |
| 🦼 | wheelchair.motor | None |
| 🌬️ | wind | None |
| 🎐 | windchime | None |
| 🪟 | window | None |
| 🍷 | wine | None |
| 🪽 | wing | None |
| 🛜 | wireless | None |
| 🐺 | wolf | None |
| 👩 | woman | None |
| 🚺️ | woman.box | None |
| 👸 | woman.crown | None |
| 👵 | woman.old | None |
| 🤰 | woman.pregnant | None |
| 🪵 | wood | None |
| 🪱 | worm | None |
| 🔧 | wrench | None |
| 🤼 | wrestling | None |
| 🩻 | xray | None |
| 🧶 | yarn | None |
| 🈺 | yo | None |
| 🪀 | yoyo | None |
| 🈯️ | yubi | None |
| 🈶 | yuryo | None |
| 🦓 | zebra | None |
| ♒️ | zodiac.aquarius | None |
| ♈️ | zodiac.aries | Normal |
| ♋️ | zodiac.cancer | None |
| ♑️ | zodiac.capri | None |
| ♊️ | zodiac.gemini | None |
| ♌️ | zodiac.leo | None |
| ♎️ | zodiac.libra | None |
| ⛎️ | zodiac.ophi | None |
| ♓️ | zodiac.pisces | None |
| ♐️ | zodiac.sagit | None |
| ♏️ | zodiac.scorpio | None |
| ♉️ | zodiac.taurus | Normal |
| ♍️ | zodiac.virgo | None |
| 🧟 | zombie | None |
| 💤 | zzz | None |
docs/reference/symbols/index.md
# Symbols
These two modules give names to symbols and emoji to make them easy to insert with a normal keyboard. Alternatively, you can also always directly enter Unicode symbols into your text and formulas. In addition to the symbols listed below, math mode defines `dif` and `Dif`. These are not normal symbol values because they also affect spacing and font style.
You can define custom symbols with the constructor function of the [symbol](/docs/reference/foundations/symbol/) type.
## Definitions
| Name | Description |
| --- | --- |
| [`sym`](/reference/symbols/sym/) | These two modules give names to symbols and emoji to make them easy to insert with a normal keyboard. |
| [`emoji`](/reference/symbols/emoji/) | These two modules give names to symbols and emoji to make them easy to insert with a normal keyboard. |
docs/reference/symbols/sym.md
# General
Named general symbols.
For example, `#sym.arrow` produces the → symbol. Within [formulas](/docs/reference/math/), these symbols can be used without the `#sym.` prefix.
The `d` in an integral's `dx` can be written as `$dif x$`. Outside math formulas, `dif` can be accessed as `math.dif`.
| Symbol | Name | Math Class |
| ----- | ----- | ----- |
| 𝔸 | AA | Alphabetic |
| Α | Alpha | Alphabetic |
| 𝔹 | BB | Alphabetic |
| Β | Beta | Alphabetic |
| ℂ | CC | Alphabetic |
| Χ | Chi | Alphabetic |
| 𝔻 | DD | Alphabetic |
| Δ | Delta | Alphabetic |
| Ϝ | Digamma | Alphabetic |
| 𝔼 | EE | Alphabetic |
| Ε | Epsilon | Alphabetic |
| Η | Eta | Alphabetic |
| 𝔽 | FF | Alphabetic |
| 𝔾 | GG | Alphabetic |
| Γ | Gamma | Alphabetic |
| ℍ | HH | Alphabetic |
| 𝕀 | II | Alphabetic |
| ℑ | Im | Alphabetic |
| Ι | Iota | Alphabetic |
| 𝕁 | JJ | Alphabetic |
| 𝕂 | KK | Alphabetic |
| Ϗ | Kai | None |
| Κ | Kappa | Alphabetic |
| 𝕃 | LL | Alphabetic |
| Λ | Lambda | Alphabetic |
| 𝕄 | MM | Alphabetic |
| Μ | Mu | Alphabetic |
| ℕ | NN | Alphabetic |
| Ν | Nu | Alphabetic |
| 𝕆 | OO | Alphabetic |
| Ω | Omega | Alphabetic |
| ℧ | Omega.inv | Normal |
| Ο | Omicron | Alphabetic |
| ℙ | PP | Alphabetic |
| Φ | Phi | Alphabetic |
| Π | Pi | Alphabetic |
| Ψ | Psi | Alphabetic |
| ℚ | QQ | Alphabetic |
| ℝ | RR | Alphabetic |
| ℜ | Re | Alphabetic |
| Ρ | Rho | Alphabetic |
| 𝕊 | SS | Alphabetic |
| Ш | Sha | Alphabetic |
| Σ | Sigma | Alphabetic |
| 𝕋 | TT | Alphabetic |
| Τ | Tau | Alphabetic |
| Θ | Theta | Alphabetic |
| ϴ | Theta.alt | Alphabetic |
| 𝕌 | UU | Alphabetic |
| Υ | Upsilon | None |
| 𝕍 | VV | Alphabetic |
| 𝕎 | WW | Alphabetic |
| 𝕏 | XX | Alphabetic |
| Ξ | Xi | Alphabetic |
| 𝕐 | YY | Alphabetic |
| ℤ | ZZ | Alphabetic |
| Ζ | Zeta | Alphabetic |
| ´ | acute | Normal |
| ˝ | acute.double | None |
| ؋ | afghani | None |
| א | alef | None |
| א | aleph | None |
| α | alpha | Alphabetic |
| & | amp | Normal |
| ⅋ | amp.inv | Binary |
| ∧ | and | Binary |
| ⋀ | and.big | Large |
| ⋏ | and.curly | Binary |
| ⟑ | and.dot | Binary |
| ⩓ | and.double | Binary |
| ∠ | angle | Normal |
| ⟨ | angle.l | Opening |
| ⧼ | angle.l.curly | Opening |
| ⦑ | angle.l.dot | Opening |
| ⟪ | angle.l.double | Opening |
| ⟩ | angle.r | Closing |
| ⧽ | angle.r.curly | Closing |
| ⦒ | angle.r.dot | Closing |
| ⟫ | angle.r.double | Closing |
| ⦟ | angle.acute | Normal |
| ∡ | angle.arc | Normal |
| ⦛ | angle.arc.rev | Normal |
| ⍼ | angle.azimuth | Relation |
| ⦦ | angle.obtuse | Normal |
| ⦦ | angle.oblique | Normal |
| ⦣ | angle.rev | Normal |
| ∟ | angle.right | Normal |
| ⯾ | angle.right.rev | None |
| ⊾ | angle.right.arc | Normal |
| ⦝ | angle.right.dot | Normal |
| ⦜ | angle.right.square | Normal |
| ⦜ | angle.right.sq | Normal |
| ⦞ | angle.s | Normal |
| ⟀ | angle.spatial | Normal |
| ∢ | angle.spheric | Normal |
| ⦠ | angle.spheric.rev | Normal |
| ⦡ | angle.spheric.t | Normal |
| ⦡ | angle.spheric.top | Normal |
| Å | angstrom | None |
| ⍼ | angzarr | Relation |
| ≈ | approx | Relation |
| ≊ | approx.eq | Relation |
| ≉ | approx.not | Relation |
| → | arrow.r | Relation |
| ⟼ | arrow.r.long.bar | Relation |
| ↦ | arrow.r.bar | Relation |
| ⤷ | arrow.r.curve | Relation |
| ⮎ | arrow.r.turn | None |
| ⇢ | arrow.r.dashed | Relation |
| ⤑ | arrow.r.dotted | Relation |
| ⇒ | arrow.r.double | Relation |
| ⤇ | arrow.r.double.bar | Relation |
| ⟹ | arrow.r.double.long | Relation |
| ⟾ | arrow.r.double.long.bar | Relation |
| ⇏ | arrow.r.double.not | Relation |
| ⤃ | arrow.r.double.struck | Relation |
| ➡︎ | arrow.r.filled | None |
| ↪︎ | arrow.r.hook | Relation |
| ⟶ | arrow.r.long | Relation |
| ⟿ | arrow.r.long.squiggly | Relation |
| ↬ | arrow.r.loop | Relation |
| ↛ | arrow.r.not | Relation |
| ⭆ | arrow.r.quad | Relation |
| ⇝ | arrow.r.squiggly | Relation |
| ⇥ | arrow.r.stop | Relation |
| ⇨ | arrow.r.stroked | Relation |
| ⇸ | arrow.r.struck | Relation |
| ⇻ | arrow.r.dstruck | Relation |
| ↣ | arrow.r.tail | Relation |
| ⤔ | arrow.r.tail.struck | Relation |
| ⤕ | arrow.r.tail.dstruck | Relation |
| ⥲ | arrow.r.tilde | Relation |
| ⇛ | arrow.r.triple | Relation |
| ↠ | arrow.r.twohead | Relation |
| ⤅ | arrow.r.twohead.bar | Relation |
| ⤀ | arrow.r.twohead.struck | Relation |
| ⤁ | arrow.r.twohead.dstruck | Relation |
| ⤖ | arrow.r.twohead.tail | Relation |
| ⤗ | arrow.r.twohead.tail.struck | Relation |
| ⤘ | arrow.r.twohead.tail.dstruck | Relation |
| ⇾ | arrow.r.open | Relation |
| ↝ | arrow.r.wave | Relation |
| ← | arrow.l | Relation |
| ↤ | arrow.l.bar | Relation |
| ⤶ | arrow.l.curve | Relation |
| ⮌ | arrow.l.turn | None |
| ⇠ | arrow.l.dashed | Relation |
| ⬸ | arrow.l.dotted | Relation |
| ⇐ | arrow.l.double | Relation |
| ⤆ | arrow.l.double.bar | Relation |
| ⟸ | arrow.l.double.long | Relation |
| ⟽ | arrow.l.double.long.bar | Relation |
| ⇍ | arrow.l.double.not | Relation |
| ⤂ | arrow.l.double.struck | Relation |
| ⬅︎ | arrow.l.filled | Relation |
| ↩︎ | arrow.l.hook | Relation |
| ⟵ | arrow.l.long | Relation |
| ⟻ | arrow.l.long.bar | Relation |
| ⬳ | arrow.l.long.squiggly | Relation |
| ↫ | arrow.l.loop | Relation |
| ↚ | arrow.l.not | Relation |
| ⭅ | arrow.l.quad | Relation |
| ⇜ | arrow.l.squiggly | Relation |
| ⇤ | arrow.l.stop | Relation |
| ⇦ | arrow.l.stroked | Relation |
| ⇷ | arrow.l.struck | Relation |
| ⇺ | arrow.l.dstruck | Relation |
| ↢ | arrow.l.tail | Relation |
| ⬹ | arrow.l.tail.struck | Relation |
| ⬺ | arrow.l.tail.dstruck | Relation |
| ⭉ | arrow.l.tilde | Relation |
| ⇚ | arrow.l.triple | Relation |
| ↞ | arrow.l.twohead | Relation |
| ⬶ | arrow.l.twohead.bar | Relation |
| ⬴ | arrow.l.twohead.struck | Relation |
| ⬵ | arrow.l.twohead.dstruck | Relation |
| ⬻ | arrow.l.twohead.tail | Relation |
| ⬼ | arrow.l.twohead.tail.struck | Relation |
| ⬽ | arrow.l.twohead.tail.dstruck | Relation |
| ⇽ | arrow.l.open | Relation |
| ↜ | arrow.l.wave | Relation |
| ↑ | arrow.t | Relation |
| ↥ | arrow.t.bar | Relation |
| ⤴︎ | arrow.t.curve | Relation |
| ⮍ | arrow.t.turn | None |
| ⇡ | arrow.t.dashed | Relation |
| ⇑ | arrow.t.double | Relation |
| ⬆︎ | arrow.t.filled | Relation |
| ⟰ | arrow.t.quad | Relation |
| ⤒ | arrow.t.stop | Relation |
| ⇧ | arrow.t.stroked | Relation |
| ⤉ | arrow.t.struck | Relation |
| ⇞ | arrow.t.dstruck | Relation |
| ⤊ | arrow.t.triple | Relation |
| ↟ | arrow.t.twohead | Relation |
| ↓ | arrow.b | Relation |
| ↧ | arrow.b.bar | Relation |
| ⤵︎ | arrow.b.curve | Relation |
| ⮏ | arrow.b.turn | None |
| ⇣ | arrow.b.dashed | Relation |
| ⇓ | arrow.b.double | Relation |
| ⬇︎ | arrow.b.filled | Relation |
| ⟱ | arrow.b.quad | Relation |
| ⤓ | arrow.b.stop | Relation |
| ⇩ | arrow.b.stroked | Relation |
| ⤈ | arrow.b.struck | Relation |
| ⇟ | arrow.b.dstruck | Relation |
| ⤋ | arrow.b.triple | Relation |
| ↡ | arrow.b.twohead | Relation |
| ↔︎ | arrow.l.r | Relation |
| ⇔ | arrow.l.r.double | Relation |
| ⟺ | arrow.l.r.double.long | Relation |
| ⇎ | arrow.l.r.double.not | Relation |
| ⤄ | arrow.l.r.double.struck | Relation |
| ⬌ | arrow.l.r.filled | Relation |
| ⟷ | arrow.l.r.long | Relation |
| ↮ | arrow.l.r.not | Relation |
| ⬄ | arrow.l.r.stroked | Relation |
| ⇹ | arrow.l.r.struck | Relation |
| ⇼ | arrow.l.r.dstruck | Relation |
| ⇿ | arrow.l.r.open | Relation |
| ↭ | arrow.l.r.wave | Relation |
| ↕︎ | arrow.t.b | Relation |
| ⇕ | arrow.t.b.double | Relation |
| ⬍ | arrow.t.b.filled | Relation |
| ⇳ | arrow.t.b.stroked | Relation |
| ↗︎ | arrow.tr | Relation |
| ⇗ | arrow.tr.double | Relation |
| ⬈ | arrow.tr.filled | Relation |
| ⤤ | arrow.tr.hook | Relation |
| ⬀ | arrow.tr.stroked | Relation |
| ↘︎ | arrow.br | Relation |
| ⇘ | arrow.br.double | Relation |
| ⬊ | arrow.br.filled | Relation |
| ⤥ | arrow.br.hook | Relation |
| ⬂ | arrow.br.stroked | Relation |
| ↖︎ | arrow.tl | Relation |
| ⇖ | arrow.tl.double | Relation |
| ⬉ | arrow.tl.filled | Relation |
| ⤣ | arrow.tl.hook | Relation |
| ⬁ | arrow.tl.stroked | Relation |
| ↙︎ | arrow.bl | Relation |
| ⇙ | arrow.bl.double | Relation |
| ⬋ | arrow.bl.filled | Relation |
| ⤦ | arrow.bl.hook | Relation |
| ⬃ | arrow.bl.stroked | Relation |
| ⤡ | arrow.tl.br | Relation |
| ⤢ | arrow.tr.bl | Relation |
| ↺ | arrow.ccw | Relation |
| ↶ | arrow.ccw.half | Relation |
| ↻ | arrow.cw | Relation |
| ↷ | arrow.cw.half | Relation |
| ↯ | arrow.zigzag | Relation |
| ⌃ | arrowhead.t | None |
| ⌄ | arrowhead.b | None |
| ⇉ | arrows.rr | Relation |
| ⇇ | arrows.ll | Relation |
| ⇈ | arrows.tt | Relation |
| ⇊ | arrows.bb | Relation |
| ⇆ | arrows.lr | Relation |
| ↹ | arrows.lr.stop | None |
| ⇄ | arrows.rl | Relation |
| ⇅ | arrows.tb | Relation |
| ⇵ | arrows.bt | Relation |
| ⇶ | arrows.rrr | Relation |
| ⬱ | arrows.lll | Relation |
| ∗ | ast.op | Binary |
| ⊛ | ast.op.o | Binary |
| *︎ | ast.basic | Normal |
| ⁎ | ast.low | Binary |
| ⁑ | ast.double | Normal |
| ⁂ | ast.triple | None |
| ﹡ | ast.small | Special |
| ⊛ | ast.circle | Binary |
| ⧆ | ast.square | Binary |
| ≍ | asymp | Relation |
| ≭ | asymp.not | Relation |
| @ | at | Normal |
| \\ | backslash | Binary |
| ⦸ | backslash.o | Binary |
| ⦸ | backslash.circle | Binary |
| ⧷ | backslash.not | Binary |
| ⟅ | bag.l | Opening |
| ⟆ | bag.r | Closing |
| ฿ | baht | None |
| ☐ | ballot | None |
| ☒ | ballot.cross | None |
| ☑︎ | ballot.check | None |
| 🗹 | ballot.check.heavy | None |
| \| | bar.v | Fence |
| ‖ | bar.v.double | Fence |
| ⦀ | bar.v.triple | Fence |
| ¦ | bar.v.broken | Normal |
| ⦶ | bar.v.o | Binary |
| ⦶ | bar.v.circle | Binary |
| ― | bar.h | None |
| ∵ | because | Relation |
| ב | bet | None |
| β | beta | Alphabetic |
| ϐ | beta.alt | Alphabetic |
| ב | beth | None |
| ₿ | bitcoin | None |
| ⊥ | bot | Normal |
| \{ | brace.l | Opening |
| ⦃ | brace.l.stroked | Opening |
| ⦃ | brace.l.double | Opening |
| \} | brace.r | Closing |
| ⦄ | brace.r.stroked | Closing |
| ⦄ | brace.r.double | Closing |
| ⏞ | brace.t | Normal |
| ⏟ | brace.b | Normal |
| [ | bracket.l | Opening |
| ⦍ | bracket.l.tick.t | Opening |
| ⦏ | bracket.l.tick.b | Opening |
| ⟦ | bracket.l.stroked | Opening |
| ⟦ | bracket.l.double | Opening |
| ] | bracket.r | Closing |
| ⦐ | bracket.r.tick.t | Closing |
| ⦎ | bracket.r.tick.b | Closing |
| ⟧ | bracket.r.stroked | Closing |
| ⟧ | bracket.r.double | Closing |
| ⎴ | bracket.t | Normal |
| ⎵ | bracket.b | Normal |
| ˘ | breve | Diacritic |
| • | bullet | Binary |
| ∙ | bullet.op | Binary |
| ⦿ | bullet.o | Normal |
| ◦ | bullet.stroked | Binary |
| ⦾ | bullet.stroked.o | Normal |
| ◘ | bullet.hole | None |
| ⁃ | bullet.hyph | None |
| ‣ | bullet.tri | None |
| ⁌ | bullet.l | None |
| ⁍ | bullet.r | None |
| ‸ | caret | None |
| ˇ | caron | Diacritic |
| 🅭 | cc | None |
| 🅯 | cc.by | None |
| 🄏 | cc.nc | None |
| ⊜ | cc.nd | Binary |
| 🅮 | cc.public | None |
| 🄎 | cc.sa | None |
| 🄍 | cc.zero | None |
| ₵ | cedi | None |
| ⌈ | ceil.l | Opening |
| ⌉ | ceil.r | Closing |
| ¢ | cent | Normal |
| ✓ | checkmark | Normal |
| 🗸 | checkmark.light | None |
| ✔︎ | checkmark.heavy | None |
| ⟨ | chevron.l | Opening |
| ⧼ | chevron.l.curly | Opening |
| ⦑ | chevron.l.dot | Opening |
| ⦉ | chevron.l.closed | Opening |
| ⟪ | chevron.l.double | Opening |
| ⟩ | chevron.r | Closing |
| ⧽ | chevron.r.curly | Closing |
| ⦒ | chevron.r.dot | Closing |
| ⦊ | chevron.r.closed | Closing |
| ⟫ | chevron.r.double | Closing |
| χ | chi | Alphabetic |
| ○ | circle.stroked | Binary |
| ∘ | circle.stroked.tiny | Binary |
| ⚬ | circle.stroked.small | Normal |
| ◯ | circle.stroked.big | Normal |
| ● | circle.filled | Normal |
| ⦁ | circle.filled.tiny | Normal |
| ∙ | circle.filled.small | Binary |
| ⬤ | circle.filled.big | Normal |
| ◌ | circle.dotted | None |
| ⊚ | circle.nested | Binary |
| ℅ | co | None |
| : | colon | Relation |
| ₡ | colon.currency | None |
| ∷ | colon.double | Relation |
| ⁝ | colon.tri | None |
| ⫶ | colon.tri.op | Binary |
| ≔ | colon.eq | Relation |
| ⩴ | colon.double.eq | Relation |
| , | comma | Punctuation |
| ⸲ | comma.inv | None |
| ⹁ | comma.rev | None |
| ∁ | complement | Unary |
| ∘ | compose | Binary |
| ⊚ | compose.o | Binary |
| ∗ | convolve | Binary |
| ⊛ | convolve.o | Binary |
| 🄯 | copyleft | None |
| ©︎ | copyright | None |
| ℗ | copyright.sound | None |
| ⌜ | corner.l.t | Opening |
| ⌞ | corner.l.b | Opening |
| ⌝ | corner.r.t | Closing |
| ⌟ | corner.r.b | Closing |
| ✗ | crossmark | Normal |
| ✘ | crossmark.heavy | None |
| ¤ | currency | Normal |
| † | dagger | Relation |
| ‡ | dagger.double | Relation |
| ⹋ | dagger.triple | None |
| ⸶ | dagger.l | None |
| ⸷ | dagger.r | None |
| ⸸ | dagger.inv | None |
| ד | dalet | None |
| ד | daleth | None |
| – | dash.en | Punctuation |
| — | dash.em | Punctuation |
| ⸺ | dash.em.two | None |
| ⸻ | dash.em.three | None |
| ‒ | dash.fig | Punctuation |
| ∹ | dash.colon | Relation |
| ⊝ | dash.o | Binary |
| ⊝ | dash.circle | Binary |
| 〜 | dash.wave | None |
| 〰︎ | dash.wave.double | None |
| ° | degree | Normal |
| δ | delta | Alphabetic |
| ¨ | diaer | Diacritic |
| ⌀ | diameter | Normal |
| ◇ | diamond.stroked | Normal |
| ⋄ | diamond.stroked.small | Binary |
| ⬦ | diamond.stroked.medium | Normal |
| ⟐ | diamond.stroked.dot | Normal |
| ◆ | diamond.filled | Normal |
| ⬥ | diamond.filled.medium | Normal |
| ⬩ | diamond.filled.small | Normal |
| ⚅ | die.six | Normal |
| ⚄ | die.five | Normal |
| ⚃ | die.four | Normal |
| ⚂ | die.three | Normal |
| ⚁ | die.two | Normal |
| ⚀ | die.one | Normal |
| ∂ | diff | Normal |
| ϝ | digamma | Alphabetic |
| ÷ | div | Binary |
| ⨸ | div.o | Binary |
| ⦼ | div.slanted.o | Normal |
| ⨸ | div.circle | Binary |
| ∣ | divides | Relation |
| ∤ | divides.not | Relation |
| ⫮ | divides.not.rev | Relation |
| ⟊ | divides.struck | Relation |
| $ | dollar | Normal |
| ₫ | dong | None |
| ߾ | dorome | None |
| ⋅ | dot.op | Binary |
| . | dot.basic | Normal |
| · | dot.c | Binary |
| ⊙ | dot.o | Binary |
| ⨀ | dot.o.big | Large |
| ⊙ | dot.circle | Binary |
| ⨀ | dot.circle.big | Large |
| ⊡ | dot.square | Binary |
| ¨ | dot.double | Diacritic |
| ⃛ | dot.triple | Diacritic |
| ⃜ | dot.quad | Diacritic |
| ı | dotless.i | Alphabetic |
| ȷ | dotless.j | Alphabetic |
| ⋯ | dots.h.c | Normal |
| … | dots.h | Normal |
| ⋮ | dots.v | Normal |
| ⋱ | dots.down | Normal |
| ⋰ | dots.up | Normal |
| ֏ | dram | None |
| 🜨 | earth | None |
| ♁ | earth.alt | Normal |
| ℓ | ell | Alphabetic |
| ⬭ | ellipse.stroked.h | Normal |
| ⬯ | ellipse.stroked.v | Normal |
| ⬬ | ellipse.filled.h | Normal |
| ⬮ | ellipse.filled.v | Normal |
| ∅ | emptyset | Normal |
| ⦳ | emptyset.arrow.r | Normal |
| ⦴ | emptyset.arrow.l | Normal |
| ⦱ | emptyset.bar | Normal |
| ⦲ | emptyset.circle | Normal |
| ⦰ | emptyset.rev | Normal |
| ε | epsilon | Alphabetic |
| ϵ | epsilon.alt | Alphabetic |
| ϶ | epsilon.alt.rev | Normal |
| = | eq | Relation |
| ≛ | eq.star | Relation |
| ⊜ | eq.o | Binary |
| ⊜ | eq.circle | Binary |
| ≕ | eq.colon | Relation |
| ≑ | eq.dots | Relation |
| ≒ | eq.dots.down | Relation |
| ≓ | eq.dots.up | Relation |
| ≝ | eq.def | Relation |
| ≜ | eq.delta | Relation |
| ≚ | eq.equi | Relation |
| ≙ | eq.est | Relation |
| ⋝ | eq.gt | Relation |
| ⋜ | eq.lt | Relation |
| ≞ | eq.m | Relation |
| ≠ | eq.not | Relation |
| ⋞ | eq.prec | Relation |
| ≟ | eq.quest | Relation |
| ﹦ | eq.small | Special |
| ⋟ | eq.succ | Relation |
| ≡ | eq.triple | Relation |
| ≢ | eq.triple.not | Relation |
| ≣ | eq.quad | Relation |
| ≡ | equiv | Relation |
| ≢ | equiv.not | Relation |
| ⧮ | errorbar.square.stroked | Normal |
| ⧯ | errorbar.square.filled | Normal |
| ⧰ | errorbar.diamond.stroked | Normal |
| ⧱ | errorbar.diamond.filled | Normal |
| ⧲ | errorbar.circle.stroked | Normal |
| ⧳ | errorbar.circle.filled | Normal |
| η | eta | Alphabetic |
| € | euro | None |
| ! | excl | Normal |
| ‼︎ | excl.double | Normal |
| ¡ | excl.inv | Punctuation |
| ⁉︎ | excl.quest | None |
| ∃ | exists | Unary |
| ∄ | exists.not | Unary |
| ⧘ | fence.l | Opening |
| ⧚ | fence.l.double | Opening |
| ⧙ | fence.r | Closing |
| ⧛ | fence.r.double | Closing |
| ⦙ | fence.dotted | Fence |
| ♭ | flat | Normal |
| 𝄬 | flat.t | None |
| 𝄭 | flat.b | None |
| 𝄫 | flat.double | None |
| 𝄳 | flat.quarter | None |
| ⌊ | floor.l | Opening |
| ⌋ | floor.r | Closing |
| ❦ | floral | None |
| ☙ | floral.l | None |
| ❧ | floral.r | None |
| ∀ | forall | Unary |
| ⊩ | forces | Relation |
| ⊮ | forces.not | Relation |
| ₣ | franc | None |
| ⌢ | frown | Relation |
| γ | gamma | Alphabetic |
| ג | gimel | None |
| ג | gimmel | None |
| ∇ | gradient | Unary |
| \` | grave | Diacritic |
| \> | gt | Relation |
| ⧁ | gt.o | Binary |
| ⧁ | gt.circle | Binary |
| ⋗ | gt.dot | Relation |
| ⪆ | gt.approx | Relation |
| ≫ | gt.double | Relation |
| ≥ | gt.eq | Relation |
| ⩾ | gt.eq.slant | Relation |
| ⋛ | gt.eq.lt | Relation |
| ≱ | gt.eq.not | Relation |
| ≧ | gt.equiv | Relation |
| ≷ | gt.lt | Relation |
| ≹ | gt.lt.not | Relation |
| ⪈ | gt.neq | Relation |
| ⪊ | gt.napprox | Relation |
| ≩ | gt.nequiv | Relation |
| ≯ | gt.not | Relation |
| ⋧ | gt.ntilde | Relation |
| ﹥ | gt.small | Special |
| ≳ | gt.tilde | Relation |
| ≵ | gt.tilde.not | Relation |
| ⊳ | gt.tri | Relation |
| ⊵ | gt.tri.eq | Relation |
| ⋭ | gt.tri.eq.not | Relation |
| ⋫ | gt.tri.not | Relation |
| ⋙ | gt.triple | Relation |
| ⫸ | gt.triple.nested | Relation |
| ₲ | guarani | None |
| ⇀ | harpoon.rt | Relation |
| ⥛ | harpoon.rt.bar | Relation |
| ⥓ | harpoon.rt.stop | Relation |
| ⇁ | harpoon.rb | Relation |
| ⥟ | harpoon.rb.bar | Relation |
| ⥗ | harpoon.rb.stop | Relation |
| ↼ | harpoon.lt | Relation |
| ⥚ | harpoon.lt.bar | Relation |
| ⥒ | harpoon.lt.stop | Relation |
| ↽ | harpoon.lb | Relation |
| ⥞ | harpoon.lb.bar | Relation |
| ⥖ | harpoon.lb.stop | Relation |
| ↿ | harpoon.tl | Relation |
| ⥠ | harpoon.tl.bar | Relation |
| ⥘ | harpoon.tl.stop | Relation |
| ↾ | harpoon.tr | Relation |
| ⥜ | harpoon.tr.bar | Relation |
| ⥔ | harpoon.tr.stop | Relation |
| ⇃ | harpoon.bl | Relation |
| ⥡ | harpoon.bl.bar | Relation |
| ⥙ | harpoon.bl.stop | Relation |
| ⇂ | harpoon.br | Relation |
| ⥝ | harpoon.br.bar | Relation |
| ⥕ | harpoon.br.stop | Relation |
| ⥎ | harpoon.lt.rt | Relation |
| ⥐ | harpoon.lb.rb | Relation |
| ⥋ | harpoon.lb.rt | Relation |
| ⥊ | harpoon.lt.rb | Relation |
| ⥑ | harpoon.tl.bl | Relation |
| ⥏ | harpoon.tr.br | Relation |
| ⥍ | harpoon.tl.br | Relation |
| ⥌ | harpoon.tr.bl | Relation |
| ⥤ | harpoons.rtrb | Relation |
| ⥥ | harpoons.blbr | Relation |
| ⥯ | harpoons.bltr | Relation |
| ⥧ | harpoons.lbrb | Relation |
| ⥢ | harpoons.ltlb | Relation |
| ⇋ | harpoons.ltrb | Relation |
| ⥦ | harpoons.ltrt | Relation |
| ⥩ | harpoons.rblb | Relation |
| ⇌ | harpoons.rtlb | Relation |
| ⥨ | harpoons.rtlt | Relation |
| ⥮ | harpoons.tlbr | Relation |
| ⥣ | harpoons.tltr | Relation |
| #︎ | hash | Normal |
| ^ | hat | Normal |
| ⬡ | hexa.stroked | Normal |
| ⬢ | hexa.filled | Normal |
| ⧖ | hourglass.stroked | Binary |
| ⧗ | hourglass.filled | Binary |
| ₴ | hryvnia | None |
| ‐ | hyph | Punctuation |
| \- | hyph.minus | Normal |
| ‑ | hyph.nobreak | None |
| ‧ | hyph.point | None |
| | hyph.soft | None |
| ⊷ | image | Relation |
| ∈ | in | Relation |
| ∉ | in.not | Relation |
| ∋ | in.rev | Relation |
| ∌ | in.rev.not | Relation |
| ∍ | in.rev.small | Relation |
| ∊ | in.small | Relation |
| ∞ | infinity | Normal |
| ⧞ | infinity.bar | Normal |
| ⧜ | infinity.incomplete | Normal |
| ⧝ | infinity.tie | Normal |
| ∫ | integral | Large |
| ⨗ | integral.arrow.hook | Large |
| ⨑ | integral.ccw | Large |
| ∮ | integral.cont | Large |
| ∳ | integral.cont.ccw | Large |
| ∲ | integral.cont.cw | Large |
| ∱ | integral.cw | Large |
| ⨍ | integral.dash | Large |
| ⨎ | integral.dash.double | Large |
| ∬ | integral.double | Large |
| ⨌ | integral.quad | Large |
| ⨙ | integral.inter | Large |
| ⨙ | integral.sect | Large |
| ⨏ | integral.slash | Large |
| ⨖ | integral.square | Large |
| ∯ | integral.surf | Large |
| ⨘ | integral.times | Large |
| ∭ | integral.triple | Large |
| ⨚ | integral.union | Large |
| ∰ | integral.vol | Large |
| ∩ | inter | Binary |
| ⩄ | inter.and | Binary |
| ⋂ | inter.big | Large |
| ⩀ | inter.dot | Binary |
| ⋒ | inter.double | Binary |
| ⊓ | inter.sq | Binary |
| ⨅ | inter.sq.big | Large |
| ⩎ | inter.sq.double | Binary |
| ⫴ | interleave | Binary |
| ⫼ | interleave.big | Large |
| ⫵ | interleave.struck | Binary |
| ‽ | interrobang | None |
| ⸘ | interrobang.inv | None |
| ι | iota | Alphabetic |
| ℩ | iota.inv | Normal |
| ⨝ | join | Large |
| ⟖ | join.r | Large |
| ⟕ | join.l | Large |
| ⟗ | join.l.r | Large |
| ♃ | jupiter | Normal |
| ϗ | kai | None |
| κ | kappa | Alphabetic |
| ϰ | kappa.alt | Alphabetic |
| ₭ | kip | None |
| λ | lambda | Alphabetic |
| ∆ | laplace | Unary |
| ₾ | lari | None |
| ⪫ | lat | Relation |
| ⪭ | lat.eq | Relation |
| ₺ | lira | None |
| ◊ | lozenge.stroked | Binary |
| ⬫ | lozenge.stroked.small | Normal |
| ⬨ | lozenge.stroked.medium | Normal |
| ⧫ | lozenge.filled | Binary |
| ⬪ | lozenge.filled.small | Normal |
| ⬧ | lozenge.filled.medium | Normal |
| | lrm | None |
| \< | lt | Relation |
| ⧀ | lt.o | Binary |
| ⧀ | lt.circle | Binary |
| ⋖ | lt.dot | Relation |
| ⪅ | lt.approx | Relation |
| ≪ | lt.double | Relation |
| ≤ | lt.eq | Relation |
| ⩽ | lt.eq.slant | Relation |
| ⋚ | lt.eq.gt | Relation |
| ≰ | lt.eq.not | Relation |
| ≦ | lt.equiv | Relation |
| ≶ | lt.gt | Relation |
| ≸ | lt.gt.not | Relation |
| ⪇ | lt.neq | Relation |
| ⪉ | lt.napprox | Relation |
| ≨ | lt.nequiv | Relation |
| ≮ | lt.not | Relation |
| ⋦ | lt.ntilde | Relation |
| ﹤ | lt.small | Special |
| ≲ | lt.tilde | Relation |
| ≴ | lt.tilde.not | Relation |
| ⊲ | lt.tri | Relation |
| ⊴ | lt.tri.eq | Relation |
| ⋬ | lt.tri.eq.not | Relation |
| ⋪ | lt.tri.not | Relation |
| ⋘ | lt.triple | Relation |
| ⫷ | lt.triple.nested | Relation |
| ¯ | macron | Diacritic |
| ✠ | maltese | Normal |
| ₼ | manat | None |
| ↦ | mapsto | Relation |
| ⟼ | mapsto.long | Relation |
| ♂︎ | mars | Normal |
| ☿ | mercury | Normal |
| − | minus | Vary |
| ⊖ | minus.o | Binary |
| ⊖ | minus.circle | Binary |
| ∸ | minus.dot | Binary |
| ∓ | minus.plus | Vary |
| ⊟ | minus.square | Binary |
| ≂ | minus.tilde | Relation |
| ⨺ | minus.triangle | Binary |
| ⧿ | miny | Binary |
| ⊧ | models | Relation |
| μ | mu | Alphabetic |
| ⊸ | multimap | Relation |
| ⧟ | multimap.double | Relation |
| ⎰ | mustache.l | Opening |
| ⎱ | mustache.r | Closing |
| ∇ | nabla | Unary |
| ₦ | naira | None |
| ♮ | natural | Normal |
| 𝄮 | natural.t | None |
| 𝄯 | natural.b | None |
| ♆ | neptune | Normal |
| ⯉ | neptune.alt | None |
| ¬ | not | Unary |
| 🎜 | note.up | None |
| 🎝 | note.down | None |
| 𝅝 | note.whole | None |
| 𝅗𝅥 | note.half | None |
| 𝅘𝅥 | note.quarter | None |
| ♩ | note.quarter.alt | Normal |
| 𝅘𝅥𝅮 | note.eighth | None |
| ♪ | note.eighth.alt | None |
| ♫ | note.eighth.beamed | None |
| 𝅘𝅥𝅯 | note.sixteenth | None |
| ♬ | note.sixteenth.beamed | None |
| 𝆕 | note.grace | None |
| 𝆔 | note.grace.slash | None |
| ∅ | nothing | Normal |
| ⦳ | nothing.arrow.r | Normal |
| ⦴ | nothing.arrow.l | Normal |
| ⦱ | nothing.bar | Normal |
| ⦲ | nothing.circle | Normal |
| ⦰ | nothing.rev | Normal |
| ν | nu | Alphabetic |
| № | numero | None |
| ω | omega | Alphabetic |
| ο | omicron | Alphabetic |
| ∞ | oo | Normal |
| ∨ | or | Binary |
| ⋁ | or.big | Large |
| ⋎ | or.curly | Binary |
| ⟇ | or.dot | Binary |
| ⩔ | or.double | Binary |
| ⊶ | original | Relation |
| ∥ | parallel | Relation |
| ⫲ | parallel.struck | Relation |
| ⦷ | parallel.o | Binary |
| ⦷ | parallel.circle | Binary |
| ⋕ | parallel.eq | Relation |
| ⩨ | parallel.equiv | Relation |
| ∦ | parallel.not | Relation |
| ⧣ | parallel.slanted.eq | Relation |
| ⧤ | parallel.slanted.eq.tilde | Relation |
| ⧥ | parallel.slanted.equiv | Relation |
| ⫳ | parallel.tilde | Relation |
| ▱ | parallelogram.stroked | Normal |
| ▰ | parallelogram.filled | Normal |
| ( | paren.l | Opening |
| ⟮ | paren.l.flat | Opening |
| ⦇ | paren.l.closed | Opening |
| ⦅ | paren.l.stroked | Opening |
| ⦅ | paren.l.double | Opening |
| ) | paren.r | Closing |
| ⟯ | paren.r.flat | Closing |
| ⦈ | paren.r.closed | Closing |
| ⦆ | paren.r.stroked | Closing |
| ⦆ | paren.r.double | Closing |
| ⏜ | paren.t | Normal |
| ⏝ | paren.b | Normal |
| ∂ | partial | Normal |
| $ | pataca | Normal |
| ⬠ | penta.stroked | Normal |
| ⬟ | penta.filled | Normal |
| % | percent | Normal |
| ‰ | permille | None |
| ‱ | permyriad | None |
| ⟂ | perp | Relation |
| ⦹ | perp.o | Binary |
| ⦹ | perp.circle | Binary |
| $ | peso | Normal |
| ₱ | peso.philippine | None |
| φ | phi | Alphabetic |
| ϕ | phi.alt | Alphabetic |
| π | pi | Alphabetic |
| ϖ | pi.alt | Alphabetic |
| ¶ | pilcrow | Normal |
| ⁋ | pilcrow.rev | None |
| ħ | planck | None |
| ħ | planck.reduce | None |
| + | plus | Vary |
| ⊕ | plus.o | Binary |
| ⨭ | plus.o.l | Binary |
| ⨮ | plus.o.r | Binary |
| ⟴ | plus.o.arrow | Relation |
| ⨁ | plus.o.big | Large |
| ⊕ | plus.circle | Binary |
| ⟴ | plus.circle.arrow | Relation |
| ⨁ | plus.circle.big | Large |
| ∔ | plus.dot | Binary |
| ⧺ | plus.double | Binary |
| ± | plus.minus | Vary |
| ﹢ | plus.small | Special |
| ⊞ | plus.square | Binary |
| ⨹ | plus.triangle | Binary |
| ⧻ | plus.triple | Binary |
| £ | pound | Normal |
| ⏻ | power.standby | None |
| ⏽ | power.on | None |
| ⭘ | power.off | None |
| ⏼ | power.on.off | None |
| ⏾ | power.sleep | None |
| ≺ | prec | Relation |
| ⪷ | prec.approx | Relation |
| ≼ | prec.curly.eq | Relation |
| ⋠ | prec.curly.eq.not | Relation |
| ⪻ | prec.double | Relation |
| ⪯ | prec.eq | Relation |
| ⪳ | prec.equiv | Relation |
| ⪹ | prec.napprox | Relation |
| ⪱ | prec.neq | Relation |
| ⪵ | prec.nequiv | Relation |
| ⊀ | prec.not | Relation |
| ⋨ | prec.ntilde | Relation |
| ≾ | prec.tilde | Relation |
| ′ | prime | Normal |
| ‵ | prime.rev | Normal |
| ″ | prime.double | Normal |
| ‶ | prime.double.rev | Normal |
| ‴ | prime.triple | Normal |
| ‷ | prime.triple.rev | Normal |
| ⁗ | prime.quad | Normal |
| ∏ | product | Large |
| ∐ | product.co | Large |
| ∝ | prop | Relation |
| ψ | psi | Alphabetic |
| ∎ | qed | Normal |
| ? | quest | Punctuation |
| ⁇ | quest.double | None |
| ⁈ | quest.excl | None |
| ¿ | quest.inv | Punctuation |
| \" | quote.double | None |
| \' | quote.single | None |
| “ | quote.l.double | None |
| ‘ | quote.l.single | None |
| ” | quote.r.double | None |
| ’ | quote.r.single | None |
| « | quote.chevron.l.double | None |
| ‹ | quote.chevron.l.single | None |
| » | quote.chevron.r.double | None |
| › | quote.chevron.r.single | None |
| « | quote.angle.l.double | None |
| ‹ | quote.angle.l.single | None |
| » | quote.angle.r.double | None |
| › | quote.angle.r.single | None |
| ‟ | quote.high.double | None |
| ‛ | quote.high.single | None |
| „ | quote.low.double | None |
| ‚ | quote.low.single | None |
| ∶ | ratio | Relation |
| ▭ | rect.stroked.h | Normal |
| ▯ | rect.stroked.v | Normal |
| ▬ | rect.filled.h | None |
| ▮ | rect.filled.v | Normal |
| ※ | refmark | Normal |
| 𝄻 | rest.whole | None |
| 𝄺 | rest.multiple | None |
| 𝄩 | rest.multiple.measure | None |
| 𝄼 | rest.half | None |
| 𝄽 | rest.quarter | None |
| 𝄾 | rest.eighth | None |
| 𝄿 | rest.sixteenth | None |
| ρ | rho | Alphabetic |
| ϱ | rho.alt | Alphabetic |
| ៛ | riel | None |
| | rlm | None |
| ₽ | ruble | None |
| ₹ | rupee.indian | None |
| ₨ | rupee.generic | None |
| ௹ | rupee.tamil | None |
| 𞋿 | rupee.wancho | None |
| ♄ | saturn | Normal |
| ∩ | sect | Binary |
| ⩄ | sect.and | Binary |
| ⋂ | sect.big | Large |
| ⩀ | sect.dot | Binary |
| ⋒ | sect.double | Binary |
| ⊓ | sect.sq | Binary |
| ⨅ | sect.sq.big | Large |
| ⩎ | sect.sq.double | Binary |
| § | section | Normal |
| ; | semi | Punctuation |
| ⸵ | semi.inv | None |
| ⁏ | semi.rev | Relation |
| ш | sha | None |
| ♯ | sharp | Normal |
| 𝄰 | sharp.t | None |
| 𝄱 | sharp.b | None |
| 𝄪 | sharp.double | None |
| 𝄲 | sharp.quarter | None |
| ₪ | shekel | None |
| ❲ | shell.l | Opening |
| ⟬ | shell.l.stroked | Opening |
| ⦗ | shell.l.filled | Opening |
| ⟬ | shell.l.double | Opening |
| ❳ | shell.r | Closing |
| ⟭ | shell.r.stroked | Closing |
| ⦘ | shell.r.filled | Closing |
| ⟭ | shell.r.double | Closing |
| ⏠ | shell.t | Normal |
| ⏡ | shell.b | Normal |
| ש | shin | None |
| σ | sigma | Alphabetic |
| ς | sigma.alt | None |
| / | slash | Normal |
| ⊘ | slash.o | Binary |
| ⫽ | slash.double | Binary |
| ⫻ | slash.triple | Binary |
| ⧸ | slash.big | Large |
| ⨳ | smash | Binary |
| ⌣ | smile | Relation |
| ⪪ | smt | Relation |
| ⪬ | smt.eq | Relation |
| ⃀ | som | None |
| | space | Space |
| | space.nobreak | Space |
| | space.nobreak.narrow | None |
| | space.en | Space |
| | space.quad | Space |
| | space.third | Space |
| | space.quarter | Space |
| | space.sixth | Space |
| | space.med | Space |
| | space.fig | Space |
| | space.punct | None |
| | space.thin | Space |
| | space.hair | Space |
| □ | square.stroked | Normal |
| ▫︎ | square.stroked.tiny | Normal |
| ◽︎ | square.stroked.small | Binary |
| ◻︎ | square.stroked.medium | Binary |
| ⬜︎ | square.stroked.big | Normal |
| ⬚ | square.stroked.dotted | None |
| ▢ | square.stroked.rounded | None |
| ■ | square.filled | Normal |
| ▪︎ | square.filled.tiny | Normal |
| ◾︎ | square.filled.small | Binary |
| ◼︎ | square.filled.medium | Binary |
| ⬛︎ | square.filled.big | Normal |
| ⋆ | star.op | Binary |
| ☆ | star.stroked | Binary |
| ★ | star.filled | Binary |
| ⊂ | subset | Relation |
| ⪽ | subset.dot | Relation |
| ⋐ | subset.double | Relation |
| ⊆ | subset.eq | Relation |
| ⊈ | subset.eq.not | Relation |
| ⊑ | subset.eq.sq | Relation |
| ⋢ | subset.eq.sq.not | Relation |
| ⊊ | subset.neq | Relation |
| ⊄ | subset.not | Relation |
| ⊏ | subset.sq | Relation |
| ⋤ | subset.sq.neq | Relation |
| ≻ | succ | Relation |
| ⪸ | succ.approx | Relation |
| ≽ | succ.curly.eq | Relation |
| ⋡ | succ.curly.eq.not | Relation |
| ⪼ | succ.double | Relation |
| ⪰ | succ.eq | Relation |
| ⪴ | succ.equiv | Relation |
| ⪺ | succ.napprox | Relation |
| ⪲ | succ.neq | Relation |
| ⪶ | succ.nequiv | Relation |
| ⊁ | succ.not | Relation |
| ⋩ | succ.ntilde | Relation |
| ≿ | succ.tilde | Relation |
| ♣︎ | suit.club.filled | Normal |
| ♧ | suit.club.stroked | Normal |
| ♦︎ | suit.diamond.filled | Normal |
| ♢ | suit.diamond.stroked | Normal |
| ♥︎ | suit.heart.filled | Normal |
| ♡ | suit.heart.stroked | Normal |
| ♠︎ | suit.spade.filled | Normal |
| ♤ | suit.spade.stroked | Normal |
| ∑ | sum | Large |
| ⨋ | sum.integral | Large |
| ☉ | sun | Normal |
| ⊃ | supset | Relation |
| ⪾ | supset.dot | Relation |
| ⋑ | supset.double | Relation |
| ⊇ | supset.eq | Relation |
| ⊉ | supset.eq.not | Relation |
| ⊒ | supset.eq.sq | Relation |
| ⋣ | supset.eq.sq.not | Relation |
| ⊋ | supset.neq | Relation |
| ⊅ | supset.not | Relation |
| ⊐ | supset.sq | Relation |
| ⋥ | supset.sq.neq | Relation |
| ⊢ | tack.r | Relation |
| ⊬ | tack.r.not | Relation |
| ⟝ | tack.r.long | Relation |
| ⊦ | tack.r.short | Relation |
| ⊨ | tack.r.double | Relation |
| ⊭ | tack.r.double.not | Relation |
| ⊣ | tack.l | Relation |
| ⟞ | tack.l.long | Relation |
| ⫞ | tack.l.short | Relation |
| ⫤ | tack.l.double | Relation |
| ⊥ | tack.t | Normal |
| ⟘ | tack.t.big | Large |
| ⫫ | tack.t.double | Relation |
| ⫠ | tack.t.short | Relation |
| ⊤ | tack.b | Normal |
| ⟙ | tack.b.big | Large |
| ⫪ | tack.b.double | Relation |
| ⫟ | tack.b.short | Relation |
| ⟛ | tack.l.r | Relation |
| ৳ | taka | None |
| ߿ | taman | None |
| τ | tau | Alphabetic |
| ₸ | tenge | None |
| ∴ | therefore | Relation |
| θ | theta | Alphabetic |
| ϑ | theta.alt | Alphabetic |
| ∼ | tilde.op | Relation |
| ~ | tilde.basic | Normal |
| ⩪ | tilde.dot | Relation |
| ≃ | tilde.eq | Relation |
| ≄ | tilde.eq.not | Relation |
| ⋍ | tilde.eq.rev | Relation |
| ≅ | tilde.equiv | Relation |
| ≇ | tilde.equiv.not | Relation |
| ≆ | tilde.nequiv | Relation |
| ≁ | tilde.not | Relation |
| ∽ | tilde.rev | Relation |
| ≌ | tilde.rev.equiv | Relation |
| ≋ | tilde.triple | Relation |
| × | times | Binary |
| ⨉ | times.big | Large |
| ⊗ | times.o | Binary |
| ⨴ | times.o.l | Binary |
| ⨵ | times.o.r | Binary |
| ⨶ | times.o.hat | Binary |
| ⨂ | times.o.big | Large |
| ⊗ | times.circle | Binary |
| ⨂ | times.circle.big | Large |
| ⋇ | times.div | Binary |
| ⋋ | times.three.l | Binary |
| ⋌ | times.three.r | Binary |
| ⋉ | times.l | Binary |
| ⋊ | times.r | Binary |
| ⊠ | times.square | Binary |
| ⨻ | times.triangle | Binary |
| ⧾ | tiny | Binary |
| ₮ | togrog | None |
| ⊤ | top | Normal |
| ™︎ | trademark | None |
| ®︎ | trademark.registered | None |
| ℠ | trademark.service | None |
| △ | triangle.stroked.t | Binary |
| ▽ | triangle.stroked.b | Binary |
| ▷ | triangle.stroked.r | Binary |
| ◁ | triangle.stroked.l | Binary |
| ◺ | triangle.stroked.bl | Binary |
| ◿ | triangle.stroked.br | Binary |
| ◸ | triangle.stroked.tl | Binary |
| ◹ | triangle.stroked.tr | Binary |
| ▵ | triangle.stroked.small.t | Binary |
| ▿ | triangle.stroked.small.b | Binary |
| ▹ | triangle.stroked.small.r | Binary |
| ◃ | triangle.stroked.small.l | Binary |
| 🛆 | triangle.stroked.rounded | None |
| ⟁ | triangle.stroked.nested | Normal |
| ◬ | triangle.stroked.dot | Binary |
| ▲ | triangle.filled.t | Binary |
| ▼ | triangle.filled.b | Binary |
| ▶︎ | triangle.filled.r | Binary |
| ◀︎ | triangle.filled.l | Binary |
| ◣ | triangle.filled.bl | Normal |
| ◢ | triangle.filled.br | Normal |
| ◤ | triangle.filled.tl | Normal |
| ◥ | triangle.filled.tr | Normal |
| ▴ | triangle.filled.small.t | Binary |
| ▾ | triangle.filled.small.b | Binary |
| ▸ | triangle.filled.small.r | Binary |
| ◂ | triangle.filled.small.l | Binary |
| ∪ | union | Binary |
| ⊌ | union.arrow | Binary |
| ⋃ | union.big | Large |
| ⊍ | union.dot | Binary |
| ⨃ | union.dot.big | Large |
| ⋓ | union.double | Binary |
| ⩁ | union.minus | Binary |
| ⩅ | union.or | Binary |
| ⊎ | union.plus | Binary |
| ⨄ | union.plus.big | Large |
| ⊔ | union.sq | Binary |
| ⨆ | union.sq.big | Large |
| ⩏ | union.sq.double | Binary |
| υ | upsilon | Alphabetic |
| ⛢ | uranus | None |
| ♅ | uranus.alt | None |
| ♀︎ | venus | Normal |
| ∖ | without | Binary |
| | wj | None |
| ₩ | won | None |
| ≀ | wreath | Binary |
| ξ | xi | Alphabetic |
| ⊕ | xor | Binary |
| ⨁ | xor.big | Large |
| ¥ | yen | Normal |
| ¥ | yuan | Normal |
| ζ | zeta | Alphabetic |
| | zwj | None |
| | zwnj | None |
| | zws | Space |
docs/reference/syntax.md
# Syntax
Typst is a markup language. This means that you can use simple syntax to accomplish common layout tasks. The lightweight markup syntax is complemented by set and show rules, which let you style your document easily and automatically. All this is backed by a tightly integrated scripting language with built-in and user-defined functions.
## Modes
Typst has three syntactical modes: Markup, math, and code. Markup mode is the default in a Typst document, math mode lets you write mathematical formulas, and code mode lets you use Typst's scripting features.
You can switch to a specific mode at any point by referring to the following table:
| New mode | Syntax | Example |
| --- | --- | --- |
| Code | Prefix the code with `#` | `Number: #(1 + 2)` |
| Math | Surround equation with `$..$` | `$-x$ is the opposite of $x$` |
| Markup | Surround markup with `[..]` | `let name = [*Typst!*]` |
Once you have entered code mode with `#`, you don't need to use further hashes unless you switched back to markup or math mode in between.
## Markup
Typst provides built-in markup for the most common document elements. Most of the syntax elements are just shortcuts for a corresponding function. The table below lists all markup that is available and links to the best place to learn more about their syntax and usage.
| Name | Example | See |
| --- | --- | --- |
| Paragraph break | Blank line | [`parbreak`](/docs/reference/model/parbreak/) |
| Strong emphasis | `*strong*` | [`strong`](/docs/reference/model/strong/) |
| Emphasis | `_emphasis_` | [`emph`](/docs/reference/model/emph/) |
| Raw text | ``print(1)`` | [`raw`](/docs/reference/text/raw/) |
| Link | `https://typst.app/` | [`link`](/docs/reference/model/link/) |
| Label | `<intro>` | [`label`](/docs/reference/foundations/label/) |
| Reference | `@intro` | [`ref`](/docs/reference/model/ref/) |
| Heading | `= Heading` | [`heading`](/docs/reference/model/heading/) |
| Bullet list | `- item` | [`list`](/docs/reference/model/list/) |
| Numbered list | `+ item` | [`enum`](/docs/reference/model/enum/) |
| Term list | `/ Term: description` | [`terms`](/docs/reference/model/terms/) |
| Math | `$x^2$` | [Math](/docs/reference/math/) |
| Line break | `\` | [`linebreak`](/docs/reference/text/linebreak/) |
| Smart quote | `'single' or "double"` | [`smartquote`](/docs/reference/text/smartquote/) |
| Symbol shorthand | `~`, `---` | [Symbols](/docs/reference/symbols/sym/) |
| Code expression | `#rect(width: 1cm)` | [Scripting](/docs/reference/scripting/#expressions) |
| Character escape | `Tweet at us \#ad` | [Below](#escapes) |
| Comment | `/* block */`, `// line` | [Below](#comments) |
## Math mode
Math mode is a special markup mode that is used to typeset mathematical formulas. It is entered by wrapping an equation in `$` characters. This works both in markup and code. The equation will be typeset into its own block if it starts and ends with at least one space (e.g. `$ x^2 $`). Inline math can be produced by omitting the whitespace (e.g. `$x^2$`). An overview over the syntax specific to math mode follows:
| Name | Example | See |
| --- | --- | --- |
| Inline math | `$x^2$` | [Math](/docs/reference/math/) |
| Block-level math | `$ x^2 $` | [Math](/docs/reference/math/) |
| Bottom attachment | `$x_1$` | [`attach`](/docs/reference/math/attach/) |
| Top attachment | `$x^2$` | [`attach`](/docs/reference/math/attach/) |
| Fraction | `$1 + (a+b)/5$` | [`frac`](/docs/reference/math/frac/) |
| Line break | `$x \ y$` | [`linebreak`](/docs/reference/text/linebreak/) |
| Alignment point | `$x &= 2 \ &= 3$` | [Math](/docs/reference/math/) |
| Variable access | `$#x$, $pi$` | [Math](/docs/reference/math/) |
| Field access | `$arrow.r.long$` | [Scripting](/docs/reference/scripting/#fields) |
| Implied multiplication | `$x y$` | [Math](/docs/reference/math/) |
| Symbol shorthand | `$->$`, `$!=$` | [Symbols](/docs/reference/symbols/sym/) |
| Text/string in math | `$a "is natural"$` | [Math](/docs/reference/math/) |
| Math function call | `$floor(x)$` | [Math](/docs/reference/math/) |
| Code expression | `$#rect(width: 1cm)$` | [Scripting](/docs/reference/scripting/#expressions) |
| Character escape | `$x\^2$` | [Below](#escapes) |
| Comment | `$/* comment */$` | [Below](#comments) |
## Code mode
Within code blocks and expressions, new expressions can start without a leading `#` character. Many syntactic elements are specific to expressions. Below is a table listing all syntax that is available in code mode:
| Name | Example | See |
| --- | --- | --- |
| None | `none` | [`none`](/docs/reference/foundations/none/) |
| Auto | `auto` | [`auto`](/docs/reference/foundations/auto/) |
| Boolean | `false`, `true` | [`bool`](/docs/reference/foundations/bool/) |
| Integer | `10`, `0xff` | [`int`](/docs/reference/foundations/int/) |
| Floating-point number | `3.14`, `1e5` | [`float`](/docs/reference/foundations/float/) |
| Length | `2pt`, `3mm`, `1em`, .. | [`length`](/docs/reference/layout/length/) |
| Angle | `90deg`, `1rad` | [`angle`](/docs/reference/layout/angle/) |
| Fraction | `2fr` | [`fraction`](/docs/reference/layout/fraction/) |
| Ratio | `50%` | [`ratio`](/docs/reference/layout/ratio/) |
| String | `"hello"` | [`str`](/docs/reference/foundations/str/) |
| Label | `<intro>` | [`label`](/docs/reference/foundations/label/) |
| Math | `$x^2$` | [Math](/docs/reference/math/) |
| Raw text | ``print(1)`` | [`raw`](/docs/reference/text/raw/) |
| Variable access | `x` | [Scripting](/docs/reference/scripting/#blocks) |
| Code block | `\{ let x = 1; x + 2 \}` | [Scripting](/docs/reference/scripting/#blocks) |
| Content block | `[*Hello*]` | [Scripting](/docs/reference/scripting/#blocks) |
| Parenthesized expression | `(1 + 2)` | [Scripting](/docs/reference/scripting/#blocks) |
| Array | `(1, 2, 3)` | [Array](/docs/reference/foundations/array/) |
| Dictionary | `(a: "hi", b: 2)` | [Dictionary](/docs/reference/foundations/dictionary/) |
| Unary operator | `-x` | [Scripting](/docs/reference/scripting/#operators) |
| Binary operator | `x + y` | [Scripting](/docs/reference/scripting/#operators) |
| Assignment | `x = 1` | [Scripting](/docs/reference/scripting/#operators) |
| Field access | `x.y` | [Scripting](/docs/reference/scripting/#fields) |
| Method call | `x.flatten()` | [Scripting](/docs/reference/scripting/#methods) |
| Function call | `min(x, y)` | [Function](/docs/reference/foundations/function/) |
| Argument spreading | `min(..nums)` | [Arguments](/docs/reference/foundations/arguments/) |
| Unnamed function | `(x, y) => x + y` | [Function](/docs/reference/foundations/function/) |
| Let binding | `let x = 1` | [Scripting](/docs/reference/scripting/#bindings) |
| Named function | `let f(x) = 2 * x` | [Function](/docs/reference/foundations/function/) |
| Set rule | `set text(14pt)` | [Styling](/docs/reference/styling/#set-rules) |
| Set-if rule | `set text(..) if ..` | [Styling](/docs/reference/styling/#set-rules) |
| Show-set rule | `show heading: set block(..)` | [Styling](/docs/reference/styling/#show-rules) |
| Show rule with function | `show raw: it => \{..\}` | [Styling](/docs/reference/styling/#show-rules) |
| Show-everything rule | `show: template` | [Styling](/docs/reference/styling/#show-rules) |
| Context expression | `context text.lang` | [Context](/docs/reference/context/) |
| Conditional | `if x == 1 \{..\} else \{..\}` | [Scripting](/docs/reference/scripting/#conditionals) |
| For loop | `for x in (1, 2, 3) \{..\}` | [Scripting](/docs/reference/scripting/#loops) |
| While loop | `while x < 10 \{..\}` | [Scripting](/docs/reference/scripting/#loops) |
| Loop control flow | `break, continue` | [Scripting](/docs/reference/scripting/#loops) |
| Return from function | `return x` | [Function](/docs/reference/foundations/function/) |
| Include module | `include "bar.typ"` | [Scripting](/docs/reference/scripting/#modules) |
| Import module | `import "bar.typ"` | [Scripting](/docs/reference/scripting/#modules) |
| Import items from module | `import "bar.typ": a, b, c` | [Scripting](/docs/reference/scripting/#modules) |
| Comment | `/* block */`, `// line` | [Below](#comments) |
## Comments
Comments are ignored by Typst and will not be included in the output. This is useful to exclude old versions or to add annotations. To comment out a single line, start it with `//`:
```typst
// our data barely supports
// this claim
We show with $p < 0.05$
that the difference is
significant.
```
Comments can also be wrapped between `/*` and `*/`. In this case, the comment can span over multiple lines:
```typst
Our study design is as follows:
/* Somebody write this up:
- 1000 participants.
- 2x2 data design. */
```
## Escape sequences
Escape sequences are used to insert special characters that are hard to type or otherwise have special meaning in Typst. To escape a character, precede it with a backslash. To insert any Unicode codepoint, you can write a hexadecimal escape sequence: `\u\{1f600\}`. The same kind of escape sequences also work in [strings](/docs/reference/foundations/str/).
```typst
I got an ice cream for
\$1.50! \u{1f600}
```
## Identifiers
Names of variables, functions, and so on (_identifiers_) can contain letters, numbers, hyphens (`-`), and underscores (`_`). They must start with a letter or an underscore.
More specifically, the identifier syntax in Typst is based on the [Unicode Standard Annex #31](https://www.unicode.org/reports/tr31/), with two extensions: Allowing `_` as a starting character, and allowing both `_` and `-` as continuing characters.
For multi-word identifiers, the recommended case convention is [Kebab case](https://en.wikipedia.org/wiki/Letter_case#Kebab_case). In Kebab case, words are written in lowercase and separated by hyphens (as in `top-edge`). This is especially relevant when developing modules and packages for others to use, as it keeps things predictable.
```typst
#let kebab-case = [Using hyphen]
#let _schön = "😊"
#let 始料不及 = "😱"
#let π = calc.pi
#kebab-case
#if -π < 0 { _schön } else { 始料不及 }
// -π means -1 * π,
// so it's not a valid identifier
```
## Paths
Typst has various features that require a file path to reference external resources such as images, Typst files, or data files. Paths are represented as [strings](/docs/reference/foundations/str/). There are two kinds of paths: Relative and absolute.
- A **relative path** searches from the location of the Typst file where the feature is invoked. It is the default: `#image("images/logo.png")`
- An **absolute path** searches from the _root_ of the project. It starts with a leading `/`: `#image("/assets/logo.png")`
### Project root
By default, the project root is the parent directory of the main Typst file. For security reasons, you cannot read any files outside of the root directory.
If you want to set a specific folder as the root of your project, you can use the CLI's `--root` flag. Make sure that the main file is contained in the folder's subtree!
```typst
typst compile --root .. file.typ
```
In the web app, the project itself is the root directory. You can always read all files within it, no matter which one is previewed (via the eye toggle next to each Typst file in the file panel).
### Paths and packages
A package can only load files from its own directory. Within it, absolute paths point to the package root, rather than the project root. For this reason, it cannot directly load files from the project directory. If a package needs resources from the project (such as a logo image), you must pass the already loaded image, e.g. as a named parameter `logo: image("mylogo.svg")`. Note that you can then still customize the image's appearance with a set rule within the package.
In the future, paths might become a [distinct type from strings](https://github.com/typst/typst/issues/971), so that they can retain knowledge of where they were constructed. This way, resources could be loaded from a different root.
docs/reference/text/highlight.md
# Highlight
# highlight
Highlights text with a background color.
## Example
```typst
This is #highlight[important].
```
```typst
#highlight(
fill: none | color | gradient | tiling,
stroke: none | length | color | gradient | stroke | tiling | dictionary,
top-edge: length | str,
bottom-edge: length | str,
extent: length,
radius: relative | dictionary,
body
) -> content
```
## Parameters
- fill:
- description: The color to highlight the text with. ```typst This is #highlight( fill: blue )[highlighted with blue]. ```
- type: none | color | gradient | tiling
- default: rgb ("#fffd11a1")
- stroke:
- description: The highlight\'s border color. See the [rectangle\'s documentation](/docs/reference/visualize/rect/#parameters-stroke) for more details. ```typst This is a #highlight( stroke: fuchsia )[stroked highlighting]. ```
- type: none | length | color | gradient | stroke | tiling | dictionary
- default: (:)
- top-edge:
- description: The top end of the background rectangle. ```typst #set highlight(top-edge: "ascender") #highlight[a] #highlight[aib] #set highlight(top-edge: "x-height") #highlight[a] #highlight[aib] ```
- type: length | str
- default: "ascender"
- bottom-edge:
- description: The bottom end of the background rectangle. ```typst #set highlight(bottom-edge: "descender") #highlight[a] #highlight[ap] #set highlight(bottom-edge: "baseline") #highlight[a] #highlight[ap] ```
- type: length | str
- default: "descender"
- extent:
- description: The amount by which to extend the background to the sides beyond (or within if negative) the content. ```typst A long #highlight(extent: 4pt)[background]. ```
- type: length
- default: 0pt
- radius:
- description: How much to round the highlight\'s corners. See the [rectangle\'s documentation](/docs/reference/visualize/rect/#parameters-radius) for more details. ```typst Listen #highlight( radius: 5pt, extent: 2pt )[carefully], it will be on the test. ```
- type: relative | dictionary
- default: (:)
- body:
- description: The content that should be highlighted.
- type: content
- default: None
docs/reference/text/index.md
# Text
Text styling.
The [text function](/docs/reference/text/text/) is of particular interest.
## Definitions
| Name | Description |
| --- | --- |
| [`highlight`](/reference/text/highlight/) | Highlights text with a background color. |
| [`linebreak`](/reference/text/linebreak/) | Inserts a line break. |
| [`lorem`](/reference/text/lorem/) | Creates blind text. |
| [`lower`](/reference/text/lower/) | Converts a string or content to lowercase. |
| [`overline`](/reference/text/overline/) | Adds a line over text. |
| [`raw`](/reference/text/raw/) | Raw text with optional syntax highlighting. |
| [`smallcaps`](/reference/text/smallcaps/) | Displays text in small capitals. |
| [`smartquote`](/reference/text/smartquote/) | A language-aware quote that reacts to its context. |
| [`strike`](/reference/text/strike/) | Strikes through text. |
| [`sub`](/reference/text/sub/) | Renders text in subscript. |
| [`super`](/reference/text/super/) | Renders text in superscript. |
| [`text`](/reference/text/text/) | Customizes the look and layout of text in a variety of ways. |
| [`underline`](/reference/text/underline/) | Underlines text. |
| [`upper`](/reference/text/upper/) | Converts a string or content to uppercase. |
docs/reference/text/linebreak.md
# Line Break
# linebreak
Inserts a line break.
Advances the paragraph to the next line. A single trailing line break at the end of a paragraph is ignored, but more than one creates additional empty lines.
## Example
```typst
*Date:* 26.12.2022 \
*Topic:* Infrastructure Test \
*Severity:* High \
```
## Syntax
This function also has dedicated syntax: To insert a line break, simply write a backslash followed by whitespace. This always creates an unjustified break.
```typst
#linebreak(
justify: bool
) -> content
```
## Parameters
- justify:
- description: Whether to justify the line before the break. This is useful if you found a better line break opportunity in your justified text than Typst did. ```typst #set par(justify: true) #let jb = linebreak(justify: true) I have manually tuned the #jb line breaks in this paragraph #jb for an _interesting_ result. #jb ```
- type: bool
- default: false
docs/reference/text/lorem.md
# Lorem
# lorem
Creates blind text.
This function yields a Latin-like _Lorem Ipsum_ blind text with the given number of words. The sequence of words generated by the function is always the same but randomly chosen. As usual for blind texts, it does not make any sense. Use it as a placeholder to try layouts.
## Example
```typst
= Blind Text
#lorem(30)
= More Blind Text
#lorem(15)
```
```typst
#lorem(
words
) -> str
```
## Parameters
- words:
- description: The length of the blind text in words.
- type: int
- default: None
docs/reference/text/lower.md
# Lowercase
# lower
Converts a string or content to lowercase.
## Example
```typst
#lower("ABC") \
#lower[*My Text*] \
#lower[already low]
```
```typst
#lower(
text
) -> str content
```
## Parameters
- text:
- description: The text to convert to lowercase.
- type: str | content
- default: None
docs/reference/text/overline.md
# Overline
# overline
Adds a line over text.
## Example
```typst
#overline[A line over text.]
```
```typst
#overline(
stroke: auto | length | color | gradient | stroke | tiling | dictionary,
offset: auto | length,
extent: length,
evade: bool,
background: bool,
body
) -> content
```
## Parameters
- stroke:
- description: How to [stroke](/docs/reference/visualize/stroke/) the line. If set to `auto`, takes on the text\'s color and a thickness defined in the current font. ```typst #set text(fill: olive) #overline( stroke: green.darken(20%), offset: -12pt, [The Forest Theme], ) ```
- type: auto | length | color | gradient | stroke | tiling | dictionary
- default: auto
- offset:
- description: The position of the line relative to the baseline. Read from the font tables if `auto`. ```typst #overline(offset: -1.2em)[ The Tale Of A Faraway Line II ] ```
- type: auto | length
- default: auto
- extent:
- description: The amount by which to extend the line beyond (or within if negative) the content. ```typst #set overline(extent: 4pt) #set underline(extent: 4pt) #overline(underline[Typography Today]) ```
- type: length
- default: 0pt
- evade:
- description: Whether the line skips sections in which it would collide with the glyphs. ```typst #overline( evade: false, offset: -7.5pt, stroke: 1pt, extent: 3pt, [Temple], ) ```
- type: bool
- default: true
- background:
- description: Whether the line is placed behind the content it overlines. ```typst #set overline(stroke: (thickness: 1em, paint: maroon, cap: "round")) #overline(background: true)[This is stylized.] \\ #overline(background: false)[This is partially hidden.] ```
- type: bool
- default: false
- body:
- description: The content to add a line over.
- type: content
- default: None
docs/reference/text/raw.md
# Raw Text / Code
# raw
Raw text with optional syntax highlighting.
Displays the text verbatim and in a monospace font. This is typically used to embed computer code into your document.
Note that text given to this element cannot contain arbitrary formatting, such as `*strong*` or `_emphasis_`, as it is displayed verbatim. If you'd like to display any kind of content with a monospace font, instead of using [`raw`](/docs/reference/text/raw/), you should change its font to a monospace font using the [`text`](/docs/reference/text/text/) function.
## Example
```typst
Adding `rbx` to `rcx` gives
the desired result.
What is ```rust fn main()``` in Rust
would be ```c int main()``` in C.
```rust
fn main() {
println!("Hello World!");
}
```
This has ``` `backticks` ``` in it
(but the spaces are trimmed). And
``` here``` the leading space is
also trimmed.
```
You can also construct a [`raw`](/docs/reference/text/raw/) element programmatically from a string (and provide the language tag via the optional [`lang`](/docs/reference/text/raw/#parameters-lang) argument).
```typst
#raw("fn " + "main() {}", lang: "rust")
```
## 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. This works both in markup and code.
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 (except for the language tag, if applicable) is rendered as is, in particular, there are no escape sequences.
The language tag is an identifier that directly follows the opening backticks only if there are three or more backticks. If your text starts with something that looks like an identifier, but no syntax highlighting is needed, start the text with a single space (which will be trimmed) or use the single backtick syntax. If your text should start or end with a backtick, put a space before or after it (it will be trimmed).
If no syntax highlighting is available by default for your specified language tag (or if you want to override the built-in definition), you may provide a custom syntax specification file to the [`syntaxes`](/docs/reference/text/raw/#parameters-syntaxes) field.
## Styling
By default, the `raw` element uses the `DejaVu Sans Mono` font (included with Typst), with a smaller font size of `0.8em` (that is, 80% of the global font size). This is because monospace fonts tend to be visually larger than non-monospace fonts.
You can customize these properties with show-set rules:
```typst
// Switch to Cascadia Code for both
// inline and block raw.
#show raw: set text(font: "Cascadia Code")
// Reset raw blocks to the same size as normal text,
// but keep inline raw at the reduced size.
#show raw.where(block: true): set text(1em / 0.8)
Now using the `Cascadia Code` font for raw text.
Here's some Python code. It looks larger now:
```py
def python():
return 5 + 5
```
```
In addition, you can customize the syntax highlighting colors by setting a custom theme through the [`theme`](/docs/reference/text/raw/#parameters-theme) field.
For complete customization of the appearance of a raw block, a show rule on [`raw.line`](/docs/reference/text/raw/#definitions-line) could be helpful, such as to add line numbers.
Note that, in raw text, typesetting features like [hyphenation](/docs/reference/text/text/#parameters-hyphenate), [overhang](/docs/reference/text/text/#parameters-overhang), [CJK-Latin spacing](/docs/reference/text/text/#parameters-cjk-latin-spacing) (and [justification](/docs/reference/model/par/#parameters-justify) for [raw blocks](/docs/reference/text/raw/#parameters-block)) will be disabled by default.
```typst
#raw(
text,
block: bool,
lang: none | str,
align: alignment,
syntaxes: str | bytes | array,
theme: none | auto | str | bytes,
tab-size: int
) -> content
```
## Parameters
- text:
- description: The raw text. You can also use raw blocks creatively to create custom syntaxes for your automations. ```typst // Parse numbers in raw blocks with the // `mydsl` tag and sum them up. #show raw.where(lang: "mydsl"): it => { let sum = 0 for part in it.text.split("+") { sum += int(part.trim()) } sum } ```mydsl 1 + 2 + 3 + 4 + 5 ``` ```
- type: str
- default: None
- block:
- description: Whether the raw text is displayed as a separate block. In markup mode, using one-backtick notation makes this `false`. Using three-backtick notation makes it `true` if the enclosed content contains at least one line break. ```typst // Display inline code in a small box // that retains the correct baseline. #show raw.where(block: false): box.with( fill: luma(240), inset: (x: 3pt, y: 0pt), outset: (y: 3pt), radius: 2pt, ) // Display block code in a larger block // with more padding. #show raw.where(block: true): block.with( fill: luma(240), inset: 10pt, radius: 4pt, ) With `rg`, you can search through your files quickly. This example searches the current directory recursively for the text `Hello World`: ```bash rg "Hello World" ``` ```
- type: bool
- default: false
- lang:
- description: The language to syntax-highlight in. Apart from typical language tags known from Markdown, this supports the `"typ"`, `"typc"`, and `"typm"` tags for [Typst markup](/docs/reference/syntax/#markup), [Typst code](/docs/reference/syntax/#code), and [Typst math](/docs/reference/syntax/#math), respectively. ```typst ```typ This is *Typst!* ``` This is ```typ also *Typst*```, but inline! ```
- type: none | str
- default: none
- align:
- description: The horizontal alignment that each line in a raw block should have. This option is ignored if this is not a raw block (if specified `block: false` or single backticks were used in markup mode). By default, this is set to `start`, meaning that raw text is aligned towards the start of the text direction inside the block by default, regardless of the current context\'s alignment (allowing you to center the raw block itself without centering the text inside it, for example). ```typst #set raw(align: center) ```typc let f(x) = x code = "centered" ``` ```
- type: alignment
- default: start
- syntaxes:
- description: Additional syntax definitions to load. The syntax definitions should be in the [`sublime-syntax` file format](https://www.sublimetext.com/docs/syntax.html). You can pass any of the following values: - A path string to load a syntax file from the given path. For more details about paths, see the [Paths section](/docs/reference/syntax/#paths). - Raw bytes from which the syntax should be decoded. - An array where each item is one of the above. ```typst #set raw(syntaxes: "SExpressions.sublime-syntax") ```sexp (defun factorial (x) (if (zerop x) ; with a comment 1 (* x (factorial (- x 1))))) ``` ```
- type: str | bytes | array
- default: ()
- theme:
- description: The theme to use for syntax highlighting. Themes should be in the [`tmTheme` file format](https://www.sublimetext.com/docs/color_schemes_tmtheme.html). You can pass any of the following values: - `none`: Disables syntax highlighting. - `auto`: Highlights with Typst\'s default theme. - A path string to load a theme file from the given path. For more details about paths, see the [Paths section](/docs/reference/syntax/#paths). - Raw bytes from which the theme should be decoded. Applying a theme only affects the color of specifically highlighted text. It does not consider the theme\'s foreground and background properties, so that you retain control over the color of raw text. You can apply the foreground color yourself with the [`text`](/docs/reference/text/text/) function and the background with a [filled block](/docs/reference/layout/block/#parameters-fill). You could also use the [`xml`](/docs/reference/data-loading/xml/) function to extract these properties from the theme. ```typst #set raw(theme: "halcyon.tmTheme") #show raw: it => block( fill: rgb("#1d2433"), inset: 8pt, radius: 5pt, text(fill: rgb("#a2aabc"), it) ) ```typ = Chapter 1 #let hi = "Hello World" ``` ```
- type: none | auto | str | bytes
- default: auto
- tab-size:
- description: The size for a tab stop in spaces. A tab is replaced with enough spaces to align with the next multiple of the size. ```typst #set raw(tab-size: 8) ```tsv Year Month Day 2000 2 3 2001 2 1 2002 3 10 ``` ```
- type: int
- default: 2
## Definitions
### raw.line
A highlighted line of raw text.
This is a helper element that is synthesized by [`raw`](/docs/reference/text/raw/) elements.
It allows you to access various properties of the line, such as the line number, the raw non-highlighted text, the highlighted text, and whether it is the first or last line of the raw block.
```typst
#raw.line(
number,
count,
text,
body
) -> content
```
#### Parameters
- number:
- description: The line number of the raw line inside of the raw block, starts at 1.
- type: int
- default: None
- count:
- description: The total number of lines in the raw block.
- type: int
- default: None
- text:
- description: The line of raw text.
- type: str
- default: None
- body:
- description: The highlighted raw text.
- type: content
- default: None
docs/reference/text/smallcaps.md
# Small Capitals
# smallcaps
Displays text in small capitals.
## Example
```typst
Hello \
#smallcaps[Hello]
```
## Smallcaps fonts
By default, this uses the `smcp` and `c2sc` OpenType features on the font. Not all fonts support these features. Sometimes, smallcaps are part of a dedicated font. This is, for example, the case for the _Latin Modern_ family of fonts. In those cases, you can use a show-set rule to customize the appearance of the text in smallcaps:
```typst
#show smallcaps: set text(font: "Latin Modern Roman Caps")
```
In the future, this function will support synthesizing smallcaps from normal letters, but this is not yet implemented.
## Smallcaps headings
You can use a [show rule](/docs/reference/styling/#show-rules) to apply smallcaps formatting to all your headings. In the example below, we also center-align our headings and disable the standard bold font.
```typst
#set par(justify: true)
#set heading(numbering: "I.")
#show heading: smallcaps
#show heading: set align(center)
#show heading: set text(
weight: "regular"
)
= Introduction
#lorem(40)
```
```typst
#smallcaps(
all: bool,
body
) -> content
```
## Parameters
- all:
- description: Whether to turn uppercase letters into small capitals as well. Unless overridden by a show rule, this enables the `c2sc` OpenType feature. ```typst #smallcaps(all: true)[UNICEF] is an agency of #smallcaps(all: true)[UN]. ```
- type: bool
- default: false
- body:
- description: The content to display in small capitals.
- type: content
- default: None
docs/reference/text/smartquote.md
# Smartquote
# smartquote
A language-aware quote that reacts to its context.
Automatically turns into an appropriate opening or closing quote based on the active [text language](/docs/reference/text/text/#parameters-lang).
## Example
```typst
"This is in quotes."
#set text(lang: "de")
"Das ist in Anführungszeichen."
#set text(lang: "fr")
"C'est entre guillemets."
```
## Syntax
This function also has dedicated syntax: The normal quote characters (`'` and `"`). Typst automatically makes your quotes smart.
```typst
#smartquote(
double: bool,
enabled: bool,
alternative: bool,
quotes: auto | str | array | dictionary
) -> content
```
## Parameters
- double:
- description: Whether this should be a double quote.
- type: bool
- default: true
- enabled:
- description: Whether smart quotes are enabled. To disable smartness for a single quote, you can also escape it with a backslash. ```typst #set smartquote(enabled: false) These are "dumb" quotes. ```
- type: bool
- default: true
- alternative:
- description: Whether to use alternative quotes. Does nothing for languages that don\'t have alternative quotes, or if explicit quotes were set. ```typst #set text(lang: "de") #set smartquote(alternative: true) "Das ist in anderen Anführungszeichen." ```
- type: bool
- default: false
- quotes:
- description: The quotes to use. - When set to `auto`, the appropriate single quotes for the [text language](/docs/reference/text/text/#parameters-lang) will be used. This is the default. - Custom quotes can be passed as a string, array, or dictionary of either - [string](/docs/reference/foundations/str/): a string consisting of two characters containing the opening and closing double quotes (characters here refer to Unicode grapheme clusters) - [array](/docs/reference/foundations/array/): an array containing the opening and closing double quotes - [dictionary](/docs/reference/foundations/dictionary/): a dictionary containing the double and single quotes, each specified as either `auto`, string, or array ```typst #set text(lang: "de") \'Das sind normale Anführungszeichen.\' #set smartquote(quotes: "()") "Das sind eigene Anführungszeichen." #set smartquote(quotes: (single: ("[[", "]]"), double: auto)) \'Das sind eigene Anführungszeichen.\' ```
- type: auto | str | array | dictionary
- default: auto
docs/reference/text/strike.md
# Strikethrough
# strike
Strikes through text.
## Example
```typst
This is #strike[not] relevant.
```
```typst
#strike(
stroke: auto | length | color | gradient | stroke | tiling | dictionary,
offset: auto | length,
extent: length,
background: bool,
body
) -> content
```
## Parameters
- stroke:
- description: How to [stroke](/docs/reference/visualize/stroke/) the line. If set to `auto`, takes on the text\'s color and a thickness defined in the current font. _Note:_ Please don\'t use this for real redaction as you can still copy paste the text. ```typst This is #strike(stroke: 1.5pt + red)[very stricken through]. \\ This is #strike(stroke: 10pt)[redacted]. ```
- type: auto | length | color | gradient | stroke | tiling | dictionary
- default: auto
- offset:
- description: The position of the line relative to the baseline. Read from the font tables if `auto`. This is useful if you are unhappy with the offset your font provides. ```typst #set text(font: "Inria Serif") This is #strike(offset: auto)[low-ish]. \\ This is #strike(offset: -3.5pt)[on-top]. ```
- type: auto | length
- default: auto
- extent:
- description: The amount by which to extend the line beyond (or within if negative) the content. ```typst This #strike(extent: -2pt)[skips] parts of the word. This #strike(extent: 2pt)[extends] beyond the word. ```
- type: length
- default: 0pt
- background:
- description: Whether the line is placed behind the content. ```typst #set strike(stroke: red) #strike(background: true)[This is behind.] \\ #strike(background: false)[This is in front.] ```
- type: bool
- default: false
- body:
- description: The content to strike through.
- type: content
- default: None
docs/reference/text/sub.md
# Subscript
# sub
Renders text in subscript.
The text is rendered smaller and its baseline is lowered.
## Example
```typst
Revenue#sub[yearly]
```
```typst
#sub(
typographic: bool,
baseline: auto | length,
size: auto | length,
body
) -> content
```
## Parameters
- typographic:
- description: Whether to use subscript glyphs from the font if available. Ideally, subscripts glyphs are provided by the font (using the `subs` OpenType feature). Otherwise, Typst is able to synthesize subscripts by lowering and scaling down regular glyphs. When this is set to `false`, synthesized glyphs will be used regardless of whether the font provides dedicated subscript glyphs. When `true`, synthesized glyphs may still be used in case the font does not provide the necessary subscript glyphs. ```typst N#sub(typographic: true)[1] N#sub(typographic: false)[1] ```
- type: bool
- default: true
- baseline:
- description: The downward baseline shift for synthesized subscripts. This only applies to synthesized subscripts. In other words, this has no effect if `typographic` is `true` and the font provides the necessary subscript glyphs. If set to `auto`, the baseline is shifted according to the metrics provided by the font, with a fallback to `0.2em` in case the font does not define the necessary metrics.
- type: auto | length
- default: auto
- size:
- description: The font size for synthesized subscripts. This only applies to synthesized subscripts. In other words, this has no effect if `typographic` is `true` and the font provides the necessary subscript glyphs. If set to `auto`, the size is scaled according to the metrics provided by the font, with a fallback to `0.6em` in case the font does not define the necessary metrics.
- type: auto | length
- default: auto
- body:
- description: The text to display in subscript.
- type: content
- default: None
docs/reference/text/super.md
# Superscript
# super
Renders text in superscript.
The text is rendered smaller and its baseline is raised.
## Example
```typst
1#super[st] try!
```
```typst
#super(
typographic: bool,
baseline: auto | length,
size: auto | length,
body
) -> content
```
## Parameters
- typographic:
- description: Whether to use superscript glyphs from the font if available. Ideally, superscripts glyphs are provided by the font (using the `sups` OpenType feature). Otherwise, Typst is able to synthesize superscripts by raising and scaling down regular glyphs. When this is set to `false`, synthesized glyphs will be used regardless of whether the font provides dedicated superscript glyphs. When `true`, synthesized glyphs may still be used in case the font does not provide the necessary superscript glyphs. ```typst N#super(typographic: true)[1] N#super(typographic: false)[1] ```
- type: bool
- default: true
- baseline:
- description: The downward baseline shift for synthesized superscripts. This only applies to synthesized superscripts. In other words, this has no effect if `typographic` is `true` and the font provides the necessary superscript glyphs. If set to `auto`, the baseline is shifted according to the metrics provided by the font, with a fallback to `-0.5em` in case the font does not define the necessary metrics. Note that, since the baseline shift is applied downward, you will need to provide a negative value for the content to appear as raised above the normal baseline.
- type: auto | length
- default: auto
- size:
- description: The font size for synthesized superscripts. This only applies to synthesized superscripts. In other words, this has no effect if `typographic` is `true` and the font provides the necessary superscript glyphs. If set to `auto`, the size is scaled according to the metrics provided by the font, with a fallback to `0.6em` in case the font does not define the necessary metrics.
- type: auto | length
- default: auto
- body:
- description: The text to display in superscript.
- type: content
- default: None
docs/reference/text/text.md
# Text
# text
Customizes the look and layout of text in a variety of ways.
This function is used frequently, both with set rules and directly. While the set rule is often the simpler choice, calling the `text` function directly can be useful when passing text as an argument to another function.
## Example
```typst
#set text(18pt)
With a set rule.
#emph(text(blue)[
With a function call.
])
```
```typst
#text(
font: str | array | dictionary,
fallback: bool,
style: str,
weight: int | str,
stretch: ratio,
size: length,
fill: color | gradient | tiling,
stroke: none | length | color | gradient | stroke | tiling | dictionary,
tracking: length,
spacing: relative,
cjk-latin-spacing: none | auto,
baseline: length,
overhang: bool,
top-edge: length | str,
bottom-edge: length | str,
lang: str,
region: none | str,
script: auto | str,
dir: auto | direction,
hyphenate: auto | bool,
costs: dictionary,
kerning: bool,
alternates: bool,
stylistic-set: none | int | array,
ligatures: bool,
discretionary-ligatures: bool,
historical-ligatures: bool,
number-type: auto | str,
number-width: auto | str,
slashed-zero: bool,
fractions: bool,
features: array | dictionary,
body: content,
text
) -> content
```
## Parameters
- font:
- description: A font family descriptor or priority list of font family descriptors. A font family descriptor can be a plain string representing the family name or a dictionary with the following keys: - `name` (required): The font family name. - `covers` (optional): Defines the Unicode codepoints for which the family shall be used. This can be: - A predefined coverage set: - `"latin-in-cjk"` covers all codepoints except for those which exist in Latin fonts, but should preferably be taken from CJK fonts. - A [regular expression](/docs/reference/foundations/regex/) that defines exactly which codepoints shall be covered. Accepts only the subset of regular expressions which consist of exactly one dot, letter, or character class. 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. The collection of available fonts differs by platform: - In the web app, you can see the list of available fonts by clicking on the "Ag" button. You can provide additional fonts by uploading `.ttf` or `.otf` files into your project. They will be discovered automatically. The priority is: project fonts \\> server fonts. - Locally, Typst uses your installed system fonts or embedded fonts in the CLI, which are `Libertinus Serif`, `New Computer Modern`, `New Computer Modern Math`, and `DejaVu Sans Mono`. In addition, you can use the `--font-path` argument or `TYPST_FONT_PATHS` environment variable to add directories that should be scanned for fonts. The priority is: `--font-paths` \\> system fonts \\> embedded fonts. Run `typst fonts` to see the fonts that Typst has discovered on your system. Note that you can pass the `--ignore-system-fonts` parameter to the CLI to ensure Typst won\'t search for system fonts. ```typst #set text(font: "PT Sans") This is sans-serif. #set text(font: ( "Inria Serif", "Noto Sans Arabic", )) This is Latin. \\ هذا عربي. // Change font only for numbers. #set text(font: ( (name: "PT Sans", covers: regex("[0-9]")), "Libertinus Serif" )) The number 123. // Mix Latin and CJK fonts. #set text(font: ( (name: "Inria Serif", covers: "latin-in-cjk"), "Noto Serif CJK SC" )) 分别设置“中文”和English字体 ```
- type: str | array | dictionary
- default: "libertinus serif"
- fallback:
- description: Whether to allow last resort font fallback when the primary font list contains no match. This lets Typst search through all available fonts for the most similar one that has the necessary glyphs. _Note:_ Currently, there are no warnings when fallback is disabled and no glyphs are found. Instead, your text shows up in the form of "tofus": Small boxes that indicate the lack of an appropriate glyph. In the future, you will be able to instruct Typst to issue warnings so you know something is up. ```typst #set text(font: "Inria Serif") هذا عربي #set text(fallback: false) هذا عربي ```
- type: bool
- default: true
- style:
- description: The desired font style. When an italic style is requested and only an oblique one is available, it is used. Similarly, the other way around, an italic style can stand in for an oblique one. When neither an italic nor an oblique style is available, Typst selects the normal style. Since most fonts are only available either in an italic or oblique style, the difference between italic and oblique style is rarely observable. If you want to emphasize your text, you should do so using the [emph](/docs/reference/model/emph/) function instead. This makes it easy to adapt the style later if you change your mind about how to signify the emphasis. ```typst #text(font: "Libertinus Serif", style: "italic")[Italic] #text(font: "DejaVu Sans", style: "oblique")[Oblique] ```
- type: str
- default: "normal"
- weight:
- description: The desired thickness of the font\'s glyphs. Accepts an integer between `100` and `900` or one of the predefined weight names. When the desired weight is not available, Typst selects the font from the family that is closest in weight. If you want to strongly emphasize your text, you should do so using the [strong](/docs/reference/model/strong/) function instead. This makes it easy to adapt the style later if you change your mind about how to signify the strong emphasis. ```typst #set text(font: "IBM Plex Sans") #text(weight: "light")[Light] \\ #text(weight: "regular")[Regular] \\ #text(weight: "medium")[Medium] \\ #text(weight: 500)[Medium] \\ #text(weight: "bold")[Bold] ```
- type: int | str
- default: "regular"
- stretch:
- description: The desired width of the glyphs. Accepts a ratio between `50%` and `200%`. When the desired width is not available, Typst selects the font from the family that is closest in stretch. This will only stretch the text if a condensed or expanded version of the font is available. If you want to adjust the amount of space between characters instead of stretching the glyphs itself, use the [`tracking`](/docs/reference/text/text/#parameters-tracking) property instead. ```typst #text(stretch: 75%)[Condensed] \\ #text(stretch: 100%)[Normal] ```
- type: ratio
- default: 100 %
- size:
- description: The size of the glyphs. This value forms the basis of the `em` unit: `1em` is equivalent to the font size. You can also give the font size itself in `em` units. Then, it is relative to the previous font size. ```typst #set text(size: 20pt) very #text(1.5em)[big] text ```
- type: length
- default: 11pt
- fill:
- description: The glyph fill paint. ```typst #set text(fill: red) This text is red. ```
- type: color | gradient | tiling
- default: luma (0 % )
- stroke:
- description: How to stroke the text. ```typst #text(stroke: 0.5pt + red)[Stroked] ```
- type: none | length | color | gradient | stroke | tiling | dictionary
- default: none
- tracking:
- description: The amount of space that should be added between characters. ```typst #set text(tracking: 1.5pt) Distant text. ```
- type: length
- default: 0pt
- spacing:
- description: The amount of space between words. Can be given as an absolute length, but also relative to the width of the space character in the font. If you want to adjust the amount of space between characters rather than words, use the [`tracking`](/docs/reference/text/text/#parameters-tracking) property instead. ```typst #set text(spacing: 200%) Text with distant words. ```
- type: relative
- default: 100 % + 0pt
- cjk-latin-spacing:
- description: Whether to automatically insert spacing between CJK and Latin characters. ```typst #set text(cjk-latin-spacing: auto) 第4章介绍了基本的API。 #set text(cjk-latin-spacing: none) 第4章介绍了基本的API。 ```
- type: none | auto
- default: auto
- baseline:
- description: An amount to shift the text baseline by. ```typst A #text(baseline: 3pt)[lowered] word. ```
- type: length
- default: 0pt
- overhang:
- description: Whether certain glyphs can hang over into the margin in justified text. This can make justification visually more pleasing. ```typst #set page(width: 220pt) #set par(justify: true) This justified text has a hyphen in the paragraph\'s second line. Hanging the hyphen slightly into the margin results in a clearer paragraph edge. #set text(overhang: false) This justified text has a hyphen in the paragraph\'s second line. Hanging the hyphen slightly into the margin results in a clearer paragraph edge. ```
- type: bool
- default: true
- top-edge:
- description: The top end of the conceptual frame around the text used for layout and positioning. This affects the size of containers that hold text. ```typst #set rect(inset: 0pt) #set text(size: 20pt) #set text(top-edge: "ascender") #rect(fill: aqua)[Typst] #set text(top-edge: "cap-height") #rect(fill: aqua)[Typst] ```
- type: length | str
- default: "cap - height"
- bottom-edge:
- description: The bottom end of the conceptual frame around the text used for layout and positioning. This affects the size of containers that hold text. ```typst #set rect(inset: 0pt) #set text(size: 20pt) #set text(bottom-edge: "baseline") #rect(fill: aqua)[Typst] #set text(bottom-edge: "descender") #rect(fill: aqua)[Typst] ```
- type: length | str
- default: "baseline"
- lang:
- description: An [ISO 639-1/2/3 language code.](https://en.wikipedia.org/wiki/ISO_639) Setting the correct language affects various parts of Typst: - The text processing pipeline can make more informed choices. - Hyphenation will use the correct patterns for the language. - [Smart quotes](/docs/reference/text/smartquote/) turns into the correct quotes for the language. - And all other things which are language-aware. Choosing the correct language is important for accessibility. For example, screen readers will use it to choose a voice that matches the language of the text. If your document is in another language than English (the default), you should set the text language at the start of your document, before any other content. You can, for example, put it right after the `#set document(/* ... */)` rule that [sets your document\'s title](/docs/reference/model/document/#parameters-title). If your document contains passages in a different language than the main language, you should locally change the text language just for those parts, either with a set rule [scoped to a block](/docs/reference/scripting/#blocks) or using a direct text function call such as `#text(lang: "de")[...]`. If multiple codes are available for your language, you should prefer the two-letter code (ISO 639-1) over the three-letter codes (ISO 639-2/3). When you have to use a three-letter code and your language differs between ISO 639-2 and ISO 639-3, use ISO 639-2 for PDF 1.7 (Typst\'s default for PDF export) and below and ISO 639-3 for PDF 2.0 and HTML export. The language code is case-insensitive, and will be lowercased when accessed through [context](/docs/reference/context/). ```typst #set text(lang: "de") #outline() = Einleitung In diesem Dokument, ... ```
- type: str
- default: "en"
- region:
- description: An [ISO 3166-1 alpha-2 region code.](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) This lets the text processing pipeline make more informed choices. The region code is case-insensitive, and will be uppercased when accessed through [context](/docs/reference/context/).
- type: none | str
- default: none
- script:
- description: The OpenType writing script. The combination of `lang` and `script` determine how font features, such as glyph substitution, are implemented. Frequently the value is a modified (all-lowercase) ISO 15924 script identifier, and the `math` writing script is used for features appropriate for mathematical symbols. When set to `auto`, the default and recommended setting, an appropriate script is chosen for each block of characters sharing a common Unicode script property. ```typst #set text( font: "Libertinus Serif", size: 20pt, ) #let scedilla = [Ş] #scedilla // S with a cedilla #set text(lang: "ro", script: "latn") #scedilla // S with a subscript comma #set text(lang: "ro", script: "grek") #scedilla // S with a cedilla ```
- type: auto | str
- default: auto
- dir:
- description: The dominant direction for text and inline objects. Possible values are: - `auto`: Automatically infer the direction from the `lang` property. - `ltr`: Layout text from left to right. - `rtl`: Layout text from right to left. When writing in right-to-left scripts like Arabic or Hebrew, you should set the [text language](/docs/reference/text/text/#parameters-lang) or direction. While individual runs of text are automatically layouted in the correct direction, setting the dominant direction gives the bidirectional reordering algorithm the necessary information to correctly place punctuation and inline objects. Furthermore, setting the direction affects the alignment values `start` and `end`, which are equivalent to `left` and `right` in `ltr` text and the other way around in `rtl` text. If you set this to `rtl` and experience bugs or in some way bad looking output, please get in touch with us through the [Forum](https://forum.typst.app/), [Discord server](https://discord.gg/2uDybryKPe), or our [contact form](https://typst.app/contact). ```typst #set text(dir: rtl) هذا عربي. ```
- type: auto | direction
- default: auto
- hyphenate:
- description: Whether to hyphenate text to improve line breaking. When `auto`, text will be hyphenated if and only if justification is enabled. Setting the [text language](/docs/reference/text/text/#parameters-lang) ensures that the correct hyphenation patterns are used. ```typst #set page(width: 200pt) #set par(justify: true) This text illustrates how enabling hyphenation can improve justification. #set text(hyphenate: false) This text illustrates how enabling hyphenation can improve justification. ```
- type: auto | bool
- default: auto
- costs:
- description: The "cost" of various choices when laying out text. A higher cost means the layout engine will make the choice less often. Costs are specified as a ratio of the default cost, so `50%` will make text layout twice as eager to make a given choice, while `200%` will make it half as eager. Currently, the following costs can be customized: - `hyphenation`: splitting a word across multiple lines - `runt`: ending a paragraph with a line with a single word - `widow`: leaving a single line of paragraph on the next page - `orphan`: leaving single line of paragraph on the previous page Hyphenation is generally avoided by placing the whole word on the next line, so a higher hyphenation cost can result in awkward justification spacing. Note: Hyphenation costs will only be applied when the [`linebreaks`](/docs/reference/model/par/#parameters-linebreaks) are set to "optimized". (For example by default implied by [`justify`](/docs/reference/model/par/#parameters-justify).) Runts are avoided by placing more or fewer words on previous lines, so a higher runt cost can result in more awkward in justification spacing. Text layout prevents widows and orphans by default because they are generally discouraged by style guides. However, in some contexts they are allowed because the prevention method, which moves a line to the next page, can result in an uneven number of lines between pages. The `widow` and `orphan` costs allow disabling these modifications. (Currently, `0%` allows widows/orphans; anything else, including the default of `100%`, prevents them. More nuanced cost specification for these modifications is planned for the future.) ```typst #set text(hyphenate: true, size: 11.4pt) #set par(justify: true) #lorem(10) // Set hyphenation to ten times the normal cost. #set text(costs: (hyphenation: 1000%)) #lorem(10) ```
- type: dictionary
- default: (hyphenation : 100 % , runt : 100 % , widow : 100 % , orphan : 100 % ,)
- kerning:
- description: Whether to apply kerning. When enabled, specific letter pairings move closer together or further apart for a more visually pleasing result. The example below demonstrates how decreasing the gap between the "T" and "o" results in a more natural look. Setting this to `false` disables kerning by turning off the OpenType `kern` font feature. ```typst #set text(size: 25pt) Totally #set text(kerning: false) Totally ```
- type: bool
- default: true
- alternates:
- description: Whether to apply stylistic alternates. Sometimes fonts contain alternative glyphs for the same codepoint. Setting this to `true` switches to these by enabling the OpenType `salt` font feature. ```typst #set text( font: "IBM Plex Sans", size: 20pt, ) 0, a, g, ß #set text(alternates: true) 0, a, g, ß ```
- type: bool
- default: false
- stylistic-set:
- description: Which stylistic sets to apply. Font designers can categorize alternative glyphs forms into stylistic sets. As this value is highly font-specific, you need to consult your font to know which sets are available. This can be set to an integer or an array of integers, all of which must be between `1` and `20`, enabling the corresponding OpenType feature(s) from `ss01` to `ss20`. Setting this to `none` will disable all stylistic sets. ```typst #set text(font: "IBM Plex Serif") ß vs #text(stylistic-set: 5)[ß] \\ 10 years ago vs #text(stylistic-set: (1, 2, 3))[10 years ago] ```
- type: none | int | array
- default: ()
- ligatures:
- description: Whether standard ligatures are active. Certain letter combinations like "fi" are often displayed as a single merged glyph called a _ligature._ Setting this to `false` disables these ligatures by turning off the OpenType `liga` and `clig` font features. ```typst #set text(size: 20pt) A fine ligature. #set text(ligatures: false) A fine ligature. ``` Note that some programming fonts use other OpenType font features to implement "ligatures," including the contextual alternates (`calt`) feature, which is also enabled by default. Use the general [`features`](/docs/reference/text/text/#parameters-features) parameter to control such features.
- type: bool
- default: true
- discretionary-ligatures:
- description: Whether ligatures that should be used sparingly are active. Setting this to `true` enables the OpenType `dlig` font feature.
- type: bool
- default: false
- historical-ligatures:
- description: Whether historical ligatures are active. Setting this to `true` enables the OpenType `hlig` font feature.
- type: bool
- default: false
- number-type:
- description: Which kind of numbers / figures to select. When set to `auto`, the default numbers for the font are used. ```typst #set text(font: "Noto Sans", 20pt) #set text(number-type: "lining") Number 9. #set text(number-type: "old-style") Number 9. ```
- type: auto | str
- default: auto
- number-width:
- description: The width of numbers / figures. When set to `auto`, the default numbers for the font are used. ```typst #set text(font: "Noto Sans", 20pt) #set text(number-width: "proportional") A 12 B 34. \\ A 56 B 78. #set text(number-width: "tabular") A 12 B 34. \\ A 56 B 78. ```
- type: auto | str
- default: auto
- slashed-zero:
- description: Whether to have a slash through the zero glyph. Setting this to `true` enables the OpenType `zero` font feature. ```typst 0, #text(slashed-zero: true)[0] ```
- type: bool
- default: false
- fractions:
- description: Whether to turn numbers into fractions. Setting this to `true` enables the OpenType `frac` font feature. It is not advisable to enable this property globally as it will mess with all appearances of numbers after a slash (e.g., in URLs). Instead, enable it locally when you want a fraction. ```typst 1/2 \\ #text(fractions: true)[1/2] ```
- type: bool
- default: false
- features:
- description: Raw OpenType features to apply. - If given an array of strings, sets the features identified by the strings to `1`. - If given a dictionary mapping to numbers, sets the features identified by the keys to the values. ```typst // Enable the `frac` feature manually. #set text(features: ("frac",)) 1/2 ``` ```typst #set text(font: "Cascadia Code") => // Disable the contextual alternates (`calt`) feature. #set text(features: (calt: 0)) => ```
- type: array | dictionary
- default: (:)
- body:
- description: Content in which all text is styled according to the other arguments.
- type: content
- default: []
- text:
- description: The text.
- type: str
- default: None
docs/reference/text/underline.md
# Underline
# underline
Underlines text.
## Example
```typst
This is #underline[important].
```
```typst
#underline(
stroke: auto | length | color | gradient | stroke | tiling | dictionary,
offset: auto | length,
extent: length,
evade: bool,
background: bool,
body
) -> content
```
## Parameters
- stroke:
- description: How to [stroke](/docs/reference/visualize/stroke/) the line. If set to `auto`, takes on the text\'s color and a thickness defined in the current font. ```typst Take #underline( stroke: 1.5pt + red, offset: 2pt, [care], ) ```
- type: auto | length | color | gradient | stroke | tiling | dictionary
- default: auto
- offset:
- description: The position of the line relative to the baseline, read from the font tables if `auto`. ```typst #underline(offset: 5pt)[ The Tale Of A Faraway Line I ] ```
- type: auto | length
- default: auto
- extent:
- description: The amount by which to extend the line beyond (or within if negative) the content. ```typst #align(center, underline(extent: 2pt)[Chapter 1] ) ```
- type: length
- default: 0pt
- evade:
- description: Whether the line skips sections in which it would collide with the glyphs. ```typst This #underline(evade: true)[is great]. This #underline(evade: false)[is less great]. ```
- type: bool
- default: true
- background:
- description: Whether the line is placed behind the content it underlines. ```typst #set underline(stroke: (thickness: 1em, paint: maroon, cap: "round")) #underline(background: true)[This is stylized.] \\ #underline(background: false)[This is partially hidden.] ```
- type: bool
- default: false
- body:
- description: The content to underline.
- type: content
- default: None
docs/reference/text/upper.md
# Uppercase
# upper
Converts a string or content to uppercase.
## Example
```typst
#upper("abc") \
#upper[*my text*] \
#upper[ALREADY HIGH]
```
```typst
#upper(
text
) -> str content
```
## Parameters
- text:
- description: The text to convert to uppercase.
- type: str | content
- default: None
docs/reference/visualize/circle.md
# Circle
# circle
A circle with optional content.
## Example
```typst
// Without content.
#circle(radius: 25pt)
// With content.
#circle[
#set align(center + horizon)
Automatically \
sized to fit.
]
```
```typst
#circle(
radius: length,
width: auto | relative,
height: auto | relative | fraction,
fill: none | color | gradient | tiling,
stroke: none | auto | length | color | gradient | stroke | tiling | dictionary,
inset: relative | dictionary,
outset: relative | dictionary,
body
) -> content
```
## Parameters
- radius:
- description: The circle\'s radius. This is mutually exclusive with `width` and `height`.
- type: length
- default: 0pt
- width:
- description: The circle\'s width. This is mutually exclusive with `radius` and `height`. In contrast to `radius`, this can be relative to the parent container\'s width.
- type: auto | relative
- default: auto
- height:
- description: The circle\'s height. This is mutually exclusive with `radius` and `width`. In contrast to `radius`, this can be relative to the parent container\'s height.
- type: auto | relative | fraction
- default: auto
- fill:
- description: How to fill the circle. See the [rectangle\'s documentation](/docs/reference/visualize/rect/#parameters-fill) for more details.
- type: none | color | gradient | tiling
- default: none
- stroke:
- description: How to stroke the circle. See the [rectangle\'s documentation](/docs/reference/visualize/rect/#parameters-stroke) for more details.
- type: none | auto | length | color | gradient | stroke | tiling | dictionary
- default: auto
- inset:
- description: How much to pad the circle\'s content. See the [box\'s documentation](/docs/reference/layout/box/#parameters-inset) for more details.
- type: relative | dictionary
- default: 0 % + 5pt
- outset:
- description: How much to expand the circle\'s size without affecting the layout. See the [box\'s documentation](/docs/reference/layout/box/#parameters-outset) for more details.
- type: relative | dictionary
- default: (:)
- body:
- description: The content to place into the circle. The circle expands to fit this content, keeping the 1-1 aspect ratio.
- type: none | content
- default: none
docs/reference/visualize/color.md
# Color
A color in a specific color space.
Typst supports:
- sRGB through the [`rgb` function](/docs/reference/visualize/color/#definitions-rgb)
- Device CMYK through the [`cmyk` function](/docs/reference/visualize/color/#definitions-cmyk)
- D65 Gray through the [`luma` function](/docs/reference/visualize/color/#definitions-luma)
- Oklab through the [`oklab` function](/docs/reference/visualize/color/#definitions-oklab)
- Oklch through the [`oklch` function](/docs/reference/visualize/color/#definitions-oklch)
- Linear RGB through the [`color.linear-rgb` function](/docs/reference/visualize/color/#definitions-linear-rgb)
- HSL through the [`color.hsl` function](/docs/reference/visualize/color/#definitions-hsl)
- HSV through the [`color.hsv` function](/docs/reference/visualize/color/#definitions-hsv)
## Example
```typst
#rect(fill: aqua)
```
## Predefined colors
Typst defines the following built-in colors:
| Color | Definition |
| --- | --- |
| `black` | `luma(0)` |
| `gray` | `luma(170)` |
| `silver` | `luma(221)` |
| `white` | `luma(255)` |
| `navy` | `rgb("#001f3f")` |
| `blue` | `rgb("#0074d9")` |
| `aqua` | `rgb("#7fdbff")` |
| `teal` | `rgb("#39cccc")` |
| `eastern` | `rgb("#239dad")` |
| `purple` | `rgb("#b10dc9")` |
| `fuchsia` | `rgb("#f012be")` |
| `maroon` | `rgb("#85144b")` |
| `red` | `rgb("#ff4136")` |
| `orange` | `rgb("#ff851b")` |
| `yellow` | `rgb("#ffdc00")` |
| `olive` | `rgb("#3d9970")` |
| `green` | `rgb("#2ecc40")` |
| `lime` | `rgb("#01ff70")` |
The predefined colors and the most important color constructors are available globally and also in the color type's scope, so you can write either `color.red` or just `red`.
## Predefined color maps
Typst also includes a number of preset color maps that can be used for [gradients](/docs/reference/visualize/gradient/#stops). These are simply arrays of colors defined in the module `color.map`.
```typst
#circle(fill: gradient.linear(..color.map.crest))
```
| Map | Details |
| --- | --- |
| `turbo` | A perceptually uniform rainbow-like color map. Read [this blog post](https://ai.googleblog.com/2019/08/turbo-improved-rainbow-colormap-for.html) for more details. |
| `cividis` | A blue to gray to yellow color map. See [this blog post](https://bids.github.io/colormap/) for more details. |
| `rainbow` | Cycles through the full color spectrum. This color map is best used by setting the interpolation color space to [HSL](/docs/reference/visualize/color/#definitions-hsl). The rainbow gradient is **not suitable** for data visualization because it is not perceptually uniform, so the differences between values become unclear to your readers. It should only be used for decorative purposes. |
| `spectral` | Red to yellow to blue color map. |
| `viridis` | A purple to teal to yellow color map. |
| `inferno` | A black to red to yellow color map. |
| `magma` | A black to purple to yellow color map. |
| `plasma` | A purple to pink to yellow color map. |
| `rocket` | A black to red to white color map. |
| `mako` | A black to teal to white color map. |
| `vlag` | A light blue to white to red color map. |
| `icefire` | A light teal to black to orange color map. |
| `flare` | A orange to purple color map that is perceptually uniform. |
| `crest` | A light green to blue color map. |
Some popular presets are not included because they are not available under a free licence. Others, like [Jet](https://jakevdp.github.io/blog/2014/10/16/how-bad-is-your-colormap/), are not included because they are not color blind friendly. Feel free to use or create a package with other presets that are useful to you!
## Methods
## color.luma
Create a grayscale color.
A grayscale color is represented internally by a single `lightness` component.
These components are also available using the [`components`](/docs/reference/visualize/color/#definitions-components) method.
```typst
#for x in range(250, step: 50) {
box(square(fill: luma(x)))
}
```
```typst
#color.luma(
lightness,
alpha,
color
) -> color
```
### Parameters
- lightness:
- description: The lightness component.
- type: int | ratio
- default: None
- alpha:
- description: The alpha component.
- type: ratio
- default: None
- color:
- description: Alternatively: The color to convert to grayscale. If this is given, the `lightness` should not be given.
- type: color
- default: None
## color.oklab
Create an [Oklab](https://bottosson.github.io/posts/oklab/) color.
This color space is well suited for the following use cases:
- Color manipulation such as saturating while keeping perceived hue
- Creating grayscale images with uniform perceived lightness
- Creating smooth and uniform color transition and gradients
A linear Oklab color is represented internally by an array of four components:
- lightness ([`ratio`](/docs/reference/layout/ratio/))
- a ([`float`](/docs/reference/foundations/float/) or [`ratio`](/docs/reference/layout/ratio/). Ratios are relative to `0.4`; meaning `50%` is equal to `0.2`)
- b ([`float`](/docs/reference/foundations/float/) or [`ratio`](/docs/reference/layout/ratio/). Ratios are relative to `0.4`; meaning `50%` is equal to `0.2`)
- alpha ([`ratio`](/docs/reference/layout/ratio/))
These components are also available using the [`components`](/docs/reference/visualize/color/#definitions-components) method.
```typst
#square(
fill: oklab(27%, 20%, -3%, 50%)
)
```
```typst
#color.oklab(
lightness,
a,
b,
alpha,
color
) -> color
```
### Parameters
- lightness:
- description: The lightness component.
- type: ratio
- default: None
- a:
- description: The a ("green/red") component.
- type: float | ratio
- default: None
- b:
- description: The b ("blue/yellow") component.
- type: float | ratio
- default: None
- alpha:
- description: The alpha component.
- type: ratio
- default: None
- color:
- description: Alternatively: The color to convert to Oklab. If this is given, the individual components should not be given.
- type: color
- default: None
## color.oklch
Create an [Oklch](https://bottosson.github.io/posts/oklab/) color.
This color space is well suited for the following use cases:
- Color manipulation involving lightness, chroma, and hue
- Creating grayscale images with uniform perceived lightness
- Creating smooth and uniform color transition and gradients
A linear Oklch color is represented internally by an array of four components:
- lightness ([`ratio`](/docs/reference/layout/ratio/))
- chroma ([`float`](/docs/reference/foundations/float/) or [`ratio`](/docs/reference/layout/ratio/). Ratios are relative to `0.4`; meaning `50%` is equal to `0.2`)
- hue ([`angle`](/docs/reference/layout/angle/))
- alpha ([`ratio`](/docs/reference/layout/ratio/))
These components are also available using the [`components`](/docs/reference/visualize/color/#definitions-components) method.
```typst
#square(
fill: oklch(40%, 0.2, 160deg, 50%)
)
```
```typst
#color.oklch(
lightness,
chroma,
hue,
alpha,
color
) -> color
```
### Parameters
- lightness:
- description: The lightness component.
- type: ratio
- default: None
- chroma:
- description: The chroma component.
- type: float | ratio
- default: None
- hue:
- description: The hue component.
- type: angle
- default: None
- alpha:
- description: The alpha component.
- type: ratio
- default: None
- color:
- description: Alternatively: The color to convert to Oklch. If this is given, the individual components should not be given.
- type: color
- default: None
## color.linear-rgb
Create an RGB(A) color with linear luma.
This color space is similar to sRGB, but with the distinction that the color component are not gamma corrected. This makes it easier to perform color operations such as blending and interpolation. Although, you should prefer to use the [`oklab` function](/docs/reference/visualize/color/#definitions-oklab) for these.
A linear RGB(A) color is represented internally by an array of four components:
- red ([`ratio`](/docs/reference/layout/ratio/))
- green ([`ratio`](/docs/reference/layout/ratio/))
- blue ([`ratio`](/docs/reference/layout/ratio/))
- alpha ([`ratio`](/docs/reference/layout/ratio/))
These components are also available using the [`components`](/docs/reference/visualize/color/#definitions-components) method.
```typst
#square(fill: color.linear-rgb(
30%, 50%, 10%,
))
```
```typst
#color.linear-rgb(
red,
green,
blue,
alpha,
color
) -> color
```
### Parameters
- red:
- description: The red component.
- type: int | ratio
- default: None
- green:
- description: The green component.
- type: int | ratio
- default: None
- blue:
- description: The blue component.
- type: int | ratio
- default: None
- alpha:
- description: The alpha component.
- type: int | ratio
- default: None
- color:
- description: Alternatively: The color to convert to linear RGB(A). If this is given, the individual components should not be given.
- type: color
- default: None
## color.rgb
Create an RGB(A) color.
The color is specified in the sRGB color space.
An RGB(A) color is represented internally by an array of four components:
- red ([`ratio`](/docs/reference/layout/ratio/))
- green ([`ratio`](/docs/reference/layout/ratio/))
- blue ([`ratio`](/docs/reference/layout/ratio/))
- alpha ([`ratio`](/docs/reference/layout/ratio/))
These components are also available using the [`components`](/docs/reference/visualize/color/#definitions-components) method.
```typst
#square(fill: rgb("#b1f2eb"))
#square(fill: rgb(87, 127, 230))
#square(fill: rgb(25%, 13%, 65%))
```
```typst
#color.rgb(
red,
green,
blue,
alpha,
hex,
color
) -> color
```
### Parameters
- red:
- description: The red component.
- type: int | ratio
- default: None
- green:
- description: The green component.
- type: int | ratio
- default: None
- blue:
- description: The blue component.
- type: int | ratio
- default: None
- alpha:
- description: The alpha component.
- type: int | ratio
- default: None
- hex:
- description: Alternatively: The color in hexadecimal notation. Accepts three, four, six or eight hexadecimal digits and optionally a leading hash. If this is given, the individual components should not be given. ```typst #text(16pt, rgb("#239dad"))[ *Typst* ] ```
- type: str
- default: None
- color:
- description: Alternatively: The color to convert to RGB(a). If this is given, the individual components should not be given.
- type: color
- default: None
## color.cmyk
Create a CMYK color.
This is useful if you want to target a specific printer. The conversion to RGB for display preview might differ from how your printer reproduces the color.
A CMYK color is represented internally by an array of four components:
- cyan ([`ratio`](/docs/reference/layout/ratio/))
- magenta ([`ratio`](/docs/reference/layout/ratio/))
- yellow ([`ratio`](/docs/reference/layout/ratio/))
- key ([`ratio`](/docs/reference/layout/ratio/))
These components are also available using the [`components`](/docs/reference/visualize/color/#definitions-components) method.
Note that CMYK colors are not currently supported when PDF/A output is enabled.
```typst
#square(
fill: cmyk(27%, 0%, 3%, 5%)
)
```
```typst
#color.cmyk(
cyan,
magenta,
yellow,
key,
color
) -> color
```
### Parameters
- cyan:
- description: The cyan component.
- type: ratio
- default: None
- magenta:
- description: The magenta component.
- type: ratio
- default: None
- yellow:
- description: The yellow component.
- type: ratio
- default: None
- key:
- description: The key component.
- type: ratio
- default: None
- color:
- description: Alternatively: The color to convert to CMYK. If this is given, the individual components should not be given.
- type: color
- default: None
## color.hsl
Create an HSL color.
This color space is useful for specifying colors by hue, saturation and lightness. It is also useful for color manipulation, such as saturating while keeping perceived hue.
An HSL color is represented internally by an array of four components:
- hue ([`angle`](/docs/reference/layout/angle/))
- saturation ([`ratio`](/docs/reference/layout/ratio/))
- lightness ([`ratio`](/docs/reference/layout/ratio/))
- alpha ([`ratio`](/docs/reference/layout/ratio/))
These components are also available using the [`components`](/docs/reference/visualize/color/#definitions-components) method.
```typst
#square(
fill: color.hsl(30deg, 50%, 60%)
)
```
```typst
#color.hsl(
hue,
saturation,
lightness,
alpha,
color
) -> color
```
### Parameters
- hue:
- description: The hue angle.
- type: angle
- default: None
- saturation:
- description: The saturation component.
- type: int | ratio
- default: None
- lightness:
- description: The lightness component.
- type: int | ratio
- default: None
- alpha:
- description: The alpha component.
- type: int | ratio
- default: None
- color:
- description: Alternatively: The color to convert to HSL. If this is given, the individual components should not be given.
- type: color
- default: None
## color.hsv
Create an HSV color.
This color space is useful for specifying colors by hue, saturation and value. It is also useful for color manipulation, such as saturating while keeping perceived hue.
An HSV color is represented internally by an array of four components:
- hue ([`angle`](/docs/reference/layout/angle/))
- saturation ([`ratio`](/docs/reference/layout/ratio/))
- value ([`ratio`](/docs/reference/layout/ratio/))
- alpha ([`ratio`](/docs/reference/layout/ratio/))
These components are also available using the [`components`](/docs/reference/visualize/color/#definitions-components) method.
```typst
#square(
fill: color.hsv(30deg, 50%, 60%)
)
```
```typst
#color.hsv(
hue,
saturation,
value,
alpha,
color
) -> color
```
### Parameters
- hue:
- description: The hue angle.
- type: angle
- default: None
- saturation:
- description: The saturation component.
- type: int | ratio
- default: None
- value:
- description: The value component.
- type: int | ratio
- default: None
- alpha:
- description: The alpha component.
- type: int | ratio
- default: None
- color:
- description: Alternatively: The color to convert to HSL. If this is given, the individual components should not be given.
- type: color
- default: None
## color.components
Extracts the components of this color.
The size and values of this array depends on the color space. You can obtain the color space using [`space`](/docs/reference/visualize/color/#definitions-space). Below is a table of the color spaces and their components:
| Color space | C1 | C2 | C3 | C4 |
| --- | --- | --- | --- | --- |
| [`luma`](/docs/reference/visualize/color/#definitions-luma) | Lightness | | | |
| [`oklab`](/docs/reference/visualize/color/#definitions-oklab) | Lightness | `a` | `b` | Alpha |
| [`oklch`](/docs/reference/visualize/color/#definitions-oklch) | Lightness | Chroma | Hue | Alpha |
| [`linear-rgb`](/docs/reference/visualize/color/#definitions-linear-rgb) | Red | Green | Blue | Alpha |
| [`rgb`](/docs/reference/visualize/color/#definitions-rgb) | Red | Green | Blue | Alpha |
| [`cmyk`](/docs/reference/visualize/color/#definitions-cmyk) | Cyan | Magenta | Yellow | Key |
| [`hsl`](/docs/reference/visualize/color/#definitions-hsl) | Hue | Saturation | Lightness | Alpha |
| [`hsv`](/docs/reference/visualize/color/#definitions-hsv) | Hue | Saturation | Value | Alpha |
For the meaning and type of each individual value, see the documentation of the corresponding color space. The alpha component is optional and only included if the `alpha` argument is `true`. The length of the returned array depends on the number of components and whether the alpha component is included.
```typst
// note that the alpha component is included by default
#rgb(40%, 60%, 80%).components()
```
```typst
#color.components(
alpha: bool
) -> array
```
### Parameters
- alpha:
- description: Whether to include the alpha component.
- type: bool
- default: true
## color.space
Returns the constructor function for this color's space.
Returns one of:
- [`luma`](/docs/reference/visualize/color/#definitions-luma)
- [`oklab`](/docs/reference/visualize/color/#definitions-oklab)
- [`oklch`](/docs/reference/visualize/color/#definitions-oklch)
- [`linear-rgb`](/docs/reference/visualize/color/#definitions-linear-rgb)
- [`rgb`](/docs/reference/visualize/color/#definitions-rgb)
- [`cmyk`](/docs/reference/visualize/color/#definitions-cmyk)
- [`hsl`](/docs/reference/visualize/color/#definitions-hsl)
- [`hsv`](/docs/reference/visualize/color/#definitions-hsv)
```typst
#let color = cmyk(1%, 2%, 3%, 4%)
#(color.space() == cmyk)
```
## color.to-hex
Returns the color's RGB(A) hex representation (such as `#ffaa32` or `#020304fe`). The alpha component (last two digits in `#020304fe`) is omitted if it is equal to `ff` (255 / 100%).
## color.lighten
Lightens a color by a given factor.
```typst
#color.lighten(
factor
) -> color
```
### Parameters
- factor:
- description: The factor to lighten the color by.
- type: ratio
- default: None
## color.darken
Darkens a color by a given factor.
```typst
#color.darken(
factor
) -> color
```
### Parameters
- factor:
- description: The factor to darken the color by.
- type: ratio
- default: None
## color.saturate
Increases the saturation of a color by a given factor.
```typst
#color.saturate(
factor
) -> color
```
### Parameters
- factor:
- description: The factor to saturate the color by.
- type: ratio
- default: None
## color.desaturate
Decreases the saturation of a color by a given factor.
```typst
#color.desaturate(
factor
) -> color
```
### Parameters
- factor:
- description: The factor to desaturate the color by.
- type: ratio
- default: None
## color.negate
Produces the complementary color using a provided color space. You can think of it as the opposite side on a color wheel.
```typst
#square(fill: yellow)
#square(fill: yellow.negate())
#square(fill: yellow.negate(space: rgb))
```
```typst
#color.negate(
space: any
) -> color
```
### Parameters
- space:
- description: The color space used for the transformation. By default, a perceptual color space is used.
- type: any
- default: oklab
## color.rotate
Rotates the hue of the color by a given angle.
```typst
#color.rotate(
angle,
space: any
) -> color
```
### Parameters
- angle:
- description: The angle to rotate the hue by.
- type: angle
- default: None
- space:
- description: The color space used to rotate. By default, this happens in a perceptual color space ([`oklch`](/docs/reference/visualize/color/#definitions-oklch)).
- type: any
- default: oklch
## color.mix
Create a color by mixing two or more colors.
In color spaces with a hue component (hsl, hsv, oklch), only two colors can be mixed at once. Mixing more than two colors in such a space will result in an error!
```typst
#set block(height: 20pt, width: 100%)
#block(fill: red.mix(blue))
#block(fill: red.mix(blue, space: rgb))
#block(fill: color.mix(red, blue, white))
#block(fill: color.mix((red, 70%), (blue, 30%)))
```
```typst
#color.mix(
colors,
space: any
) -> color
```
### Parameters
- colors:
- description: The colors, optionally with weights, specified as a pair (array of length two) of color and weight (float or ratio). The weights do not need to add to `100%`, they are relative to the sum of all weights.
- type: color | array
- default: None
- space:
- description: The color space to mix in. By default, this happens in a perceptual color space ([`oklab`](/docs/reference/visualize/color/#definitions-oklab)).
- type: any
- default: oklab
## color.transparentize
Makes a color more transparent by a given factor.
This method is relative to the existing alpha value. If the scale is positive, calculates `alpha - alpha * scale`. Negative scales behave like `color.opacify(-scale)`.
```typst
#block(fill: red)[opaque]
#block(fill: red.transparentize(50%))[half red]
#block(fill: red.transparentize(75%))[quarter red]
```
```typst
#color.transparentize(
scale
) -> color
```
### Parameters
- scale:
- description: The factor to change the alpha value by.
- type: ratio
- default: None
## color.opacify
Makes a color more opaque by a given scale.
This method is relative to the existing alpha value. If the scale is positive, calculates `alpha + scale - alpha * scale`. Negative scales behave like `color.transparentize(-scale)`.
```typst
#let half-red = red.transparentize(50%)
#block(fill: half-red.opacify(100%))[opaque]
#block(fill: half-red.opacify(50%))[three quarters red]
#block(fill: half-red.opacify(-50%))[one quarter red]
```
```typst
#color.opacify(
scale
) -> color
```
### Parameters
- scale:
- description: The scale to change the alpha value by.
- type: ratio
- default: None
docs/reference/visualize/curve.md
# Curve
# curve
A curve consisting of movements, lines, and Bézier segments.
At any point in time, there is a conceptual pen or cursor.
- Move elements move the cursor without drawing.
- Line/Quadratic/Cubic elements draw a segment from the cursor to a new position, potentially with control point for a Bézier curve.
- Close elements draw a straight or smooth line back to the start of the curve or the latest preceding move segment.
For layout purposes, the bounding box of the curve is a tight rectangle containing all segments as well as the point `(0pt, 0pt)`.
Positions may be specified absolutely (i.e. relatively to `(0pt, 0pt)`), or relative to the current pen/cursor position, that is, the position where the previous segment ended.
Bézier curve control points can be skipped by passing `none` or automatically mirrored from the preceding segment by passing `auto`.
## Example
```typst
#curve(
fill: blue.lighten(80%),
stroke: blue,
curve.move((0pt, 50pt)),
curve.line((100pt, 50pt)),
curve.cubic(none, (90pt, 0pt), (50pt, 0pt)),
curve.close(),
)
```
```typst
#curve(
fill: none | color | gradient | tiling,
fill-rule: str,
stroke: none | auto | length | color | gradient | stroke | tiling | dictionary,
components
) -> content
```
## Parameters
- fill:
- description: How to fill the curve. When setting a fill, the default stroke disappears. To create a curve with both fill and stroke, you have to configure both.
- type: none | color | gradient | tiling
- default: none
- fill-rule:
- description: The drawing rule used to fill the curve. ```typst // We use `.with` to get a new // function that has the common // arguments pre-applied. #let star = curve.with( fill: red, curve.move((25pt, 0pt)), curve.line((10pt, 50pt)), curve.line((50pt, 20pt)), curve.line((0pt, 20pt)), curve.line((40pt, 50pt)), curve.close(), ) #star(fill-rule: "non-zero") #star(fill-rule: "even-odd") ```
- type: str
- default: "non - zero"
- stroke:
- description: How to [stroke](/docs/reference/visualize/stroke/) the curve. Can be set to `none` to disable the stroke or to `auto` for a stroke of `1pt` black if and only if no fill is given. ```typst #let down = curve.line((40pt, 40pt), relative: true) #let up = curve.line((40pt, -40pt), relative: true) #curve( stroke: 4pt + gradient.linear(red, blue), down, up, down, up, down, ) ```
- type: none | auto | length | color | gradient | stroke | tiling | dictionary
- default: auto
- components:
- description: The components of the curve, in the form of moves, line and Bézier segment, and closes.
- type: content
- default: None
## Definitions
### curve.move
Starts a new curve component.
If no `curve.move` element is passed, the curve will start at `(0pt, 0pt)`.
```typst
#curve(
fill: blue.lighten(80%),
fill-rule: "even-odd",
stroke: blue,
curve.line((50pt, 0pt)),
curve.line((50pt, 50pt)),
curve.line((0pt, 50pt)),
curve.close(),
curve.move((10pt, 10pt)),
curve.line((40pt, 10pt)),
curve.line((40pt, 40pt)),
curve.line((10pt, 40pt)),
curve.close(),
)
```
```typst
#curve.move(
start,
relative: bool
) -> content
```
#### Parameters
- start:
- description: The starting point for the new component.
- type: array
- default: None
- relative:
- description: Whether the coordinates are relative to the previous point.
- type: bool
- default: false
### curve.line
Adds a straight line from the current point to a following one.
```typst
#curve(
stroke: blue,
curve.line((50pt, 0pt)),
curve.line((50pt, 50pt)),
curve.line((100pt, 50pt)),
curve.line((100pt, 0pt)),
curve.line((150pt, 0pt)),
)
```
```typst
#curve.line(
end,
relative: bool
) -> content
```
#### Parameters
- end:
- description: The point at which the line shall end.
- type: array
- default: None
- relative:
- description: Whether the coordinates are relative to the previous point. ```typst #curve( stroke: blue, curve.line((50pt, 0pt), relative: true), curve.line((0pt, 50pt), relative: true), curve.line((50pt, 0pt), relative: true), curve.line((0pt, -50pt), relative: true), curve.line((50pt, 0pt), relative: true), ) ```
- type: bool
- default: false
### curve.quad
Adds a quadratic Bézier curve segment from the last point to `end`, using `control` as the control point.
```typst
// Function to illustrate where the control point is.
#let mark((x, y)) = place(
dx: x - 1pt, dy: y - 1pt,
circle(fill: aqua, radius: 2pt),
)
#mark((20pt, 20pt))
#curve(
stroke: blue,
curve.move((0pt, 100pt)),
curve.quad((20pt, 20pt), (100pt, 0pt)),
)
```
```typst
#curve.quad(
control,
end,
relative: bool
) -> content
```
#### Parameters
- control:
- description: The control point of the quadratic Bézier curve. - If `auto` and this segment follows another quadratic Bézier curve, the previous control point will be mirrored. - If `none`, the control point defaults to `end`, and the curve will be a straight line. ```typst #curve( stroke: 2pt, curve.quad((20pt, 40pt), (40pt, 40pt), relative: true), curve.quad(auto, (40pt, -40pt), relative: true), ) ```
- type: none | auto | array
- default: None
- end:
- description: The point at which the segment shall end.
- type: array
- default: None
- relative:
- description: Whether the `control` and `end` coordinates are relative to the previous point.
- type: bool
- default: false
### curve.cubic
Adds a cubic Bézier curve segment from the last point to `end`, using `control-start` and `control-end` as the control points.
```typst
// Function to illustrate where the control points are.
#let handle(start, end) = place(
line(stroke: red, start: start, end: end)
)
#handle((0pt, 80pt), (10pt, 20pt))
#handle((90pt, 60pt), (100pt, 0pt))
#curve(
stroke: blue,
curve.move((0pt, 80pt)),
curve.cubic((10pt, 20pt), (90pt, 60pt), (100pt, 0pt)),
)
```
```typst
#curve.cubic(
control-start,
control-end,
end,
relative: bool
) -> content
```
#### Parameters
- control-start:
- description: The control point going out from the start of the curve segment. - If `auto` and this element follows another `curve.cubic` element, the last control point will be mirrored. In SVG terms, this makes `curve.cubic` behave like the `S` operator instead of the `C` operator. - If `none`, the curve has no first control point, or equivalently, the control point defaults to the curve\'s starting point. ```typst #curve( stroke: blue, curve.move((0pt, 50pt)), // - No start control point // - End control point at `(20pt, 0pt)` // - End point at `(50pt, 0pt)` curve.cubic(none, (20pt, 0pt), (50pt, 0pt)), // - No start control point // - No end control point // - End point at `(50pt, 0pt)` curve.cubic(none, none, (100pt, 50pt)), ) #curve( stroke: blue, curve.move((0pt, 50pt)), curve.cubic(none, (20pt, 0pt), (50pt, 0pt)), // Passing `auto` instead of `none` means the start control point // mirrors the end control point of the previous curve. Mirror of // `(20pt, 0pt)` w.r.t `(50pt, 0pt)` is `(80pt, 0pt)`. curve.cubic(auto, none, (100pt, 50pt)), ) #curve( stroke: blue, curve.move((0pt, 50pt)), curve.cubic(none, (20pt, 0pt), (50pt, 0pt)), // `(80pt, 0pt)` is the same as `auto` in this case. curve.cubic((80pt, 0pt), none, (100pt, 50pt)), ) ```
- type: none | auto | array
- default: None
- control-end:
- description: The control point going into the end point of the curve segment. If set to `none`, the curve has no end control point, or equivalently, the control point defaults to the curve\'s end point.
- type: none | array
- default: None
- end:
- description: The point at which the curve segment shall end.
- type: array
- default: None
- relative:
- description: Whether the `control-start`, `control-end`, and `end` coordinates are relative to the previous point.
- type: bool
- default: false
### curve.close
Closes the curve by adding a segment from the last point to the start of the curve (or the last preceding `curve.move` point).
```typst
// We define a function to show the same shape with
// both closing modes.
#let shape(mode: "smooth") = curve(
fill: blue.lighten(80%),
stroke: blue,
curve.move((0pt, 50pt)),
curve.line((100pt, 50pt)),
curve.cubic(auto, (90pt, 0pt), (50pt, 0pt)),
curve.close(mode: mode),
)
#shape(mode: "smooth")
#shape(mode: "straight")
```
```typst
#curve.close(
mode: str
) -> content
```
#### Parameters
- mode:
- description: How to close the curve.
- type: str
- default: "smooth"
docs/reference/visualize/ellipse.md
# Ellipse
# ellipse
An ellipse with optional content.
## Example
```typst
// Without content.
#ellipse(width: 35%, height: 30pt)
// With content.
#ellipse[
#set align(center)
Automatically sized \
to fit the content.
]
```
```typst
#ellipse(
width: auto | relative,
height: auto | relative | fraction,
fill: none | color | gradient | tiling,
stroke: none | auto | length | color | gradient | stroke | tiling | dictionary,
inset: relative | dictionary,
outset: relative | dictionary,
body
) -> content
```
## Parameters
- width:
- description: The ellipse\'s width, relative to its parent container.
- type: auto | relative
- default: auto
- height:
- description: The ellipse\'s height, relative to its parent container.
- type: auto | relative | fraction
- default: auto
- fill:
- description: How to fill the ellipse. See the [rectangle\'s documentation](/docs/reference/visualize/rect/#parameters-fill) for more details.
- type: none | color | gradient | tiling
- default: none
- stroke:
- description: How to stroke the ellipse. See the [rectangle\'s documentation](/docs/reference/visualize/rect/#parameters-stroke) for more details.
- type: none | auto | length | color | gradient | stroke | tiling | dictionary
- default: auto
- inset:
- description: How much to pad the ellipse\'s content. See the [box\'s documentation](/docs/reference/layout/box/#parameters-inset) for more details.
- type: relative | dictionary
- default: 0 % + 5pt
- outset:
- description: How much to expand the ellipse\'s size without affecting the layout. See the [box\'s documentation](/docs/reference/layout/box/#parameters-outset) for more details.
- type: relative | dictionary
- default: (:)
- body:
- description: The content to place into the ellipse. When this is omitted, the ellipse takes on a default size of at most `45pt` by `30pt`.
- type: none | content
- default: none
docs/reference/visualize/gradient.md
# Gradient
A color gradient.
Typst supports linear gradients through the [`gradient.linear` function](/docs/reference/visualize/gradient/#definitions-linear), radial gradients through the [`gradient.radial` function](/docs/reference/visualize/gradient/#definitions-radial), and conic gradients through the [`gradient.conic` function](/docs/reference/visualize/gradient/#definitions-conic).
A gradient can be used for the following purposes:
- As a fill to paint the interior of a shape: `rect(fill: gradient.linear(..))`
- As a stroke to paint the outline of a shape: `rect(stroke: 1pt + gradient.linear(..))`
- As the fill of text: `set text(fill: gradient.linear(..))`
- As a color map you can [sample](/docs/reference/visualize/gradient/#definitions-sample) from: `gradient.linear(..).sample(50%)`
## Examples
```typst
#stack(
dir: ltr,
spacing: 1fr,
square(fill: gradient.linear(..color.map.rainbow)),
square(fill: gradient.radial(..color.map.rainbow)),
square(fill: gradient.conic(..color.map.rainbow)),
)
```
Gradients are also supported on text, but only when setting the [relativeness](/docs/reference/visualize/gradient/#definitions-relative) to either `auto` (the default value) or `"parent"`. To create word-by-word or glyph-by-glyph gradients, you can wrap the words or characters of your text in [boxes](/docs/reference/layout/box/) manually or through a [show rule](/docs/reference/styling/#show-rules).
```typst
#set text(fill: gradient.linear(red, blue))
#let rainbow(content) = {
set text(fill: gradient.linear(..color.map.rainbow))
box(content)
}
This is a gradient on text, but with a #rainbow[twist]!
```
## Stops
A gradient is composed of a series of stops. Each of these stops has a color and an offset. The offset is a [ratio](/docs/reference/layout/ratio/) between `0%` and `100%` or an angle between `0deg` and `360deg`. The offset is a relative position that determines how far along the gradient the stop is located. The stop's color is the color of the gradient at that position. You can choose to omit the offsets when defining a gradient. In this case, Typst will space all stops evenly.
Typst predefines color maps that you can use as stops. See the [`color`](/docs/reference/visualize/color/#predefined-color-maps) documentation for more details.
## Relativeness
The location of the `0%` and `100%` stops depends on the dimensions of a container. This container can either be the shape that it is being painted on, or the closest surrounding container. This is controlled by the `relative` argument of a gradient constructor. By default, gradients are relative to the shape they are being painted on, unless the gradient is applied on text, in which case they are relative to the closest ancestor container.
Typst determines the ancestor container as follows:
- For shapes that are placed at the root/top level of the document, the closest ancestor is the page itself.
- For other shapes, the ancestor is the innermost [`block`](/docs/reference/layout/block/) or [`box`](/docs/reference/layout/box/) that contains the shape. This includes the boxes and blocks that are implicitly created by show rules and elements. For example, a [`rotate`](/docs/reference/layout/rotate/) will not affect the parent of a gradient, but a [`grid`](/docs/reference/layout/grid/) will.
## Color spaces and interpolation
Gradients can be interpolated in any color space. By default, gradients are interpolated in the [Oklab](/docs/reference/visualize/color/#definitions-oklab) color space, which is a [perceptually uniform](https://programmingdesignsystems.com/color/perceptually-uniform-color-spaces/index.html) color space. This means that the gradient will be perceived as having a smooth progression of colors. This is particularly useful for data visualization.
However, you can choose to interpolate the gradient in any supported color space you want, but beware that some color spaces are not suitable for perceptually interpolating between colors. Consult the table below when choosing an interpolation space.
| Color space | Perceptually uniform? |
| --- | --- |
| [Oklab](/docs/reference/visualize/color/#definitions-oklab) | _Yes_ |
| [Oklch](/docs/reference/visualize/color/#definitions-oklch) | _Yes_ |
| [sRGB](/docs/reference/visualize/color/#definitions-rgb) | _No_ |
| [linear-RGB](/docs/reference/visualize/color/#definitions-linear-rgb) | _Yes_ |
| [CMYK](/docs/reference/visualize/color/#definitions-cmyk) | _No_ |
| [Grayscale](/docs/reference/visualize/color/#definitions-luma) | _Yes_ |
| [HSL](/docs/reference/visualize/color/#definitions-hsl) | _No_ |
| [HSV](/docs/reference/visualize/color/#definitions-hsv) | _No_ |
## Direction
Some gradients are sensitive to direction. For example, a linear gradient has an angle that determines its direction. Typst uses a clockwise angle, with 0° being from left to right, 90° from top to bottom, 180° from right to left, and 270° from bottom to top.
```typst
#stack(
dir: ltr,
spacing: 1fr,
square(fill: gradient.linear(red, blue, angle: 0deg)),
square(fill: gradient.linear(red, blue, angle: 90deg)),
square(fill: gradient.linear(red, blue, angle: 180deg)),
square(fill: gradient.linear(red, blue, angle: 270deg)),
)
```
## Note on file sizes
Gradients can be quite large, especially if they have many stops. This is because gradients are stored as a list of colors and offsets, which can take up a lot of space. If you are concerned about file sizes, you should consider the following:
- SVG gradients are currently inefficiently encoded. This will be improved in the future.
- PDF gradients in the [`color.oklab`](/docs/reference/visualize/color/#definitions-oklab), [`color.hsv`](/docs/reference/visualize/color/#definitions-hsv), [`color.hsl`](/docs/reference/visualize/color/#definitions-hsl), and [`color.oklch`](/docs/reference/visualize/color/#definitions-oklch) color spaces are stored as a list of [`color.rgb`](/docs/reference/visualize/color/#definitions-rgb) colors with extra stops in between. This avoids needing to encode these color spaces in your PDF file, but it does add extra stops to your gradient, which can increase the file size.
## Methods
## gradient.linear
Creates a new linear gradient, in which colors transition along a straight line.
```typst
#rect(
width: 100%,
height: 20pt,
fill: gradient.linear(
..color.map.viridis,
),
)
```
```typst
#gradient.linear(
stops,
space: any,
relative: auto | str,
dir,
angle
) -> gradient
```
### Parameters
- stops:
- description: The color [stops](#stops) of the gradient.
- type: color | array
- default: None
- space:
- description: The color space in which to interpolate the gradient. Defaults to a perceptually uniform color space called [Oklab](/docs/reference/visualize/color/#definitions-oklab).
- type: any
- default: oklab
- relative:
- description: The [relative placement](#relativeness) of the gradient. For an element placed at the root/top level of the document, the parent is the page itself. For other elements, the parent is the innermost block, box, column, grid, or stack that contains the element.
- type: auto | str
- default: auto
- dir:
- description: The direction of the gradient.
- type: direction
- default: ltr
- angle:
- description: The angle of the gradient.
- type: angle
- default: None
## gradient.radial
Creates a new radial gradient, in which colors radiate away from an origin.
The gradient is defined by two circles: the focal circle and the end circle. The focal circle is a circle with center `focal-center` and radius `focal-radius`, that defines the points at which the gradient starts and has the color of the first stop. The end circle is a circle with center `center` and radius `radius`, that defines the points at which the gradient ends and has the color of the last stop. The gradient is then interpolated between these two circles.
Using these four values, also called the focal point for the starting circle and the center and radius for the end circle, we can define a gradient with more interesting properties than a basic radial gradient.
```typst
#stack(
dir: ltr,
spacing: 1fr,
circle(fill: gradient.radial(
..color.map.viridis,
)),
circle(fill: gradient.radial(
..color.map.viridis,
focal-center: (10%, 40%),
focal-radius: 5%,
)),
)
```
```typst
#gradient.radial(
stops,
space: any,
relative: auto | str,
center: array,
radius: ratio,
focal-center: auto | array,
focal-radius: ratio
) -> gradient
```
### Parameters
- stops:
- description: The color [stops](#stops) of the gradient.
- type: color | array
- default: None
- space:
- description: The color space in which to interpolate the gradient. Defaults to a perceptually uniform color space called [Oklab](/docs/reference/visualize/color/#definitions-oklab).
- type: any
- default: oklab
- relative:
- description: The [relative placement](#relativeness) of the gradient. For an element placed at the root/top level of the document, the parent is the page itself. For other elements, the parent is the innermost block, box, column, grid, or stack that contains the element.
- type: auto | str
- default: auto
- center:
- description: The center of the end circle of the gradient. A value of `(50%, 50%)` means that the end circle is centered inside of its container.
- type: array
- default: (50 % , 50 % )
- radius:
- description: The radius of the end circle of the gradient. By default, it is set to `50%`. The ending radius must be bigger than the focal radius.
- type: ratio
- default: 50 %
- focal-center:
- description: The center of the focal circle of the gradient. The focal center must be inside of the end circle. A value of `(50%, 50%)` means that the focal circle is centered inside of its container. By default it is set to the same as the center of the last circle.
- type: auto | array
- default: auto
- focal-radius:
- description: The radius of the focal circle of the gradient. The focal center must be inside of the end circle. By default, it is set to `0%`. The focal radius must be smaller than the ending radius\\`.
- type: ratio
- default: 0 %
## gradient.conic
Creates a new conic gradient, in which colors change radially around a center point.
You can control the center point of the gradient by using the `center` argument. By default, the center point is the center of the shape.
```typst
#stack(
dir: ltr,
spacing: 1fr,
circle(fill: gradient.conic(
..color.map.viridis,
)),
circle(fill: gradient.conic(
..color.map.viridis,
center: (20%, 30%),
)),
)
```
```typst
#gradient.conic(
stops,
angle: angle,
space: any,
relative: auto | str,
center: array
) -> gradient
```
### Parameters
- stops:
- description: The color [stops](#stops) of the gradient.
- type: color | array
- default: None
- angle:
- description: The angle of the gradient.
- type: angle
- default: 0deg
- space:
- description: The color space in which to interpolate the gradient. Defaults to a perceptually uniform color space called [Oklab](/docs/reference/visualize/color/#definitions-oklab).
- type: any
- default: oklab
- relative:
- description: The [relative placement](#relativeness) of the gradient. For an element placed at the root/top level of the document, the parent is the page itself. For other elements, the parent is the innermost block, box, column, grid, or stack that contains the element.
- type: auto | str
- default: auto
- center:
- description: The center of the circle of the gradient. A value of `(50%, 50%)` means that the circle is centered inside of its container.
- type: array
- default: (50 % , 50 % )
## gradient.sharp
Creates a sharp version of this gradient.
Sharp gradients have discrete jumps between colors, instead of a smooth transition. They are particularly useful for creating color lists for a preset gradient.
```typst
#set rect(width: 100%, height: 20pt)
#let grad = gradient.linear(..color.map.rainbow)
#rect(fill: grad)
#rect(fill: grad.sharp(5))
#rect(fill: grad.sharp(5, smoothness: 20%))
```
```typst
#gradient.sharp(
steps,
smoothness: ratio
) -> gradient
```
### Parameters
- steps:
- description: The number of stops in the gradient.
- type: int
- default: None
- smoothness:
- description: How much to smooth the gradient.
- type: ratio
- default: 0 %
## gradient.repeat
Repeats this gradient a given number of times, optionally mirroring it at every second repetition.
```typst
#circle(
radius: 40pt,
fill: gradient
.radial(aqua, white)
.repeat(4),
)
```
```typst
#gradient.repeat(
repetitions,
mirror: bool
) -> gradient
```
### Parameters
- repetitions:
- description: The number of times to repeat the gradient.
- type: int
- default: None
- mirror:
- description: Whether to mirror the gradient at every second repetition, i.e., the first instance (and all odd ones) stays unchanged. ```typst #circle( radius: 40pt, fill: gradient .conic(green, black) .repeat(2, mirror: true) ) ```
- type: bool
- default: false
## gradient.kind
Returns the kind of this gradient.
## gradient.stops
Returns the stops of this gradient.
## gradient.space
Returns the mixing space of this gradient.
## gradient.relative
Returns the relative placement of this gradient.
## gradient.angle
Returns the angle of this gradient.
Returns `none` if the gradient is neither linear nor conic.
## gradient.center
Returns the center of this gradient.
Returns `none` if the gradient is neither radial nor conic.
## gradient.radius
Returns the radius of this gradient.
Returns `none` if the gradient is not radial.
## gradient.focal-center
Returns the focal-center of this gradient.
Returns `none` if the gradient is not radial.
## gradient.focal-radius
Returns the focal-radius of this gradient.
Returns `none` if the gradient is not radial.
## gradient.sample
Sample the gradient at a given position.
The position is either a position along the gradient (a [ratio](/docs/reference/layout/ratio/) between `0%` and `100%`) or an [angle](/docs/reference/layout/angle/). Any value outside of this range will be clamped.
```typst
#gradient.sample(
t
) -> color
```
### Parameters
- t:
- description: The position at which to sample the gradient.
- type: angle | ratio
- default: None
## gradient.samples
Samples the gradient at multiple positions at once and returns the results as an array.
```typst
#gradient.samples(
ts
) -> array
```
### Parameters
- ts:
- description: The positions at which to sample the gradient.
- type: angle | ratio
- default: None
docs/reference/visualize/image.md
# Image
# image
A raster or vector graphic.
You can wrap the image in a [`figure`](/docs/reference/model/figure/) to give it a number and caption.
Like most elements, images are _block-level_ by default and thus do not integrate themselves into adjacent paragraphs. To force an image to become inline, put it into a [`box`](/docs/reference/layout/box/).
## Example
```typst
#figure(
image("molecular.jpg", width: 80%),
caption: [
A step in the molecular testing
pipeline of our lab.
],
)
```
```typst
#image(
source,
format: auto | str | dictionary,
width: auto | relative,
height: auto | relative | fraction,
alt: none | str,
page: int,
fit: str,
scaling: auto | str,
icc: auto | str | bytes
) -> content
```
## Parameters
- source:
- description: A [path](/docs/reference/syntax/#paths) to an image file or raw bytes making up an image in one of the supported [formats](/docs/reference/visualize/image/#parameters-format). Bytes can be used to specify raw pixel data in a row-major, left-to-right, top-to-bottom format. ```typst #let original = read("diagram.svg") #let changed = original.replace( "#2B80FF", // blue green.to-hex(), ) #image(bytes(original)) #image(bytes(changed)) ```
- type: str | bytes
- default: None
- format:
- description: The image\'s format. By default, the format is detected automatically. Typically, you thus only need to specify this when providing raw bytes as the [`source`](/docs/reference/visualize/image/#parameters-source) (even then, Typst will try to figure out the format automatically, but that\'s not always possible). Supported formats are `"png"`, `"jpg"`, `"gif"`, `"svg"`, `"pdf"`, `"webp"` as well as raw pixel data. Note that several restrictions apply when using PDF files as images: - When exporting to PDF, any PDF image file used must have a version equal to or lower than the [export target PDF version](/docs/reference/pdf/#pdf-versions). - PDF files as images are currently not supported when exporting with a specific PDF standard, like PDF/A-3 or PDF/UA-1. In these cases, you can instead use SVGs to embed vector images. - The image file must not be password-protected. - Tags in your PDF image will not be preserved. Instead, you must provide an [alternative description](/docs/reference/visualize/image/#parameters-alt) to make the image accessible. When providing raw pixel data as the `source`, you must specify a dictionary with the following keys as the `format`: - `encoding` ([str](/docs/reference/foundations/str/)): The encoding of the pixel data. One of: - `"rgb8"` (three 8-bit channels: red, green, blue) - `"rgba8"` (four 8-bit channels: red, green, blue, alpha) - `"luma8"` (one 8-bit channel) - `"lumaa8"` (two 8-bit channels: luma and alpha) - `width` ([int](/docs/reference/foundations/int/)): The pixel width of the image. - `height` ([int](/docs/reference/foundations/int/)): The pixel height of the image. The pixel width multiplied by the height multiplied by the channel count for the specified encoding must then match the `source` data. ```typst #image( read( "tetrahedron.svg", encoding: none, ), format: "svg", width: 2cm, ) #image( bytes(range(16).map(x => x * 16)), format: ( encoding: "luma8", width: 4, height: 4, ), width: 2cm, ) ```
- type: auto | str | dictionary
- default: auto
- width:
- description: The width of the image.
- type: auto | relative
- default: auto
- height:
- description: The height of the image.
- type: auto | relative | fraction
- default: auto
- alt:
- description: An alternative description of the image. This text is used by Assistive Technology (AT) like screen readers to describe the image to users with visual impairments. When the image is wrapped in a [`figure`](/docs/reference/model/figure/), use this parameter rather than the [figure\'s `alt` parameter](/docs/reference/model/figure/#parameters-alt) to describe the image. The only exception to this rule is when the image and the other contents in the figure form a single semantic unit. In this case, use the figure\'s `alt` parameter to describe the entire composition and do not use this parameter. You can learn how to write good alternative descriptions in the [Accessibility Guide](/docs/guides/accessibility/#textual-representations).
- type: none | str
- default: none
- page:
- description: The page number that should be embedded as an image. This attribute only has an effect for PDF files.
- type: int
- default: 1
- fit:
- description: How the image should adjust itself to a given area (the area is defined by the `width` and `height` fields). Note that `fit` doesn\'t visually change anything if the area\'s aspect ratio is the same as the image\'s one. ```typst #set page(width: 300pt, height: 50pt, margin: 10pt) #image("tiger.jpg", width: 100%, fit: "cover") #image("tiger.jpg", width: 100%, fit: "contain") #image("tiger.jpg", width: 100%, fit: "stretch") ```
- type: str
- default: "cover"
- scaling:
- description: A hint to viewers how they should scale the image. When set to `auto`, the default is left up to the viewer. For PNG export, Typst will default to smooth scaling, like most PDF and SVG viewers. _Note:_ The exact look may differ across PDF viewers.
- type: auto | str
- default: auto
- icc:
- description: An ICC profile for the image. ICC profiles define how to interpret the colors in an image. When set to `auto`, Typst will try to extract an ICC profile from the image.
- type: auto | str | bytes
- default: auto
## Definitions
### image.decode
Decode a raster or vector graphic from bytes or a string.
```typst
#image.decode(
data,
format: auto | str | dictionary,
width: auto | relative,
height: auto | relative | fraction,
alt: none | str,
fit: str,
scaling: auto | str
) -> content
```
#### Parameters
- data:
- description: The data to decode as an image. Can be a string for SVGs.
- type: str | bytes
- default: None
- format:
- description: The image\'s format. Detected automatically by default.
- type: auto | str | dictionary
- default: None
- width:
- description: The width of the image.
- type: auto | relative
- default: None
- height:
- description: The height of the image.
- type: auto | relative | fraction
- default: None
- alt:
- description: A text describing the image.
- type: none | str
- default: None
- fit:
- description: How the image should adjust itself to a given area.
- type: str
- default: None
- scaling:
- description: A hint to viewers how they should scale the image.
- type: auto | str
- default: None
docs/reference/visualize/index.md
# Visualize
Drawing and data visualization.
If you want to create more advanced drawings or plots, also have a look at the [CeTZ](https://github.com/johannes-wolf/cetz) package as well as more specialized [packages](https://typst.app/universe/) for your use case.
## Accessibility
All shapes and paths drawn by Typst are automatically marked as [artifacts](/docs/reference/pdf/artifact/) to make them invisible to Assistive Technology (AT) during PDF export. However, their contents (if any) remain accessible.
If you are using the functions in this model to create an illustration with semantic meaning, make it accessible by wrapping it in a [`figure`](/docs/reference/model/figure/) function call. Use its [`alt` parameter](/docs/reference/model/figure/#parameters-alt) to provide an [alternative description](/docs/guides/accessibility/#textual-representations).
## Definitions
| Name | Description |
| --- | --- |
| [`circle`](/reference/visualize/circle/) | A circle with optional content. |
| [`color`](/reference/visualize/color/) | A color in a specific color space. |
| [`curve`](/reference/visualize/curve/) | A curve consisting of movements, lines, and Bézier segments. |
| [`ellipse`](/reference/visualize/ellipse/) | An ellipse with optional content. |
| [`gradient`](/reference/visualize/gradient/) | A color gradient. |
| [`image`](/reference/visualize/image/) | A raster or vector graphic. |
| [`line`](/reference/visualize/line/) | A line from one point to another. |
| [`path`](/reference/visualize/path/) | A path through a list of points, connected by Bézier curves. |
| [`polygon`](/reference/visualize/polygon/) | A closed polygon. |
| [`rect`](/reference/visualize/rect/) | A rectangle with optional content. |
| [`square`](/reference/visualize/square/) | A square with optional content. |
| [`stroke`](/reference/visualize/stroke/) | Defines how to draw a line. |
| [`tiling`](/reference/visualize/tiling/) | A repeating tiling fill. |
docs/reference/visualize/line.md
# Line
# line
A line from one point to another.
## Example
```typst
#set page(height: 100pt)
#line(length: 100%)
#line(end: (50%, 50%))
#line(
length: 4cm,
stroke: 2pt + maroon,
)
```
```typst
#line(
start: array,
end: none | array,
length: relative,
angle: angle,
stroke: length | color | gradient | stroke | tiling | dictionary
) -> content
```
## Parameters
- start:
- description: The start point of the line. Must be an array of exactly two relative lengths.
- type: array
- default: (0 % + 0pt, 0 % + 0pt)
- end:
- description: The point where the line ends.
- type: none | array
- default: none
- length:
- description: The line\'s length. This is only respected if `end` is `none`.
- type: relative
- default: 0 % + 30pt
- angle:
- description: The angle at which the line points away from the origin. This is only respected if `end` is `none`.
- type: angle
- default: 0deg
- stroke:
- description: How to [stroke](/docs/reference/visualize/stroke/) the line. ```typst #set line(length: 100%) #stack( 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))), ) ```
- type: length | color | gradient | stroke | tiling | dictionary
- default: 1pt + black
docs/reference/visualize/path.md
# Path
# path
A path through a list of points, connected by Bézier curves.
## Example
```typst
#path(
fill: blue.lighten(80%),
stroke: blue,
closed: true,
(0pt, 50pt),
(100%, 50pt),
((50%, 0pt), (40pt, 0pt)),
)
```
```typst
#path(
fill: none | color | gradient | tiling,
fill-rule: str,
stroke: none | auto | length | color | gradient | stroke | tiling | dictionary,
closed: bool,
vertices
) -> content
```
## Parameters
- fill:
- description: How to fill the path. When setting a fill, the default stroke disappears. To create a rectangle with both fill and stroke, you have to configure both.
- type: none | color | gradient | tiling
- default: none
- fill-rule:
- description: The drawing rule used to fill the path. ```typst // We use `.with` to get a new // function that has the common // arguments pre-applied. #let star = path.with( fill: red, closed: true, (25pt, 0pt), (10pt, 50pt), (50pt, 20pt), (0pt, 20pt), (40pt, 50pt), ) #star(fill-rule: "non-zero") #star(fill-rule: "even-odd") ```
- type: str
- default: "non - zero"
- stroke:
- description: How to [stroke](/docs/reference/visualize/stroke/) the path. Can be set to `none` to disable the stroke or to `auto` for a stroke of `1pt` black if and only if no fill is given.
- type: none | auto | length | color | gradient | stroke | tiling | dictionary
- default: auto
- closed:
- description: Whether to close this path with one last Bézier curve. This curve will take into account the adjacent control points. If you want to close with a straight line, simply add one last point that\'s the same as the start point.
- type: bool
- default: false
- vertices:
- description: The vertices of the path. Each vertex can be defined in 3 ways: - A regular point, as given to the [`line`](/docs/reference/visualize/line/) or [`polygon`](/docs/reference/visualize/polygon/) function. - An array of two points, the first being the vertex and the second being the control point. The control point is expressed relative to the vertex and is mirrored to get the second control point. The given control point is the one that affects the curve coming _into_ this vertex (even for the first point). The mirrored control point affects the curve going out of this vertex. - An array of three points, the first being the vertex and the next being the control points (control point for curves coming in and out, respectively).
- type: array
- default: None
docs/reference/visualize/polygon.md
# Polygon
# polygon
A closed polygon.
The polygon is defined by its corner points and is closed automatically.
## Example
```typst
#polygon(
fill: blue.lighten(80%),
stroke: blue,
(20%, 0pt),
(60%, 0pt),
(80%, 2cm),
(0%, 2cm),
)
```
```typst
#polygon(
fill: none | color | gradient | tiling,
fill-rule: str,
stroke: none | auto | length | color | gradient | stroke | tiling | dictionary,
vertices
) -> content
```
## Parameters
- fill:
- description: How to fill the polygon. When setting a fill, the default stroke disappears. To create a rectangle with both fill and stroke, you have to configure both.
- type: none | color | gradient | tiling
- default: none
- fill-rule:
- description: The drawing rule used to fill the polygon. See the [curve documentation](/docs/reference/visualize/curve/#parameters-fill-rule) for an example.
- type: str
- default: "non - zero"
- stroke:
- description: How to [stroke](/docs/reference/visualize/stroke/) the polygon. Can be set to `none` to disable the stroke or to `auto` for a stroke of `1pt` black if and only if no fill is given.
- type: none | auto | length | color | gradient | stroke | tiling | dictionary
- default: auto
- vertices:
- description: The vertices of the polygon. Each point is specified as an array of two [relative lengths](/docs/reference/layout/relative/).
- type: array
- default: None
## Definitions
### polygon.regular
A regular polygon, defined by its size and number of vertices.
```typst
#polygon.regular(
fill: blue.lighten(80%),
stroke: blue,
size: 30pt,
vertices: 3,
)
```
```typst
#polygon.regular(
fill: none | color | gradient | tiling,
stroke: none | auto | length | color | gradient | stroke | tiling | dictionary,
size: length,
vertices: int
) -> content
```
#### Parameters
- fill:
- description: How to fill the polygon. See the general [polygon\'s documentation](/docs/reference/visualize/polygon/#parameters-fill) for more details.
- type: none | color | gradient | tiling
- default: None
- stroke:
- description: How to stroke the polygon. See the general [polygon\'s documentation](/docs/reference/visualize/polygon/#parameters-stroke) for more details.
- type: none | auto | length | color | gradient | stroke | tiling | dictionary
- default: None
- size:
- description: The diameter of the [circumcircle](https://en.wikipedia.org/wiki/Circumcircle) of the regular polygon.
- type: length
- default: 1em
- vertices:
- description: The number of vertices in the polygon.
- type: int
- default: 3
docs/reference/visualize/rect.md
# Rectangle
# rect
A rectangle with optional content.
## Example
```typst
// Without content.
#rect(width: 35%, height: 30pt)
// With content.
#rect[
Automatically sized \
to fit the content.
]
```
```typst
#rect(
width: auto | relative,
height: auto | relative | fraction,
fill: none | color | gradient | tiling,
stroke: none | auto | length | color | gradient | stroke | tiling | dictionary,
radius: relative | dictionary,
inset: relative | dictionary,
outset: relative | dictionary,
body
) -> content
```
## Parameters
- width:
- description: The rectangle\'s width, relative to its parent container.
- type: auto | relative
- default: auto
- height:
- description: The rectangle\'s height, relative to its parent container.
- type: auto | relative | fraction
- default: auto
- fill:
- description: How to fill the rectangle. When setting a fill, the default stroke disappears. To create a rectangle with both fill and stroke, you have to configure both. ```typst #rect(fill: blue) ```
- type: none | color | gradient | tiling
- default: none
- stroke:
- description: How to stroke the rectangle. This can be: - `none` to disable stroking - `auto` for a stroke of `1pt + black` if and only if no fill is given. - Any kind of [stroke](/docs/reference/visualize/stroke/) - A dictionary describing the stroke for each side individually. The dictionary can contain the following keys in order of precedence: - `top`: The top stroke. - `right`: The right stroke. - `bottom`: The bottom stroke. - `left`: The left stroke. - `x`: The horizontal stroke. - `y`: The vertical stroke. - `rest`: The stroke on all sides except those for which the dictionary explicitly sets a size. All keys are optional; omitted keys will use their previously set value, or the default stroke if never set. ```typst #stack( dir: ltr, spacing: 1fr, rect(stroke: red), rect(stroke: 2pt), rect(stroke: 2pt + red), ) ```
- type: none | auto | length | color | gradient | stroke | tiling | dictionary
- default: auto
- radius:
- description: How much to round the rectangle\'s corners, relative to the minimum of the width and height divided by two. This can be: - A relative length for a uniform corner radius. - A dictionary: With a dictionary, the stroke for each side can be set individually. The dictionary can contain the following keys in order of precedence: - `top-left`: The top-left corner radius. - `top-right`: The top-right corner radius. - `bottom-right`: The bottom-right corner radius. - `bottom-left`: The bottom-left corner radius. - `left`: The top-left and bottom-left corner radii. - `top`: The top-left and top-right corner radii. - `right`: The top-right and bottom-right corner radii. - `bottom`: The bottom-left and bottom-right corner radii. - `rest`: The radii for all corners except those for which the dictionary explicitly sets a size. ```typst #set rect(stroke: 4pt) #rect( radius: ( left: 5pt, top-right: 20pt, bottom-right: 10pt, ), stroke: ( left: red, top: yellow, right: green, bottom: blue, ), ) ```
- type: relative | dictionary
- default: (:)
- inset:
- description: How much to pad the rectangle\'s content. See the [box\'s documentation](/docs/reference/layout/box/#parameters-inset) for more details.
- type: relative | dictionary
- default: 0 % + 5pt
- outset:
- description: How much to expand the rectangle\'s size without affecting the layout. See the [box\'s documentation](/docs/reference/layout/box/#parameters-outset) for more details.
- type: relative | dictionary
- default: (:)
- body:
- description: The content to place into the rectangle. When this is omitted, the rectangle takes on a default size of at most `45pt` by `30pt`.
- type: none | content
- default: none
docs/reference/visualize/square.md
# Square
# square
A square with optional content.
## Example
```typst
// Without content.
#square(size: 40pt)
// With content.
#square[
Automatically \
sized to fit.
]
```
```typst
#square(
size: auto | length,
width: auto | relative,
height: auto | relative | fraction,
fill: none | color | gradient | tiling,
stroke: none | auto | length | color | gradient | stroke | tiling | dictionary,
radius: relative | dictionary,
inset: relative | dictionary,
outset: relative | dictionary,
body
) -> content
```
## Parameters
- size:
- description: The square\'s side length. This is mutually exclusive with `width` and `height`.
- type: auto | length
- default: auto
- width:
- description: The square\'s width. This is mutually exclusive with `size` and `height`. In contrast to `size`, this can be relative to the parent container\'s width.
- type: auto | relative
- default: auto
- height:
- description: The square\'s height. This is mutually exclusive with `size` and `width`. In contrast to `size`, this can be relative to the parent container\'s height.
- type: auto | relative | fraction
- default: auto
- fill:
- description: How to fill the square. See the [rectangle\'s documentation](/docs/reference/visualize/rect/#parameters-fill) for more details.
- type: none | color | gradient | tiling
- default: none
- stroke:
- description: How to stroke the square. See the [rectangle\'s documentation](/docs/reference/visualize/rect/#parameters-stroke) for more details.
- type: none | auto | length | color | gradient | stroke | tiling | dictionary
- default: auto
- radius:
- description: How much to round the square\'s corners. See the [rectangle\'s documentation](/docs/reference/visualize/rect/#parameters-radius) for more details.
- type: relative | dictionary
- default: (:)
- inset:
- description: How much to pad the square\'s content. See the [box\'s documentation](/docs/reference/layout/box/#parameters-inset) for more details.
- type: relative | dictionary
- default: 0 % + 5pt
- outset:
- description: How much to expand the square\'s size without affecting the layout. See the [box\'s documentation](/docs/reference/layout/box/#parameters-outset) for more details.
- type: relative | dictionary
- default: (:)
- body:
- description: The content to place into the square. The square expands to fit this content, keeping the 1-1 aspect ratio. When this is omitted, the square takes on a default size of at most `30pt`.
- type: none | content
- default: none
docs/reference/visualize/stroke.md
# Stroke
Defines how to draw a line.
A stroke has a _paint_ (a solid color or gradient), a _thickness,_ a line _cap,_ a line _join,_ a _miter limit,_ and a _dash_ pattern. All of these values are optional and have sensible defaults.
## Example
```typst
#set line(length: 100%)
#stack(
spacing: 1em,
line(stroke: 2pt + red),
line(stroke: (paint: blue, thickness: 4pt, cap: "round")),
line(stroke: (paint: blue, thickness: 1pt, dash: "dashed")),
line(stroke: 2pt + gradient.linear(..color.map.rainbow)),
)
```
## Simple strokes
You can create a simple solid stroke from a color, a thickness, or a combination of the two. Specifically, wherever a stroke is expected you can pass any of the following values:
- A length specifying the stroke's thickness. The color is inherited, defaulting to black.
- A color to use for the stroke. The thickness is inherited, defaulting to `1pt`.
- A stroke combined from color and thickness using the `+` operator as in `2pt + red`.
For full control, you can also provide a [dictionary](/docs/reference/foundations/dictionary/) or a `stroke` object to any function that expects a stroke. The dictionary's keys may include any of the parameters for the constructor function, shown below.
## Fields
On a stroke object, you can access any of the fields listed in the constructor function. For example, `(2pt + blue).thickness` is `2pt`. Meanwhile, `stroke(red).cap` is `auto` because it's unspecified. Fields set to `auto` are inherited.
## Constructor
## stroke
Converts a value to a stroke or constructs a stroke with the given parameters.
Note that in most cases you do not need to convert values to strokes in order to use them, as they will be converted automatically. However, this constructor can be useful to ensure a value has all the fields of a stroke.
```typst
#let my-func(x) = {
x = stroke(x) // Convert to a stroke
[Stroke has thickness #x.thickness.]
}
#my-func(3pt) \
#my-func(red) \
#my-func(stroke(cap: "round", thickness: 1pt))
```
```typst
#stroke(
paint,
thickness,
cap,
join,
dash,
miter-limit
) -> stroke
```
### Parameters
- paint:
- description: The color or gradient to use for the stroke. If set to `auto`, the value is inherited, defaulting to `black`.
- type: auto | color | gradient | tiling
- default: None
- thickness:
- description: The stroke\'s thickness. If set to `auto`, the value is inherited, defaulting to `1pt`.
- type: auto | length
- default: None
- cap:
- description: How the ends of the stroke are rendered. If set to `auto`, the value is inherited, defaulting to `"butt"`.
- type: auto | str
- default: None
- join:
- description: How sharp turns are rendered. If set to `auto`, the value is inherited, defaulting to `"miter"`.
- type: auto | str
- default: None
- dash:
- description: The dash pattern to use. This can be: - One of the predefined patterns: - `"solid"` or `none` - `"dotted"` - `"densely-dotted"` - `"loosely-dotted"` - `"dashed"` - `"densely-dashed"` - `"loosely-dashed"` - `"dash-dotted"` - `"densely-dash-dotted"` - `"loosely-dash-dotted"` - An [array](/docs/reference/foundations/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](/docs/reference/foundations/dictionary/) with the keys `array` (same as the array above), and `phase` (of type [length](/docs/reference/layout/length/)), which defines where in the pattern to start drawing. If set to `auto`, the value is inherited, defaulting to `none`. ```typst #set line(length: 100%, stroke: 2pt) #stack( spacing: 1em, line(stroke: (dash: "dashed")), line(stroke: (dash: (10pt, 5pt, "dot", 5pt))), line(stroke: (dash: (array: (10pt, 5pt, "dot", 5pt), phase: 10pt))), ) ```
- type: none | auto | str | array | dictionary
- default: None
- miter-limit:
- description: Number at which protruding sharp bends are rendered with a bevel instead or a miter join. The higher the number, the sharper an angle can be before it is bevelled. Only applicable if `join` is `"miter"`. Specifically, the miter limit is the maximum ratio between the corner\'s protrusion length and the stroke\'s thickness. If set to `auto`, the value is inherited, defaulting to `4.0`. ```typst #let items = ( curve.move((15pt, 0pt)), curve.line((0pt, 30pt)), curve.line((30pt, 30pt)), curve.line((10pt, 20pt)), ) #set curve(stroke: 6pt + blue) #stack( dir: ltr, spacing: 1cm, curve(stroke: (miter-limit: 1), ..items), curve(stroke: (miter-limit: 4), ..items), curve(stroke: (miter-limit: 5), ..items), ) ```
- type: auto | float
- default: None
docs/reference/visualize/tiling.md
# Tiling
A repeating tiling fill.
Typst supports the most common type of tilings, where a pattern is repeated in a grid-like fashion, covering the entire area of an element that is filled or stroked. The pattern is defined by a tile size and a body defining the content of each cell. You can also add horizontal or vertical spacing between the cells of the tiling.
## Examples
```typst
#let pat = tiling(size: (30pt, 30pt))[
#place(line(start: (0%, 0%), end: (100%, 100%)))
#place(line(start: (0%, 100%), end: (100%, 0%)))
]
#rect(fill: pat, width: 100%, height: 60pt, stroke: 1pt)
```
Tilings are also supported on text, but only when setting the [relativeness](/docs/reference/visualize/tiling/#constructor-relative) to either `auto` (the default value) or `"parent"`. To create word-by-word or glyph-by-glyph tilings, you can wrap the words or characters of your text in [boxes](/docs/reference/layout/box/) manually or through a [show rule](/docs/reference/styling/#show-rules).
```typst
#let pat = tiling(
size: (30pt, 30pt),
relative: "parent",
square(
size: 30pt,
fill: gradient
.conic(..color.map.rainbow),
)
)
#set text(fill: pat)
#lorem(10)
```
You can also space the elements further or closer apart using the [`spacing`](/docs/reference/visualize/tiling/#constructor-spacing) feature of the tiling. If the spacing is lower than the size of the tiling, the tiling will overlap. If it is higher, the tiling will have gaps of the same color as the background of the tiling.
```typst
#let pat = tiling(
size: (30pt, 30pt),
spacing: (10pt, 10pt),
relative: "parent",
square(
size: 30pt,
fill: gradient
.conic(..color.map.rainbow),
),
)
#rect(
width: 100%,
height: 60pt,
fill: pat,
)
```
## Relativeness
The location of the starting point of the tiling is dependent on the dimensions of a container. This container can either be the shape that it is being painted on, or the closest surrounding container. This is controlled by the `relative` argument of a tiling constructor. By default, tilings are relative to the shape they are being painted on, unless the tiling is applied on text, in which case they are relative to the closest ancestor container.
Typst determines the ancestor container as follows:
- For shapes that are placed at the root/top level of the document, the closest ancestor is the page itself.
- For other shapes, the ancestor is the innermost [`block`](/docs/reference/layout/block/) or [`box`](/docs/reference/layout/box/) that contains the shape. This includes the boxes and blocks that are implicitly created by show rules and elements. For example, a [`rotate`](/docs/reference/layout/rotate/) will not affect the parent of a gradient, but a [`grid`](/docs/reference/layout/grid/) will.
## Compatibility
This type used to be called `pattern`. The name remains as an alias, but is deprecated since Typst 0.13.
## Constructor
## tiling
Construct a new tiling.
```typst
#let pat = tiling(
size: (20pt, 20pt),
relative: "parent",
place(
dx: 5pt,
dy: 5pt,
rotate(45deg, square(
size: 5pt,
fill: black,
)),
),
)
#rect(width: 100%, height: 60pt, fill: pat)
```
```typst
#tiling(
size: auto | array,
spacing: array,
relative: auto | str,
body
) -> tiling
```
### Parameters
- size:
- description: The bounding box of each cell of the tiling.
- type: auto | array
- default: auto
- spacing:
- description: The spacing between cells of the tiling.
- type: array
- default: (0pt, 0pt)
- relative:
- description: The [relative placement](#relativeness) of the tiling. For an element placed at the root/top level of the document, the parent is the page itself. For other elements, the parent is the innermost block, box, column, grid, or stack that contains the element.
- type: auto | str
- default: auto
- body:
- description: The content of each cell of the tiling.
- type: content
- default: None
docs/tutorial/advanced-styling.md
# Advanced Styling
In the previous two chapters of this tutorial, you have learned how to write a document in Typst and how to change its formatting. The report you wrote throughout the last two chapters got a straight A and your supervisor wants to base a conference paper on it! The report will of course have to comply with the conference's style guide. Let's see how we can achieve that.
Before we start, let's create a team, invite your supervisor and add them to the team. You can do this by going back to the app dashboard with the back icon in the top left corner of the editor. Then, choose the plus icon in the left toolbar and create a team. Finally, click on the new team and go to its settings by clicking 'manage team' next to the team name. Now you can invite your supervisor by email.
<img src="/assets/3-advanced-team-settings.png" alt="The team settings" />
Next, move your project into the team: Open it, going to its settings by choosing the gear icon in the left toolbar and selecting your new team from the owners dropdown. Don't forget to save your changes!
Now, your supervisor can also edit the project and you can both see the changes in real time. You can join our [Discord server](https://discord.gg/2uDybryKPe) to find other users and try teams with them!
## The conference guidelines
The layout guidelines are available on the conference website. Let's take a look at them:
- The font should be an 11pt serif font
- The title should be in 17pt and bold
- The paper contains a single-column abstract and two-column main text
- The abstract should be centered
- The main text should be justified
- First level section headings should be 13pt, centered, and rendered in small capitals
- Second level headings are run-ins, italicized and have the same size as the body text
- Finally, the pages should be US letter sized, numbered in the center of the footer and the top right corner of each page should contain the title of the paper
We already know how to do many of these things, but for some of them, we'll need to learn some new tricks.
## Writing the right set rules
Let's start by writing some set rules for the document.
```typst
#set page(
paper: "us-letter",
header: align(right)[
A Fluid Dynamic Model for
Glacier Flow
],
numbering: "1",
)
#set par(justify: true)
#set text(
font: "Libertinus Serif",
size: 11pt,
)
#lorem(600)
```
You are already familiar with most of what is going on here. We set the text size to `11pt` and the font to Libertinus Serif. We also enable paragraph justification and set the page size to US letter.
The `header` argument is new: With it, we can provide content to fill the top margin of every page. In the header, we specify our paper's title as requested by the conference style guide. We use the `align` function to align the text to the right.
Last but not least is the `numbering` argument. Here, we can provide a [numbering pattern](/docs/reference/model/numbering/) that defines how to number the pages. By setting it to `"1"`, Typst only displays the bare page number. Setting it to `"(1/1)"` would have displayed the current page and total number of pages surrounded by parentheses. And we could even have provided a completely custom function here to format things to our liking.
## Creating a title and abstract
Now, let's add a title and an abstract. We'll start with the title. Typst comes with a [`title`](/docs/reference/model/title/) function. Let's start by providing our title as an argument:
```typst
#title[
A Fluid Dynamic Model
for Glacier Flow
]
```
You can see that the title is already boldfaced and has some space around it. However, it is left-aligned and not exactly 17pt large. Hence, we need to adjust its appearance. The title function does not come with any arguments for font or text size we could set. Instead, these properties are defined on the `text` and `align` functions.
> What is the difference between what the `title` function inserted and the headings we produced with equals signs?
> Headings, even first-level headings, can appear multiple times in your document whereas a title only appears once, usually at the beginning. Differentiating between the two helps Typst make your document accessible for users of Assistive Technology such as screen readers.
When we want to customize the properties of some element inside of another kind of element, we can use show-set rules. First, we use `show` to select which element we want to customize. We call this a _selector._ Then, we type a colon. Next, we write the set rule that should apply to elements matching the selector. Summarized, the syntax looks like this:
```typst
#show your-selector: set some-element(/* ... */)
```
Let's recall: We want to center-align the title and make it 17pt large. Hence, we need two show-set rules:
- One with the selector `title` and the rule `set text(size: 17pt)`
- One with the selector `title` and the rule `set align(center)`
Our example now looks like this:
```typst
#show title: set text(size: 17pt)
#show title: set align(center)
#title[
A Fluid Dynamic Model
for Glacier Flow
]
```
This looks right. Let's also add the author list: Since we are writing this paper together with our supervisor, we'll add our own and their name.
```typst
#grid(
columns: (1fr, 1fr),
align(center)[
Therese Tungsten \
Artos Institute \
#link("mailto:tung@artos.edu")
],
align(center)[
Dr. John Doe \
Artos Institute \
#link("mailto:doe@artos.edu")
]
)
```
The two author blocks are laid out next to each other. We use the [`grid`](/docs/reference/layout/grid/) function to create this layout. With a grid, we can control exactly how large each column is and which content goes into which cell. The `columns` argument takes an array of [relative lengths](/docs/reference/layout/relative/) or [fractions](/docs/reference/layout/fraction/). In this case, we passed it two equal fractional sizes, telling it to split the available space into two equal columns. We then passed two content arguments to the grid function. The first with our own details, and the second with our supervisors'. We again use the `align` function to center the content within the column. The grid takes an arbitrary number of content arguments specifying the cells. Rows are added automatically, but they can also be manually sized with the `rows` argument.
Looking at the authors and the title, they are a bit too close together. You can address this by using another show-set rule to configure the space below the title. The title, the grid, paragraphs, and all other elements that Typst arranges from the top to the bottom of the page are called _blocks._ Each block is controlled by the [`block`](/docs/reference/layout/block/) function. It controls behaviors like their distance and whether a block can contain a page break. That means that we can write another show-set rule that selects the title to set the block spacing:
```typst
#show title: set text(size: 17pt)
#show title: set align(center)
#show title: set block(below: 1.2em)
#title[
A Fluid Dynamic Model
for Glacier Flow
]
#grid(
// ...
)
```
With this show-set rule, we overrode the spacing below the title. We have used the `em` unit: It allows us to express lengths as multiples of the font size. Here, we used it to space the title and the author list exactly 1.2× the font size apart. Now, let's add the abstract. Remember that the conference wants the abstract to be set ragged and centered.
```typst
...
#align(center)[
#set par(justify: false)
*Abstract* \
#lorem(80)
]
```
Well done! One notable thing is that we used a set rule within the content argument of `align` to turn off justification for the abstract. This does not affect the remainder of the document even though it was specified after the first set rule because content blocks _scope_ styling. Anything set within a content block will only affect the content within that block.
Another tweak could be to remove the duplication between the header and the title element's argument. Since they share the title, it would be convenient to store it in a place designed to hold metadata about the document. We would then need a way to retrieve the title in both places. The `document` element can help us with the former: By using it in a set rule, we can store document metadata like title, description, and keywords.
```typst
#set document(title: [A Fluid Dynamic Model for Glacier Flow])
```
When exporting a PDF, the title set here will appear in the title bar of your PDF reader. Your operating system will also use this title to make the file retrievable with search. Last but not least, it contributes to making your document more accessible and is required if you choose to comply with PDF/UA, a PDF standard focused on accessibility.
Now, we need a way to retrieve the value we set in the main title and the header. Because the `title` function is designed to work together with the `document` element, calling it with no arguments will just print the title. For the header, we will need to be more explicit: Because Typst has no way of knowing that we want to insert the title there, we will need to tell it to do so manually.
Using _context,_ we can retrieve the contents of any values we have set on elements before. When we use the `context` keyword, we can access any property of any element, including the document element's title property. Its use looks like this:
```typst
#set document(title: [
A Fluid Dynamic Model
for Glacier Flow
])
...
#set page(
header: align(
right + horizon,
// Retrieve the document
// element's title property.
context document.title,
),
...
)
#title()
...
```
First, notice how we called the title function with empty, round parentheses. Because no argument was passed, it defaulted to what we set for the document element above. The distinction between empty round and empty square brackets is important: While empty round brackets show that you are passing nothing, empty square brackets mean that you are passing one argument: an empty content block. If called that way, the title would have no visible content.
Next, take a look at the header. Instead of the title in square parentheses, we used the context keyword to access the document title. This inserted exactly what we set above. The role of context is not limited to accessing properties: With it, you can check if some elements are present in the document, measure the physical dimensions of others, and more. Using context, you can build powerful templates that react to the preferences of the end-user.
> <details>
<summary>
Why is the context keyword required to access element properties?
</summary>
<p>Normally, when we access a variable, we know exactly what its value is going to
be:</p>
<ul>
<li>The variable could be a constant built into Typst, like <code><span class="typ-pol">#</span><span class="typ-pol">sym</span><span class="typ-punct">.</span><span class="typ-pol">pi</span></code></li>
<li>The variable could be defined by an argument</li>
<li>The variable could be defined or overwritten in the current scope</li>
</ul>
<p>However, sometimes, that's not enough. In this chapter of the tutorial, we have
inserted a page header with the title. Even though we pass only one piece of
content for the header, we may want different pages to have different headers.
For example, we may want to print the chapter name or use the page number. When
we use context, we can write a single context block that tells Typst to take a
look at where it's inserted, look for the last heading, the current page number,
or anything else, and go from there. That means that the same context block,
inserted on different pages, can produce different output.</p>
<p>For more information, read up on context <a href="/reference/context/">in its docs</a> after
completing this tutorial.</p>
</details>
## Adding columns and headings
The paper above unfortunately looks like a wall of lead. To fix that, let's add some headings and switch our paper to a two-column layout. Fortunately, that's easy to do: We just need to amend our `page` set rule with the `columns` argument.
By adding `columns: 2` to the argument list, we have wrapped the whole document in two columns. However, that would also affect the title and authors overview. To keep them spanning the whole page, we can wrap them in a function call to [`place`](/docs/reference/layout/place/). Place expects an alignment and the content it should place as positional arguments. Using the named `scope` argument, we can decide if the items should be placed relative to the current column or its parent (the page). There is one more thing to configure: If no other arguments are provided, `place` takes its content out of the flow of the document and positions it over the other content without affecting the layout of other content in its container:
```typst
#place(
top + center,
rect(fill: black),
)
#lorem(30)
```
If we hadn't used `place` here, the square would be in its own line, but here it overlaps the few lines of text following it. Likewise, that text acts as if there was no square. To change this behavior, we can pass the argument `float: true` to ensure that the space taken up by the placed item at the top or bottom of the page is not occupied by any other content.
```typst
#set page(
paper: "us-letter",
header: align(
right + horizon,
context document.title,
),
numbering: "1",
columns: 2,
)
#place(
top + center,
float: true,
scope: "parent",
clearance: 2em,
)[
...
#par(justify: false)[
*Abstract* \
#lorem(80)
]
]
= Introduction
#lorem(300)
= Related Work
#lorem(200)
```
In this example, we also used the `clearance` argument of the `place` function to provide the space between it and the body instead of using the [`v`](/docs/reference/layout/v/) function. We can also remove the explicit `align(center, ..)` calls around the various parts since they inherit the center alignment from the placement.
Now there is only one thing left to do: Style our headings. We need to make them centered and use small capitals. These properties are not available on the `heading` function, so we will need to write a few show-set rules and a show rule:
- A show-set rule to make headings center-aligned
- A show-set rule to make headings 13pt large and use the regular weight
- A show rule to wrap the headings in a call to the `smallcaps` function
```typst
#show heading: set align(center)
#show heading: set text(
size: 13pt,
weight: "regular",
)
#show heading: smallcaps
...
= Introduction
...
== Motivation
...
```
This looks great! We used show rules that apply to all headings. In the final show rule, we applied the `smallcaps` function to the complete heading. As we will see in the next example, we can also provide a custom rule to completely override the default look of headings.
The only remaining problem is that all headings look the same now. The "Motivation" and "Problem Statement" subsections ought to be italic run-in headers, but right now, they look indistinguishable from the section headings. We can fix that by using a `where` selector on our show rule: This is a [method](/docs/reference/scripting/#methods) we can call on headings (and other elements) that allows us to filter them by their properties. We can use it to differentiate between section and subsection headings:
```typst
#show heading.where(level: 1): set align(center)
#show heading.where(level: 1): set text(size: 13pt, weight: "regular")
#show heading.where(level: 1): smallcaps
#show heading.where(level: 2): set text(
size: 11pt,
weight: "regular",
style: "italic",
)
#show heading.where(level: 2): it => {
it.body + [.]
}
```
In this example, we first scope our previous rules to first-level headings by using `.where(level: 1)` to make the selector more specific. Then, we add a show-set rule for the second heading level. Finally, we need a show rule with a custom function: Headings enclose their contents with a block by default. This has the effect that the heading gets its own line. However, we want it to run into the text, so we need to provide our own show rule to get rid of this block.
We provide the rule with a function that takes the heading as a parameter. This parameter is conventionally called `it`, but can have another name. The parameter can be used as content and will just display the whole default heading. Alternatively, when we want to build our own heading instead, we can use its fields like `body`, `numbering`, and `level` to compose a custom look. Here, we are just printing the body of the heading with a trailing dot and leave out the block that the built-in show rule produces. Note that this heading will no longer react to set rules for heading numbering and similar because we did not explicitly use `it.numbering` in the show rule. If you are writing show rules like this and want the document to remain customizable, you will need to take these fields into account.
This looks great! We wrote show rules that selectively apply to the first and second level headings. We used a `where` selector to filter the headings by their level. We then rendered the subsection headings as run-ins. We also automatically add a period to the end of the subsection headings.
Let's review the conference's style guide:
- The font should be an 11pt serif font ✓
- The title should be in 17pt and bold ✓
- The paper contains a single-column abstract and two-column main text ✓
- The abstract should be centered ✓
- The main text should be justified ✓
- First level section headings should be centered, rendered in small caps and in 13pt ✓
- Second level headings are run-ins, italicized and have the same size as the body text ✓
- Finally, the pages should be US letter sized, numbered in the center and the top right corner of each page should contain the title of the paper ✓
We are now in compliance with all of these styles and can submit the paper to the conference! The finished paper looks like this:
<img src="/assets/3-advanced-paper.png" alt="The finished paper" style={{boxShadow: '0 4px 12px rgb(89 85 101 / 20%)', width: '500px', maxWidth: '100%', display: 'block', margin: '24px auto'}} />
## Review
You have now learned how to create titles, headers, and footers, how to use functions, show-set rules, and scopes to locally override styles, how to create more complex layouts with the [`grid`](/docs/reference/layout/grid/) function, how to access element properties with context, and how to write show rules for individual functions, and the whole document. You also learned how to use the [`where` selector](/docs/reference/styling/#show-rules) to filter the headings by their level.
The paper was a great success! You've met a lot of like-minded researchers at the conference and are planning a project which you hope to publish at the same venue next year. You'll need to write a new paper using the same style guide though, so maybe now you want to create a time-saving template for you and your team?
In the next section, we will learn how to create templates that can be reused in multiple documents. This is a more advanced topic, so feel free to come back to it later if you don't feel up to it right now.
docs/tutorial/formatting.md
# Formatting
So far, you have written a report with some text, a few equations and images. However, it still looks very plain. Your teaching assistant does not yet know that you are using a new typesetting system, and you want your report to fit in with the other student's submissions. In this chapter, we will see how to format your report using Typst's styling system.
## Set rules
As we have seen in the previous chapter, Typst has functions that _insert_ content (e.g. the [`image`](/docs/reference/visualize/image/) function) and others that _manipulate_ content that they received as arguments (e.g. the [`align`](/docs/reference/layout/align/) function). The first impulse you might have when you want, for example, to change the font, could be to look for a function that does that and wrap the complete document in it.
```typst
#text(font: "New Computer Modern")[
= Background
In the case of glaciers, fluid
dynamics principles can be used
to understand how the movement
and behaviour of the ice is
influenced by factors such as
temperature, pressure, and the
presence of other fluids (such as
water).
]
```
Wait, shouldn't all arguments of a function be specified within parentheses? Why is there a second set of square brackets with content _after_ the parentheses? The answer is that, as passing content to a function is such a common thing to do in Typst, there is special syntax for it: Instead of putting the content inside of the argument list, you can write it in square brackets directly after the normal arguments, saving on punctuation.
As seen above, that works. With the [`text`](/docs/reference/text/text/) function, we can adjust the font for all text within it. However, wrapping the document in countless functions and applying styles selectively and in-situ can quickly become cumbersome.
Fortunately, Typst has a more elegant solution. With _set rules,_ you can apply style properties to all occurrences of some kind of content. You write a set rule by entering the `set` keyword, followed by the name of the function whose properties you want to set, and a list of arguments in parentheses.
```typst
#set text(
font: "New Computer Modern"
)
= Background
In the case of glaciers, fluid
dynamics principles can be used
to understand how the movement
and behaviour of the ice is
influenced by factors such as
temperature, pressure, and the
presence of other fluids (such as
water).
```
> Want to know in more technical terms what is happening here?
> Set rules can be conceptualized as setting default values for some of the parameters of a function for all future uses of that function.
## The autocomplete panel
If you followed along and tried a few things in the app, you might have noticed that always after you enter a `#` character, a panel pops up to show you the available functions, and, within an argument list, the available parameters. That's the autocomplete panel. It can be very useful while you are writing your document: You can apply its suggestions by hitting the Return key or navigate to the desired completion with the arrow keys. The panel can be dismissed by hitting the Escape key and opened again by typing `#` or hitting Ctrl + Space. Use the autocomplete panel to discover the right arguments for functions. Most suggestions come with a small description of what they do.
<img src="/assets/2-formatting-autocomplete.png" alt="Autocomplete panel" />
## Set up the page
Back to set rules: When writing a rule, you choose the function depending on what type of element you want to style. Here is a list of some functions that are commonly used in set rules:
- [`text`](/docs/reference/text/text/) to set font family, size, color, and other properties of text
- [`page`](/docs/reference/layout/page/) to set the page size, margins, headers, enable columns, and footers
- [`par`](/docs/reference/model/par/) to justify paragraphs, set line spacing, and more
- [`heading`](/docs/reference/model/heading/) to set the appearance of headings and enable numbering
- [`document`](/docs/reference/model/document/) to set the metadata contained in the PDF output, such as title and author
Not all function parameters can be set. In general, only parameters that tell a function _how_ to do something can be set, not those that tell it _what_ to do it with. The function reference pages indicate which parameters are settable.
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.
```typst
#set page(
paper: "a6",
margin: (x: 1.8cm, y: 1.5cm),
)
#set text(
font: "New Computer Modern",
size: 10pt
)
#set par(
justify: true,
leading: 0.52em,
)
= Introduction
In this report, we will explore the
various factors that influence fluid
dynamics in glaciers and how they
contribute to the formation and
behaviour of these natural structures.
...
#align(center + bottom)[
#image("glacier.jpg", width: 70%)
*Glaciers form an important
part of the earth's climate
system.*
]
```
There are a few things of note here.
First is the [`page`](/docs/reference/layout/page/) set rule. It receives two arguments: the page size and margins for the page. The page size is a string. Typst accepts [many standard page sizes,](/docs/reference/layout/page/#parameters-paper) but you can also specify a custom page size. The margins are specified as a [dictionary.](/docs/reference/foundations/dictionary/) Dictionaries are a collection of key-value pairs. In this case, the keys are `x` and `y`, and the values are the horizontal and vertical margins, respectively. We could also have specified separate margins for each side by passing a dictionary with the keys `left`, `right`, `top`, and `bottom`.
Next is the set [`text`](/docs/reference/text/text/) set rule. Here, we set the font size to `10pt` and font family to `"New Computer Modern"`. The Typst app comes with many fonts that you can try for your document. When you are in the text function's argument list, you can discover the available fonts in the autocomplete panel.
We have also set the spacing between lines (a.k.a. leading): It is specified as a [length](/docs/reference/layout/length/) value, and we used the `em` unit to specify the leading relative to the size of the font: `1em` is equivalent to the current font size (which defaults to `11pt`).
Finally, we have bottom aligned our image by adding a vertical alignment to our center alignment. Vertical and horizontal alignments can be combined with the `+` operator to yield a 2D alignment.
## A hint of sophistication
To structure our document more clearly, we now want to number our headings. We can do this by setting the `numbering` parameter of the [`heading`](/docs/reference/model/heading/) function.
```typst
#set heading(numbering: "1.")
= Introduction
#lorem(10)
== Background
#lorem(12)
== Methods
#lorem(15)
```
We specified the string `"1."` as the numbering parameter. This tells Typst to number the headings with arabic numerals and to put a dot between the number of each level. We can also use [letters, roman numerals, and symbols](/docs/reference/model/numbering/) for our headings:
```typst
#set heading(numbering: "1.a")
= Introduction
#lorem(10)
== Background
#lorem(12)
== Methods
#lorem(15)
```
This example also uses the [`lorem`](/docs/reference/text/lorem/) function to generate some placeholder text. This function takes a number as an argument and generates that many words of _Lorem Ipsum_ text.
> Did you wonder why the headings and text set rules apply to all text and headings, even if they are not produced with the respective functions?
> Typst internally calls the `heading` function every time you write `= Conclusion`. In fact, the function call `#heading[Conclusion]` is equivalent to the heading markup above. Other markup elements work similarly, they are only _syntax sugar_ for the corresponding function calls.
## Show rules
You are already pretty happy with how this turned out. But one last thing needs to be fixed: The report you are writing is intended for a larger project and that project's name should always be accompanied by a logo, even in prose.
You consider your options. You could add an `#image("logo.svg")` call before every instance of the logo using search and replace. That sounds very tedious. Instead, you could maybe [define a custom function](/docs/reference/foundations/function/#defining-functions) that always yields the logo with its image. However, there is an even easier way:
With show rules, you can redefine how Typst displays certain elements. You specify which elements Typst should show differently and how they should look. Show rules can be applied to instances of text, many functions, and even the whole document.
```typst
#show "ArtosFlow": name => box[
#box(image(
"logo.svg",
height: 0.7em,
))
#name
]
This report is embedded in the
ArtosFlow project. ArtosFlow is a
project of the Artos Institute.
```
There is a lot of new syntax in this example: We write the `show` keyword, followed by a string of text we want to show differently and a colon. Then, we write a function that takes the content that shall be shown as an argument. Here, we called that argument `name`. We can now use the `name` variable in the function's body to print the ArtosFlow name. Our show rule adds the logo image in front of the name and puts the result into a box to prevent linebreaks from occurring between logo and name. The image is also put inside of a box, so that it does not appear in its own paragraph.
The calls to the first box function and the image function did not require a leading `#` because they were not embedded directly in markup. When Typst expects code instead of markup, the leading `#` is not needed to access functions, keywords, and variables. This can be observed in parameter lists, function definitions, and [code blocks](/docs/reference/scripting/).
## Review
You now know how to apply basic formatting to your Typst documents. You learned how to set the font, justify your paragraphs, change the page dimensions, and add numbering to your headings with set rules. You also learned how to use a basic show rule to change how text appears throughout your document.
You have handed in your report. Your supervisor was so happy with it that they want to adapt it into a conference paper! In the next section, we will learn how to format your document as a paper using more advanced show rules and functions.
docs/tutorial/index.md
# Tutorial
Welcome to Typst's tutorial! In this tutorial, you will learn how to write and format documents in Typst. We will start with everyday tasks and gradually introduce more advanced features. This tutorial does not assume prior knowledge of Typst, other markup languages, or programming. We do assume that you know how to edit a text file.
The best way to start is to sign up to the Typst app for free and follow along with the steps below. The app gives you instant preview, syntax highlighting and helpful autocompletions. Alternatively, you can follow along in your local text editor with the [open-source CLI](https://github.com/typst/typst).
## When to use Typst
Before we get started, let's check what Typst is and when to use it. Typst is a markup language for typesetting documents. It is designed to be easy to learn, fast, and versatile. Typst takes text files with markup in them and outputs PDFs.
Typst is a good choice for writing any long form text such as essays, articles, scientific papers, books, reports, and homework assignments. Moreover, Typst is a great fit for any documents containing mathematical notation, such as papers in the math, physics, and engineering fields. Finally, due to its strong styling and automation features, it is an excellent choice for any set of documents that share a common style, such as a book series.
## What you will learn
This tutorial has four chapters. Each chapter builds on the previous one. Here is what you will learn in each of them:
1. [Writing in Typst:](/docs/tutorial/writing-in-typst/) Learn how to write text and insert images, equations, and other elements.
2. [Formatting:](/docs/tutorial/formatting/) Learn how to adjust the formatting of your document, including font size, heading styles, and more.
3. [Advanced Styling:](/docs/tutorial/advanced-styling/) Create a complex page layout for a scientific paper with typographic features such as an author list and run-in headings.
4. [Making a Template:](/docs/tutorial/making-a-template/) Build a reusable template from the paper you created in the previous chapter.
We hope you'll enjoy Typst!
docs/tutorial/making-a-template.md
# Making a Template
In the previous three chapters of this tutorial, you have learned how to write a document in Typst, apply basic styles, and customize its appearance in-depth to comply with a publisher's style guide. Because the paper you wrote in the previous chapter was a tremendous success, you have been asked to write a follow-up article for the same conference. This time, you want to take the style you created in the previous chapter and turn it into a reusable template. In this chapter you will learn how to create a template that you and your team can use with just one show rule. Let's get started!
## Reusing data with variables
In the past chapters, most of the content of the document was entered by hand. In the third chapter, we used the `document` element and context to cut down on repetition and only enter the title once. But in practice, there may be many more things that occur multiple times in your document. There are multiple good reasons to just define these repeated values once:
1. It makes changing them later easier
2. It allows you to quickly find all instances where you used something
3. It makes it easy to be consistent throughout
4. For long or hard-to-enter repeated segments, a shorter variable name is often more convenient to type
If you were using a conventional word processor, you might resort to using a placeholder value that you can later search for. In Typst, however, you can instead use variables to safely store content and reuse it across your whole document through a variable name.
The technique of using context to reproduce an element's property we have learned earlier is not always the most appropriate for this: Typst's built-in elements focus on semantic properties like the title and description of a document, or things that directly relate to typesetting, like the text size.
For our example, we want to take a look at Typst's pronunciation. One of the best ways to transcribe pronunciation is the International Phonetic Alphabet (IPA). But because it uses characters not found on common keyboards, typing IPA repeatedly can become cumbersome. So let's instead define a variable that we can reference multiple times.
```typst
#let ipa = [taɪpst]
```
Here, we use a new keyword, `let`, to indicate a variable definition. Then, we put the name of our variable, in this case, `ipa`. Finally, we type an equals sign and the value of our variable. It is enclosed in square brackets because it is content, mirroring how you would call a function accepting content. In other words, this syntax mirrors the phrase _"Let the variable ipa have the
value [taɪpst]."_
Now, we can use the variable in our document:
```typst
#let ipa = [taɪpst]
The canonical way to
pronounce Typst is #ipa.
#table(
columns: (1fr, 1fr),
[Name], [Typst],
[Pronunciation], ipa,
)
```
In the example, you can see that the variable can be used both in markup (prefixed with a `#`) and in a function call (by just typing its name). Of course, we can change the value of the variable and all its occurrences will automatically change with it. Let's make it a bit clearer what is IPA and what is normal prose by rendering IPA in italics. We are also using slashes which, by convention, often enclose IPA.
```typst
#let ipa = text(
style: "italic",
)[/taɪpst/]
The canonical way to
pronounce Typst is #ipa.
#table(
columns: (1fr, 1fr),
[Name], [Typst],
[Pronunciation], ipa,
)
```
Here, we called the text function and assigned its _return value_ to the variable. When you call a function, it processes its arguments and then yields another value (often content). So far in this tutorial, we called most functions directly in markup, like this: `#text(fill: red)[CRIMSON!]`. This call to the text function returns the red text as a return value. Because we placed it in markup, its return value just immediately got inserted into the content we wrote. With variables, we can instead store it to use it later or compose it with other values.
Variables are not limited to storing content: they can store any data type Typst knows about. Throughout this tutorial, you made use of many data types when you passed them to Typst's built-in functions. Here is an example assigning each of them to a variable:
```typst
// Content with markup inside
#let blind-text = [_Lorem ipsum_ dolor sit amet]
// Unformatted strings
#let funny-font = "MS Comic Sans"
// Absolute lengths (see also pt, in, ...)
#let mile = 160934cm
// Lengths relative to the font size
#let double-space = 2em
// Ratios
#let progress = 80%
// Integer numbers
#let answer = 42
// Booleans
#let truth = false
// Horizontal and vertical alignment
#let focus = center
```
In this chapter of the tutorial, you will leverage variables and your own functions to build templates that can be reused across multiple documents.
## A toy template
In Typst, templates are functions in which you can wrap your whole document. To learn how to do that, let's first review how to write your very own functions. They can do anything you want them to, so why not go a bit crazy?
```typst
#let amazed(term) = box[✨ #term ✨]
You are #amazed[beautiful]!
```
Comparing this against the previous section, you may have noticed that this looks a lot like a variable definition using `let`. This instinct is correct: Functions are just another data type. Here, we are defining the variable `amazed`, assigning it a function that takes a single argument, `term`, and returns content with the `term` surrounded by sparkles. We also put the whole thing in a [`box`](/docs/reference/layout/box/) so that the term we are amazed by cannot be separated from its sparkles by a line break. The special function definition syntax makes the definition shorter and more readable, but you can also use the regular variable definition syntax (see [the scripting reference](/docs/reference/scripting/#bindings) for details). After its definition, we are able to call the function just like all built-in functions.
Many functions that come with Typst have optional named parameters. Our functions can also have them. Let's add a parameter to our function that lets us choose the color of the text. We need to provide a default color in case the parameter isn't given.
```typst
#let amazed(term, color: blue) = {
text(color, box[✨ #term ✨])
}
You are #amazed[beautiful]!
I am #amazed(color: purple)[amazed]!
```
Templates now work by wrapping our whole document in a custom function like `amazed`. But wrapping a whole document in a giant function call would be cumbersome! Instead, we can use an "everything" show rule to achieve the same with cleaner code. To write such a show rule, put a colon directly after the show keyword and then provide a function. This function is given the rest of the document as a parameter. The function can then do anything with this content. Since the `amazed` function can be called with a single content argument, we can just pass it by name to the show rule. Let's try it:
```typst
#show: amazed
I choose to focus on the good
in my life and let go of any
negative thoughts or beliefs.
In fact, I am amazing!
```
Our whole document will now be passed to the `amazed` function, as if we wrapped it around it. Of course, this is not especially useful with this particular function, but when combined with set rules and named arguments, it can be very powerful.
## Embedding set and show rules
To apply some set and show rules to our template, we can use `set` and `show` within a content block in our function and then insert the document into that content block.
```typst
#let template(doc) = [
#set text(font: "Inria Serif")
#show "something cool": [Typst]
#doc
]
#show: template
I am learning something cool today.
It's going great so far!
```
Just like we already discovered in the previous chapter, set rules will apply to everything within their content block. Since the everything show rule passes our whole document to the `template` function, the text set rule and string show rule in our template will apply to the whole document. Let's use this knowledge to create a template that reproduces the body style of the paper we wrote in the previous chapter.
```typst
#let conf(title, doc) = {
set page(
paper: "us-letter",
header: align(
right + horizon,
title
),
columns: 2,
...
)
set par(justify: true)
set text(
font: "Libertinus Serif",
size: 11pt,
)
// Heading show rules.
...
doc
}
#show: doc => conf(
[Paper title],
doc,
)
= Introduction
...
```
We copy-pasted most of that code from the previous chapter. The two differences are this:
1. We wrapped everything in the function `conf` using an everything show rule. The function applies a few set and show rules and echoes the content it has been passed at the end.
2. Moreover, we used a curly-braced code block instead of a content block. This way, we don't need to prefix all set rules and function calls with a `#`. In exchange, we cannot write markup directly in the code block anymore.
Also note where the title comes from: We previously had it inside of a variable. Now, we are receiving it as the first parameter of the template function. To do so, we passed a closure (that's a function without a name that is used right away) to the everything show rule. We did that because the `conf` function expects two positional arguments, the title and the body, but the show rule will only pass the body. Therefore, we add a new function definition that allows us to set a paper title and use the single parameter from the show rule.
## Templates with named arguments
Our paper in the previous chapter had a title and an author list. Let's add these things to our template. In addition to the title, we want our template to accept a list of authors with their affiliations and the paper's abstract. To keep things readable, we'll add those as named arguments. In the end, we want it to work like this:
```typst
#show: doc => conf(
title: [
A Fluid Dynamic Model for
Glacier Flow
],
authors: (
(
name: "Theresa Tungsten",
affiliation: "Artos Institute",
email: "tung@artos.edu",
),
(
name: "Eugene Deklan",
affiliation: "Honduras State",
email: "e.deklan@hstate.hn",
),
),
abstract: lorem(80),
doc,
)
...
```
Let's build this new template function. First, we add a default value to the `title` argument. This way, we can call the template without specifying a title. We also add the named `authors` and `abstract` parameters with empty defaults. Next, we copy the code that generates title, abstract and authors from the previous chapter into the template, replacing the fixed details with the parameters.
The new `authors` parameter expects an [array](/docs/reference/foundations/array/) of [dictionaries](/docs/reference/foundations/dictionary/) with the keys `name`, `affiliation` and `email`. Because we can have an arbitrary number of authors, we dynamically determine if we need one, two or three columns for the author list. First, we determine the number of authors using the [`.len()`](/docs/reference/foundations/array/#definitions-len) method on the `authors` array. Then, we set the number of columns as the minimum of this count and three, so that we never create more than three columns. If there are more than three authors, a new row will be inserted instead. For this purpose, we have also added a `row-gutter` parameter to the `grid` function. Otherwise, the rows would be too close together. To extract the details about the authors from the dictionary, we use the [field access syntax](/docs/reference/scripting/#fields).
We still have to provide an argument to the grid for each author: Here is where the array's [`map` method](/docs/reference/foundations/array/#definitions-map) comes in handy. It takes a function as an argument that gets called with each item of the array. We pass it a function that formats the details for each author and returns a new array containing content values. We've now got one array of values that we'd like to use as multiple arguments for the grid. We can do that by using the [`spread` operator](/docs/reference/foundations/arguments/). It takes an array and applies each of its items as a separate argument to the function.
The resulting template function looks like this:
```typst
#let conf(
authors: (),
abstract: [],
doc,
) = {
// Set and show rules from before.
...
place(
top + center,
float: true,
scope: "parent",
clearance: 2em,
{
title()
let count = authors.len()
let ncols = calc.min(count, 3)
grid(
columns: (1fr,) * ncols,
row-gutter: 24pt,
..authors.map(author => [
#author.name \
#author.affiliation \
#link("mailto:" + author.email)
]),
)
par(justify: false)[
*Abstract* \
#abstract
]
}
)
doc
}
```
## A separate file
Most of the time, a template is specified in a different file and then imported into the document. This way, the main file you write in is kept clutter free and your template is easily reused. Create a new text file in the file panel by clicking the plus button and name it `conf.typ`. Move the `conf` function definition inside of that new file. Now you can access it from your main file by adding an import before the show rule. Specify the path of the file between the `import` keyword and a colon, then name the function that you want to import.
Another thing that you can do to make applying templates just a bit more elegant is to use the [`.with`](/docs/reference/foundations/function/#definitions-with) method on functions to pre-populate all the named arguments. This way, you can avoid spelling out a closure and appending the content argument at the bottom of your template list. Templates on [Typst Universe](https://typst.app/universe/) are designed to work with this style of function call.
```typst
#import "conf.typ": conf
#set document(title: [
A Fluid Dynamic Model for
Glacier Flow
])
#show: conf.with(
authors: (
(
name: "Theresa Tungsten",
affiliation: "Artos Institute",
email: "tung@artos.edu",
),
(
name: "Eugene Deklan",
affiliation: "Honduras State",
email: "e.deklan@hstate.hn",
),
),
abstract: lorem(80),
)
= Introduction
#lorem(90)
== Motivation
#lorem(140)
== Problem Statement
#lorem(50)
= Related Work
#lorem(200)
```
We have now converted the conference paper into a reusable template for that conference! Why not share it in the [Forum](https://forum.typst.app/) or on [Typst's Discord server](https://discord.gg/2uDybryKPe) so that others can use it too?
## Review
Congratulations, you have completed Typst's Tutorial! In this section, you have learned how to define your own functions and how to create and apply templates that define reusable document styles. You've made it far and learned a lot. You can now use Typst to write your own documents and share them with others.
We are still a super young project and are looking for feedback. If you have any questions, suggestions or you found a bug, please let us know in the [Forum](https://forum.typst.app/), on our [Discord server](https://discord.gg/2uDybryKPe), on [GitHub](https://github.com/typst/typst/), or via the web app's feedback form (always available in the Help menu).
So what are you waiting for? [Sign up](https://typst.app) and write something!
docs/tutorial/writing-in-typst.md
# Writing in Typst
Let's get started! Suppose you got assigned to write a technical report for university. It will contain prose, maths, headings, and figures. To get started, you create a new project on the Typst app. You'll be taken to the editor where you see two panels: A source panel where you compose your document and a preview panel where you see the rendered document.
<img src="/assets/1-writing-app.png" alt="Typst app screenshot" />
You already have a good angle for your report in mind. So let's start by writing the introduction. Enter some text in the editor panel. You'll notice that the text immediately appears on the previewed page.
```typst
In this report, we will explore the
various factors that influence fluid
dynamics in glaciers and how they
contribute to the formation and
behaviour of these natural structures.
```
_Throughout this tutorial, we'll show code examples like this one. Just like in the app, the first panel contains markup and the second panel shows a preview. We shrunk the page to fit the examples so you can see what's going on._
The next step is to add a heading and emphasize some text. Typst uses simple markup for the most common formatting tasks. To add a heading, enter the `=` character and to emphasize some text with italics, enclose it in `_underscores_`.
```typst
= Introduction
In this report, we will explore the
various factors that influence _fluid
dynamics_ in glaciers and how they
contribute to the formation and
behaviour of these natural structures.
```
That was easy! To add a new paragraph, just add a blank line in between two lines of text. If that paragraph needs a subheading, produce it by typing `==` instead of `=`. The number of `=` characters determines the nesting level of the heading.
Now we want to list a few of the circumstances that influence glacier dynamics. To do that, we use a numbered list. For each item of the list, we type a `+` character at the beginning of the line. Typst will automatically number the items.
```typst
+ The climate
+ The topography
+ The geology
```
If we wanted to add a bulleted list, we would use the `-` character instead of the `+` character. We can also nest lists: For example, we can add a sub-list to the first item of the list above by indenting it.
```typst
+ The climate
- Temperature
- Precipitation
+ The topography
+ The geology
```
## Adding a figure
You think that your report would benefit from a figure. Let's add one. Typst supports images in the formats PNG, JPEG, GIF, SVG, PDF, and WebP. To add an image file to your project, first open the _file panel_ by clicking the box icon in the left sidebar. Here, you can see a list of all files in your project. Currently, there is only one: The main Typst file you are writing in. To upload another file, click the button with the arrow in the top-right corner. This opens the upload dialog, in which you can pick files to upload from your computer. Select an image file for your report.
<img src="/assets/1-writing-upload.png" alt="Upload dialog" />
We have seen before that specific symbols (called _markup_) have specific meaning in Typst. We can use `=`, `-`, `+`, and `_` to create headings, lists and emphasized text, respectively. However, having a special symbol for everything we want to insert into our document would soon become cryptic and unwieldy. For this reason, Typst reserves markup symbols only for the most common things. Everything else is inserted with _functions._ For our image to show up on the page, we use Typst's [`image`](/docs/reference/visualize/image/) function.
```typst
#image("glacier.jpg")
```
In general, a function produces some output for a set of _arguments_. When you _call_ a function within markup, you provide the arguments and Typst inserts the result (the function's _return value_) into the document. In our case, the `image` function takes one argument: The path to the image file. To call a function in markup, we first need to type the `#` character, immediately followed by the name of the function. Then, we enclose the arguments in parentheses. Typst recognizes many different data types within argument lists. Our file path is a short [string of text](/docs/reference/foundations/str/), so we need to enclose it in double quotes.
The inserted image uses the whole width of the page. To change that, pass the `width` argument to the `image` function. This is a _named_ argument and therefore specified as a `name: value` pair. If there are multiple arguments, they are separated by commas, so we first need to put a comma behind the path.
```typst
#image("glacier.jpg", width: 70%)
```
The `width` argument is a [relative length](/docs/reference/layout/relative/). In our case, we specified a percentage, determining that the image shall take up `70%` of the page's width. We also could have specified an absolute value like `1cm` or `0.7in`.
Just like text, the image is now aligned at the left side of the page by default. It's also lacking a caption. Let's fix that by using the [figure](/docs/reference/model/figure/) function. This function takes the figure's contents as a positional argument and an optional caption as a named argument.
Within the argument list of the `figure` function, Typst is already in code mode. This means, you now have to remove the hash before the image function call. The hash is only needed directly in markup (to disambiguate text from function calls).
The caption consists of arbitrary markup. To give markup to a function, we enclose it in square brackets. This construct is called a _content block._
```typst
#figure(
image("glacier.jpg", width: 70%),
caption: [
_Glaciers_ form an important part
of the earth's climate system.
],
)
```
You continue to write your report and now want to reference the figure. To do that, first attach a label to figure. A label uniquely identifies an element in your document. Add one after the figure by enclosing some name in angle brackets. You can then reference the figure in your text by writing an `@` symbol followed by that name. Headings and equations can also be labelled to make them referenceable.
```typst
Glaciers as the one shown in
@glaciers will cease to exist if
we don't take action soon!
#figure(
image("glacier.jpg", width: 70%),
caption: [
_Glaciers_ form an important part
of the earth's climate system.
],
) <glaciers>
```
> So far, we've passed content blocks (markup in square brackets) and strings (text in double quotes) to our functions. Both seem to contain text. What's the difference?
> A content block can contain text, but also any other kind of markup, function calls, and more, whereas a string is really just a _sequence of characters_ and nothing else.
> For example, the image function expects a path to an image file. It would not make sense to pass, e.g., a paragraph of text or another image as the image's path parameter. That's why only strings are allowed here. In contrast, strings work wherever content is expected because text is a valid kind of content.
## Adding a bibliography
As you write up your report, you need to back up some of your claims. You can add a bibliography to your document with the [`bibliography`](/docs/reference/model/bibliography/) function. This function expects a path to a bibliography file.
Typst's native bibliography format is [Hayagriva](https://github.com/typst/hayagriva/blob/main/docs/file-format.md), but for compatibility you can also use BibLaTeX files. As your classmate has already done a literature survey and sent you a `.bib` file, you'll use that one. Upload the file through the file panel to access it in Typst.
Once the document contains a bibliography, you can start citing from it. Citations use the same syntax as references to a label. As soon as you cite a source for the first time, it will appear in the bibliography section of your document. Typst supports different citation and bibliography styles. Consult the [reference](/docs/reference/model/bibliography/#parameters-style) for more details.
```typst
= Methods
We follow the glacier melting models
established in @glacier-melt.
#bibliography("works.bib")
```
## Maths
After fleshing out the methods section, you move on to the meat of the document: Your equations. Typst has built-in mathematical typesetting and uses its own math notation. Let's start with a simple equation. We wrap it in `$` signs to let Typst know it should expect a mathematical expression:
```typst
The equation $Q = rho A v + C$
defines the glacial flow rate.
```
The equation is typeset inline, on the same line as the surrounding text. If you want to have it on its own line instead, you should insert a single space at its start and end:
```typst
The flow rate of a glacier is
defined by the following equation:
$ Q = rho A v + C $
```
We can see that Typst displayed the single letters `Q`, `A`, `v`, and `C` as-is, while it translated `rho` into a Greek letter. Math mode will always show single letters verbatim. Multiple letters, however, are interpreted as symbols, variables, or function names. To imply a multiplication between single letters, put spaces between them.
If you want to have a variable that consists of multiple letters, you can enclose it in quotes:
```typst
The flow rate of a glacier is given
by the following equation:
$ Q = rho A v + "time offset" $
```
You'll also need a sum formula in your paper. We can use the `sum` symbol and then specify the range of the summation in sub- and superscripts:
```typst
Total displaced soil by glacial flow:
$ 7.32 beta +
sum_(i=0)^nabla Q_i / 2 $
```
To add a subscript to a symbol or variable, type a `_` character and then the subscript. Similarly, use the `^` character for a superscript. If your sub- or superscript consists of multiple things, you must enclose them in round parentheses.
The above example also showed us how to insert fractions: Simply put a `/` character between the numerator and the denominator and Typst will automatically turn it into a fraction. Parentheses are smartly resolved, so you can enter your expression as you would into a calculator and Typst will replace parenthesized sub-expressions with the appropriate notation.
```typst
Total displaced soil by glacial flow:
$ 7.32 beta +
sum_(i=0)^nabla
(Q_i (a_i - epsilon)) / 2 $
```
Not all math constructs have special syntax. Instead, we use functions, just like the `image` function we have seen before. For example, to insert a column vector, we can use the [`vec`](/docs/reference/math/vec/) function. Within math mode, function calls don't need to start with the `#` character.
```typst
$ v := vec(x_1, x_2, x_3) $
```
Some functions are only available within math mode. For example, the [`cal`](/docs/reference/math/variants/#functions-cal) function is used to typeset calligraphic letters commonly used for sets. The [math section of the reference](/docs/reference/math/) provides a complete list of all functions that math mode makes available.
One more thing: Many symbols, such as the arrow, have a lot of variants. You can select among these variants by appending a dot and a modifier name to a symbol's name:
```typst
$ a arrow.squiggly b $
```
This notation is also available in markup mode, but the symbol name must be preceded with `#sym.` there. See the [symbols section](/docs/reference/symbols/sym/) for a list of all available symbols.
## Review
You have now seen how to write a basic document in Typst. You learned how to emphasize text, write lists, insert images, align content, and typeset mathematical expressions. You also learned about Typst's functions. There are many more kinds of content that Typst lets you insert into your document, such as [tables](/docs/reference/model/table/), [shapes](/docs/reference/visualize/), and [code blocks](/docs/reference/text/raw/). You can peruse the [reference](/docs/reference/) to learn more about these and other features.
For the moment, you have completed writing your report. You have already saved a PDF by clicking on the download button in the top right corner. However, you think the report could look a bit less plain. In the next section, we'll learn how to customize the look of our document.
SKILL.md
---
name: typst-author
description: Generate idiomatic Typst (.typ) code, edit and troubleshoot Typst documents and projects, and answer Typst syntax/reference questions. Use when working with .typ files or when the user explicitly asks for Typst document creation, editing, debugging, compilation, formatting, template work, or package usage.
---
# typst-author skill
## Overview
This skill helps agents generate, edit, and reason about Typst documents. It provides quick‑start examples, detailed workflows, and links to the full Typst documentation (guides, tutorials, reference).
## Minimal document example
```typst
#set document(title: "My Document", author: "Author Name")
#set page(numbering: "1")
#set text(lang: "en")
// Enable paragraph justification and character-level justification
#set par(
justify: true,
justification-limits: (
tracking: (min: -0.012em, max: 0.012em),
spacing: (min: 75%, max: 120%),
)
)
#title[My Document]
= Heading 1
This is a paragraph in Typst.
== Heading 2
#lorem(50)
```
## Workflows
- **Creating a new Typst project**: Use the "Minimal document example" above as a starting point. Skim the tutorial for the basics ([docs/tutorial/writing-in-typst.md](docs/tutorial/writing-in-typst.md)), then create the `.typ` file(s). After each `.typ` edit, follow the post-edit formatting checks below when `typstyle` is available.
- **Editing existing content**: Locate the target text and apply changes; confirm syntax against the reference when needed ([docs/reference/](docs/reference/)). After each modified `.typ` file, follow the post-edit formatting checks below.
- **Formatting & Styling**: Consult the styling guide ([docs/reference/styling.md](docs/reference/styling.md)) for `set rule`, `show rule`, and custom themes.
## Documentation
- **Syntax & foundations**: `docs/reference/syntax.md`
- **Styling & show/set rules**: `docs/reference/styling.md`
- **Scripting & runtime behavior**: `docs/reference/scripting.md`
- **Page setup & tables**: `docs/guides/page-setup.md` and `docs/guides/tables.md`
- **Task-oriented authoring help**: `docs/tutorial/writing-in-typst.md`, `docs/guides/*.md`, and `docs/reference/**/*.md`
## Detailed instructions
1. **PRIORITY: Trust local documentation**. Your internal training data regarding Typst may be outdated or hallucinated. Always verify function names, parameters, and syntax against the local `docs/` folder before generating code.
2. **Read the relevant documentation** using local file search and open tools on the paths above.
3. **Use local docs for syntax and reference questions**. Verify syntax, function names, parameters, and reference behavior from the bundled docs. Run a minimal Typst probe only when runtime or evaluation behavior remains unclear after checking the docs.
4. **Generate or modify the `.typ` source** according to the user's request.
5. **Run the post-edit formatting checks below** for every `.typ` file you created or edited in that pass.
6. **Validate** with `typst compile` after the formatting decision is complete when you created or edited `.typ` files, or when the user explicitly asks for verification (if tool access is allowed).
7. **Summarize touched files and outcomes**. Provide full `.typ` content only when the user requests it or when direct editing is not possible, and optionally include a rendered preview (PDF/HTML).
### Probing uncertain behavior
- Use a probe when the bundled docs do not settle runtime or evaluation behavior.
- Model the case with Typst scripting as described in [docs/reference/scripting.md](docs/reference/scripting.md).
- When a probe is necessary, prefer a fileless probe through stdin instead of creating scratch `.typ` files. Expose the value with `metadata(...) <probe>` and read it with `typst query - "<probe>" --field value --one`. See [docs/reference/introspection/query.md](docs/reference/introspection/query.md) and [docs/reference/introspection/metadata.md](docs/reference/introspection/metadata.md).
- Example: `printf '#metadata(1 + 2) <probe>\n' | typst query - "<probe>" --field value --one`
### Post-edit formatting checks
1. **Check whether `typstyle` is available** with `command -v typstyle`. If it is unavailable, skip the remaining formatting checks.
2. **After each `.typ` file modification, run `typstyle --check <file>`** for the file you just created or edited.
3. **If `typstyle --check` fails, inspect the formatter changes with `typstyle --diff <file>`** before deciding what to do.
4. **Apply formatting with `typstyle -i <file>`** only when the formatter changes are limited to a newly created file or to code you created or edited in the current task.
5. **Stop and ask the user when formatting would change untouched pre-existing code**. If the diff reaches outside your own edits, or if you cannot confidently prove that every formatter change is limited to your edits, ask instead of formatting.
## Quick syntax reference
### Critical distinctions
- **Arrays**: `(item1, item2)` (parentheses). See [docs/reference/foundations/array.md](docs/reference/foundations/array.md).
- **Dictionaries**: `(key: value, key2: value2)` (parentheses with colons). See [docs/reference/foundations/dictionary.md](docs/reference/foundations/dictionary.md).
- **Content blocks**: `[markup content]` (square brackets). See [docs/reference/foundations/content.md](docs/reference/foundations/content.md).
- **NO tuples**: Typst only has arrays.
### Hash usage (markup vs code)
- Use `#` to start a code expression inside markup or content blocks; it disambiguates code from text. This is required for content-producing function calls and field access in markup: `#figure[...]`, `#image("file.png")`, `text(...)[#numbering(...)]`.
- Do not use `#` inside code contexts (argument lists, code blocks, show-rule bodies). Example: `#figure(image("file.png"))` (no `#` before `image`).
- Reference: [docs/reference/scripting.md](docs/reference/scripting.md), [docs/tutorial/writing-in-typst.md](docs/tutorial/writing-in-typst.md)
```typst
// Incorrect (missing # inside content block)
text(...)[(numbering(...))]
// Correct
text(...)[(#numbering(...))]
```
### Styling rules: set vs show
- `set`: Set rule to configure optional parameters on element functions (style defaults scoped to the current block or file).
- `show`: Show rule to target selected elements and apply a set rule or transform/replace the element output.
- Use `set` for common styling; use `show` for selective or structural changes (e.g., `heading.where(level: 1)`, labels, text, regex).
```typst
// Set rule: configure optional parameters for an element type
#set heading(numbering: "I.")
#set text(font: "New Computer Modern")
// Show-set rule: apply a set rule only to selected elements
#show heading: set text(navy)
// Show transform rule: replace/reshape element output
#show heading: it => block[#emph(it.body)]
```
## Common mistakes to avoid
- Calling things "tuples" (Typst only has arrays).
- Using `[]` for arrays (use `()` instead).
- Accessing array elements with `arr[0]` (use `arr.at(0)`).
- Omitting `#` in markup/content blocks (e.g., `text(...)[numbering(...)]` should be `text(...)[#numbering(...)]`).
- Using `#` inside code contexts (e.g., `figure(#image("x.png"))` in an argument list).
- Mixing up content blocks `[]` with code blocks `{}`.
- Forgetting to include the namespace when accessing imported variables/functions (e.g., use `color.hsl` instead of just `hsl`).
- Using LaTeX syntax (do **NOT** use `\begin{...}`, `\section`, or other LaTeX commands).
- Hallucinating environments (e.g., `tabular` does not exist; use `table`).
## Advanced features
- **Custom themes**: See [docs/reference/styling.md](docs/reference/styling.md) for theme creation.
- **Scripting**: Use Typst's scripting capabilities ([docs/reference/scripting.md](docs/reference/scripting.md)) for automatic generation.
- **Math and visualisation**: Reference [docs/reference/math/](docs/reference/math/) and [docs/reference/visualize/](docs/reference/visualize/) for formulas and diagrams.
### For large projects
When working on large projects, consider organizing the project across multiple files.
- Use `#include "file.typ"` to split into multiple files
- Relevant documentation: [docs/reference/foundations/module.md](docs/reference/foundations/module.md)
## Troubleshooting
### Missing font warnings
If you see "unknown font family" warnings, remove the font specification to use system defaults. Note: Font warnings don't prevent compilation; the document will use fallback fonts.
### Template/Package not found
If import fails with "package not found":
- Verify exact package name and version on Typst Universe.
- Check for typos in `@preview/package:version` syntax.
### Compilation errors
Common fixes:
- **"expected content, found ..."**: You're using code where markup is expected - wrap in `#{ }` or use proper syntax.
- **"expected expression, found ..."**: Missing `#` (or `#(...)`) in markup/content blocks.
- **"unknown variable"**: Check spelling, ensure imports are correct.
- **Array/dictionary errors**: Review syntax - use `()` for both, dictionaries need `key: value`, singleton arrays are `(elem,)`.