diff options
Diffstat (limited to 'docs/src')
| -rw-r--r-- | docs/src/contribs.rs | 86 | ||||
| -rw-r--r-- | docs/src/general/changelog.md | 726 | ||||
| -rw-r--r-- | docs/src/general/community.md | 72 | ||||
| -rw-r--r-- | docs/src/general/overview.md | 15 | ||||
| -rw-r--r-- | docs/src/guides/guide-for-latex-users.md | 602 | ||||
| -rw-r--r-- | docs/src/guides/welcome.md | 11 | ||||
| -rw-r--r-- | docs/src/html.rs | 513 | ||||
| -rw-r--r-- | docs/src/lib.rs | 1002 | ||||
| -rw-r--r-- | docs/src/reference/details.yml | 174 | ||||
| -rw-r--r-- | docs/src/reference/groups.yml | 76 | ||||
| -rw-r--r-- | docs/src/reference/scripting.md | 345 | ||||
| -rw-r--r-- | docs/src/reference/styling.md | 145 | ||||
| -rw-r--r-- | docs/src/reference/syntax.md | 138 | ||||
| -rw-r--r-- | docs/src/reference/types.md | 1190 | ||||
| -rw-r--r-- | docs/src/reference/welcome.md | 29 | ||||
| -rw-r--r-- | docs/src/tutorial/1-writing.md | 308 | ||||
| -rw-r--r-- | docs/src/tutorial/2-formatting.md | 283 | ||||
| -rw-r--r-- | docs/src/tutorial/3-advanced.md | 509 | ||||
| -rw-r--r-- | docs/src/tutorial/4-template.md | 380 | ||||
| -rw-r--r-- | docs/src/tutorial/welcome.md | 44 |
20 files changed, 0 insertions, 6648 deletions
diff --git a/docs/src/contribs.rs b/docs/src/contribs.rs deleted file mode 100644 index 901b5f69..00000000 --- a/docs/src/contribs.rs +++ /dev/null @@ -1,86 +0,0 @@ -use std::cmp::Reverse; -use std::collections::HashMap; -use std::fmt::Write; - -use serde::Deserialize; - -use super::{Html, Resolver}; - -/// Build HTML detailing the contributors between two tags. -pub fn contributors(resolver: &dyn Resolver, from: &str, to: &str) -> Option<Html> { - let staff = ["laurmaedje", "reknih"]; - - // Determine number of contributions per person. - let mut contributors = HashMap::<String, Contributor>::new(); - for commit in resolver.commits(from, to) { - contributors - .entry(commit.author.login.clone()) - .or_insert_with(|| Contributor { - login: commit.author.login, - avatar: commit.author.avatar_url, - contributions: 0, - }) - .contributions += 1; - } - - // Keep only non-staff people. - let mut contributors: Vec<_> = contributors - .into_values() - .filter(|c| !staff.contains(&c.login.as_str())) - .collect(); - - // Sort by highest number of commits. - contributors.sort_by_key(|c| (Reverse(c.contributions), c.login.clone())); - if contributors.is_empty() { - return None; - } - - let mut html = "Thanks to everyone who contributed to this release!".to_string(); - html += "<ul class=\"contribs\">"; - - for Contributor { login, avatar, contributions } in contributors { - let login = login.replace('\"', """).replace('&', "&"); - let avatar = avatar.replace("?v=", "?s=64&v="); - let s = if contributions > 1 { "s" } else { "" }; - write!( - html, - r#"<li> - <a href="https://github.com/{login}" target="_blank"> - <img - width="64" - height="64" - src="{avatar}" - alt="GitHub avatar of {login}" - title="@{login} made {contributions} contribution{s}" - crossorigin="anonymous" - > - </a> - </li>"# - ) - .unwrap(); - } - - html += "</ul>"; - - Some(Html::new(html)) -} - -#[derive(Debug)] -struct Contributor { - login: String, - avatar: String, - contributions: usize, -} - -/// A commit on the `typst` repository. -#[derive(Debug, Deserialize)] -pub struct Commit { - author: Author, -} - -/// A commit author. -#[derive(Debug, Deserialize)] -pub struct Author { - login: String, - avatar_url: String, -} diff --git a/docs/src/general/changelog.md b/docs/src/general/changelog.md deleted file mode 100644 index 95808fab..00000000 --- a/docs/src/general/changelog.md +++ /dev/null @@ -1,726 +0,0 @@ ---- -description: | - Learn what has changed in the latest Typst releases and move your documents - forward. ---- - -# Changelog -## Version 0.6.0 (June 30, 2023) { #v0.6.0 } -- Package Management - - Typst now has built-in [package management]($scripting/#packages) - - You can import [published]($packages) 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`]($func/math.limits) conditionally - depending on whether the equation is set in [`display`]($func/math.display) - or [`inline`]($func/math.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]($func/math.underline) and - [overlines]($func/math.overline) in math mode - - Fixed usage of [`limits`]($func/math.limits) function in show rules - - Fixed bugs with line breaks in equations - -- Text and Layout - - Added support for alternating page [margins]($func/page.margin) with the - `inside` and `outside` keys - - Added support for specifying the page [`binding`]($func/page.binding) - - Added [`to`]($func/pagebreak.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]($func/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`]($func/outline.entry) to customize outline entries - with show rules - - Added some hints for error messages - - Added some missing syntaxes for [`raw`]($func/raw) highlighting - - Improved rendering of rotated images in PNG export and web app - - Made [footnotes]($func/footnote) reusable and referenceable - - Fixed bug with citations and bibliographies in [`locate`]($func/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 from="v0.5.0" to="v0.6.0" /> - -## Version 0.5.0 (June 9, 2023) { #v0.5.0 } -- Text and Layout - - Added [`raw`]($func/raw) syntax highlighting for many more languages - - Added support for Korean [numbering]($func/numbering) - - Added basic i18n for a few more languages (NL, SV, DA) - - Improved linebreaking for East Asian languages - - Expanded functionality of outline [`indent`]($func/outline.indent) property - - Fixed footnotes in columns - - Fixed page breaking bugs with [footnotes]($func/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`]($func/line) elements - -- Math - - **Breaking change:** The syntax rules for mathematical - [attachments]($func/math.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]($category/math/sizes) commands for math - (e.g., [`display`]($func/math.display)) - - Added [`supplement`]($func/math.equation.supplement) parameter to - [`equation`]($func/math.equation), used by [references]($func/ref) - - New [symbols]($category/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`]($func/math.attach) function - -- Scripting - - Added new [`datetime`]($type/datetime) type and - [`datetime.today()`]($func/datetime.today) to retrieve the current date - - Added [`str.from-unicode`]($func/str.from-unicode) and - [`str.to-unicode`]($func/str.to-unicode) functions - - Added [`fields`]($type/content.fields) method on content - - Added `base` parameter to [`str`]($func/str) function - - Added [`calc.exp`]($func/calc.exp) and [`calc.ln`]($func/calc.ln) - - Improved accuracy of [`calc.pow`]($func/calc.pow) and - [`calc.log`]($func/calc.log) for specific bases - - Fixed [removal]($type/dictionary.remove) order for dictionary - - Fixed `.at(default: ..)` for [strings]($type/string.at) and - [content]($type/content.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 non-existent 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`]($func/hide) - - Fixed bugs with [reference supplements]($func/ref.supplement) - - Fixed Nix flake - -<contributors from="v0.4.0" to="v0.5.0" /> - -## Version 0.4.0 (May 20, 2023) { #v0.4.0 } -- Footnotes - - Implemented support for footnotes - - The [`footnote`]($func/footnote) function inserts a footnote - - The [`footnote.entry`]($func/footnote.entry) function can be used to - customize the footnote listing - - The `{"chicago-notes"}` [citation style]($func/cite.style) is now available - -- Documentation - - Added a [Guide for LaTeX users]($guides/guide-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]($func/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`]($func/math.attach) alignment - - Fixed spacing on decorated elements - (e.g., spacing around a [canceled]($func/math.cancel) operator) - - Fixed styling for stretchable symbols - - Added `tack.r.double`, `tack.l.double`, `dotless.i` and `dotless.j` - [symbols]($category/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`]($func/assert.eq) - function, for instance, is part of the [`assert`]($func/assert) function's - scope. Note that function scopes are currently only available for built-in - functions. - - Added [`assert.eq`]($func/assert.eq) and [`assert.ne`]($func/assert.ne) - functions for simpler equality and inequality assertions with more helpful - error messages - - Exposed [list]($func/list.item), [enum]($func/enum.item), and - [term list]($func/terms.item) items in their respective functions' scope - - The `at` methods on [strings]($type/string.at), [arrays]($type/array.at), - [dictionaries]($type/dictionary.at), and [content]($type/content.at) now support - specifying a default value - - Added support for passing a function to [`replace`]($type/string.replace) - that is called with each match. - - Fixed [replacement]($type/string.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]($func/int) or - [float]($func/float) fails - -- Text and Layout - - Implemented sophisticated CJK punctuation adjustment - - Disabled [overhang]($func/text.overhang) for CJK punctuation - - Added basic translations for Traditional Chinese - - Fixed [alignment]($func/raw.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]($func/table.align) and [fill]($func/table.fill) per column - - Fixed automatic figure [`kind`]($func/figure.kind) detection - - Made alignment of [enum numbers]($func/enum.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 from="v0.3.0" to="v0.4.0" /> - -## Version 0.3.0 (April 26, 2023) { #v0.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`]($func/calc.rem) to more accurately reflect - the behaviour. 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`]($func/query). This is - now handled through flexible [selectors]($type/selector) combinator methods - - Added support for [attachments]($func/math.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]($func/line.stroke) - (configurable caps, joins, and dash patterns) - - Added [`cancel`]($func/math.cancel) function for equations - - Added support for [destructuring]($scripting/#bindings) in argument lists - and assignments - - Added [`alt`]($func/image.alt) text argument to image function - - Added [`toml`]($func/toml) function for loading data from a TOML file - - Added [`zip`]($type/array.zip), [`sum`]($type/array.sum), and - [`product`]($type/array.product) methods for arrays - - Added `fact`, `perm`, `binom`, `gcd`, `lcm`, `atan2`, `quo`, `trunc`, and - `fract` [calculation]($category/calculate) - -- Improvements - - Text in SVGs now displays properly - - Typst now generates a PDF heading outline - - [References]($func/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`]($func/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]($type/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]($func/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 from="v0.2.0" to="v0.3.0" /> - -## Version 0.2.0 (April 11, 2023) { #v0.2.0 } -- **Breaking changes:** - - Removed support for iterating over index and value in - [for loops]($scripting/#loops). This is now handled via unpacking and - enumerating. Same goes for the [`map()`]($type/array.map) method. - - [Dictionaries]($type/dictionary) now iterate in insertion order instead of - alphabetical order. - -- New features - - Added [unpacking syntax]($scripting/#bindings) for let bindings, which - allows things like `{let (1, 2) = array}` - - Added [`enumerate()`]($type/array.enumerate) method - - Added [`path`]($func/path) function for drawing Bézier paths - - Added [`layout`]($func/layout) function to access the size of the - surrounding page or container - - Added `key` parameter to [`sorted()`]($type/array.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]($func/math.op) - - Fixed bug where math could not be hidden with [`hide`]($func/hide) - - Fixed sizing issues with box, block, and shapes - - Fixed some translations - - Fixed inversion of "R" in [`cal`]($func/math.cal) and - [`frak`]($func/math.frak) styles - - Fixed some styling issues in math - - Fixed supplements of references to headings - - Fixed syntax highlighting of identifiers in certain scenarios - - [Ratios]($type/ratio) can now be multiplied with more types and be converted - to [floats]($type/float) with the [`float`]($func/float) function - -<contributors from="v0.1.0" to="v0.2.0" /> - -## Version 0.1.0 (April 04, 2023) { #v0.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]($func/counter) for more details - - The [bibliography styles]($func/bibliography.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 - behaviour. 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`]($func/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`]($func/polygon) function for drawing polygons - - Added support for clipping in [boxes]($func/box.clip) and - [blocks]($func/block.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`]($func/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]($type/integer) with base 2, 8, and 16 - - Added symbols for double bracket and laplace operator - - The [`link`]($func/link) function now accepts [labels]($func/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`]($func/par.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`]($func/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 from="v23-03-28" to="v0.1.0" /> - -## 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]($func/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]($func/math.mat) and - [vector]($func/math.vec) delimiters. Generally with - `[#set math.mat(delim: none)]` or one-off with - `[$mat(delim: #none, 1, 2; 3, 4)$]`. - - Added [`separator`]($func/terms.separator) argument to term lists - - Added [`round`]($func/math.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`]($func/locate) 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`]($func/repeat) is used in page with - automatic width - - Fixed [matrices]($func/math.mat) with explicit delimiter - - Fixed [`indent`]($func/terms.indent) property of term lists - - Numerous documentation fixes - - Links in bibliographies are now affected by link styling - - Fixed hovering over comments in web app - -<contributors from="v23-03-21" to="v23-03-28" /> - -## March 21, 2023 -- Reference and bibliography management - - [Bibliographies]($func/bibliography) and [citations]($func/cite) (currently - supported styles are APA, Chicago Author Date, IEEE, and MLA) - - You can now [reference]($func/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`]($func/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`]($func/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`]($func/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`]($func/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`]($func/measure) function - - Measure the layouted size of elements - - To be used in combination with the new [`style`]($func/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`]($func/repr) - - New [methods]($type/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`]($func/figure) function - - Added [`numbering`]($func/math.equation.numbering) parameter on equation function - - Added [`numbering`]($func/page.numbering) and - [`number-align`]($func/page.number-align) parameters on page function - - The page function's [`header`]($func/page.header) and - [`footer`]($func/page.footer) parameters do not take functions anymore. If - you want to customize them based on the page number, use the new - [`numbering`]($func/page.numbering) parameter or [`counter`]($func/counter) - function instead. - - Added [`footer-descent`]($func/page.footer-descent) and - [`header-ascent`]($func/page.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`]($func/math.equation) - - Font family must be a named argument now: `[#set text(font: "..")]` - - Added support for [hanging indent]($func/par.hanging-indent) - - Renamed paragraph `indent` to - [`first-line-indent`]($func/par.first-line-indent) - - More accurate [logarithm]($func/calc.log) when base is `2` or `10` - - Improved some error messages - - Fixed layout of [`terms`]($func/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`]($func/smallcaps) function -- Improved default spacing for headings -- Added [`panic`]($func/panic) function -- Added [`clusters`]($type/string.clusters) and - [`codepoints`]($type/string.codepoints) - methods for strings -- Support for multiple authors in [`set document`]($func/document.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]($func/box) and [block]($func/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`]($func/block.breakable) or not -- [Numbering style]($func/enum.numbering) can now be configured for nested enums -- [Markers]($func/list.marker) can now be configured for nested lists -- The [`eval`]($func/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`]($func/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]($func/text.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`]($func/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`]($func/box.baseline) property on [`box`]($func/box) -- Added [`tg`]($func/math.op) and [`ctg`]($func/math.op) operators in math -- Added delimiter setting for [`cases`]($func/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 hashtag - - More expressions available with hashtag, 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 hashtag) 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 hashtag - - 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 diff --git a/docs/src/general/community.md b/docs/src/general/community.md deleted file mode 100644 index 32d2d185..00000000 --- a/docs/src/general/community.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -description: | - Join the Typst community, get help from other users and have a say in the - future of Typst. ---- - -# Community -Hey and welcome to the Community page! We're so glad you're here. Typst is -developed by an early-stage startup and is still in its infancy, but it -would be pointless without people like you who are interested in it. - -We would love to not only hear from you but to also provide spaces where you can -discuss any topic around Typst, typesetting, writing, the sciences, and -typography with other likeminded people. - -For the time being, **we would like to invite you to our [Discord -server](https://discord.gg/2uDybryKPe).** The server is open for everyone, even -if you do not have preview access to Typst yet. Of course, you are also very -welcome to connect with us on social media -([Twitter](https://twitter.com/typstapp/), -[Instagram](https://instagram.com/typstapp/), -[LinkedIn](https://linkedin.com/company/typst), and -[GitHub](https://github.com/typst)). - -## What to share? { #want-to-share } -For our community, we want to foster versatility and inclusivity. -You are welcome to post about any topic that you think would interest other -community members, but if you need a little inspiration, here are a few ideas: - -- Share and discuss your thoughts and ideas for new features or improvements - you'd like to see in Typst -- Showcase documents you've created with Typst, or share any unique or creative - ways you've used the platform -- Share importable files or templates that you use to style your documents -- Alert us of bugs you encounter while using Typst - -## Beta test { #beta-test } -We are starting a public beta test of our product on March 21st, 2023. -The Typst compiler is still under active development and breaking changes can -occur at any point. The compiler is developed in the open on -[GitHub](https://github.com/typst/typst). - -We will update the members of our Discord server and our social media followers -when new features become available in the preview. We'll also update you on the -development progress of large features. A development tracker will become -available on the documentation pages soon. - -## How to support Typst { #support-typst } -If you want to support Typst, there are multiple ways to do that! You can -[contribute to the code](https://github.com/typst/typst) or -[translate the strings in Typst](https://github.com/search?q=repo%3Atypst%2Ftypst+impl+LocalName+for&type=code) -to your native language if it's not supported yet. You can also help us by -[sponsoring us!](https://github.com/sponsors/typst) Multiple recurring -sponsorship tiers are available and all of them come with a set of goodies. -No matter how you contribute, thank you for your support! - -## Community Rules { #rules } -We want to make our community a safe and inclusive space for everyone. -Therefore, we will not tolerate any sexual harassment, sexism, political -attacks, derogatory language or personal insults, racism, doxing, and other -inappropriate behavior. We pledge to remove members that are in violation of -these rules. [Contact us](https://typst.app/contact/) if you think another -community member acted inappropriately towards you. All complaints will be -reviewed and investigated promptly and fairly. - -In addition, our [privacy policy](https://typst.app/privacy/) applies on all -community spaces operated by us, such as the Discord server. Please also note -that the terms of service and privacy policies of the respective services apply. - -## See you soon! { #see-you } -Thanks again for learning more about Typst. We would be delighted to meet you on -our [Discord server](https://discord.gg/2uDybryKPe)! diff --git a/docs/src/general/overview.md b/docs/src/general/overview.md deleted file mode 100644 index e3fa3b3c..00000000 --- a/docs/src/general/overview.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -description: | - Learn how to use Typst to compose documents faster. Get started with the - tutorial, or dive into the reference. ---- - -# 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. diff --git a/docs/src/guides/guide-for-latex-users.md b/docs/src/guides/guide-for-latex-users.md deleted file mode 100644 index b51e8cf1..00000000 --- a/docs/src/guides/guide-for-latex-users.md +++ /dev/null @@ -1,602 +0,0 @@ ---- -description: | - Are you a LaTeX user? This guide explains the differences and - similarities between Typst and LaTeX so you can get started quickly. ---- - -# Guide 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. - -<!-- Mention that Typst is not built upon LaTeX --> - -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]($tutorial). - -## How do I create a new, empty document? { #getting-started } -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]($func/parbreak) work just as they do in LaTeX, just -use a blank line. - -```example -Hey there! - -Here are two paragraphs. The -output is shown to the right. -``` - -## How do I create section headings, emphasis, ...? { #elements } -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]($func/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]($syntax). - -| Element | LaTeX | Typst | See | -|:-----------------|:--------------------------|:-----------------------|:-------------------------| -| Strong emphasis | `\textbf{strong}` | `[*strong*]` | [`strong`]($func/strong) | -| Emphasis | `\emph{emphasis}` | `[_emphasis_]` | [`emph`]($func/emph) | -| Monospace / code | `\texttt{print(1)}` | ``[`print(1)`]`` | [`raw`]($func/raw) | -| Link | `\url{https://typst.app}` | `[https://typst.app/]` | [`link`]($func/link) | -| Label | `\label{intro}` | `[<intro>]` | [`label`]($func/label) | -| Reference | `\ref{intro}` | `[@intro]` | [`ref`]($func/ref) | -| Citation | `\cite{humphrey97}` | `[@humphrey97]` | [`cite`]($func/cite) | -| Bullet list | `itemize` environment | `[- List]` | [`list`]($func/list) | -| Numbered list | `enumerate` environment | `[+ List]` | [`enum`]($func/enum) | -| Term list | `description` environment | `[/ Term: List]` | [`terms`]($func/terms) | -| Figure | `figure` environment | `figure` function | [`figure`]($func/figure) | -| Table | `table` environment | `table` function | [`table`]($func/table) | -| Equation | `$x$`, `align` / `equation` environments | `[$x$]`, `[$ x = y $]` | [`equation`]($func/math.equation) | - -[Lists]($func/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: - -````example -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]($func/list.tight) spaced list. - -To get a [numbered list]($func/enum) (`enumerate`) instead, use a `+` instead of -the hyphen. For a [term list]($func/terms) (`description`), write -`[/ Term: Description]` instead. - -## How do I use a command? { #commands } -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]($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 hashtag (`#`). This is how you call functions to, -for example, split your project into different [files]($scripting/#modules) -or render text based on some [condition]($scripting/#conditionals). -Within code mode, it is possible to include normal markup -[_content_]($type/content) by using square brackets. Within code mode, this -content is treated just as any other normal value for a variable. - -```example -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`]($func/rect), -[`underline`]($func/underline), [`calc.max`]($func/calc.max), -[`range`]($func/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]($reference). - -### Arguments { #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: - -```example -#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]($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]($type/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]($type/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). - -```example -Typst is an #underline[alternative] -to LaTeX. - -#rect(fill: aqua)[Get started here!] -``` - -### Data types { #data-types } -You likely already noticed that the arguments have distinctive data types. Typst -supports [many data types]($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]($type/content) | `{[*fast* typesetting]}` | -| [String]($type/string) | `{"Pietro S. Author"}` | -| [Integer]($type/integer) | `{23}` | -| [Floating point number]($type/float) | `{1.459}` | -| [Absolute length]($type/length) | `{12pt}`, `{5in}`, `{0.3cm}`, ... | -| [Relative length]($type/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]($scripting/#conditionals) and -[operators]($scripting/#operators) such as `+` for adding things or `==` for -checking equality between two variables. You can also define your own -[variables]($scripting/#bindings) and perform computations on them. - -### Commands to affect the remaining document { #rules } -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, 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, if there is none, document. The effects of a function are -immediately obvious based on whether it is used in a call or a -[set rule.]($styling/#set-rules) - -```example -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: - -```example -#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}`]($func/enum) function, to which we apply a set rule above. [Most -syntax is linked to a function in this way.]($syntax) If you need to style an -element beyond what its arguments enable, you can completely redefine its -appearance with a [show rule]($styling/#show-rules) (somewhat comparable to -`\renewcommand`). - -## How do I load a document class? { #templates } -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]($type/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]($styling/#show-rules) that wraps the following document in a given -function. The following example illustrates how it works: - -```example:single ->>> #let conf( ->>> title: none, ->>> authors: (), ->>> abstract: [], ->>> doc, ->>> ) = { ->>> set text(font: "Linux Libertine", 11pt) ->>> set par(justify: true) ->>> set page( ->>> "us-letter", ->>> margin: auto, ->>> header: align( ->>> right + horizon, ->>> title ->>> ), ->>> numbering: "1", ->>> ) ->>> ->>> show heading.where( ->>> level: 1 ->>> ): it => block( ->>> align(center, ->>> text( ->>> 13pt, ->>> weight: "regular", ->>> smallcaps(it.body), ->>> ) ->>> ), ->>> ) ->>> show heading.where( ->>> level: 2 ->>> ): it => box( ->>> text( ->>> 11pt, ->>> weight: "regular", ->>> style: "italic", ->>> it.body + [.], ->>> ) ->>> ) ->>> ->>> set align(center) ->>> text(17pt, title) ->>> ->>> let count = calc.min(authors.len(), 3) ->>> grid( ->>> columns: (1fr,) * count, ->>> row-gutter: 24pt, ->>> ..authors.map(author => [ ->>> #author.name \ ->>> #author.affiliation \ ->>> #link("mailto:" + author.email) ->>> ]), ->>> ) ->>> ->>> par(justify: false)[ ->>> *Abstract* \ ->>> #abstract ->>> ] ->>> ->>> set align(left) ->>> columns(2, doc) ->>>} -<<< #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}`]($scripting/#modules) statement makes -[functions]($type/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! - -<div class="info-box"> - -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 if its arguments before passing it on to the -show rule. -</div> - -In the web app, you can choose from predefined templates or even -create your own using the template wizard. You can also check out the -[`awesome-typst` repository](https://github.com/qjcg/awesome-typst) to find -templates made by the community. We plan to build a package manager to make -templates even easier to share in the future! - -You can also [create your own, custom templates.]($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! - -## How do I load packages? { #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`]($func/image) function | -| tabularx | [`table`]($func/table), [`grid`]($func/grid) functions | -| fontenc, inputenc, unicode-math | Just start writing! | -| babel, polyglossia | [`text`]($func/text.lang) function: `[#set text(lang: "zh")]` | -| amsmath | [Math mode]($category/math) | -| amsfonts, amssymb | [`sym`]($category/symbols) module and [syntax]($syntax/#math) | -| geometry, fancyhdr | [`page`]($func/page) function | -| xcolor | [`text`]($func/text.fill) function: `[#set text(fill: rgb("#0178A4"))]` | -| hyperref | [`link`]($func/link) function | -| bibtex, biblatex, natbib | [`cite`]($func/cite), [`bibliography`]($func/bibliography) functions | -| lstlisting, minted | [`raw`]($func/raw) function and syntax | -| parskip | [`block`]($func/block.spacing) and [`par`]($func/par.first-line-indent) functions | -| csquotes | Set the [`text`]($func/text.lang) language and type `["]` or `[']` | -| caption | [`figure`]($func/figure) function | -| enumitem | [`list`]($func/list), [`enum`]($func/enum), [`terms`]($func/terms) functions | - -If you need to load functions and variables from another file, for example, to -use a template, you can use an [`import`]($scripting/#modules) statement. If you -want to include the textual content of another file instead, you can use an -[`{include}`]($scripting/#modules) statement. It will retrieve the content of -the specified file and put it in your document. - -Currently, there is no package manager for Typst, but we plan to build one so -that you can easily use packages with tools and templates from the community and -publish your own. Until then, you might want to check out the -[awesome-typst repository](https://github.com/qjcg/awesome-typst), which -compiles a curated list of libraries created for Typst. - -## How do I input maths? { #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. - -```example -The sum of the numbers from -$1$ to $n$ is: - -$ sum_(k=1)^n k = (n(n+1))/2 $ -``` - -[Math mode]($category/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 page]($func/symbol) for a full list of the symbols. -If a symbol is missing, you can also access it through a -[Unicode escape sequence]($syntax/#escapes). - -Alternate and related forms of symbols can often be selected by -[appending a modifier]($type/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: - -```example -$ 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 behavior using the [`lr` function]($func/math.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. - -```example -$ f(x) = (x + 1) / x $ -``` - -[Sub- and superscripts]($func/math.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 preprended with a `#` or a `/`, -you can also call functions without these special characters: - -```example -$ 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]($func/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 `#`: - -```example -$ (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: - -```example -$ 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]($func/math.mat) that creates -matrices: - -```example -$ 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?" { #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]($func/page.margin) -- enables [justification]($func/par.justify), [tighter lines]($func/par.leading) - and [first-line-indent]($func/par.first-line-indent) -- [sets the font]($func/text.font) to "New Computer Modern", an OpenType - derivate of Computer Modern for both text and [code blocks]($func/raw) -- disables paragraph [spacing]($func/block.spacing) -- increases [spacing]($func/block.spacing) around [headings]($func/heading) - -```typ -#set page(margin: 1.75in) -#set par(leading: 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 par: set block(spacing: 0.55em) -#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? - -## What limitations does Typst currently have compared to LaTeX? { #limitations } -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. - -- **Native charts and plots.** LaTeX users often create charts along with their - documents in PGF/TikZ. Typst does not yet include tools to draw diagrams, but - the community is stepping up with solutions such as - [`typst-canvas`](https://github.com/johannes-wolf/typst-canvas), - [`typst-plot`](https://github.com/johannes-wolf/typst-plot), and - [`circuitypst`](https://github.com/fenjalien/circuitypst). You can add those - to your document to get started with drawing diagrams. - -- **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]($func/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]($func/pad) with negative padding. - -- **Floating figures.** The figure command of LaTeX will smartly choose where to - place a figure, be it on the top or bottom of the page, or a dedicated figure - page. Typst's figure will always appear at the spot where they have been - inserted in the markup. While this behavior can save some headache, it is - often cumbersome to manually place figures. We will be adding this feature - soon! - -- **Include PDFs as images.** In LaTeX, it has become customary to insert vector - graphics as PDF or EPS files. Typst supports neither format as an image - format, but you can easily convert both into SVG files with [online - tools](https://cloudconvert.com/pdf-to-svg) or - [Inkscape](https://inkscape.org/). We plan to add automatic conversion for - these file formats to the Typst web app, too! - -- **Page break optimization.** LaTeX runs some smart algorithms to not only - optimize line but also page breaks. While Typst tries to avoid widows and - orphans, it uses less sophisticated algorithms to determine page breaks. You - can insert custom page breaks in Typst using `[#pagebreak(weak: true)]` before - submitting your document. The argument `weak` ensures that no double page - break will be created if this spot would be a natural page break - anyways. You can also use `[#v(1fr)]` to distribute space on your page. It - works quite similar to LaTeX's `\vfill`. - -- **Bibliographies are not customizable.** In LaTeX, the packages `bibtex`, - `biblatex`, and `natbib` provide a wide range of reference and bibliography - formats. You can also use custom `.bbx` files to define your own styles there. - Typst only supports a small set of citation styles at the moment, but we want - to build upon this by supporting [Citation Style Language - (CSL)](https://citationstyles.org), an XML-based format backed by Zotero that - allows you to describe your own bibliography styles. diff --git a/docs/src/guides/welcome.md b/docs/src/guides/welcome.md deleted file mode 100644 index 43ecd181..00000000 --- a/docs/src/guides/welcome.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -description: Guides for Typst. ---- - -# Guides -Welcome to the Guides section! Here, you'll find helpful material for specific -user groups or use cases. Currently, one guide is available: An introduction -to Typst for LaTeX users. Feel free to propose other topics for guides! - -## List of Guides { #list-of-guides } -- [Guide for LaTeX users]($guides/guide-for-latex-users) diff --git a/docs/src/html.rs b/docs/src/html.rs deleted file mode 100644 index 0d40f46b..00000000 --- a/docs/src/html.rs +++ /dev/null @@ -1,513 +0,0 @@ -use std::ops::Range; - -use comemo::Prehashed; -use pulldown_cmark as md; -use typed_arena::Arena; -use typst::diag::FileResult; -use typst::eval::Datetime; -use typst::file::FileId; -use typst::font::{Font, FontBook}; -use typst::geom::{Point, Size}; -use typst::syntax::Source; -use typst::util::Bytes; -use typst::World; -use yaml_front_matter::YamlFrontMatter; - -use super::*; - -/// HTML documentation. -#[derive(Serialize)] -#[serde(transparent)] -pub struct Html { - raw: String, - #[serde(skip)] - md: String, - #[serde(skip)] - description: Option<String>, - #[serde(skip)] - outline: Vec<OutlineItem>, -} - -impl Html { - /// Create HTML from a raw string. - pub fn new(raw: String) -> Self { - Self { - md: String::new(), - raw, - description: None, - outline: vec![], - } - } - - /// Convert markdown to HTML. - #[track_caller] - pub fn markdown(resolver: &dyn Resolver, md: &str) -> Self { - Self::markdown_with_id_base(resolver, md, "") - } - - /// Convert markdown to HTML, preceding all fragment identifiers with the - /// `id_base`. - #[track_caller] - pub fn markdown_with_id_base( - resolver: &dyn Resolver, - md: &str, - id_base: &str, - ) -> Self { - let mut text = md; - let mut description = None; - let document = YamlFrontMatter::parse::<Metadata>(md); - if let Ok(document) = &document { - text = &document.content; - description = Some(document.metadata.description.clone()) - } - - let options = md::Options::ENABLE_TABLES | md::Options::ENABLE_HEADING_ATTRIBUTES; - - let ids = Arena::new(); - let mut handler = Handler::new(resolver, id_base.into(), &ids); - let iter = md::Parser::new_ext(text, options) - .filter_map(|mut event| handler.handle(&mut event).then_some(event)); - - let mut raw = String::new(); - md::html::push_html(&mut raw, iter); - raw.truncate(raw.trim_end().len()); - - Html { - md: text.into(), - raw, - description, - outline: handler.outline, - } - } - - /// The raw HTML. - pub fn as_str(&self) -> &str { - &self.raw - } - - /// The original Markdown, if any. - pub fn md(&self) -> &str { - &self.md - } - - /// The title of the HTML. - /// - /// Returns `None` if the HTML doesn't start with an `h1` tag. - pub fn title(&self) -> Option<&str> { - let mut s = Scanner::new(&self.raw); - s.eat_if("<h1>").then(|| s.eat_until("</h1>")) - } - - /// The outline of the HTML. - pub fn outline(&self) -> Vec<OutlineItem> { - self.outline.clone() - } - - /// The description from the front matter. - pub fn description(&self) -> Option<String> { - self.description.clone() - } -} - -impl Debug for Html { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - write!(f, "Html({:?})", self.title().unwrap_or("..")) - } -} - -/// Front matter metadata. -#[derive(Deserialize)] -struct Metadata { - description: String, -} - -struct Handler<'a> { - resolver: &'a dyn Resolver, - lang: Option<String>, - code: String, - outline: Vec<OutlineItem>, - id_base: String, - ids: &'a Arena<String>, -} - -impl<'a> Handler<'a> { - fn new(resolver: &'a dyn Resolver, id_base: String, ids: &'a Arena<String>) -> Self { - Self { - resolver, - lang: None, - code: String::new(), - outline: vec![], - id_base, - ids, - } - } - - fn handle(&mut self, event: &mut md::Event<'a>) -> bool { - match event { - // Rewrite Markdown images. - md::Event::Start(md::Tag::Image(_, path, _)) => { - *path = self.handle_image(path).into(); - } - - // Rewrite HTML images. - md::Event::Html(html) if html.starts_with("<img") => { - let range = html_attr_range(html, "src").unwrap(); - let path = &html[range.clone()]; - let mut buf = html.to_string(); - buf.replace_range(range, &self.handle_image(path)); - *html = buf.into(); - } - - // Register HTML headings for the outline. - md::Event::Start(md::Tag::Heading(level, Some(id), _)) => { - self.handle_heading(id, level); - } - - // Also handle heading closings. - md::Event::End(md::Tag::Heading(level, Some(_), _)) => { - if *level > md::HeadingLevel::H1 && !self.id_base.is_empty() { - nest_heading(level); - } - } - - // Rewrite contributor sections. - md::Event::Html(html) if html.starts_with("<contributors") => { - let from = html_attr(html, "from").unwrap(); - let to = html_attr(html, "to").unwrap(); - let Some(output) = contributors(self.resolver, from, to) else { return false }; - *html = output.raw.into(); - } - - // Rewrite links. - md::Event::Start(md::Tag::Link(ty, dest, _)) => { - assert!( - matches!(ty, md::LinkType::Inline | md::LinkType::Reference), - "unsupported link type: {ty:?}", - ); - - *dest = self - .handle_link(dest) - .unwrap_or_else(|| panic!("invalid link: {dest}")) - .into(); - } - - // Inline raw. - md::Event::Code(code) => { - let mut chars = code.chars(); - let parser = match (chars.next(), chars.next_back()) { - (Some('['), Some(']')) => typst::syntax::parse, - (Some('{'), Some('}')) => typst::syntax::parse_code, - _ => return true, - }; - - let root = parser(&code[1..code.len() - 1]); - let html = typst::ide::highlight_html(&root); - *event = md::Event::Html(html.into()); - } - - // Code blocks. - md::Event::Start(md::Tag::CodeBlock(md::CodeBlockKind::Fenced(lang))) => { - self.lang = Some(lang.as_ref().into()); - self.code = String::new(); - return false; - } - md::Event::End(md::Tag::CodeBlock(md::CodeBlockKind::Fenced(_))) => { - let Some(lang) = self.lang.take() else { return false }; - let html = code_block(self.resolver, &lang, &self.code); - *event = md::Event::Html(html.raw.into()); - } - - // Example with preview. - md::Event::Text(text) => { - if self.lang.is_some() { - self.code.push_str(text); - return false; - } - } - - _ => {} - } - - true - } - - fn handle_image(&self, link: &str) -> String { - if let Some(file) = FILES.get_file(link) { - self.resolver.image(link, file.contents()) - } else if let Some(url) = self.resolver.link(link) { - url - } else { - panic!("missing image: {link}") - } - } - - fn handle_heading(&mut self, id: &mut &'a str, level: &mut md::HeadingLevel) { - if *level == md::HeadingLevel::H1 { - return; - } - - // Special case for things like "v0.3.0". - let name = if id.starts_with('v') && id.contains('.') { - id.to_string() - } else { - id.to_title_case() - }; - - let mut children = &mut self.outline; - let mut depth = *level as usize; - while depth > 2 { - if !children.is_empty() { - children = &mut children.last_mut().unwrap().children; - } - depth -= 1; - } - - // Put base before id. - if !self.id_base.is_empty() { - nest_heading(level); - *id = self.ids.alloc(format!("{}-{id}", self.id_base)).as_str(); - } - - children.push(OutlineItem { id: id.to_string(), name, children: vec![] }); - } - - fn handle_link(&self, link: &str) -> Option<String> { - if link.starts_with('#') || link.starts_with("http") { - return Some(link.into()); - } - - if !link.starts_with('$') { - return self.resolver.link(link); - } - - let root = link.split('/').next()?; - let rest = &link[root.len()..].trim_matches('/'); - let base = match root { - "$tutorial" => "/docs/tutorial/", - "$reference" => "/docs/reference/", - "$category" => "/docs/reference/", - "$syntax" => "/docs/reference/syntax/", - "$styling" => "/docs/reference/styling/", - "$scripting" => "/docs/reference/scripting/", - "$types" => "/docs/reference/types/", - "$type" => "/docs/reference/types/", - "$func" => "/docs/reference/", - "$guides" => "/docs/guides/", - "$packages" => "/docs/packages/", - "$changelog" => "/docs/changelog/", - "$community" => "/docs/community/", - _ => panic!("unknown link root: {root}"), - }; - - let mut route = base.to_string(); - if root == "$type" && rest.contains('.') { - let mut parts = rest.split('.'); - let ty = parts.next()?; - let method = parts.next()?; - route.push_str(ty); - route.push_str("/#methods-"); - route.push_str(method); - } else if root == "$func" { - let mut parts = rest.split('.').peekable(); - let first = parts.peek().copied(); - let mut focus = &LIBRARY.global; - while let Some(m) = first.and_then(|name| module(focus, name).ok()) { - focus = m; - parts.next(); - } - - let name = parts.next()?; - - let value = focus.get(name).ok()?; - let Value::Func(func) = value else { return None }; - let info = func.info()?; - route.push_str(info.category); - route.push('/'); - - if let Some(group) = GROUPS - .iter() - .filter(|_| first == Some("math")) - .find(|group| group.functions.iter().any(|func| func == info.name)) - { - route.push_str(&group.name); - route.push_str("/#"); - route.push_str(info.name); - if let Some(param) = parts.next() { - route.push_str("-parameters-"); - route.push_str(param); - } - } else { - route.push_str(name); - route.push('/'); - if let Some(next) = parts.next() { - if info.params.iter().any(|param| param.name == next) { - route.push_str("#parameters-"); - route.push_str(next); - } else if info.scope.iter().any(|(name, _)| name == next) { - route.push('#'); - route.push_str(info.name); - route.push('-'); - route.push_str(next); - } else { - return None; - } - } - } - } else { - route.push_str(rest); - } - - if !route.contains('#') && !route.ends_with('/') { - route.push('/'); - } - - Some(route) - } -} - -/// Render a code block to HTML. -fn code_block(resolver: &dyn Resolver, lang: &str, text: &str) -> Html { - let mut display = String::new(); - let mut compile = String::new(); - for line in text.lines() { - if let Some(suffix) = line.strip_prefix(">>>") { - compile.push_str(suffix); - compile.push('\n'); - } else if let Some(suffix) = line.strip_prefix("<<< ") { - display.push_str(suffix); - display.push('\n'); - } else { - display.push_str(line); - display.push('\n'); - compile.push_str(line); - compile.push('\n'); - } - } - - let mut parts = lang.split(':'); - let lang = parts.next().unwrap_or(lang); - - let mut zoom: Option<[Abs; 4]> = None; - let mut single = false; - if let Some(args) = parts.next() { - single = true; - if !args.contains("single") { - zoom = args - .split(',') - .take(4) - .map(|s| Abs::pt(s.parse().unwrap())) - .collect::<Vec<_>>() - .try_into() - .ok(); - } - } - - if lang.is_empty() { - let mut buf = String::from("<pre>"); - md::escape::escape_html(&mut buf, &display).unwrap(); - buf.push_str("</pre>"); - return Html::new(buf); - } else if !matches!(lang, "example" | "typ") { - let set = &*typst_library::text::SYNTAXES; - let buf = syntect::html::highlighted_html_for_string( - &display, - set, - set.find_syntax_by_token(lang) - .unwrap_or_else(|| panic!("unsupported highlighting language: {lang}")), - &typst_library::text::THEME, - ) - .expect("failed to highlight code"); - return Html::new(buf); - } - - let root = typst::syntax::parse(&display); - let highlighted = Html::new(typst::ide::highlight_html(&root)); - if lang == "typ" { - return Html::new(format!("<pre>{}</pre>", highlighted.as_str())); - } - - let id = FileId::new(None, Path::new("/main.typ")); - let source = Source::new(id, compile); - let world = DocWorld(source); - let mut frames = match typst::compile(&world) { - Ok(doc) => doc.pages, - Err(err) => { - let msg = &err[0].message; - panic!("while trying to compile:\n{text}:\n\nerror: {msg}"); - } - }; - - if let Some([x, y, w, h]) = zoom { - frames[0].translate(Point::new(-x, -y)); - *frames[0].size_mut() = Size::new(w, h); - } - - if single { - frames.truncate(1); - } - - resolver.example(highlighted, &frames) -} - -/// Extract an attribute value from an HTML element. -fn html_attr<'a>(html: &'a str, attr: &str) -> Option<&'a str> { - html.get(html_attr_range(html, attr)?) -} - -/// Extract the range of the attribute value of an HTML element. -fn html_attr_range(html: &str, attr: &str) -> Option<Range<usize>> { - let needle = format!("{attr}=\""); - let offset = html.find(&needle)? + needle.len(); - let len = html[offset..].find('"')?; - Some(offset..offset + len) -} - -/// Increase the nesting level of a Markdown heading. -fn nest_heading(level: &mut md::HeadingLevel) { - *level = match &level { - md::HeadingLevel::H1 => md::HeadingLevel::H2, - md::HeadingLevel::H2 => md::HeadingLevel::H3, - md::HeadingLevel::H3 => md::HeadingLevel::H4, - md::HeadingLevel::H4 => md::HeadingLevel::H5, - md::HeadingLevel::H5 => md::HeadingLevel::H6, - v => **v, - }; -} - -/// A world for example compilations. -struct DocWorld(Source); - -impl World for DocWorld { - fn library(&self) -> &Prehashed<Library> { - &LIBRARY - } - - fn book(&self) -> &Prehashed<FontBook> { - &FONTS.0 - } - - fn main(&self) -> Source { - self.0.clone() - } - - fn source(&self, _: FileId) -> FileResult<Source> { - Ok(self.0.clone()) - } - - fn file(&self, id: FileId) -> FileResult<Bytes> { - assert!(id.package().is_none()); - Ok(FILES - .get_file(id.path().strip_prefix("/").unwrap()) - .unwrap_or_else(|| panic!("failed to load {:?}", id.path().display())) - .contents() - .into()) - } - - fn font(&self, index: usize) -> Option<Font> { - Some(FONTS.1[index].clone()) - } - - fn today(&self, _: Option<i64>) -> Option<Datetime> { - Some(Datetime::from_ymd(1970, 1, 1).unwrap()) - } -} diff --git a/docs/src/lib.rs b/docs/src/lib.rs deleted file mode 100644 index afceff22..00000000 --- a/docs/src/lib.rs +++ /dev/null @@ -1,1002 +0,0 @@ -//! Documentation provider for Typst. - -mod contribs; -mod html; - -pub use contribs::{contributors, Author, Commit}; -pub use html::Html; - -use std::fmt::{self, Debug, Formatter}; -use std::path::Path; - -use comemo::Prehashed; -use heck::ToTitleCase; -use include_dir::{include_dir, Dir}; -use once_cell::sync::Lazy; -use serde::de::DeserializeOwned; -use serde::{Deserialize, Serialize}; -use serde_yaml as yaml; -use typst::doc::Frame; -use typst::eval::{CastInfo, Func, FuncInfo, Library, Module, ParamInfo, Value}; -use typst::font::{Font, FontBook}; -use typst::geom::{Abs, Smart}; -use typst_library::layout::{Margin, PageElem}; -use unscanny::Scanner; - -static SRC: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/src"); -static FILES: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/../assets/files"); -static DETAILS: Lazy<yaml::Mapping> = Lazy::new(|| yaml("reference/details.yml")); -static GROUPS: Lazy<Vec<GroupData>> = Lazy::new(|| yaml("reference/groups.yml")); - -static FONTS: Lazy<(Prehashed<FontBook>, Vec<Font>)> = Lazy::new(|| { - static DIR: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/../assets/fonts"); - let fonts: Vec<_> = DIR - .files() - .flat_map(|file| Font::iter(file.contents().into())) - .collect(); - let book = FontBook::from_fonts(&fonts); - (Prehashed::new(book), fonts) -}); - -static LIBRARY: Lazy<Prehashed<Library>> = Lazy::new(|| { - let mut lib = typst_library::build(); - lib.styles - .set(PageElem::set_width(Smart::Custom(Abs::pt(240.0).into()))); - lib.styles.set(PageElem::set_height(Smart::Auto)); - lib.styles.set(PageElem::set_margin(Margin::splat(Some(Smart::Custom( - Abs::pt(15.0).into(), - ))))); - typst::eval::set_lang_items(lib.items.clone()); - Prehashed::new(lib) -}); - -/// Build documentation pages. -pub fn provide(resolver: &dyn Resolver) -> Vec<PageModel> { - vec![ - markdown_page(resolver, "/docs/", "general/overview.md").with_route("/docs/"), - tutorial_pages(resolver), - reference_pages(resolver), - guides_pages(resolver), - packages_page(resolver), - markdown_page(resolver, "/docs/", "general/changelog.md"), - markdown_page(resolver, "/docs/", "general/community.md"), - ] -} - -/// Resolve consumer dependencies. -pub trait Resolver { - /// Try to resolve a link that the system cannot resolve itself. - fn link(&self, link: &str) -> Option<String>; - - /// Produce an URL for an image file. - fn image(&self, filename: &str, data: &[u8]) -> String; - - /// Produce HTML for an example. - fn example(&self, source: Html, frames: &[Frame]) -> Html; - - /// Determine the commits between two tags. - fn commits(&self, from: &str, to: &str) -> Vec<Commit>; -} - -/// Details about a documentation page and its children. -#[derive(Debug, Serialize)] -pub struct PageModel { - pub route: String, - pub title: String, - pub description: String, - pub part: Option<&'static str>, - pub outline: Vec<OutlineItem>, - pub body: BodyModel, - pub children: Vec<Self>, -} - -impl PageModel { - fn with_route(self, route: &str) -> Self { - Self { route: route.into(), ..self } - } - - fn with_part(self, part: &'static str) -> Self { - Self { part: Some(part), ..self } - } -} - -/// An element in the "On This Page" outline. -#[derive(Debug, Clone, Serialize)] -pub struct OutlineItem { - id: String, - name: String, - children: Vec<Self>, -} - -/// Details about the body of a documentation page. -#[derive(Debug, Serialize)] -#[serde(rename_all = "camelCase")] -#[serde(tag = "kind", content = "content")] -pub enum BodyModel { - Html(Html), - Category(CategoryModel), - Func(FuncModel), - Funcs(FuncsModel), - Type(TypeModel), - Symbols(SymbolsModel), - Packages(Html), -} - -/// Build the tutorial. -fn tutorial_pages(resolver: &dyn Resolver) -> PageModel { - let mut page = markdown_page(resolver, "/docs/", "tutorial/welcome.md"); - page.children = SRC - .get_dir("tutorial") - .unwrap() - .files() - .filter(|file| file.path() != Path::new("tutorial/welcome.md")) - .map(|file| markdown_page(resolver, "/docs/tutorial/", file.path())) - .collect(); - page -} - -/// Build the reference. -fn reference_pages(resolver: &dyn Resolver) -> PageModel { - let mut page = markdown_page(resolver, "/docs/", "reference/welcome.md"); - page.children = vec![ - markdown_page(resolver, "/docs/reference/", "reference/syntax.md") - .with_part("Language"), - markdown_page(resolver, "/docs/reference/", "reference/styling.md"), - markdown_page(resolver, "/docs/reference/", "reference/scripting.md"), - types_page(resolver, "/docs/reference/"), - category_page(resolver, "text").with_part("Content"), - category_page(resolver, "math"), - category_page(resolver, "layout"), - category_page(resolver, "visualize"), - category_page(resolver, "meta"), - category_page(resolver, "symbols"), - category_page(resolver, "foundations").with_part("Compute"), - category_page(resolver, "calculate"), - category_page(resolver, "construct"), - category_page(resolver, "data-loading"), - ]; - page -} - -/// Build the guides section. -fn guides_pages(resolver: &dyn Resolver) -> PageModel { - let mut page = markdown_page(resolver, "/docs/", "guides/welcome.md"); - page.children = - vec![markdown_page(resolver, "/docs/guides/", "guides/guide-for-latex-users.md")]; - page -} - -/// Build the packages section. -fn packages_page(resolver: &dyn Resolver) -> PageModel { - PageModel { - route: "/docs/packages/".into(), - title: "Packages".into(), - description: "Packages for Typst.".into(), - part: None, - outline: vec![], - body: BodyModel::Packages(Html::markdown(resolver, details("packages"))), - children: vec![], - } -} - -/// Create a page from a markdown file. -#[track_caller] -fn markdown_page( - resolver: &dyn Resolver, - parent: &str, - path: impl AsRef<Path>, -) -> PageModel { - assert!(parent.starts_with('/') && parent.ends_with('/')); - let md = SRC.get_file(path).unwrap().contents_utf8().unwrap(); - let html = Html::markdown(resolver, md); - let title = html.title().expect("chapter lacks a title").to_string(); - PageModel { - route: format!("{parent}{}/", urlify(&title)), - title, - description: html.description().unwrap(), - part: None, - outline: html.outline(), - body: BodyModel::Html(html), - children: vec![], - } -} - -/// Details about a category. -#[derive(Debug, Serialize)] -pub struct CategoryModel { - pub name: String, - pub details: Html, - pub kind: &'static str, - pub items: Vec<CategoryItem>, -} - -/// Details about a category item. -#[derive(Debug, Serialize)] -pub struct CategoryItem { - pub name: String, - pub route: String, - pub oneliner: String, - pub code: bool, -} - -/// Create a page for a category. -#[track_caller] -fn category_page(resolver: &dyn Resolver, category: &str) -> PageModel { - let route = format!("/docs/reference/{category}/"); - let mut children = vec![]; - let mut items = vec![]; - - let focus = match category { - "math" => &LIBRARY.math, - "calculate" => module(&LIBRARY.global, "calc").unwrap(), - _ => &LIBRARY.global, - }; - - let parents: &[&str] = match category { - "math" => &[], - "calculate" => &["calc"], - _ => &[], - }; - - let grouped = match category { - "math" => GROUPS.as_slice(), - _ => &[], - }; - - // Add functions. - for (_, value) in focus.scope().iter() { - let Value::Func(func) = value else { continue }; - let Some(info) = func.info() else { continue }; - if info.category != category { - continue; - } - - // Skip grouped functions. - if grouped - .iter() - .flat_map(|group| &group.functions) - .any(|f| f == info.name) - { - continue; - } - - let subpage = function_page(resolver, &route, func, info, parents); - items.push(CategoryItem { - name: info.name.into(), - route: subpage.route.clone(), - oneliner: oneliner(info.docs).into(), - code: true, - }); - children.push(subpage); - } - - // Add grouped functions. - for group in grouped { - let mut functions = vec![]; - let mut outline = vec![OutlineItem { - id: "summary".into(), - name: "Summary".into(), - children: vec![], - }]; - - for name in &group.functions { - let value = focus.get(name).unwrap(); - let Value::Func(func) = value else { panic!("not a function") }; - let info = func.info().unwrap(); - let func = func_model(resolver, func, info, &[], info.name); - let id = urlify(&func.path.join("-")); - let children = func_outline(&func, &id, false); - outline.push(OutlineItem { id, name: func.display.into(), children }); - functions.push(func); - } - - let route = format!("{}{}/", route, group.name); - items.push(CategoryItem { - name: group.name.clone(), - route: route.clone(), - oneliner: oneliner(&group.description).into(), - code: false, - }); - - children.push(PageModel { - route, - title: group.display.clone(), - description: format!("Documentation for {} group of functions.", group.name), - part: None, - outline, - body: BodyModel::Funcs(FuncsModel { - name: group.name.clone(), - display: group.display.clone(), - details: Html::markdown(resolver, &group.description), - functions, - }), - children: vec![], - }); - } - - children.sort_by_cached_key(|child| child.title.clone()); - items.sort_by_cached_key(|item| item.name.clone()); - - // Add symbol pages. These are ordered manually. - if category == "symbols" { - for module in ["sym", "emoji"] { - let subpage = symbol_page(resolver, &route, module); - items.push(CategoryItem { - name: module.into(), - route: subpage.route.clone(), - oneliner: oneliner(details(module)).into(), - code: true, - }); - children.push(subpage); - } - } - - let name = category.to_title_case(); - let kind = match category { - "symbols" => "Modules", - _ => "Functions", - }; - - PageModel { - route, - title: name.clone(), - description: format!("Documentation for functions related to {name} in Typst."), - part: None, - outline: category_outline(kind), - body: BodyModel::Category(CategoryModel { - name, - details: Html::markdown(resolver, details(category)), - kind, - items, - }), - children, - } -} - -/// Produce an outline for a category page. -fn category_outline(kind: &str) -> Vec<OutlineItem> { - vec![ - OutlineItem { - id: "summary".into(), - name: "Summary".into(), - children: vec![], - }, - OutlineItem { - id: urlify(kind), - name: kind.into(), - children: vec![], - }, - ] -} - -/// Details about a function. -#[derive(Debug, Serialize)] -pub struct FuncModel { - pub path: Vec<&'static str>, - pub display: &'static str, - pub keywords: Option<&'static str>, - pub oneliner: &'static str, - pub element: bool, - pub details: Html, - pub params: Vec<ParamModel>, - pub returns: Vec<&'static str>, - pub methods: Vec<MethodModel>, - pub scope: Vec<Self>, -} - -/// Details about a group of functions. -#[derive(Debug, Serialize)] -pub struct FuncsModel { - pub name: String, - pub display: String, - pub details: Html, - pub functions: Vec<FuncModel>, -} - -/// Create a page for a function. -fn function_page( - resolver: &dyn Resolver, - parent: &str, - func: &Func, - info: &FuncInfo, - parents: &[&'static str], -) -> PageModel { - let model = func_model(resolver, func, info, parents, ""); - PageModel { - route: format!("{parent}{}/", urlify(info.name)), - title: info.display.to_string(), - description: format!("Documentation for the `{}` function.", info.name), - part: None, - outline: func_outline(&model, "", true), - body: BodyModel::Func(model), - children: vec![], - } -} - -/// Produce a function's model. -fn func_model( - resolver: &dyn Resolver, - func: &Func, - info: &FuncInfo, - parents: &[&'static str], - id_base: &str, -) -> FuncModel { - let mut s = unscanny::Scanner::new(info.docs); - let docs = s.eat_until("\n## Methods").trim(); - - let mut path = parents.to_vec(); - let mut name = info.name; - for parent in parents.iter().rev() { - name = name - .strip_prefix(parent) - .or(name.strip_prefix(parent.strip_suffix('s').unwrap_or(parent))) - .unwrap_or(name) - .trim_matches('-'); - } - path.push(name); - - let scope = info - .scope - .iter() - .filter_map(|(_, value)| { - let Value::Func(func) = value else { return None }; - let info = func.info().unwrap(); - Some(func_model(resolver, func, info, &path, id_base)) - }) - .collect(); - - let mut returns = vec![]; - casts(resolver, &mut returns, &mut vec![], &info.returns); - returns.sort_by_key(|ty| type_index(ty)); - if returns == ["none"] { - returns.clear(); - } - - FuncModel { - path, - display: info.display, - keywords: info.keywords, - oneliner: oneliner(docs), - element: func.element().is_some(), - details: Html::markdown_with_id_base(resolver, docs, id_base), - params: info.params.iter().map(|param| param_model(resolver, param)).collect(), - returns, - methods: method_models(resolver, info.docs), - scope, - } -} - -/// Produce an outline for a function page. -fn func_outline(model: &FuncModel, base: &str, summary: bool) -> Vec<OutlineItem> { - let mut outline = vec![]; - - if summary { - outline.push(OutlineItem { - id: "summary".into(), - name: "Summary".into(), - children: vec![], - }); - } - - outline.extend(model.details.outline()); - - if !model.params.is_empty() { - let join = if base.is_empty() { "" } else { "-" }; - outline.push(OutlineItem { - id: format!("{base}{join}parameters"), - name: "Parameters".into(), - children: model - .params - .iter() - .map(|param| OutlineItem { - id: format!("{base}{join}parameters-{}", urlify(param.name)), - name: param.name.into(), - children: vec![], - }) - .collect(), - }); - } - - for func in &model.scope { - let id = urlify(&func.path.join("-")); - let children = func_outline(func, &id, false); - outline.push(OutlineItem { id, name: func.display.into(), children }) - } - - outline.extend(methods_outline(&model.methods)); - outline -} - -/// Details about a function parameter. -#[derive(Debug, Serialize)] -pub struct ParamModel { - pub name: &'static str, - pub details: Html, - pub example: Option<Html>, - pub types: Vec<&'static str>, - pub strings: Vec<StrParam>, - pub default: Option<Html>, - pub positional: bool, - pub named: bool, - pub required: bool, - pub variadic: bool, - pub settable: bool, -} - -/// A specific string that can be passed as an argument. -#[derive(Debug, Serialize)] -pub struct StrParam { - pub string: String, - pub details: Html, -} - -/// Produce a parameter's model. -fn param_model(resolver: &dyn Resolver, info: &ParamInfo) -> ParamModel { - let mut types = vec![]; - let mut strings = vec![]; - casts(resolver, &mut types, &mut strings, &info.cast); - if !strings.is_empty() && !types.contains(&"string") { - types.push("string"); - } - types.sort_by_key(|ty| type_index(ty)); - - let mut details = info.docs; - let mut example = None; - if let Some(mut i) = info.docs.find("```example") { - while info.docs[..i].ends_with('`') { - i -= 1; - } - details = &info.docs[..i]; - example = Some(&info.docs[i..]); - } - - ParamModel { - name: info.name, - details: Html::markdown(resolver, details), - example: example.map(|md| Html::markdown(resolver, md)), - types, - strings, - default: info.default.map(|default| { - let node = typst::syntax::parse_code(&default().repr()); - Html::new(typst::ide::highlight_html(&node)) - }), - positional: info.positional, - named: info.named, - required: info.required, - variadic: info.variadic, - settable: info.settable, - } -} - -/// Process cast information into types and strings. -fn casts( - resolver: &dyn Resolver, - types: &mut Vec<&'static str>, - strings: &mut Vec<StrParam>, - info: &CastInfo, -) { - match info { - CastInfo::Any => types.push("any"), - CastInfo::Value(Value::Str(string), docs) => strings.push(StrParam { - string: string.to_string(), - details: Html::markdown(resolver, docs), - }), - CastInfo::Value(..) => {} - CastInfo::Type(ty) => types.push(ty), - CastInfo::Union(options) => { - for option in options { - casts(resolver, types, strings, option); - } - } - } -} - -/// A collection of symbols. -#[derive(Debug, Serialize)] -pub struct TypeModel { - pub name: String, - pub oneliner: &'static str, - pub details: Html, - pub methods: Vec<MethodModel>, -} - -/// Details about a built-in method on a type. -#[derive(Debug, Serialize)] -pub struct MethodModel { - pub name: &'static str, - pub details: Html, - pub params: Vec<ParamModel>, - pub returns: Vec<&'static str>, -} - -/// Create a page for the types. -fn types_page(resolver: &dyn Resolver, parent: &str) -> PageModel { - let route = format!("{parent}types/"); - let mut children = vec![]; - let mut items = vec![]; - - for model in type_models(resolver) { - let route = format!("{route}{}/", urlify(&model.name)); - items.push(CategoryItem { - name: model.name.clone(), - route: route.clone(), - oneliner: model.oneliner.into(), - code: true, - }); - children.push(PageModel { - route, - title: model.name.to_title_case(), - description: format!("Documentation for the `{}` type.", model.name), - part: None, - outline: type_outline(&model), - body: BodyModel::Type(model), - children: vec![], - }); - } - - PageModel { - route, - title: "Types".into(), - description: "Documentation for Typst's built-in types.".into(), - part: None, - outline: category_outline("Types"), - body: BodyModel::Category(CategoryModel { - name: "Types".into(), - details: Html::markdown(resolver, details("types")), - kind: "Types", - items, - }), - children, - } -} - -/// Produce the types' models. -fn type_models(resolver: &dyn Resolver) -> Vec<TypeModel> { - let file = SRC.get_file("reference/types.md").unwrap(); - let text = file.contents_utf8().unwrap(); - - let mut s = unscanny::Scanner::new(text); - let mut types = vec![]; - - while s.eat_if("# ") { - let part = s.eat_until("\n# "); - types.push(type_model(resolver, part)); - s.eat_if('\n'); - } - - types -} - -/// Produce a type's model. -fn type_model(resolver: &dyn Resolver, part: &'static str) -> TypeModel { - let mut s = unscanny::Scanner::new(part); - let display = s.eat_until('\n').trim(); - let docs = s.eat_until("\n## Methods").trim(); - TypeModel { - name: display.to_lowercase(), - oneliner: oneliner(docs), - details: Html::markdown(resolver, docs), - methods: method_models(resolver, part), - } -} - -/// Produce multiple methods' models. -fn method_models(resolver: &dyn Resolver, docs: &'static str) -> Vec<MethodModel> { - let mut s = unscanny::Scanner::new(docs); - s.eat_until("\n## Methods"); - s.eat_whitespace(); - - let mut methods = vec![]; - if s.eat_if("## Methods") { - s.eat_until("\n### "); - while s.eat_if("\n### ") { - methods.push(method_model(resolver, s.eat_until("\n### "))); - } - } - - methods -} - -/// Produce a method's model. -fn method_model(resolver: &dyn Resolver, part: &'static str) -> MethodModel { - let mut s = unscanny::Scanner::new(part); - let mut params = vec![]; - let mut returns = vec![]; - - let name = s.eat_until('(').trim(); - s.expect("()"); - let docs = s.eat_until("\n- ").trim(); - - while s.eat_if("\n- ") { - let name = s.eat_until(':'); - s.expect(": "); - let types: Vec<_> = - s.eat_until(['(', '\n']).split(" or ").map(str::trim).collect(); - if !types.iter().all(|ty| type_index(ty) != usize::MAX) { - panic!( - "unknown type in method {} parameter {}", - name, - types.iter().find(|ty| type_index(ty) == usize::MAX).unwrap() - ) - } - - if name == "returns" { - returns = types; - continue; - } - - s.expect('('); - - let mut named = false; - let mut positional = false; - let mut required = false; - let mut variadic = false; - for part in s.eat_until(')').split(',').map(str::trim) { - match part { - "named" => named = true, - "positional" => positional = true, - "required" => required = true, - "variadic" => variadic = true, - _ => panic!("unknown parameter flag {:?}", part), - } - } - - s.expect(')'); - - params.push(ParamModel { - name, - details: Html::markdown(resolver, s.eat_until("\n- ").trim()), - example: None, - types, - strings: vec![], - default: None, - positional, - named, - required, - variadic, - settable: false, - }); - } - - MethodModel { - name, - details: Html::markdown(resolver, docs), - params, - returns, - } -} - -/// Produce an outline for a type page. -fn type_outline(model: &TypeModel) -> Vec<OutlineItem> { - let mut outline = vec![OutlineItem { - id: "summary".into(), - name: "Summary".into(), - children: vec![], - }]; - - outline.extend(methods_outline(&model.methods)); - outline -} - -/// Produce an outline for a type's method. -fn methods_outline(methods: &[MethodModel]) -> Option<OutlineItem> { - (!methods.is_empty()).then(|| OutlineItem { - id: "methods".into(), - name: "Methods".into(), - children: methods.iter().map(method_outline).collect(), - }) -} - -/// Produce an outline for a type's method. -fn method_outline(model: &MethodModel) -> OutlineItem { - OutlineItem { - id: format!("methods-{}", urlify(model.name)), - name: model.name.into(), - children: model - .params - .iter() - .map(|param| OutlineItem { - id: format!( - "methods-{}-parameters-{}", - urlify(model.name), - urlify(param.name) - ), - name: param.name.into(), - children: vec![], - }) - .collect(), - } -} - -/// A collection of symbols. -#[derive(Debug, Serialize)] -pub struct SymbolsModel { - pub name: &'static str, - pub details: Html, - pub list: Vec<SymbolModel>, -} - -/// Details about a symbol. -#[derive(Debug, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct SymbolModel { - pub name: String, - pub shorthand: Option<&'static str>, - pub codepoint: u32, - pub accent: bool, - pub unicode_name: Option<String>, - pub alternates: Vec<String>, -} - -/// Create a page for symbols. -fn symbol_page(resolver: &dyn Resolver, parent: &str, name: &str) -> PageModel { - let module = module(&LIBRARY.global, name).unwrap(); - - let mut list = vec![]; - for (name, value) in module.scope().iter() { - let Value::Symbol(symbol) = value else { continue }; - let complete = |variant: &str| { - if variant.is_empty() { - name.into() - } else { - format!("{}.{}", name, variant) - } - }; - - for (variant, c) in symbol.variants() { - list.push(SymbolModel { - name: complete(variant), - shorthand: typst::syntax::ast::Shorthand::LIST - .iter() - .copied() - .find(|&(_, x)| x == c) - .map(|(s, _)| s), - codepoint: c as u32, - accent: typst::eval::Symbol::combining_accent(c).is_some(), - unicode_name: unicode_names2::name(c) - .map(|s| s.to_string().to_title_case()), - alternates: symbol - .variants() - .filter(|(other, _)| other != &variant) - .map(|(other, _)| complete(other)) - .collect(), - }); - } - } - - let title = match name { - "sym" => "General", - "emoji" => "Emoji", - _ => unreachable!(), - }; - - PageModel { - route: format!("{parent}{name}/"), - title: title.into(), - description: format!("Documentation for the `{name}` module."), - part: None, - outline: vec![], - body: BodyModel::Symbols(SymbolsModel { - name: title, - details: Html::markdown(resolver, details(name)), - list, - }), - children: vec![], - } -} - -/// Data about a collection of functions. -#[derive(Debug, Deserialize)] -struct GroupData { - name: String, - display: String, - functions: Vec<String>, - description: String, -} - -/// Extract a module from another module. -#[track_caller] -fn module<'a>(parent: &'a Module, name: &str) -> Result<&'a Module, String> { - match parent.scope().get(name) { - Some(Value::Module(module)) => Ok(module), - _ => Err(format!("module doesn't contain module `{name}`")), - } -} - -/// Load YAML from a path. -#[track_caller] -fn yaml<T: DeserializeOwned>(path: &str) -> T { - let file = SRC.get_file(path).unwrap(); - yaml::from_slice(file.contents()).unwrap() -} - -/// Load details for an identifying key. -#[track_caller] -fn details(key: &str) -> &str { - DETAILS - .get(&yaml::Value::String(key.into())) - .and_then(|value| value.as_str()) - .unwrap_or_else(|| panic!("missing details for {key}")) -} - -/// Turn a title into an URL fragment. -pub fn urlify(title: &str) -> String { - title - .chars() - .map(|c| c.to_ascii_lowercase()) - .map(|c| match c { - 'a'..='z' | '0'..='9' => c, - _ => '-', - }) - .collect() -} - -/// Extract the first line of documentation. -fn oneliner(docs: &str) -> &str { - docs.lines().next().unwrap_or_default() -} - -/// The order of types in the documentation. -fn type_index(ty: &str) -> usize { - TYPE_ORDER.iter().position(|&v| v == ty).unwrap_or(usize::MAX) -} - -const TYPE_ORDER: &[&str] = &[ - "any", - "none", - "auto", - "boolean", - "integer", - "float", - "length", - "angle", - "ratio", - "relative length", - "fraction", - "color", - "datetime", - "string", - "regex", - "label", - "content", - "array", - "dictionary", - "function", - "arguments", - "location", - "dir", - "alignment", - "2d alignment", - "selector", - "stroke", -]; - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_docs() { - provide(&TestResolver); - } - - struct TestResolver; - - impl Resolver for TestResolver { - fn link(&self, _: &str) -> Option<String> { - None - } - - fn example(&self, _: Html, _: &[Frame]) -> Html { - Html::new(String::new()) - } - - fn image(&self, _: &str, _: &[u8]) -> String { - String::new() - } - - fn commits(&self, _: &str, _: &str) -> Vec<Commit> { - vec![] - } - } -} diff --git a/docs/src/reference/details.yml b/docs/src/reference/details.yml deleted file mode 100644 index 8e9af3a0..00000000 --- a/docs/src/reference/details.yml +++ /dev/null @@ -1,174 +0,0 @@ -types: | - 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 very basic types for numeric values and typical types known from - programming languages, Typst provides a special type for _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. - - In some places of Typst more specialized data types are used. Instead of listing - all of them here, they are explained where they are relevant. - -text: | - Text styling. - - The [text function]($func/text) is of particular interest. - -math: | - Typst has special [syntax]($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 $]`). - - 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 - [hashtag syntax]($scripting/#expressions). - - ```example - $ A = pi r^2 $ - $ "area" = pi dot "radius"^2 $ - $ cal(A) := - { x in RR | x "is natural" } $ - #let x = 5 - $ #x < 17 $ - ``` - - Math mode makes a wide selection of [symbols]($category/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]($type/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. - - ```example - $ x < y => x gt.eq.not y $ - ``` - - Formulas can also contain line breaks. Each line can contain one or multiple - _alignment points_ (`&`) which are then aligned. - ```example - $ sum_(k=0)^n k - &= 1 + ... + n \ - &= (n(n+1)) / 2 $ - ``` - - Math mode supports special function calls without the hashtag 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 hashtag syntax to pass code expressions (except - for strings, which are available in the math syntax). - - They support positional and named arguments, but don't support - trailing content blocks and argument spreading. - - They provide additional syntax for 2-dimensional argument lists. The - semicolon (`;`) merges preceding arguments separated by commas into an array - argument. - - ```example - $ frac(a^2, 2) $ - $ vec(1, 2, delim: "[") $ - $ mat(1, 2; 3, 4) $ - $ 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 hashtag are normal code function calls and not - affected by these rules. - - All math functions are part of the `math` [module]($scripting/#modules), which - is available by default in equations. Outside of equations, they can be - accessed with the `math.` prefix. For example, to set the font used for - equations, write: - - ```example - #show math.equation: set text(font: "Fira Math") - $ sum_(i in NN) 1 + i $ - ``` - -layout: | - Arranging elements on the page in different ways. - - By combining layout functions, you can create complex and automatic layouts. - -visualize: | - Drawing and data visualization. - - _Note:_ Functions for plotting and diagrams are not yet available. They will - be in the future. - -meta: | - Document structuring, introspection, and metadata configuration. - - Here, you can find functions to structure your document and interact with that - structure. This includes section headings and figures, bibliography - management, cross-referencing and more. - - Moreover, 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. And 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. - -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. - -sym: | - Named general symbols. - - For example, `#sym.arrow` produces the → symbol. Within - [formulas]($category/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`. - -emoji: | - Named emoji. - - 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. - -foundations: | - Foundational functions for computation. - -calculate: | - Calculations and processing of numeric values. - - These functions 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`, `e`, `inf`, and `nan`. - -construct: | - Construction of and conversions between values of different types. - -data-loading: | - Data loading from external files. - - These functions help you with embedding data from experiments in your - documents. - -utility: | - Useful utility functions. - -packages: | - Typst [packages]($scripting/#packages) encapsulate reusable building blocks - and make them reusable across projects. Below is a list of Typst packages - created by the community. Due to the early and experimental nature of Typst's - package management, they all live in a `preview` namespace. Click on a - package's name to view its documentation and use the copy button on the right - to get a full import statement for it. diff --git a/docs/src/reference/groups.yml b/docs/src/reference/groups.yml deleted file mode 100644 index 3bc80339..00000000 --- a/docs/src/reference/groups.yml +++ /dev/null @@ -1,76 +0,0 @@ -# This is responsible for the fact that certain math functions are grouped -# together into one documentation page although they are not part of any scope. - -- name: variants - display: Variants - functions: ["serif", "sans", "frak", "mono", "bb", "cal"] - description: | - Alternate typefaces within formulas. - - These functions are distinct from the [`text`]($func/text) function because - math fonts contain multiple variants of each letter. - -- name: styles - display: Styles - functions: ["upright", "italic", "bold"] - description: | - Alternate letterforms within formulas. - - These functions are distinct from the [`text`]($func/text) function because - math fonts contain multiple variants of each letter. - -- name: sizes - display: Sizes - functions: ["display", "inline", "script", "sscript"] - description: | - 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. - -- name: underover - display: Under/Over - functions: [ - "underline", - "overline", - "underbrace", - "overbrace", - "underbracket", - "overbracket", - ] - description: | - Delimiters above or below parts of an equation. - - The braces and brackets further allow you to add an optional annotation - below or above themselves. - -- name: roots - display: Roots - functions: ["root", "sqrt"] - description: Square and non-square roots. - -- name: attach - display: Attach - functions: ["attach", "scripts", "limits"] - description: | - Subscript, superscripts, and limits. - - The `attach` function backs the `[$a_b^c$]` syntax that adds top and bottom - attachments to a part of an equation. 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. - -- name: lr - display: Left/Right - functions: ["lr", "abs", "norm", "floor", "ceil", "round"] - description: | - 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. diff --git a/docs/src/reference/scripting.md b/docs/src/reference/scripting.md deleted file mode 100644 index c18bdc4b..00000000 --- a/docs/src/reference/scripting.md +++ /dev/null @@ -1,345 +0,0 @@ ---- -description: Automate your document with Typst's scripting capabilities. ---- - -# 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 { #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 hashtag (`#`) 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 -(`;`). - -```example -#emph[Hello] \ -#emoji.face \ -#"hello".len() -``` - -The example above shows a few of the available expressions, including -[function calls]($type/function), -[field accesses]($scripting/#fields), and -[method calls]($scripting/#methods). More kinds of expressions are -discussed in the remainder of this chapter. A few kinds of expressions are not -compatible with the hashtag syntax (e.g. binary operator expressions). To embed -these into markup, you can use parentheses, as in `[#(1 + 2)]`. - -## Blocks { #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]($type/function). Content - blocks are delimited by square brackets and can contain arbitrary markup. A - content block results in a value of type [content]($type/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*]}`. - -```example -#{ - let a = [from] - let b = [*world*] - [hello ] - a + [ the ] + b -} -``` - -## Bindings and Destructuring { #bindings } -As already demonstrated above, variables can be defined with `{let}` bindings. -The variable is assigned the value of the expression that follows the `=` sign. -The assignment of a value is optional, if no value is assigned, the variable -will be initialized as `{none}`. The `{let}` keyword can also be used to create -a [custom named function]($type/function/#definitions). Let bindings can be -accessed for the rest of the containing block or document. - -```example -#let name = "Typst" -This is #name's documentation. -It explains #name. - -#let add(x, y) = x + y -Sum is #add(2, 3). -``` - -Let bindings can also be used to destructure [arrays]($type/array) and -[dictionaries]($type/dictionary). In this case, the left-hand side of the -assignment should mirror an array or dictionary. The `..` operator can be used -once in the pattern to collect the remainder of the array's or dictionary's -items. - -```example -#let (x, y) = (1, 2) -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: - -```example -#let (_, y, _) = (1, 2, 3) -The y coordinate is #y. -``` - -Destructuring also work in argument lists of functions ... - -```example -#let left = (2, 4, 5) -#let right = (3, 2, 6) -#left.zip(right).map( - ((a,b)) => a + b -) -``` - -... and on the left-hand side of normal assignments. This can be useful to -swap variables among other things. - -```example -#{ - let a = 1 - let b = 2 - (a, b) = (b, a) - [a = #a, b = #b] -} -``` - -## Conditionals { #conditionals } -With a conditional, you can display or compute different things depending on -whether some condition is fulfilled. Typst supports `{if}`, `{else if}` and -`{else}` expression. 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. - -```example -#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 { #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. - -```example -#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 letter in "abc" {..}}` \ - Iterates over the characters of the [string]($type/string). - (Technically, iterates over the grapheme clusters of the string. Most of the - time, a grapheme cluster is just a single character/codepoint. However, some - constructs like flag emojis that consist of multiple codepoints are still only - one cluster.) - -- `{for value in array {..}}` \ - Iterates over the items in the [array]($type/array). The destructuring syntax - described in [Let binding]($scripting/#bindings) can also be used here. - -- `{for pair in dict {..}}` \ - Iterates over the key-value pairs of the [dictionary]($type/dictionary). - The pairs can also be destructured by using `{for (key, value) in dict {..}}`. - -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. - -```example -#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 { #fields } -You can use _dot notation_ to access fields on a value. The value in question -can be either: -- a [dictionary]($type/dictionary) that has the specified key, -- a [symbol]($type/symbol) that has the specified modifier, -- a [module]($type/module) containing the specified definition, -- [content]($type/content) consisting of an element that has the specified - field. The available fields match the arguments of the - [element function]($type/function/#element-functions) that were given when - the element was constructed. - -```example -#let dict = (greet: "Hello") -#dict.greet \ -#emoji.face - -#let it = [= Heading] -#it.body \ -#it.level -``` - -## Methods { #methods } -A method is a kind of a [function]($type/function) that is tightly coupled with -a specific type. It is called on a value of its type using the same dot notation -that is also used for fields: `{value.method(..)}`. The -[type documentation]($type) lists the available methods for each of the built-in -types. You cannot define your own methods. - -```example -#let array = (1, 2, 3, 4) -#array.pop() \ -#array.len() \ - -#("a, b, c" - .split(", ") - .join[ --- ]) -``` - -Methods are the only functions in Typst that can modify the value they are -called on. - -## Modules { #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]($type/content). - -- **Import:** `{import "bar.typ"}` \ - Evaluates the file at the path `bar.typ` and inserts the resulting - [module]($type/module) into the current scope as `bar` (filename without - extension). - -- **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. - -Instead of a path, you can also use a [module value]($type/module), as shown in -the following example: - -```example -#import emoji: face -#face.grin -``` - -## Packages { #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. - -```example ->>> #let add(x, y) = x + y -<<< #import "@preview/example:0.1.0": add -#add(2, 7) -``` - -The `preview` namespace contains packages shared by the community. You can find -a searchable list of available community packages in the [packages]($packages) -section. - -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 { #operators } -The following table lists all available unary and binary operators with effect, -arity (unary, binary) and precedence level (higher binds stronger). - -| 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 | - -[semver]: https://semver.org/ diff --git a/docs/src/reference/styling.md b/docs/src/reference/styling.md deleted file mode 100644 index 85095e34..00000000 --- a/docs/src/reference/styling.md +++ /dev/null @@ -1,145 +0,0 @@ ---- -description: All concepts needed to style your document with Typst. ---- - -# 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 { #set-rules } -With set rules, you can customize the appearance of elements. They are written -as a [function call]($type/function) to an -[element function]($type/function/#element-functions) preceded by the `{set}` -keyword (or `[#set]` in markup). Only optional parameters of that function can -be provided to the set rule. Refer to each function's documentation to see which -parameters are optional. In the example below, we use two set rules to change -the [font family]($func/text.font) and -[heading numbering]($func/heading.numbering). - -```example -#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. - -```example -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. - -```example -#let task(body, critical: false) = { - set text(red) if critical - [- #body] -} - -#task(critical: true)[Food today?] -#task(critical: false)[Work deadline] -``` - -## Show rules { #show-rules } -With show rules, you can deeply customize the look of a type of element. The -most basic form of show rule is a _show-set rule._ Such a rule is written as the -`{show}` keyword followed by a [selector]($type/selector), a colon and then a set rule. The most basic form of selector is an -[element function]($type/function/#element-functions). This lets the set rule -only apply to the selected element. In the example below, headings become dark -blue while all other text stays black. - -```example -#show heading: set text(navy) - -= 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 show rule that -defines how to format an element from scratch. To write such a show rule, -replace the set rule behind the colon with an arbitrary -[function]($type/function). This function receives the element in question and -can return arbitrary content. Different -[fields]($scripting/#fields) are available on the element passed -to the function. Below, we define a show rule that formats headings for a -fantasy encyclopedia. - -```example -#set heading(numbering: "(I)") -#show heading: it => block[ - #set align(center) - #set text(font: "Inria Serif") - \~ #emph(it.body) - #counter(heading).display() \~ -] - -= 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` function]($func/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` function]($func/label) for more details. - -```example -#show "Project": smallcaps -#show "badly": "great" - -We started Project in 2019 -and are still working on it. -Project is progressing badly. -``` diff --git a/docs/src/reference/syntax.md b/docs/src/reference/syntax.md deleted file mode 100644 index d0cd80d7..00000000 --- a/docs/src/reference/syntax.md +++ /dev/null @@ -1,138 +0,0 @@ ---- -description: | - A compact reference for Typst's syntax. Learn more about the language within - markup, math, and code mode. ---- - -# 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. - -## Markup { #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`]($func/parbreak) | -| Strong emphasis | `[*strong*]` | [`strong`]($func/strong) | -| Emphasis | `[_emphasis_]` | [`emph`]($func/emph) | -| Raw text | ``[`print(1)`]`` | [`raw`]($func/raw) | -| Link | `[https://typst.app/]` | [`link`]($func/link) | -| Label | `[<intro>]` | [`label`]($func/label) | -| Reference | `[@intro]` | [`ref`]($func/ref) | -| Heading | `[= Heading]` | [`heading`]($func/heading) | -| Bullet list | `[- item]` | [`list`]($func/list) | -| Numbered list | `[+ item]` | [`enum`]($func/enum) | -| Term list | `[/ Term: description]` | [`terms`]($func/terms) | -| Math | `[$x^2$]` | [Math]($category/math) | -| Line break | `[\]` | [`linebreak`]($func/linebreak) | -| Smart quote | `['single' or "double"]` | [`smartquote`]($func/smartquote) | -| Symbol shorthand | `[~, ---]` | [Symbols]($category/symbols/sym) | -| Code expression | `[#rect(width: 1cm)]` | [Scripting]($scripting/#expressions) | -| Character escape | `[Tweet at us \#ad]` | [Below](#escapes) | -| Comment | `[/* block */, // line]` | [Below](#comments) | - -## Math mode { #math } -Math mode is a special markup mode that is used to typeset mathematical -formulas. It is entered by wrapping an equation in `[$]` characters. 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]($category/math) | -| Block-level math | `[$ x^2 $]` | [Math]($category/math) | -| Bottom attachment | `[$x_1$]` | [`attach`]($category/math/attach) | -| Top attachment | `[$x^2$]` | [`attach`]($category/math/attach) | -| Fraction | `[$1 + (a+b)/5$]` | [`frac`]($func/math.frac) | -| Line break | `[$x \ y$]` | [`linebreak`]($func/linebreak) | -| Alignment point | `[$x &= 2 \ &= 3$]` | [Math]($category/math) | -| Variable access | `[$#x$, $pi$]` | [Math]($category/math) | -| Field access | `[$arrow.r.long$]` | [Scripting]($scripting/#fields) | -| Implied multiplication | `[$x y$]` | [Math]($category/math) | -| Symbol shorthand | `[$->, !=$]` | [Symbols]($category/symbols/sym) | -| Text/string in math | `[$a "is natural"$]` | [Math]($category/math) | -| Math function call | `[$floor(x)$]` | [Math]($category/math) | -| Code expression | `[$#rect(width: 1cm)$]` | [Scripting]($scripting/#expressions) | -| Character escape | `[$x\^2$]` | [Below](#escapes) | -| Comment | `[$/* comment */$]` | [Below](#comments) | - -## Code mode { #code } -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 | -| ------------------------ | ----------------------------- | ---------------------------------- | -| Variable access | `{x}` | [Scripting]($scripting/#blocks) | -| Any literal | `{1pt, "hey"}` | [Types]($types) | -| Code block | `{{ let x = 1; x + 2 }}` | [Scripting]($scripting/#blocks) | -| Content block | `{[*Hello*]}` | [Scripting]($scripting/#blocks) | -| Parenthesized expression | `{(1 + 2)}` | [Scripting]($scripting/#blocks) | -| Array | `{(1, 2, 3)}` | [Array]($type/array) | -| Dictionary | `{(a: "hi", b: 2)}` | [Dictionary]($type/dictionary) | -| Unary operator | `{-x}` | [Scripting]($scripting/#operators) | -| Binary operator | `{x + y}` | [Scripting]($scripting/#operators) | -| Assignment | `{x = 1}` | [Scripting]($scripting/#operators) | -| Field access | `{x.y}` | [Scripting]($scripting/#fields) | -| Method call | `{x.flatten()}` | [Scripting]($scripting/#methods) | -| Function call | `{min(x, y)}` | [Function]($type/function) | -| Unnamed function | `{(x, y) => x + y}` | [Function]($type/function) | -| Let binding | `{let x = 1}` | [Scripting]($scripting/#bindings) | -| Named function | `{let f(x) = 2 * x}` | [Function]($type/function) | -| Set rule | `{set text(14pt)}` | [Styling]($styling/#set-rules) | -| Set-if rule | `{set text(..) if .. }` | [Styling]($styling/#set-rules) | -| Show-set rule | `{show par: set block(..)}` | [Styling]($styling/#show-rules) | -| Show rule with function | `{show raw: it => {..}}` | [Styling]($styling/#show-rules) | -| Show-everything rule | `{show: columns.with(2)}` | [Styling]($styling/#show-rules) | -| Conditional | `{if x == 1 {..} else {..}}` | [Scripting]($scripting/#conditionals) | -| For loop | `{for x in (1, 2, 3) {..}}` | [Scripting]($scripting/#loops) | -| While loop | `{while x < 10 {..}}` | [Scripting]($scripting/#loops) | -| Loop control flow | `{break, continue}` | [Scripting]($scripting/#loops) | -| Return from function | `{return x}` | [Function]($type/function) | -| Include module | `{include "bar.typ"}` | [Scripting]($scripting/#modules) | -| Import module | `{import "bar.typ"}` | [Scripting]($scripting/#modules) | -| Import items from module | `{import "bar.typ": a, b, c}` | [Scripting]($scripting/#modules) | -| Comment | `[/* block */, // line]` | [Below](#comments) | - -## 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 `//`: -```example -// 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: -```example -Our study design is as follows: -/* Somebody write this up: - - 1000 participants. - - 2x2 data design. */ -``` - -## Escape sequences { #escapes } -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]($type/string). - -```example -I got an ice cream for -\$1.50! \u{1f600} -``` diff --git a/docs/src/reference/types.md b/docs/src/reference/types.md deleted file mode 100644 index 3e08d670..00000000 --- a/docs/src/reference/types.md +++ /dev/null @@ -1,1190 +0,0 @@ -# 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]($scripting/#blocks) with any value, yielding -the other value. - -## Example -```example -Not visible: #none -``` - -# 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]($func/text.dir) parameter. -Setting it to `{auto}` lets Typst automatically determine the direction from the -[text language]($func/text.lang). - -# Boolean -Either `{true}` or `{false}`. - -The boolean type has two values: `{true}` and `{false}`. It denotes whether -something is active or enabled. - -## Example -```example -#false \ -#true \ -#(1 < 2) -``` - -# 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}`. - -The number can also be specified as hexadecimal, octal, or binary by starting it -with a zero followed by either `x`, `o`, or `b`. - -## Example -```example -#(1 + 2) \ -#(2 - 5) \ -#(3 + 4 < 8) - -#0xff \ -#0o10 \ -#0b1001 -``` - -# Float -A floating-pointer 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]($type/integer). - -## Example -```example -#3.14 \ -#1e4 \ -#(10 / 4) -``` - -# 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}` - -## Example -```example -#rect(width: 20pt) -#rect(width: 2em) -#rect(width: 1in) -``` - -# Angle -An angle describing a rotation. -Typst supports the following angular units: - -- Degrees: `{180deg}` -- Radians: `{3.14rad}` - -## Example -```example -#rotate(10deg)[Hello there!] -``` - -# Ratio -A ratio of a whole. - -Written as a number, followed by a percent sign. - -## Example -```example -#set align(center) -#scale(x: 150%)[ - Scaled apart. -] -``` - -# Relative Length -A length in relation to some known length. - -This type is a combination of a [length]($type/length) with a -[ratio]($type/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. - -## Example -```example -#rect(width: 100% - 50pt) -``` - -# Fraction -Defines how the 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]($func/h) and [v]($func/v) functions and the -[grid function]($func/grid). - -## Example -```example -Left #h(1fr) Left-ish #h(2fr) Right -``` - -# Color -A color in a specific color space. - -Typst supports: -- sRGB through the [`rgb` function]($func/rgb) -- Device CMYK through [`cmyk` function]($func/cmyk) -- D65 Gray through the [`luma` function]($func/luma) - -Furthermore, Typst provides the following built-in colors: - -`black`, `gray`, `silver`, `white`, `navy`, `blue`, `aqua`, `teal`, `eastern`, -`purple`, `fuchsia`, `maroon`, `red`, `orange`, `yellow`, `olive`, `green`, and -`lime`. - -## Methods -### lighten() -Lightens a color. - -- amount: ratio (positional, required) - The factor to lighten the color by. -- returns: color - -### darken() -Darkens a color. - -- amount: ratio (positional, required) - The factor to darken the color by. -- returns: color - -### negate() -Produces the negative of the color. - -- returns: color - -# Datetime -Represents a date, a time, or a combination of both. Can be created by either -specifying a custom datetime using the [`datetime`]($func/datetime) function or -getting the current date with [`datetime.today`]($func/datetime.today). - -## Example -```example -#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]" -) -``` - -## Format -You can specify a customized formatting using the -[`display`]($type/datetime.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. - -## Methods -### display() -Displays the datetime in a certain way. 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]]`. - -- pattern: string (positional) - The format used to display the datetime. -- returns: string - -### year() -Returns the year of the datetime, if it exists. Otherwise, it returns `{none}`. - -- returns: integer or none - -### month() -Returns the month of the datetime, if it exists. Otherwise, it returns `{none}`. - -- returns: integer or none - -### weekday() -Returns the weekday of the datetime as a number starting with 1 from Monday, if -it exists. Otherwise, it returns `{none}`. - -- returns: integer or none - -### day() -Returns the day of the datetime, if it exists. Otherwise, it returns `{none}`. - -- returns: integer or none - -### hour() -Returns the hour of the datetime, if it exists. Otherwise, it returns `{none}`. - -- returns: integer or none - -### minute() -Returns the minute of the datetime, if it exists. Otherwise, it returns -`{none}`. - -- returns: integer or none - -### second() -Returns the second of the datetime, if it exists. Otherwise, it returns -`{none}`. - -- returns: integer or none - -# 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]($scripting/#fields): - -- General symbols are defined in the [`sym` module]($category/symbols/sym) -- Emoji are defined in the [`emoji` module]($category/symbols/emoji) - -Moreover, you can define custom symbols with the [symbol]($func/symbol) -function. - -```example -#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. - -```example -$arrow.l$ \ -$arrow.r$ \ -$arrow.t.quad$ -``` - -# String -A sequence of Unicode codepoints. - -You can iterate over the grapheme clusters of the string using a -[for loop]($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]($scripting/#blocks) and multiplied with integers. - -Typst provides utility methods for string manipulation. Many of these methods -(e.g., `split`, `trim` and `replace`) operate on _patterns:_ A pattern can be -either a string or a [regular expression]($func/regex). This makes the methods -quite versatile. - -All lengths and indices are expressed in terms of UTF-8 characters. Indices are -zero-based and negative indices wrap around to the end of the string. - -### Example -```example -#"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 - -## Methods -### len() -The length of the string in UTF-8 encoded bytes. - -- returns: integer - -### first() -Extract the first grapheme cluster of the string. -Fails with an error if the string is empty. - -- returns: any - -### last() -Extract the last grapheme cluster of the string. -Fails with an error if the string is empty. - -- returns: any - -### at() -Extract 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. - -- index: integer (positional, required) - The byte index. -- default: any (named) - A default value to return if the index is out of bounds. -- returns: string - -### slice() -Extract a substring of the string. -Fails with an error if the start or end index is out of bounds. - -- start: integer (positional, required) - The start byte index (inclusive). -- end: integer (positional) - The end byte index (exclusive). If omitted, the whole slice until the end of the - string is extracted. -- count: integer (named) - The number of bytes to extract. This is equivalent to passing `start + count` - as the `end` position. Mutually exclusive with `end`. -- returns: string - -### clusters() -Returns the grapheme clusters of the string as an array of substrings. - -- returns: array - -### codepoints() -Returns the Unicode codepoints of the string as an array of substrings. - -- returns: array - -### 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")}`. - -- pattern: string or regex (positional, required) - The pattern to search for. -- returns: boolean - -### starts-with() -Whether the string starts with the specified pattern. - -- pattern: string or regex (positional, required) - The pattern the string might start with. -- returns: boolean - -### ends-with() -Whether the string ends with the specified pattern. - -- pattern: string or regex (positional, required) - The pattern the string might end with. -- returns: boolean - -### find() -Searches for the specified pattern in the string and returns the first match -as a string or `{none}` if there is no match. - -- pattern: string or regex (positional, required) - The pattern to search for. -- returns: string or none - -### 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. - -- pattern: string or regex (positional, required) - The pattern to search for. -- returns: integer or none - -### 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. - -- pattern: string or regex (positional, required) - The pattern to search for. -- returns: dictionary or none - -### 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. - -- pattern: string or regex (positional, required) - The pattern to search for. -- returns: array - -### replace() -Replaces all or a specified number of matches of a pattern with a replacement -string and returns the resulting string. - -- pattern: string or regex (positional, required) - The pattern to search for. -- replacement: string or function (positional, required) - The string to replace the matches with or a function that gets a dictionary for each match and can return individual replacement strings. -- count: integer (named) - If given, only the first `count` matches of the pattern are placed. -- returns: string - -### trim() -Removes matches of a pattern from one or both sides of the string, once or -repeatedly and returns the resulting string. - -- pattern: string or regex (positional, required) - The pattern to search for. -- at: alignment (named) - Can be `start` or `end` to only trim the start or end of the string. - If omitted, both sides are trimmed. -- repeat: boolean (named) - Whether to repeatedly removes matches of the pattern or just once. - Defaults to `{true}`. -- returns: string - -### split() -Splits a string at matches of a specified pattern and returns an array of -the resulting parts. - -- pattern: string or regex (positional) - The pattern to split at. Defaults to whitespace. -- returns: array - -# Content -A piece of document content. - -This type is at the heart of Typst. All markup you write and most -[functions]($type/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 -Type of *Hello!* is -#type([*Hello!*]) -``` - -Content can be added with the `+` operator, -[joined together]($scripting/#blocks) and multiplied with -integers. Wherever content is expected, you can also pass a -[string]($type/string) 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]($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]($styling/#set-rules) to apply them to all -elements within a scope. Optional fields are only available with field access -syntax when they are 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]($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`]($func/repr) function. - -## Methods -### 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. - -- returns: function - -### has() -Whether the content has the specified field. - -- field: string (positional, required) - The field to look for. -- returns: boolean - -### 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. - -- field: string (positional, required) - The field to access. -- default: any (named) - A default value to return if the field does not exist. -- returns: any - -### fields() -Return the fields of this content. - -```example -#rect( - width: 10cm, - height: 10cm, -).fields() -``` - -### location() -The location of the content. This is only available on content returned by -[query]($func/query), for other content it will fail with an error. The -resulting location can be used with [counters]($func/counter), -[state]($func/state) and [queries]($func/query). - -- returns: location - -# 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]($scripting/#loops). -Arrays can be added together with the `+` operator, -[joined together]($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 -```example -#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 ")) -``` - -## Methods -### len() -The number of values in the array. - -- returns: integer - -### first() -Returns the first item in the array. -May be used on the left-hand side of an assignment. -Fails with an error if the array is empty. - -- returns: any - -### last() -Returns the last item in the array. -May be used on the left-hand side of an assignment. -Fails with an error if the array is empty. - -- returns: any - -### 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. - -- index: integer (positional, required) - The index at which to retrieve the item. -- default: any (named) - A default value to return if the index is out of bounds. -- returns: any - -### push() -Add a value to the end of the array. - -- value: any (positional, required) - The value to insert at the end of the array. - -### pop() -Remove the last item from the array and return it. -Fails with an error if the array is empty. - -- returns: any - The removed last value. - -### insert() -Insert a value into the array at the specified index. -Fails with an error if the index is out of bounds. - -- index: integer (positional, required) - The index at which to insert the item. -- value: any (positional, required) - The value to insert into the array. - -### remove() -Remove the value at the specified index from the array and return it. - -- index: integer (positional, required) - The index at which to remove the item. -- returns: any - -### slice() -Extract a subslice of the array. -Fails with an error if the start or index is out of bounds. - -- start: integer (positional, required) - The start index (inclusive). -- end: integer (positional) - The end index (exclusive). If omitted, the whole slice until the end of the - array is extracted. -- count: integer (named) - The number of items to extract. This is equivalent to passing `start + - count` as the `end` position. Mutually exclusive with `end`. -- returns: 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)}`. - -- value: any (positional, required) - The value to search for. -- returns: boolean - -### find() -Searches for an item for which the given function returns `{true}` and -returns the first match or `{none}` if there is no match. - -- searcher: function (positional, required) - The function to apply to each item. Must return a boolean. -- returns: any or none - -### 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. - -- searcher: function (positional, required) - The function to apply to each item. Must return a boolean. -- returns: integer or none - -### filter() -Produces a new array with only the items from the original one for which the -given function returns true. - -- test: function (positional, required) - The function to apply to each item. Must return a boolean. -- returns: array - -### map() -Produces a new array in which all items from the original one were -transformed with the given function. - -- mapper: function (positional, required) - The function to apply to each item. -- returns: 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]($scripting/#bindings) with a let binding or -for loop. - -- returns: array - -### zip() -Zips the array with another array. If the two arrays are of unequal length, it -will only zip up until the last element of the smaller array and the remaining -elements will be ignored. The return value is an array where each element is yet -another array of size 2. - -- other: array (positional, required) - The other array which should be zipped with the current one. -- returns: array - -### fold() -Folds all items into a single value using an accumulator function. - -- init: any (positional, required) - The initial value to start with. -- folder: function (positional, required) - The folding function. Must have two parameters: One for the accumulated value - and one for an item. -- returns: any - -### sum() -Sums all items (works for any types that can be added). - -- default: any (named) - What to return if the array is empty. Must be set if the array can be empty. -- returns: any - -### product() -Calculates the product all items (works for any types that can be multiplied) - -- default: any (named) - What to return if the array is empty. Must be set if the array can be empty. -- returns: any - -### any() -Whether the given function returns `{true}` for any item in the array. - -- test: function (positional, required) - The function to apply to each item. Must return a boolean. -- returns: boolean - -### all() -Whether the given function returns `{true}` for all items in the array. - -- test: function (positional, required) - The function to apply to each item. Must return a boolean. -- returns: boolean - -### flatten() -Combine all nested arrays into a single flat one. - -- returns: array - -### rev() -Return a new array with the same items, but in reverse order. - -- returns: array - -### join() -Combine all items in the array into one. - -- separator: any (positional) - A value to insert between each item of the array. -- last: any (named) - An alternative separator between the last two items -- returns: any - -### sorted() -Return a new array with the same items, but sorted. - -- key: function (named) - If given, applies this function to the elements in the array to determine the keys to sort by. -- returns: array - -# 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, 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]($scripting/#fields) (`.key`) to access -the value. Dictionaries can be added with the `+` operator and -[joined together]($scripting/#blocks). -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]($scripting/#loops). This will iterate in the order the pairs were -inserted / declared. - -## Example -```example -#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) -``` - -## Methods -### len() -The number of pairs in the dictionary. - -- returns: integer - -### 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. - -- key: string (positional, required) - The key at which to retrieve the item. -- default: any (named) - A default value to return if the key is not part of the dictionary. -- returns: any - -### insert() -Insert a new pair into the dictionary and return the value. -If the dictionary already contains this key, the value is updated. - -- key: string (positional, required) - The key of the pair that should be inserted. -- value: any (positional, required) - The value of the pair that should be inserted. - -### keys() -Returns the keys of the dictionary as an array in insertion order. - -- returns: array - -### values() -Returns the values of the dictionary as an array in insertion order. - -- returns: array - -### pairs() -Returns the keys and values of the dictionary as an array of pairs. Each pair is -represented as an array of length two. - -- returns: array - -### remove() -Remove a pair from the dictionary by key and return the value. - -- key: string (positional, required) - The key of the pair that should be removed. -- returns: any - -# 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 blocks 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 later are written as -`name: value`. - -Within math mode, function calls have special behaviour. See the -[math documentation]($category/math) for more details. - -### Example -```example -// 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]($styling/#set-rules) and -[show]($styling/#show-rules) rules to learn about additional ways -you can work with functions in Typst. - -### Element functions { #element-functions } -Some functions are associated with _elements_ like [headings]($func/heading) or -[tables]($func/table). When called, these create an element of their respective -kind. In contrast to normal functions, they can further be used in -[set rules]($styling/#set-rules), [show rules]($styling/#show-rules), and -[selectors]($type/selector). - -### Function scopes { #function-scopes } -Functions can hold related definitions in their own scope, similar to a -[module]($scripting/#modules). Examples of this are -[`assert.eq`]($func/assert.eq) or [`list.item`]($func/list.item). However, this -feature is currently only available for built-in functions. - -### Defining functions { #definitions } -You can define your own function with a -[let binding]($scripting/#bindings) that has a parameter list after -the binding's name. The parameter list can contain positional parameters, -named parameters with default values and -[argument sinks]($type/arguments). -The right-hand side of the binding can be a block or any other expression. It -defines the function's return value and can depend on the parameters. - -```example -#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 -] -``` - -### Unnamed functions { #unnamed } -You can also created 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`]($func/page.footer) property. - -```example -#show "once?": it => [#it #it] -once? -``` - -### Notable fact -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)`]($type/array.push). These can modify the values they are -called on. - -## Methods -### with() -Returns a new function that has the given arguments pre-applied. - -- arguments: any (variadic) - The named and positional arguments to apply. -- returns: function - -### where() -Returns a selector that filters for elements belonging to this function -whose fields have the values of the given arguments. - -- fields: any (named, variadic) - The field values to filter by. -- returns: selector - -# Arguments -Captured arguments to a function. - -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 and is iterable -with a [for loop]($scripting/#loops). Inversely, you can spread -arguments, arrays and dictionaries into a function call with the spread operator: -`{func(..args)}`. - -## Example -```example -#let format(title, ..authors) = [ - *#title* \ - _Written by #(authors - .pos() - .join(", ", last: " and "));._ -] - -#format("ArtosFlow", "Jane", "Joe") -``` - -## Methods -### pos() -Returns the captured positional arguments as an array. - -- returns: array - -### named() -Returns the captured named arguments as a dictionary. - -- returns: dictionary - -# Selector -A filter for selecting elements within the document. - -You can construct a selector in the following ways: -- you can use an element [function]($type/function) -- you can filter for an element function with - [specific fields]($type/function.where) -- you can use a [string]($type/string) or [regular expression]($func/regex) -- you can use a [`{<label>}`]($func/label) -- you can use a [`location`]($func/locate) -- call the [`selector`]($func/selector) function to convert any of the above - types into a selector value and use the methods below to refine it - -Selectors are used to [apply styling rules]($styling/#show-rules) to elements. -You can also use selectors to [query]($func/query) the document for certain -types of elements. - -Furthermore, you can pass a selector to several of Typst's built-in functions to -configure their behaviour. One such example is the [outline]($func/outline) -where it can be used to change which elements are listed within the outline. - -Multiple selectors can be combined using the methods shown below. However, not -all kinds of selectors are supported in all places, at the moment. - -## Example -```example -#locate(loc => query( - heading.where(level: 1) - .or(heading.where(level: 2)), - loc, -)) - -= This will be found -== So will this -=== But this will not. -``` - -## Methods -### or() -Allows combining any of a series of selectors. This is used to -select multiple components or components with different properties -all at once. - -- other: selector (variadic, required) - The list of selectors to match on. - -### and() -Allows combining all of a series of selectors. This is used to check -whether a component meets multiple selection rules simultaneously. - -- other: selector (variadic, required) - The list of selectors to match on. - -### before() -Returns a modified selector that will only match elements that occur before the -first match of the selector argument. - -- end: selector (positional, required) - The original selection will end at the first match of `end`. -- inclusive: boolean (named) - Whether `end` itself should match or not. This is only relevant if both - selectors match the same type of element. Defaults to `{true}`. - -### after() -Returns a modified selector that will only match elements that occur after the -first match of the selector argument. - -- start: selector (positional, required) - The original selection will start at the first match of `start`. -- inclusive: boolean (named) - Whether `start` itself should match or not. This is only relevant if both - selectors match the same type of element. Defaults to `{true}`. - -# Module -An evaluated module, either built-in or resulting from a file. - -You can access definitions from the module using -[field access notation]($scripting/#fields) and interact with it using the -[import and include syntaxes]($scripting/#modules). - -## Example -```example -<<< #import "utils.typ" -<<< #utils.add(2, 5) - -<<< #import utils: sub -<<< #sub(1, 4) ->>> #7 ->>> ->>> #(-3) -``` diff --git a/docs/src/reference/welcome.md b/docs/src/reference/welcome.md deleted file mode 100644 index fc526f52..00000000 --- a/docs/src/reference/welcome.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -description: | - The Typst reference is a systematic and comprehensive guide to the Typst - typesetting language. ---- - -# 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]($tutorial) and then coming back to -the reference to learn more about Typst's features as you need them. - -## Language { #language } -The reference starts with a language part that gives an overview over [Typst's -syntax]($syntax) and contains information about concepts involved in -[styling documents,]($styling) using -[Typst's scripting capabilities,]($scripting) and a detailed documentation of -all [data types]($types) in Typst. - -## Functions { #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. diff --git a/docs/src/tutorial/1-writing.md b/docs/src/tutorial/1-writing.md deleted file mode 100644 index a2a2ca65..00000000 --- a/docs/src/tutorial/1-writing.md +++ /dev/null @@ -1,308 +0,0 @@ ---- -description: Typst's tutorial. ---- - -# 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. - - - -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. - -```example -In this report, we will explore the -various factors that influence fluid -dynamics in glaciers and how they -contribute to the formation and -behavior 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_]`. - -```example -= Introduction -In this report, we will explore the -various factors that influence _fluid -dynamics_ in glaciers and how they -contribute to the formation and -behavior 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. - -```example -+ 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. - -```example -+ The climate - - Temperature - - Precipitation -+ The topography -+ The geology -``` - -## Adding a figure { #figure } -You think that your report would benefit from a figure. Let's add one. Typst -supports images in the formats PNG, JPEG, GIF, and SVG. 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. - - - -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`]($func/image) function. - -```example -#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]($type/string), 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. - -```example -#image("glacier.jpg", width: 70%) -``` - -The `width` argument is a [relative length]($type/relative-length). 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]($func/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 can now remove the hashtag before the image function call. -The hashtag 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._ - -```example -#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. - -```example -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> -``` - -<div class="info-box"> - -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. -On the contrary, strings work wherever content is expected because text is a -valid kind of content. -</div> - -## Adding a bibliography { #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`]($func/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]($func/bibliography.style) for more details. - -```example -= Methods -We follow the glacier melting models -established in @glacier-melt. - -#bibliography("works.bib") -``` - -## Maths { #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: - -```example -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: - -```example -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: - -```example -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: - -```example -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. - -```example -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`]($func/math.vec) function. Within math mode, -function calls don't need to start with the `#` character. - -```example -$ v := vec(x_1, x_2, x_3) $ -``` - -Some functions are only available within math mode. For example, the -[`cal`]($func/math.cal) function is used to typeset calligraphic letters -commonly used for sets. The [math section of the reference]($category/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: - -```example -$ 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]($category/symbols/sym) -for a list of all available symbols. - -## Review { #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]($func/table), [shapes]($category/visualize), and -[code blocks]($func/raw). You can peruse the [reference]($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. diff --git a/docs/src/tutorial/2-formatting.md b/docs/src/tutorial/2-formatting.md deleted file mode 100644 index c231b878..00000000 --- a/docs/src/tutorial/2-formatting.md +++ /dev/null @@ -1,283 +0,0 @@ ---- -description: Typst's tutorial. ---- - -# 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 { #set-rules } -As we have seen in the previous chapter, Typst has functions that _insert_ -content (e.g. the [`image`]($func/image) function) and others that _manipulate_ -content that they received as arguments (e.g. the [`align`]($func/align) -function). The first impulse you might have when you want, for example, to -justify the report, could be to look for a function that does that and wrap the -complete document in it. - -```example -#par(justify: true)[ - = Background - In the case of glaciers, fluid - dynamics principles can be used - to understand how the movement - and behavior 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. The [`par`]($func/par) function justifies all -paragraphs 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. - -```example -#set par(justify: true) - -= Background -In the case of glaciers, fluid -dynamics principles can be used -to understand how the movement -and behavior of the ice is -influenced by factors such as -temperature, pressure, and the -presence of other fluids (such as -water). -``` - -<div class="info-box"> - -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. -</div> - -## The autocomplete panel { #autocomplete } -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 -<kbd>Ctrl</kbd> + <kbd>Space</kbd>. Use the autocomplete panel to discover the -right arguments for functions. Most suggestions come with a small description of -what they do. - - - -## Set up the page { #page-setup } -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`]($func/text) to set font family, size, color, and other properties of - text -- [`page`]($func/page) to set the page size, margins, headers, enable columns, - and footers -- [`par`]($func/par) to justify paragraphs, set line spacing, and more -- [`heading`]($func/heading) to set the appearance of headings and enable - numbering -- [`document`]($func/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. - -```example -#set text( - font: "New Computer Modern", - size: 10pt -) -#set page( - paper: "a6", - margin: (x: 1.8cm, y: 1.5cm), -) -#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 -behavior of these natural structures. - ->>> Glacier displacement is influenced ->>> by a number of factors, including ->>> + The climate ->>> + The topography ->>> + The geology ->>> ->>> This report will present a physical ->>> model of glacier displacement and ->>> dynamics, and will explore the ->>> influence of these factors on the ->>> movement of large bodies of ice. -<<< ... - -#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`]($func/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,]($func/page.paper) but you can also specify a custom -page size. The margins are specified as a [dictionary.]($type/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`]($func/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]($type/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 { #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`]($func/heading) function. - -```example ->>> #set text(font: "New Computer Modern") -#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]($func/numbering) for our headings: - -```example ->>> #set text(font: "New Computer Modern") -#set heading(numbering: "1.a") - -= Introduction -#lorem(10) - -== Background -#lorem(12) - -== Methods -#lorem(15) -``` - -This example also uses the [`lorem`]($func/lorem) function to generate some -placeholder text. This function takes a number as an argument and generates that -many words of _Lorem Ipsum_ text. - -<div class="info-box"> - -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. -</div> - -## Show rules { #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]($type/function/#definitions) 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. - -```example -#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]($scripting). - -## Review { #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. diff --git a/docs/src/tutorial/3-advanced.md b/docs/src/tutorial/3-advanced.md deleted file mode 100644 index 42a810fd..00000000 --- a/docs/src/tutorial/3-advanced.md +++ /dev/null @@ -1,509 +0,0 @@ ---- -description: Typst's tutorial. ---- - -# 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 four-circles -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. - - - -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 others with preview access and try teams with them! - -## The conference guidelines { #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 left 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 { #set-rules } -Let's start by writing some set rules for the document. - -```example -#set page( ->>> margin: auto, - paper: "us-letter", - header: align(right)[ - A fluid dynamic model for - glacier flow - ], - numbering: "1", -) -#set par(justify: true) -#set text( - font: "Linux Libertine", - 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 Linux Libertine. 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]($func/numbering) that defines how to number the pages. By -setting into 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 { #title-and-abstract } -Now, let's add a title and an abstract. We'll start with the title. We center -align it and increase its font weight by enclosing it in `[*stars*]`. - -```example ->>> #set page(width: 300pt, margin: 30pt) ->>> #set text(font: "Linux Libertine", 11pt) -#align(center, text(17pt)[ - *A fluid dynamic model - for glacier flow* -]) -``` - -This looks right. We used the `text` function to override the previous text -set rule locally, increasing the size to 17pt for the function's argument. 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. - -```example ->>> #set page(width: 300pt, margin: 30pt) ->>> #set text(font: "Linux Libertine", 11pt) ->>> ->>> #align(center, text(17pt)[ ->>> *A fluid dynamic model ->>> for glacier flow* ->>> ]) -#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`]($func/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]($type/relative-length) -or [fractions]($type/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. - -Now, let's add the abstract. Remember that the conference wants the abstract to -be set ragged and centered. - -```example:0,0,612,317.5 ->>> #set text(font: "Linux Libertine", 11pt) ->>> #set par(justify: true) ->>> #set page( ->>> "us-letter", ->>> margin: auto, ->>> header: align(right + horizon)[ ->>> A fluid dynamic model for ->>> glacier flow ->>> ], ->>> numbering: "1", ->>> ) ->>> ->>> #align(center, text(17pt)[ ->>> *A fluid dynamic model ->>> for glacier flow* ->>> ]) ->>> ->>> #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") ->>> ] ->>> ) ->>> -<<< ... - -#align(center)[ - #set par(justify: false) - *Abstract* \ - #lorem(80) -] ->>> #lorem(600) -``` - -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 save the paper title in a variable, so that we do not -have to type it twice, for header and title. We can do that with the `{let}` -keyword: - -```example:single -#let title = [ - A fluid dynamic model - for glacier flow -] - -<<< ... - ->>> #set text(font: "Linux Libertine", 11pt) ->>> #set par(justify: true) -#set page( ->>> "us-letter", ->>> margin: auto, - header: align( - right + horizon, - title - ), -<<< ... ->>> numbering: "1", -) - -#align(center, text(17pt)[ - *#title* -]) - -<<< ... - ->>> #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") ->>> ] ->>> ) ->>> ->>> #align(center)[ ->>> #set par(justify: false) ->>> *Abstract* \ ->>> #lorem(80) ->>> ] ->>> ->>> #lorem(600) -``` - -After we bound the content to the `title` variable, we can use it in functions -and also within markup (prefixed by `#`, like functions). This way, if we decide -on another title, we can easily change it in one place. - -## Adding columns and headings { #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. The -[`columns`]($func/columns) function takes a number and content, and layouts the -content into the specified number of columns. Since we want everything after the -abstract to be in two columns, we need to apply the column function to our whole -document. - -Instead of wrapping the whole document in a giant function call, we can use an -"everything" show rule. To write such a show rule, put a colon directly behind -the show keyword and then provide a function. This function is given the rest of -the document as a parameter. We have called the parameter `rest` here, but you -are free to choose any name. The function can then do anything with this -content. In our case, it passes it on to the `columns` function. - -```example:single ->>> #let title = [ ->>> A fluid dynamic model ->>> for glacier flow ->>> ] ->>> ->>> #set text(font: "Linux Libertine", 11pt) ->>> #set par(justify: true) ->>> #set page( ->>> "us-letter", ->>> margin: auto, ->>> header: align( ->>> right + horizon, ->>> title ->>> ), ->>> numbering: "1", ->>> ) ->>> ->>> #align(center, text( ->>> 17pt, ->>> weight: "bold", ->>> title, ->>> )) ->>> ->>> #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") ->>> ] ->>> ) ->>> ->>> #align(center)[ ->>> #set par(justify: false) ->>> *Abstract* \ ->>> #lorem(80) ->>> ] ->>> #v(4mm) -<<< ... - -#show: rest => columns(2, rest) - -= Introduction -#lorem(300) - -= Related Work -#lorem(200) -``` - -Now there is only one thing left to do: Style our headings. We need to make them -centered and use small capitals. Because the `heading` function does not offer -a way to set any of that, we need to write our own heading show rule. - -```example:50,250,265,270 ->>> #let title = [ ->>> A fluid dynamic model ->>> for glacier flow ->>> ] ->>> ->>> #set text(font: "Linux Libertine", 11pt) ->>> #set par(justify: true) ->>> #set page( ->>> "us-letter", ->>> margin: auto, ->>> header: align( ->>> right + horizon, ->>> title ->>> ), ->>> numbering: "1", ->>> ) -#show heading: it => [ - #set align(center) - #set text(12pt, weight: "regular") - #block(smallcaps(it.body)) -] - -<<< ... ->>> ->>> #align(center, text( ->>> 17pt, ->>> weight: "bold", ->>> title, ->>> )) ->>> ->>> #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") ->>> ] ->>> ) ->>> ->>> #align(center)[ ->>> #set par(justify: false) ->>> *Abstract* \ ->>> #lorem(80) ->>> ] ->>> ->>> #v(4mm) ->>> #show: rest => columns(2, rest) ->>> ->>> = Introduction ->>> #lorem(35) ->>> ->>> == Motivation ->>> #lorem(45) -``` - -This looks great! We used a show rule that applies to all headings. We give it a -function that gets passed the heading as a parameter. That parameter can be used -as content but it also has some fields like `title`, `numbers`, and `level` from -which we can compose a custom look. Here, we are center-aligning, setting the -font weight to `{"regular"}` because headings are bold by default, and use the -[`smallcaps`]($func/smallcaps) function to render the heading's title in small capitals. - -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 set rule: This is a -[method]($scripting/#methods) we can call on headings (and other -elements) that allows us to filter them by their level. We can use it to -differentiate between section and subsection headings: - -```example:50,250,265,245 ->>> #let title = [ ->>> A fluid dynamic model ->>> for glacier flow ->>> ] ->>> ->>> #set text(font: "Linux Libertine", 11pt) ->>> #set par(justify: true) ->>> #set page( ->>> "us-letter", ->>> margin: auto, ->>> header: align( ->>> right + horizon, ->>> title ->>> ), ->>> numbering: "1", ->>> ) ->>> -#show heading.where( - level: 1 -): it => block(width: 100%)[ - #set align(center) - #set text(12pt, weight: "regular") - #smallcaps(it.body) -] - -#show heading.where( - level: 2 -): it => text( - size: 11pt, - weight: "regular", - style: "italic", - it.body + [.], -) ->>> ->>> #align(center, text( ->>> 17pt, ->>> weight: "bold", ->>> title, ->>> )) ->>> ->>> #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") ->>> ] ->>> ) ->>> ->>> #align(center)[ ->>> #set par(justify: false) ->>> *Abstract* \ ->>> #lorem(80) ->>> ] ->>> ->>> #v(4mm) ->>> #show: rest => columns(2, rest) ->>> ->>> = Introduction ->>> #lorem(35) ->>> ->>> == Motivation ->>> #lorem(45) -``` - -This looks great! We wrote two show rules that each 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 left 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="3-advanced-paper.png" - alt="The finished paper" - style="box-shadow: 0 4px 12px rgb(89 85 101 / 20%); width: 500px; max-width: 100%; display: block; margin: 24px auto;" -> - -## Review { #review } -You have now learned how to create headers and footers, how to use functions and -scopes to locally override styles, how to create more complex layouts with the [`grid`]($func/grid) function and how to write show rules for individual functions, and the whole document. You also learned how to use the -[`where` selector]($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. diff --git a/docs/src/tutorial/4-template.md b/docs/src/tutorial/4-template.md deleted file mode 100644 index 320f82b2..00000000 --- a/docs/src/tutorial/4-template.md +++ /dev/null @@ -1,380 +0,0 @@ ---- -description: Typst's tutorial. ---- - -# 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! - -## A toy template { #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? - -```example -#let amazed(term) = box[✨ #term ✨] - -You are #amazed[beautiful]! -``` - -This function takes a single argument, `term`, and returns a content block with -the `term` surrounded by sparkles. We also put the whole thing in a box so that -the term we are amazed by cannot be separated from its sparkles by a line break. - -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. - -```example -#let amazed(term, color: blue) = { - text(color, box[✨ #term ✨]) -} - -You are #amazed[beautiful]! -I am #amazed(color: purple)[amazed]! -``` - -Templates now work by using an "everything" show rule that applies the custom -function to our whole document. Let's do that with our `amazed` function. - -```example ->>> #let amazed(term, color: blue) = { ->>> text(color, box[✨ #term ✨]) ->>> } -#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. 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 { #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. - -```example -#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. - -```example -#let conf(title, doc) = { - set page( - paper: "us-letter", ->>> margin: auto, - header: align( - right + horizon, - title - ), -<<< ... - ) - set par(justify: true) - set text( - font: "Linux Libertine", - size: 11pt, - ) - - // Heading show rules. -<<< ... ->>> show heading.where( ->>> level: 1 ->>> ): it => block( ->>> align(center, ->>> text( ->>> 13pt, ->>> weight: "regular", ->>> smallcaps(it.body), ->>> ) ->>> ), ->>> ) ->>> show heading.where( ->>> level: 2 ->>> ): it => box( ->>> text( ->>> 11pt, ->>> weight: "regular", ->>> style: "italic", ->>> it.body + [.], ->>> ) ->>> ) - - columns(2, doc) -} - -#show: doc => conf( - [Paper title], - doc, -) - -= Introduction -#lorem(90) - -<<< ... ->>> == Motivation ->>> #lorem(140) ->>> ->>> == Problem Statement ->>> #lorem(50) ->>> ->>> = Related Work ->>> #lorem(200) -``` - -We copy-pasted most of that code from the previous chapter. The only two -differences are that we wrapped everything in the function `conf` and are -calling the columns function directly on the `doc` argument as it already -contains the content of the document. 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 into it 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. -Thus, we must specify it in the show rule where we call the template. - -## Templates with named arguments { #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: - -```typ -#show: doc => conf( - 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), - 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]($type/array) of -[dictionaries]($type/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()`]($type/array.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]($scripting/#fields). - -We still have to provide an argument to the grid for each author: Here is where -the array's [`map` method]($type/array.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]($type/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: - -```typ -#let conf( - title: none, - authors: (), - abstract: [], - doc, -) = { - // Set and show rules from before. -<<< ... - - set align(center) - text(17pt, 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 - ] - - set align(left) - columns(2, doc) -} -``` - -## A separate file { #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. - -```example:single ->>> #let conf( ->>> title: none, ->>> authors: (), ->>> abstract: [], ->>> doc, ->>> ) = { ->>> set text(font: "Linux Libertine", 11pt) ->>> set par(justify: true) ->>> set page( ->>> "us-letter", ->>> margin: auto, ->>> header: align( ->>> right + horizon, ->>> title ->>> ), ->>> numbering: "1", ->>> ) ->>> ->>> show heading.where( ->>> level: 1 ->>> ): it => block( ->>> align(center, ->>> text( ->>> 13pt, ->>> weight: "regular", ->>> smallcaps(it.body), ->>> ) ->>> ), ->>> ) ->>> show heading.where( ->>> level: 2 ->>> ): it => box( ->>> text( ->>> 11pt, ->>> weight: "regular", ->>> style: "italic", ->>> it.body + [.], ->>> ) ->>> ) ->>> ->>> set align(center) ->>> text(17pt, title) ->>> ->>> let count = calc.min(authors.len(), 3) ->>> grid( ->>> columns: (1fr,) * count, ->>> row-gutter: 24pt, ->>> ..authors.map(author => [ ->>> #author.name \ ->>> #author.affiliation \ ->>> #link("mailto:" + author.email) ->>> ]), ->>> ) ->>> ->>> par(justify: false)[ ->>> *Abstract* \ ->>> #abstract ->>> ] ->>> ->>> set align(left) ->>> columns(2, doc) ->>>} -<<< #import "conf.typ": conf -#show: doc => conf( - 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), - doc, -) - -= 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 on -[Typst's Discord server](https://discord.gg/2uDybryKPe) so that others can use -it too? - -## Review { #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 on -[Typst's Discord server](https://discord.gg/2uDybryKPe), on our -[contact form](https://typst.app/contact), or on -[social media.](https://twitter.com/typstapp) - -So what are you waiting for? [Sign up](https://typst.app) and write something! diff --git a/docs/src/tutorial/welcome.md b/docs/src/tutorial/welcome.md deleted file mode 100644 index 530336cb..00000000 --- a/docs/src/tutorial/welcome.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -description: Typst's tutorial. ---- - -# 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 { #when-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 { #learnings } -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:]($tutorial/writing-in-typst) Learn how to write text and - insert images, equations, and other elements. -2. [Formatting:]($tutorial/formatting) Learn how to adjust the formatting - of your document, including font size, heading styles, and more. -3. [Advanced Styling:]($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:]($tutorial/making-a-template) Build a reusable template - from the paper you created in the previous chapter. - -We hope you'll enjoy Typst! |
