Docs generation for types

This commit is contained in:
Laurenz 2023-09-11 15:53:20 +02:00
parent 305524d005
commit 3a979e88da
26 changed files with 1506 additions and 3000 deletions

1
Cargo.lock generated
View File

@ -2962,6 +2962,7 @@ name = "typst-docs"
version = "0.7.0" version = "0.7.0"
dependencies = [ dependencies = [
"comemo", "comemo",
"ecow",
"heck", "heck",
"include_dir", "include_dir",
"once_cell", "once_cell",

View File

@ -14,6 +14,7 @@ bench = false
typst = { path = "../typst" } typst = { path = "../typst" }
typst-library = { path = "../typst-library" } typst-library = { path = "../typst-library" }
comemo = "0.3" comemo = "0.3"
ecow = { version = "0.1.2", features = ["serde"] }
heck = "0.4" heck = "0.4"
include_dir = "0.7" include_dir = "0.7"
once_cell = "1" once_cell = "1"

View File

@ -1,17 +1,22 @@
use std::fmt::{self, Debug, Formatter};
use std::ops::Range; use std::ops::Range;
use comemo::Prehashed; use comemo::Prehashed;
use ecow::EcoString;
use heck::{ToKebabCase, ToTitleCase};
use pulldown_cmark as md; use pulldown_cmark as md;
use serde::{Deserialize, Serialize};
use typed_arena::Arena; use typed_arena::Arena;
use typst::diag::FileResult; use typst::diag::{FileResult, StrResult};
use typst::eval::{Bytes, Datetime, Tracer}; use typst::eval::{Bytes, Datetime, Library, Tracer};
use typst::font::{Font, FontBook}; use typst::font::{Font, FontBook};
use typst::geom::{Point, Size}; use typst::geom::{Abs, Point, Size};
use typst::syntax::{FileId, Source, VirtualPath}; use typst::syntax::{FileId, Source, VirtualPath};
use typst::World; use typst::World;
use unscanny::Scanner;
use yaml_front_matter::YamlFrontMatter; use yaml_front_matter::YamlFrontMatter;
use super::*; use super::{contributors, OutlineItem, Resolver, FILE_DIR, FONTS, LIBRARY};
/// HTML documentation. /// HTML documentation.
#[derive(Serialize)] #[derive(Serialize)]
@ -21,7 +26,7 @@ pub struct Html {
#[serde(skip)] #[serde(skip)]
md: String, md: String,
#[serde(skip)] #[serde(skip)]
description: Option<String>, description: Option<EcoString>,
#[serde(skip)] #[serde(skip)]
outline: Vec<OutlineItem>, outline: Vec<OutlineItem>,
} }
@ -39,18 +44,7 @@ impl Html {
/// Convert markdown to HTML. /// Convert markdown to HTML.
#[track_caller] #[track_caller]
pub fn markdown(resolver: &dyn Resolver, md: &str) -> Self { pub fn markdown(resolver: &dyn Resolver, md: &str, nesting: Option<usize>) -> 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 text = md;
let mut description = None; let mut description = None;
let document = YamlFrontMatter::parse::<Metadata>(md); let document = YamlFrontMatter::parse::<Metadata>(md);
@ -62,9 +56,18 @@ impl Html {
let options = md::Options::ENABLE_TABLES | md::Options::ENABLE_HEADING_ATTRIBUTES; let options = md::Options::ENABLE_TABLES | md::Options::ENABLE_HEADING_ATTRIBUTES;
let ids = Arena::new(); let ids = Arena::new();
let mut handler = Handler::new(resolver, id_base.into(), &ids); let mut handler = Handler::new(text, resolver, nesting, &ids);
let iter = md::Parser::new_ext(text, options) let mut events = md::Parser::new_ext(text, options).peekable();
.filter_map(|mut event| handler.handle(&mut event).then_some(event)); let iter = std::iter::from_fn(|| loop {
let mut event = events.next()?;
handler.peeked = events.peek().and_then(|event| match event {
md::Event::Text(text) => Some(text.clone()),
_ => None,
});
if handler.handle(&mut event) {
return Some(event);
}
});
let mut raw = String::new(); let mut raw = String::new();
md::html::push_html(&mut raw, iter); md::html::push_html(&mut raw, iter);
@ -93,7 +96,11 @@ impl Html {
/// Returns `None` if the HTML doesn't start with an `h1` tag. /// Returns `None` if the HTML doesn't start with an `h1` tag.
pub fn title(&self) -> Option<&str> { pub fn title(&self) -> Option<&str> {
let mut s = Scanner::new(&self.raw); let mut s = Scanner::new(&self.raw);
s.eat_if("<h1>").then(|| s.eat_until("</h1>")) s.eat_if("<h1").then(|| {
s.eat_until('>');
s.eat_if('>');
s.eat_until("</h1>")
})
} }
/// The outline of the HTML. /// The outline of the HTML.
@ -102,7 +109,7 @@ impl Html {
} }
/// The description from the front matter. /// The description from the front matter.
pub fn description(&self) -> Option<String> { pub fn description(&self) -> Option<EcoString> {
self.description.clone() self.description.clone()
} }
} }
@ -116,26 +123,35 @@ impl Debug for Html {
/// Front matter metadata. /// Front matter metadata.
#[derive(Deserialize)] #[derive(Deserialize)]
struct Metadata { struct Metadata {
description: String, description: EcoString,
} }
struct Handler<'a> { struct Handler<'a> {
text: &'a str,
resolver: &'a dyn Resolver, resolver: &'a dyn Resolver,
lang: Option<String>, peeked: Option<md::CowStr<'a>>,
code: String, lang: Option<EcoString>,
code: EcoString,
outline: Vec<OutlineItem>, outline: Vec<OutlineItem>,
id_base: String, nesting: Option<usize>,
ids: &'a Arena<String>, ids: &'a Arena<String>,
} }
impl<'a> Handler<'a> { impl<'a> Handler<'a> {
fn new(resolver: &'a dyn Resolver, id_base: String, ids: &'a Arena<String>) -> Self { fn new(
text: &'a str,
resolver: &'a dyn Resolver,
nesting: Option<usize>,
ids: &'a Arena<String>,
) -> Self {
Self { Self {
text,
resolver, resolver,
peeked: None,
lang: None, lang: None,
code: String::new(), code: EcoString::new(),
outline: vec![], outline: vec![],
id_base, nesting,
ids, ids,
} }
} }
@ -157,15 +173,13 @@ impl<'a> Handler<'a> {
} }
// Register HTML headings for the outline. // Register HTML headings for the outline.
md::Event::Start(md::Tag::Heading(level, Some(id), _)) => { md::Event::Start(md::Tag::Heading(level, id, _)) => {
self.handle_heading(id, level); self.handle_heading(id, level);
} }
// Also handle heading closings. // Also handle heading closings.
md::Event::End(md::Tag::Heading(level, Some(_), _)) => { md::Event::End(md::Tag::Heading(level, _, _)) => {
if *level > md::HeadingLevel::H1 && !self.id_base.is_empty() { nest_heading(level, self.nesting());
nest_heading(level);
}
} }
// Rewrite contributor sections. // Rewrite contributor sections.
@ -185,10 +199,10 @@ impl<'a> Handler<'a> {
"unsupported link type: {ty:?}", "unsupported link type: {ty:?}",
); );
*dest = self *dest = match self.handle_link(dest) {
.handle_link(dest) Ok(link) => link.into(),
.unwrap_or_else(|| panic!("invalid link: {dest}")) Err(err) => panic!("invalid link: {dest} ({err})"),
.into(); };
} }
// Inline raw. // Inline raw.
@ -208,7 +222,7 @@ impl<'a> Handler<'a> {
// Code blocks. // Code blocks.
md::Event::Start(md::Tag::CodeBlock(md::CodeBlockKind::Fenced(lang))) => { md::Event::Start(md::Tag::CodeBlock(md::CodeBlockKind::Fenced(lang))) => {
self.lang = Some(lang.as_ref().into()); self.lang = Some(lang.as_ref().into());
self.code = String::new(); self.code = EcoString::new();
return false; return false;
} }
md::Event::End(md::Tag::CodeBlock(md::CodeBlockKind::Fenced(_))) => { md::Event::End(md::Tag::CodeBlock(md::CodeBlockKind::Fenced(_))) => {
@ -232,7 +246,7 @@ impl<'a> Handler<'a> {
} }
fn handle_image(&self, link: &str) -> String { fn handle_image(&self, link: &str) -> String {
if let Some(file) = FILES.get_file(link) { if let Some(file) = FILE_DIR.get_file(link) {
self.resolver.image(link, file.contents()) self.resolver.image(link, file.contents())
} else if let Some(url) = self.resolver.link(link) { } else if let Some(url) = self.resolver.link(link) {
url url
@ -241,16 +255,35 @@ impl<'a> Handler<'a> {
} }
} }
fn handle_heading(&mut self, id: &mut &'a str, level: &mut md::HeadingLevel) { fn handle_heading(
&mut self,
id_slot: &mut Option<&'a str>,
level: &mut md::HeadingLevel,
) {
nest_heading(level, self.nesting());
if *level == md::HeadingLevel::H1 { if *level == md::HeadingLevel::H1 {
return; return;
} }
let default = self.peeked.as_ref().map(|text| text.to_kebab_case());
let id: &'a str = match (&id_slot, default) {
(Some(id), default) => {
if Some(*id) == default.as_deref() {
eprintln!("heading id #{id} was specified unnecessarily");
}
id
}
(None, Some(default)) => self.ids.alloc(default).as_str(),
(None, None) => panic!("missing heading id {}", self.text),
};
*id_slot = (!id.is_empty()).then_some(id);
// Special case for things like "v0.3.0". // Special case for things like "v0.3.0".
let name = if id.starts_with('v') && id.contains('.') { let name = if id.starts_with('v') && id.contains('.') {
id.to_string() id.into()
} else { } else {
id.to_title_case() id.to_title_case().into()
}; };
let mut children = &mut self.outline; let mut children = &mut self.outline;
@ -262,106 +295,22 @@ impl<'a> Handler<'a> {
depth -= 1; depth -= 1;
} }
// Put base before id. children.push(OutlineItem { id: id.into(), name, children: vec![] });
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> { fn handle_link(&self, link: &str) -> StrResult<String> {
if link.starts_with('#') || link.starts_with("http") { if let Some(link) = self.resolver.link(link) {
return Some(link.into()); return Ok(link);
} }
if !link.starts_with('$') { crate::link::resolve(link)
return self.resolver.link(link); }
fn nesting(&self) -> usize {
match self.nesting {
Some(nesting) => nesting,
None => panic!("headings are not allowed here:\n{}", self.text),
} }
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)
} }
} }
@ -466,15 +415,10 @@ fn html_attr_range(html: &str, attr: &str) -> Option<Range<usize>> {
} }
/// Increase the nesting level of a Markdown heading. /// Increase the nesting level of a Markdown heading.
fn nest_heading(level: &mut md::HeadingLevel) { fn nest_heading(level: &mut md::HeadingLevel, nesting: usize) {
*level = match &level { *level = ((*level as usize) + nesting)
md::HeadingLevel::H1 => md::HeadingLevel::H2, .try_into()
md::HeadingLevel::H2 => md::HeadingLevel::H3, .unwrap_or(md::HeadingLevel::H6);
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. /// A world for example compilations.
@ -499,7 +443,7 @@ impl World for DocWorld {
fn file(&self, id: FileId) -> FileResult<Bytes> { fn file(&self, id: FileId) -> FileResult<Bytes> {
assert!(id.package().is_none()); assert!(id.package().is_none());
Ok(FILES Ok(FILE_DIR
.get_file(id.vpath().as_rootless_path()) .get_file(id.vpath().as_rootless_path())
.unwrap_or_else(|| panic!("failed to load {:?}", id.vpath())) .unwrap_or_else(|| panic!("failed to load {:?}", id.vpath()))
.contents() .contents()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,102 @@
use typst::diag::{bail, StrResult};
use typst::eval::Func;
use super::{get_module, GROUPS, LIBRARY};
/// Resolve an intra-doc link.
pub fn resolve(link: &str) -> StrResult<String> {
if link.starts_with('#') || link.starts_with("http") {
return Ok(link.to_string());
}
let (head, tail) = split_link(link)?;
let mut route = match resolve_known(head) {
Some(route) => route.into(),
None => resolve_definition(head)?,
};
if !tail.is_empty() {
route.push('/');
route.push_str(tail);
}
if !route.contains('#') && !route.ends_with('/') {
route.push('/');
}
Ok(route)
}
/// Split a link at the first slash.
fn split_link(link: &str) -> StrResult<(&str, &str)> {
let first = link.split('/').next().unwrap_or(link);
let rest = link[first.len()..].trim_start_matches('/');
Ok((first, rest))
}
/// Resolve a `$` link head to a known destination.
fn resolve_known(head: &str) -> Option<&'static str> {
Some(match head {
"$tutorial" => "/docs/tutorial/",
"$reference" => "/docs/reference/",
"$category" => "/docs/reference/",
"$syntax" => "/docs/reference/syntax/",
"$styling" => "/docs/reference/styling/",
"$scripting" => "/docs/reference/scripting/",
"$guides" => "/docs/guides/",
"$packages" => "/docs/packages/",
"$changelog" => "/docs/changelog/",
"$community" => "/docs/community/",
_ => return None,
})
}
/// Resolve a `$` link to a global definition.
fn resolve_definition(head: &str) -> StrResult<String> {
let mut parts = head.trim_start_matches('$').split('.').peekable();
let mut focus = &LIBRARY.global;
while let Some(m) = parts.peek().and_then(|&name| get_module(focus, name).ok()) {
focus = m;
parts.next();
}
let name = parts.next().ok_or("link is missing first part")?;
let value = focus.field(name)?;
let Some(category) = focus.scope().get_category(name) else {
bail!("{name} has no category");
};
// Handle grouped functions.
if let Some(group) = GROUPS
.iter()
.filter(|_| category == "math")
.find(|group| group.functions.iter().any(|func| func == name))
{
let mut route =
format!("/docs/reference/math/{}/#functions-{}", group.name, name);
if let Some(param) = parts.next() {
route.push('-');
route.push_str(param);
}
return Ok(route);
}
let mut route = format!("/docs/reference/{category}/{name}/");
if let Some(next) = parts.next() {
if value.field(next).is_ok() {
route.push_str("#definitions-");
route.push_str(next);
} else if value
.clone()
.cast::<Func>()
.map_or(false, |func| func.param(next).is_some())
{
route.push_str("#parameters-");
route.push_str(next);
} else {
bail!("field {next} not found");
}
}
Ok(route)
}

View File

@ -0,0 +1,170 @@
use ecow::EcoString;
use heck::ToKebabCase;
use serde::Serialize;
use crate::html::Html;
/// Details about a documentation page and its children.
#[derive(Debug, Serialize)]
pub struct PageModel {
pub route: EcoString,
pub title: EcoString,
pub description: EcoString,
pub part: Option<&'static str>,
pub outline: Vec<OutlineItem>,
pub body: BodyModel,
pub children: Vec<Self>,
}
impl PageModel {
pub fn with_route(self, route: &str) -> Self {
Self { route: route.into(), ..self }
}
pub 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 {
pub id: EcoString,
pub name: EcoString,
pub children: Vec<Self>,
}
impl OutlineItem {
/// Create an outline item from a name with auto-generated id.
pub fn from_name(name: &str) -> Self {
Self {
id: name.to_kebab_case().into(),
name: name.into(),
children: vec![],
}
}
}
/// 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),
Group(GroupModel),
Type(TypeModel),
Symbols(SymbolsModel),
Packages(Html),
}
/// Details about a category.
#[derive(Debug, Serialize)]
pub struct CategoryModel {
pub name: EcoString,
pub details: Html,
pub items: Vec<CategoryItem>,
pub shorthands: Option<ShorthandsModel>,
}
/// Details about a category item.
#[derive(Debug, Serialize)]
pub struct CategoryItem {
pub name: EcoString,
pub route: EcoString,
pub oneliner: EcoString,
pub code: bool,
}
/// Details about a function.
#[derive(Debug, Serialize)]
pub struct FuncModel {
pub path: Vec<EcoString>,
pub name: EcoString,
pub title: &'static str,
pub keywords: &'static [&'static str],
pub oneliner: &'static str,
pub element: bool,
pub details: Html,
/// This example is only for nested function models. Others can have
/// their example directly in their detals.
pub example: Option<Html>,
#[serde(rename = "self")]
pub self_: bool,
pub params: Vec<ParamModel>,
pub returns: Vec<&'static str>,
pub scope: Vec<FuncModel>,
}
/// 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: EcoString,
pub details: Html,
}
/// Details about a group of functions.
#[derive(Debug, Serialize)]
pub struct GroupModel {
pub name: EcoString,
pub title: EcoString,
pub details: Html,
pub functions: Vec<FuncModel>,
}
/// Details about a type.
#[derive(Debug, Serialize)]
pub struct TypeModel {
pub name: &'static str,
pub title: &'static str,
pub keywords: &'static [&'static str],
pub oneliner: &'static str,
pub details: Html,
pub constructor: Option<FuncModel>,
pub scope: Vec<FuncModel>,
}
/// 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, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct SymbolModel {
pub name: EcoString,
pub codepoint: u32,
pub accent: bool,
pub unicode_name: Option<EcoString>,
pub alternates: Vec<EcoString>,
pub markup_shorthand: Option<&'static str>,
pub math_shorthand: Option<&'static str>,
}
/// Shorthands listed on a category page.
#[derive(Debug, Serialize)]
pub struct ShorthandsModel {
pub markup: Vec<SymbolModel>,
pub math: Vec<SymbolModel>,
}

View File

@ -207,7 +207,7 @@ impl Array {
.ok_or_else(|| out_of_bounds_no_default(index, self.len())) .ok_or_else(|| out_of_bounds_no_default(index, self.len()))
} }
/// Add a value to the end of the array. /// Adds a value to the end of the array.
#[func] #[func]
pub fn push( pub fn push(
&mut self, &mut self,
@ -217,14 +217,14 @@ impl Array {
self.0.push(value); self.0.push(value);
} }
/// Remove the last item from the array and return it. Fails with an error /// Removes the last item from the array and returns it. Fails with an error
/// if the array is empty. /// if the array is empty.
#[func] #[func]
pub fn pop(&mut self) -> StrResult<Value> { pub fn pop(&mut self) -> StrResult<Value> {
self.0.pop().ok_or_else(array_is_empty) self.0.pop().ok_or_else(array_is_empty)
} }
/// Insert a value into the array at the specified index. Fails with an /// Inserts a value into the array at the specified index. Fails with an
/// error if the index is out of bounds. /// error if the index is out of bounds.
#[func] #[func]
pub fn insert( pub fn insert(
@ -240,7 +240,7 @@ impl Array {
Ok(()) Ok(())
} }
/// Remove the value at the specified index from the array and return it. /// Removes the value at the specified index from the array and return it.
#[func] #[func]
pub fn remove( pub fn remove(
&mut self, &mut self,
@ -252,7 +252,7 @@ impl Array {
Ok(self.0.remove(i)) Ok(self.0.remove(i))
} }
/// Extract a subslice of the array. Fails with an error if the start or /// Extracts a subslice of the array. Fails with an error if the start or
/// index is out of bounds. /// index is out of bounds.
#[func] #[func]
pub fn slice( pub fn slice(

View File

@ -154,7 +154,7 @@ impl Dict {
.ok_or_else(|| missing_key_no_default(&key)) .ok_or_else(|| missing_key_no_default(&key))
} }
/// Insert a new pair into the dictionary and return the value. If the /// Inserts a new pair into the dictionary and return the value. If the
/// dictionary already contains this key, the value is updated. /// dictionary already contains this key, the value is updated.
#[func] #[func]
pub fn insert( pub fn insert(
@ -167,7 +167,7 @@ impl Dict {
Arc::make_mut(&mut self.0).insert(key, value); Arc::make_mut(&mut self.0).insert(key, value);
} }
/// Remove a pair from the dictionary by key and return the value. /// Removes a pair from the dictionary by key and return the value.
#[func] #[func]
pub fn remove(&mut self, key: Str) -> StrResult<Value> { pub fn remove(&mut self, key: Str) -> StrResult<Value> {
match Arc::make_mut(&mut self.0).shift_remove(&key) { match Arc::make_mut(&mut self.0).shift_remove(&key) {

View File

@ -8,25 +8,25 @@ description: |
## Version 0.7.0 (August 7, 2023) { #v0.7.0 } ## Version 0.7.0 (August 7, 2023) { #v0.7.0 }
- Text and Layout - Text and Layout
- Added support for floating figures through the - Added support for floating figures through the
[`placement`]($func/figure.placement) argument on the figure function [`placement`]($figure.placement) argument on the figure function
- Added support for arbitrary floating content through the - Added support for arbitrary floating content through the
[`float`]($func/place.float) argument on the place function [`float`]($place.float) argument on the place function
- Added support for loading `.sublime-syntax` files as highlighting - Added support for loading `.sublime-syntax` files as highlighting
[syntaxes]($func/raw.syntaxes) for raw blocks [syntaxes]($raw.syntaxes) for raw blocks
- Added support for loading `.tmTheme` files as highlighting - Added support for loading `.tmTheme` files as highlighting
[themes]($func/raw.theme) for raw blocks [themes]($raw.theme) for raw blocks
- Added _bounds_ option to [`top-edge`]($func/text.top-edge) and - Added _bounds_ option to [`top-edge`]($text.top-edge) and
[`bottom-edge`]($func/text.bottom-edge) arguments of text function for tight [`bottom-edge`]($text.bottom-edge) arguments of text function for tight
bounding boxes bounding boxes
- Removed nonsensical top- and bottom-edge options, e.g. _ascender_ for the - Removed nonsensical top- and bottom-edge options, e.g. _ascender_ for the
bottom edge (**Breaking change**) bottom edge (**Breaking change**)
- Added [`script`]($func/text.script) argument to text function - Added [`script`]($text.script) argument to text function
- Added [`alternative`]($func/smartquote.alternative) argument to smart quote - Added [`alternative`]($smartquote.alternative) argument to smart quote
function function
- Added basic i18n for Japanese - Added basic i18n for Japanese
- Added hyphenation support for `nb` and `nn` language codes in addition to - Added hyphenation support for `nb` and `nn` language codes in addition to
`no` `no`
- Fixed positioning of [placed elements]($func/place) in containers - Fixed positioning of [placed elements]($place) in containers
- Fixed overflowing containers due to optimized line breaks - Fixed overflowing containers due to optimized line breaks
- Export - Export
@ -38,21 +38,21 @@ description: |
- Math - Math
- Improved layout of primes (e.g. in `[$a'_1$]`) - Improved layout of primes (e.g. in `[$a'_1$]`)
- Improved display of multi-primes (e.g. in `[$a''$]`) - Improved display of multi-primes (e.g. in `[$a''$]`)
- Improved layout of [roots]($func/math.root) - Improved layout of [roots]($math.root)
- Changed relations to show attachments as [limits]($func/math.limits) by - Changed relations to show attachments as [limits]($math.limits) by default
default (e.g. in `[$a ->^x b$]`) (e.g. in `[$a ->^x b$]`)
- Large operators and delimiters are now always vertically centered - Large operators and delimiters are now always vertically centered
- [Boxes]($func/box) in equations now sit on the baseline instead of being - [Boxes]($box) in equations now sit on the baseline instead of being
vertically centered by default. Notably, this does not affect vertically centered by default. Notably, this does not affect
[blocks]($func/block) because they are not inline elements. [blocks]($block) because they are not inline elements.
- Added support for [weak spacing]($func/h.weak) - Added support for [weak spacing]($h.weak)
- Added support for OpenType character variants - Added support for OpenType character variants
- Added support for customizing the [math class]($func/math.class) of content - Added support for customizing the [math class]($math.class) of content
- Fixed spacing around `.`, `\/`, and `...` - Fixed spacing around `.`, `\/`, and `...`
- Fixed spacing between closing delimiters and large operators - Fixed spacing between closing delimiters and large operators
- Fixed a bug with math font weight selection - Fixed a bug with math font weight selection
- Symbols and Operators (**Breaking changes**) - Symbols and Operators (**Breaking changes**)
- Added `id`, `im`, and `tr` text [operators]($func/math.op) - Added `id`, `im`, and `tr` text [operators]($math.op)
- Renamed `ident` to `equiv` with alias `eq.triple` and removed - Renamed `ident` to `equiv` with alias `eq.triple` and removed
`ident.strict` in favor of `eq.quad` `ident.strict` in favor of `eq.quad`
- Renamed `ast.sq` to `ast.square` and `integral.sq` to `integral.square` - Renamed `ast.sq` to `ast.square` and `integral.sq` to `integral.square`
@ -65,36 +65,32 @@ description: |
- Scripting - Scripting
- Fields - Fields
- Added `abs` and `em` field to [lengths]($type/length) - Added `abs` and `em` field to [lengths]($length)
- Added `ratio` and `length` field to - Added `ratio` and `length` field to [relative lengths]($relative)
[relative lengths]($type/relative-length) - Added `x` and `y` field to [2d alignments]($align.alignment)
- Added `x` and `y` field to [2d alignments]($func/align.alignment)
- Added `paint`, `thickness`, `cap`, `join`, `dash`, and `miter-limit` field - Added `paint`, `thickness`, `cap`, `join`, `dash`, and `miter-limit` field
to [strokes]($func/line.stroke) to [strokes]($stroke)
- Accessor and utility methods - Accessor and utility methods
- Added [`dedup`]($type/array.dedup) method to arrays - Added [`dedup`]($array.dedup) method to arrays
- Added `pt`, `mm`, `cm`, and `inches` method to [lengths]($type/length) - Added `pt`, `mm`, `cm`, and `inches` method to [lengths]($length)
- Added `deg` and `rad` method to [angles]($type/angle) - Added `deg` and `rad` method to [angles]($angle)
- Added `kind`, `hex`, `rgba`, `cmyk`, and `luma` method to - Added `kind`, `hex`, `rgba`, `cmyk`, and `luma` method to [colors]($color)
[colors]($type/color) - Added `axis`, `start`, `end`, and `inv` method to [directions]($stack.dir)
- Added `axis`, `start`, `end`, and `inv` method to - Added `axis` and `inv` method to [alignments]($align.alignment)
[directions]($func/stack.dir) - Added `inv` method to [2d alignments]($align.alignment)
- Added `axis` and `inv` method to [alignments]($func/align.alignment) - Added `start` argument to [`enumerate`]($array.enumerate) method on arrays
- Added `inv` method to [2d alignments]($func/align.alignment) - Added [`color.mix`]($color.mix) function
- Added `start` argument to [`enumerate`]($type/array.enumerate) method on - Added `mode` and `scope` arguments to [`eval`]($eval) function
arrays - Added [`bytes`]($bytes) type for holding large byte buffers
- Added [`color.mix`]($func/color.mix) function - Added [`encoding`]($read.encoding) argument to read function to read a
- Added `mode` and `scope` arguments to [`eval`]($func/eval) function file as bytes instead of a string
- Added [`bytes`]($type/bytes) type for holding large byte buffers - Added [`image.decode`]($image.decode) function for decoding an image
- Added [`encoding`]($func/read.encoding) argument to read function to read
a file as bytes instead of a string
- Added [`image.decode`]($func/image.decode) function for decoding an image
directly from a string or bytes directly from a string or bytes
- Added [`bytes`]($func/bytes) function for converting a string or an array - Added [`bytes`]($bytes) function for converting a string or an array of
of integers to bytes integers to bytes
- Added [`array`]($func/array) function for converting bytes to an array of - Added [`array`]($array) function for converting bytes to an array of
integers integers
- Added support for converting bytes to a string with the [`str`]($func/str) - Added support for converting bytes to a string with the [`str`]($str)
function function
- Tooling and Diagnostics - Tooling and Diagnostics
@ -126,19 +122,19 @@ description: |
- Fixed displayed compilation time (now includes export) - Fixed displayed compilation time (now includes export)
- Miscellaneous Improvements - Miscellaneous Improvements
- Added [`bookmarked`]($func/heading.bookmarked) argument to heading to - Added [`bookmarked`]($heading.bookmarked) argument to heading to control
control whether a heading becomes part of the PDF outline whether a heading becomes part of the PDF outline
- Added [`caption-pos`]($func/figure.caption-pos) argument to control the - Added [`caption-pos`]($figure.caption-pos) argument to control the position
position of a figure's caption of a figure's caption
- Added [`metadata`]($func/metadata) function for exposing an arbitrary value - Added [`metadata`]($metadata) function for exposing an arbitrary value to
to the introspection system the introspection system
- Fixed that a [`state`]($func/state) was identified by the pair `(key, init)` - Fixed that a [`state`]($state) was identified by the pair `(key, init)`
instead of just its `key` instead of just its `key`
- Improved indent logic of [enumerations]($func/enum). Instead of requiring at - Improved indent logic of [enumerations]($enum). Instead of requiring at
least as much indent as the end of the marker, they now require only one least as much indent as the end of the marker, they now require only one
more space indent than the start of the marker. As a result, even long more space indent than the start of the marker. As a result, even long
markers like `12.` work with just 2 spaces of indent. markers like `12.` work with just 2 spaces of indent.
- Fixed bug with indent logic of [`raw`]($func/raw) blocks - Fixed bug with indent logic of [`raw`]($raw) blocks
- Fixed a parsing bug with dictionaries - Fixed a parsing bug with dictionaries
- Development - Development
@ -158,26 +154,26 @@ description: |
- Math - Math
- Added support for optical size variants of glyphs in math mode - Added support for optical size variants of glyphs in math mode
- Added argument to enable [`limits`]($func/math.limits) conditionally - Added argument to enable [`limits`]($math.limits) conditionally depending on
depending on whether the equation is set in [`display`]($func/math.display) whether the equation is set in [`display`]($math.display) or
or [`inline`]($func/math.inline) style [`inline`]($math.inline) style
- Added `gt.eq.slant` and `lt.eq.slant` symbols - Added `gt.eq.slant` and `lt.eq.slant` symbols
- Increased precedence of factorials in math mode (`[$1/n!$]` works correctly - Increased precedence of factorials in math mode (`[$1/n!$]` works correctly
now) now)
- Improved [underlines]($func/math.underline) and - Improved [underlines]($math.underline) and [overlines]($math.overline) in
[overlines]($func/math.overline) in math mode math mode
- Fixed usage of [`limits`]($func/math.limits) function in show rules - Fixed usage of [`limits`]($math.limits) function in show rules
- Fixed bugs with line breaks in equations - Fixed bugs with line breaks in equations
- Text and Layout - Text and Layout
- Added support for alternating page [margins]($func/page.margin) with the - Added support for alternating page [margins]($page.margin) with the `inside`
`inside` and `outside` keys and `outside` keys
- Added support for specifying the page [`binding`]($func/page.binding) - Added support for specifying the page [`binding`]($page.binding)
- Added [`to`]($func/pagebreak.to) argument to pagebreak function to skip to - Added [`to`]($pagebreak.to) argument to pagebreak function to skip to the
the next even or odd page next even or odd page
- Added basic i18n for a few more languages (TR, SQ, TL) - Added basic i18n for a few more languages (TR, SQ, TL)
- Fixed bug with missing table row at page break - Fixed bug with missing table row at page break
- Fixed bug with [underlines]($func/underline) - Fixed bug with [underlines]($underline)
- Fixed bug superfluous table lines - Fixed bug superfluous table lines
- Fixed smart quotes after line breaks - Fixed smart quotes after line breaks
- Fixed a crash related to text layout - Fixed a crash related to text layout
@ -193,13 +189,13 @@ description: |
- Now displays compilation time - Now displays compilation time
- Miscellaneous Improvements - Miscellaneous Improvements
- Added [`outline.entry`]($func/outline.entry) to customize outline entries - Added [`outline.entry`]($outline.entry) to customize outline entries with
with show rules show rules
- Added some hints for error messages - Added some hints for error messages
- Added some missing syntaxes for [`raw`]($func/raw) highlighting - Added some missing syntaxes for [`raw`]($raw) highlighting
- Improved rendering of rotated images in PNG export and web app - Improved rendering of rotated images in PNG export and web app
- Made [footnotes]($func/footnote) reusable and referenceable - Made [footnotes]($footnote) reusable and referenceable
- Fixed bug with citations and bibliographies in [`locate`]($func/locate) - Fixed bug with citations and bibliographies in [`locate`]($locate)
- Fixed inconsistent tense in documentation - Fixed inconsistent tense in documentation
- Development - Development
@ -211,45 +207,44 @@ description: |
## Version 0.5.0 (June 9, 2023) { #v0.5.0 } ## Version 0.5.0 (June 9, 2023) { #v0.5.0 }
- Text and Layout - Text and Layout
- Added [`raw`]($func/raw) syntax highlighting for many more languages - Added [`raw`]($raw) syntax highlighting for many more languages
- Added support for Korean [numbering]($func/numbering) - Added support for Korean [numbering]($numbering)
- Added basic i18n for a few more languages (NL, SV, DA) - Added basic i18n for a few more languages (NL, SV, DA)
- Improved line breaking for East Asian languages - Improved line breaking for East Asian languages
- Expanded functionality of outline [`indent`]($func/outline.indent) property - Expanded functionality of outline [`indent`]($outline.indent) property
- Fixed footnotes in columns - Fixed footnotes in columns
- Fixed page breaking bugs with [footnotes]($func/footnote) - Fixed page breaking bugs with [footnotes]($footnote)
- Fixed bug with handling of footnotes in lists, tables, and figures - Fixed bug with handling of footnotes in lists, tables, and figures
- Fixed a bug with CJK punctuation adjustment - Fixed a bug with CJK punctuation adjustment
- Fixed a crash with rounded rectangles - Fixed a crash with rounded rectangles
- Fixed alignment of [`line`]($func/line) elements - Fixed alignment of [`line`]($line) elements
- Math - Math
- **Breaking change:** The syntax rules for mathematical - **Breaking change:** The syntax rules for mathematical
[attachments]($func/math.attach) were improved: `[$f^abs(3)$]` now parses as [attachments]($math.attach) were improved: `[$f^abs(3)$]` now parses as
`[$f^(abs(3))$]` instead of `[$(f^abs)(3)$]`. To disambiguate, add a space: `[$f^(abs(3))$]` instead of `[$(f^abs)(3)$]`. To disambiguate, add a space:
`[$f^zeta (3)$]`. `[$f^zeta (3)$]`.
- Added [forced size]($category/math/sizes) commands for math - Added [forced size]($category/math/sizes) commands for math (e.g.,
(e.g., [`display`]($func/math.display)) [`display`]($math.display))
- Added [`supplement`]($func/math.equation.supplement) parameter to - Added [`supplement`]($math.equation.supplement) parameter to
[`equation`]($func/math.equation), used by [references]($func/ref) [`equation`]($math.equation), used by [references]($ref)
- New [symbols]($category/symbols/sym): `bullet`, `xor`, `slash.big`, - New [symbols]($category/symbols/sym): `bullet`, `xor`, `slash.big`,
`sigma.alt`, `tack.r.not`, `tack.r.short`, `tack.r.double.not` `sigma.alt`, `tack.r.not`, `tack.r.short`, `tack.r.double.not`
- Fixed a bug with symbols in matrices - Fixed a bug with symbols in matrices
- Fixed a crash in the [`attach`]($func/math.attach) function - Fixed a crash in the [`attach`]($math.attach) function
- Scripting - Scripting
- Added new [`datetime`]($type/datetime) type and - Added new [`datetime`]($datetime) type and
[`datetime.today`]($func/datetime.today) to retrieve the current date [`datetime.today`]($datetime.today) to retrieve the current date
- Added [`str.from-unicode`]($func/str.from-unicode) and - Added [`str.from-unicode`]($str.from-unicode) and
[`str.to-unicode`]($func/str.to-unicode) functions [`str.to-unicode`]($str.to-unicode) functions
- Added [`fields`]($type/content.fields) method on content - Added [`fields`]($content.fields) method on content
- Added `base` parameter to [`str`]($func/str) function - Added `base` parameter to [`str`]($str) function
- Added [`calc.exp`]($func/calc.exp) and [`calc.ln`]($func/calc.ln) - Added [`calc.exp`]($calc.exp) and [`calc.ln`]($calc.ln)
- Improved accuracy of [`calc.pow`]($func/calc.pow) and - Improved accuracy of [`calc.pow`]($calc.pow) and [`calc.log`]($calc.log) for
[`calc.log`]($func/calc.log) for specific bases specific bases
- Fixed [removal]($type/dictionary.remove) order for dictionary - Fixed [removal]($dictionary.remove) order for dictionary
- Fixed `.at(default: ..)` for [strings]($type/string.at) and - Fixed `.at(default: ..)` for [strings]($str.at) and [content]($content.at)
[content]($type/content.at)
- Fixed field access on styled elements - Fixed field access on styled elements
- Removed deprecated `calc.mod` function - Removed deprecated `calc.mod` function
@ -266,8 +261,8 @@ description: |
- Improved error message for failed length comparisons - Improved error message for failed length comparisons
- Fixed a bug with images not showing up in Apple Preview - Fixed a bug with images not showing up in Apple Preview
- Fixed multiple bugs with the PDF outline - Fixed multiple bugs with the PDF outline
- Fixed citations and other searchable elements in [`hide`]($func/hide) - Fixed citations and other searchable elements in [`hide`]($hide)
- Fixed bugs with [reference supplements]($func/ref.supplement) - Fixed bugs with [reference supplements]($ref.supplement)
- Fixed Nix flake - Fixed Nix flake
<contributors from="v0.4.0" to="v0.5.0" /> <contributors from="v0.4.0" to="v0.5.0" />
@ -275,29 +270,28 @@ description: |
## Version 0.4.0 (May 20, 2023) { #v0.4.0 } ## Version 0.4.0 (May 20, 2023) { #v0.4.0 }
- Footnotes - Footnotes
- Implemented support for footnotes - Implemented support for footnotes
- The [`footnote`]($func/footnote) function inserts a footnote - The [`footnote`]($footnote) function inserts a footnote
- The [`footnote.entry`]($func/footnote.entry) function can be used to - The [`footnote.entry`]($footnote.entry) function can be used to customize
customize the footnote listing the footnote listing
- The `{"chicago-notes"}` [citation style]($func/cite.style) is now available - The `{"chicago-notes"}` [citation style]($cite.style) is now available
- Documentation - Documentation
- Added a [Guide for LaTeX users]($guides/guide-for-latex-users) - Added a [Guide for LaTeX users]($guides/guide-for-latex-users)
- Now shows default values for optional arguments - Now shows default values for optional arguments
- Added richer outlines in "On this Page" - Added richer outlines in "On this Page"
- Added initial support for search keywords: "Table of Contents" will now find - Added initial support for search keywords: "Table of Contents" will now find
the [outline]($func/outline) function. Suggestions for more keywords are the [outline]($outline) function. Suggestions for more keywords are welcome!
welcome!
- Fixed issue with search result ranking - Fixed issue with search result ranking
- Fixed many more small issues - Fixed many more small issues
- Math - Math
- **Breaking change**: Alignment points (`&`) in equations now alternate - **Breaking change**: Alignment points (`&`) in equations now alternate
between left and right alignment between left and right alignment
- Added support for writing roots with Unicode: - Added support for writing roots with Unicode: For example, `[$root(x+y)$]`
For example, `[$root(x+y)$]` can now also be written as `[$√(x+y)$]` can now also be written as `[$√(x+y)$]`
- Fixed uneven vertical [`attachment`]($func/math.attach) alignment - Fixed uneven vertical [`attachment`]($math.attach) alignment
- Fixed spacing on decorated elements - Fixed spacing on decorated elements (e.g., spacing around a
(e.g., spacing around a [canceled]($func/math.cancel) operator) [canceled]($math.cancel) operator)
- Fixed styling for stretchable symbols - Fixed styling for stretchable symbols
- Added `tack.r.double`, `tack.l.double`, `dotless.i` and `dotless.j` - Added `tack.r.double`, `tack.l.double`, `dotless.i` and `dotless.j`
[symbols]($category/symbols/sym) [symbols]($category/symbols/sym)
@ -307,40 +301,37 @@ description: |
- Scripting - Scripting
- Added function scopes: A function can now hold related definitions in its - 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) own scope, similar to a module. The new [`assert.eq`]($assert.eq) function,
function, for instance, is part of the [`assert`]($func/assert) function's for instance, is part of the [`assert`]($assert) function's scope. Note that
scope. Note that function scopes are currently only available for built-in function scopes are currently only available for built-in functions.
functions. - Added [`assert.eq`]($assert.eq) and [`assert.ne`]($assert.ne) functions for
- Added [`assert.eq`]($func/assert.eq) and [`assert.ne`]($func/assert.ne) simpler equality and inequality assertions with more helpful error messages
functions for simpler equality and inequality assertions with more helpful - Exposed [list]($list.item), [enum]($enum.item), and [term list]($terms.item)
error messages items in their respective functions' scope
- Exposed [list]($func/list.item), [enum]($func/enum.item), and - The `at` methods on [strings]($str.at), [arrays]($array.at),
[term list]($func/terms.item) items in their respective functions' scope [dictionaries]($dictionary.at), and [content]($content.at) now support
- 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 specifying a default value
- Added support for passing a function to [`replace`]($type/string.replace) - Added support for passing a function to [`replace`]($str.replace) that is
that is called with each match. called with each match.
- Fixed [replacement]($type/string.replace) strings: They are now inserted - Fixed [replacement]($str.replace) strings: They are now inserted completely
completely verbatim instead of supporting the previous (unintended) magic verbatim instead of supporting the previous (unintended) magic dollar syntax
dollar syntax for capture groups for capture groups
- Fixed bug with trailing placeholders in destructuring patterns - Fixed bug with trailing placeholders in destructuring patterns
- Fixed bug with underscore in parameter destructuring - Fixed bug with underscore in parameter destructuring
- Fixed crash with nested patterns and when hovering over an invalid pattern - Fixed crash with nested patterns and when hovering over an invalid pattern
- Better error messages when casting to an [integer]($func/int) or - Better error messages when casting to an [integer]($int) or [float]($float)
[float]($func/float) fails fails
- Text and Layout - Text and Layout
- Implemented sophisticated CJK punctuation adjustment - Implemented sophisticated CJK punctuation adjustment
- Disabled [overhang]($func/text.overhang) for CJK punctuation - Disabled [overhang]($text.overhang) for CJK punctuation
- Added basic translations for Traditional Chinese - Added basic translations for Traditional Chinese
- Fixed [alignment]($func/raw.align) of text inside raw blocks (centering a - Fixed [alignment]($raw.align) of text inside raw blocks (centering a raw
raw block, e.g. through a figure, will now keep the text itself block, e.g. through a figure, will now keep the text itself left-aligned)
left-aligned)
- Added support for passing a array instead of a function to configure table - 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 cell [alignment]($table.align) and [fill]($table.fill) per column
- Fixed automatic figure [`kind`]($func/figure.kind) detection - Fixed automatic figure [`kind`]($figure.kind) detection
- Made alignment of [enum numbers]($func/enum.number-align) configurable, - Made alignment of [enum numbers]($enum.number-align) configurable,
defaulting to `end` defaulting to `end`
- Figures can now be made breakable with a show-set rule for blocks in figure - Figures can now be made breakable with a show-set rule for blocks in figure
- Initial fix for smart quotes in RTL languages - Initial fix for smart quotes in RTL languages
@ -372,8 +363,8 @@ description: |
- Improved incremental parsing for more efficient recompilations - Improved incremental parsing for more efficient recompilations
- Added support for `.yaml` extension in addition to `.yml` for bibliographies - Added support for `.yaml` extension in addition to `.yml` for bibliographies
- The CLI now emits escape codes only if the output is a TTY - 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 - For users of the `typst` crate: The `Document` is now `Sync` again and the
the `World` doesn't have to be `'static` anymore `World` doesn't have to be `'static` anymore
<contributors from="v0.3.0" to="v0.4.0" /> <contributors from="v0.3.0" to="v0.4.0" />
@ -381,41 +372,41 @@ description: |
- **Breaking changes:** - **Breaking changes:**
- Renamed a few symbols: What was previous `dot.op` is now just `dot` and the - 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`. basic dot is `dot.basic`. The same applies to `ast` and `tilde`.
- Renamed `mod` to [`rem`]($func/calc.rem) to more accurately reflect - Renamed `mod` to [`rem`]($calc.rem) to more accurately reflect the
the behaviour. It will remain available as `mod` until the next update as a behaviour. It will remain available as `mod` until the next update as a
grace period. grace period.
- A lone underscore is not a valid identifier anymore, it can now only be used - A lone underscore is not a valid identifier anymore, it can now only be used
in patterns in patterns
- Removed `before` and `after` arguments from [`query`]($func/query). This is - Removed `before` and `after` arguments from [`query`]($query). This is now
now handled through flexible [selectors]($type/selector) combinator methods handled through flexible [selectors]($selector) combinator methods
- Added support for [attachments]($func/math.attach) (sub-, superscripts) that - Added support for [attachments]($math.attach) (sub-, superscripts) that
precede the base symbol. The `top` and `bottom` arguments have been renamed precede the base symbol. The `top` and `bottom` arguments have been renamed
to `t` and `b`. to `t` and `b`.
- New features - New features
- Added support for more complex [strokes]($func/line.stroke) - Added support for more complex [strokes]($stroke) (configurable caps, joins,
(configurable caps, joins, and dash patterns) and dash patterns)
- Added [`cancel`]($func/math.cancel) function for equations - Added [`cancel`]($math.cancel) function for equations
- Added support for [destructuring]($scripting/#bindings) in argument lists - Added support for [destructuring]($scripting/#bindings) in argument lists
and assignments and assignments
- Added [`alt`]($func/image.alt) text argument to image function - Added [`alt`]($image.alt) text argument to image function
- Added [`toml`]($func/toml) function for loading data from a TOML file - Added [`toml`]($toml) function for loading data from a TOML file
- Added [`zip`]($type/array.zip), [`sum`]($type/array.sum), and - Added [`zip`]($array.zip), [`sum`]($array.sum), and
[`product`]($type/array.product) methods for arrays [`product`]($array.product) methods for arrays
- Added `fact`, `perm`, `binom`, `gcd`, `lcm`, `atan2`, `quo`, `trunc`, and - Added `fact`, `perm`, `binom`, `gcd`, `lcm`, `atan2`, `quo`, `trunc`, and
`fract` [calculation]($category/calculate) `fract` [calculation]($category/calculate)
- Improvements - Improvements
- Text in SVGs now displays properly - Text in SVGs now displays properly
- Typst now generates a PDF heading outline - Typst now generates a PDF heading outline
- [References]($func/ref) now provides the referenced element as a field in - [References]($ref) now provides the referenced element as a field in show
show rules rules
- Refined linebreak algorithm for better Chinese justification - Refined linebreak algorithm for better Chinese justification
- Locations are now a valid kind of selector - Locations are now a valid kind of selector
- Added a few symbols for algebra - Added a few symbols for algebra
- Added Spanish smart quote support - Added Spanish smart quote support
- Added [`selector`]($func/selector) function to turn a selector-like value - Added [`selector`]($selector) function to turn a selector-like value into a
into a selector on which combinator methods can be called selector on which combinator methods can be called
- Improved some error messages - Improved some error messages
- The outline and bibliography headings can now be styled with show-set rules - The outline and bibliography headings can now be styled with show-set rules
- Operations on numbers now produce an error instead of overflowing - Operations on numbers now produce an error instead of overflowing
@ -423,7 +414,7 @@ description: |
- Bug fixes - Bug fixes
- Fixed wrong linebreak before punctuation that follows inline equations, - Fixed wrong linebreak before punctuation that follows inline equations,
citations, and other elements citations, and other elements
- Fixed a bug with [argument sinks]($type/arguments) - Fixed a bug with [argument sinks]($arguments)
- Fixed strokes with thickness zero - Fixed strokes with thickness zero
- Fixed hiding and show rules in math - Fixed hiding and show rules in math
- Fixed alignment in matrices - Fixed alignment in matrices
@ -431,13 +422,13 @@ description: |
- Fixed grid cell alignment - Fixed grid cell alignment
- Fixed alignment of list marker and enum markers in presence of global - Fixed alignment of list marker and enum markers in presence of global
alignment settings alignment settings
- Fixed [path]($func/path) closing - Fixed [path]($path) closing
- Fixed compiler crash with figure references - Fixed compiler crash with figure references
- A single trailing line breaks is now ignored in math, just like in text - A single trailing line breaks is now ignored in math, just like in text
- Command line interface - Command line interface
- Font path and compilation root can now be set with the environment - Font path and compilation root can now be set with the environment variables
variables `TYPST_FONT_PATHS` and `TYPST_ROOT` `TYPST_FONT_PATHS` and `TYPST_ROOT`
- The output of `typst fonts` now includes the embedded fonts - The output of `typst fonts` now includes the embedded fonts
- Development - Development
@ -453,18 +444,18 @@ description: |
- **Breaking changes:** - **Breaking changes:**
- Removed support for iterating over index and value in - Removed support for iterating over index and value in
[for loops]($scripting/#loops). This is now handled via unpacking and [for loops]($scripting/#loops). This is now handled via unpacking and
enumerating. Same goes for the [`map`]($type/array.map) method. enumerating. Same goes for the [`map`]($array.map) method.
- [Dictionaries]($type/dictionary) now iterate in insertion order instead of - [Dictionaries]($dictionary) now iterate in insertion order instead of
alphabetical order. alphabetical order.
- New features - New features
- Added [unpacking syntax]($scripting/#bindings) for let bindings, which - Added [unpacking syntax]($scripting/#bindings) for let bindings, which
allows things like `{let (1, 2) = array}` allows things like `{let (1, 2) = array}`
- Added [`enumerate`]($type/array.enumerate) method - Added [`enumerate`]($array.enumerate) method
- Added [`path`]($func/path) function for drawing Bézier paths - Added [`path`]($path) function for drawing Bézier paths
- Added [`layout`]($func/layout) function to access the size of the - Added [`layout`]($layout) function to access the size of the surrounding
surrounding page or container page or container
- Added `key` parameter to [`sorted`]($type/array.sorted) method - Added `key` parameter to [`sorted`]($array.sorted) method
- Command line interface - Command line interface
- Fixed `--open` flag blocking the program - Fixed `--open` flag blocking the program
@ -478,17 +469,16 @@ description: |
- Added basic i18n for a few more languages - Added basic i18n for a few more languages
(AR, NB, CS, NN, PL, SL, ES, UA, VI) (AR, NB, CS, NN, PL, SL, ES, UA, VI)
- Added a few numbering patterns (Ihora, Chinese) - Added a few numbering patterns (Ihora, Chinese)
- Added `sinc` [operator]($func/math.op) - Added `sinc` [operator]($math.op)
- Fixed bug where math could not be hidden with [`hide`]($func/hide) - Fixed bug where math could not be hidden with [`hide`]($hide)
- Fixed sizing issues with box, block, and shapes - Fixed sizing issues with box, block, and shapes
- Fixed some translations - Fixed some translations
- Fixed inversion of "R" in [`cal`]($func/math.cal) and - Fixed inversion of "R" in [`cal`]($math.cal) and [`frak`]($math.frak) styles
[`frak`]($func/math.frak) styles
- Fixed some styling issues in math - Fixed some styling issues in math
- Fixed supplements of references to headings - Fixed supplements of references to headings
- Fixed syntax highlighting of identifiers in certain scenarios - Fixed syntax highlighting of identifiers in certain scenarios
- [Ratios]($type/ratio) can now be multiplied with more types and be converted - [Ratios]($ratio) can now be multiplied with more types and be converted to
to [floats]($type/float) with the [`float`]($func/float) function [floats]($float) with the [`float`]($float) function
<contributors from="v0.1.0" to="v0.2.0" /> <contributors from="v0.1.0" to="v0.2.0" />
@ -499,22 +489,22 @@ description: |
- `typst watch file.typ` or `typst w file.typ` to compile and watch - `typst watch file.typ` or `typst w file.typ` to compile and watch
- `typst fonts` to list all fonts - `typst fonts` to list all fonts
- Manual counters now start at zero. Read the "How to step" section - Manual counters now start at zero. Read the "How to step" section
[here]($func/counter) for more details [here]($counter) for more details
- The [bibliography styles]($func/bibliography.style) - The [bibliography styles]($bibliography.style) `{"author-date"}` and
`{"author-date"}` and `{"author-title"}` were renamed to `{"author-title"}` were renamed to `{"chicago-author-date"}` and
`{"chicago-author-date"}` and `{"chicago-author-title"}` `{"chicago-author-title"}`
- Figure improvements - Figure improvements
- Figures now automatically detect their content and adapt their - Figures now automatically detect their content and adapt their behaviour.
behaviour. Figures containing tables, for instance, are automatically Figures containing tables, for instance, are automatically prefixed with
prefixed with "Table X" and have a separate counter "Table X" and have a separate counter
- The figure's supplement (e.g. "Figure" or "Table") can now be customized - 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 - In addition, figures can now be completely customized because the show rule
gives access to the automatically resolved kind, supplement, and counter gives access to the automatically resolved kind, supplement, and counter
- Bibliography improvements - Bibliography improvements
- The [`bibliography`]($func/bibliography) now also accepts multiple - The [`bibliography`]($bibliography) now also accepts multiple bibliography
bibliography paths (as an array) paths (as an array)
- Parsing of BibLaTeX files is now more permissive (accepts non-numeric - Parsing of BibLaTeX files is now more permissive (accepts non-numeric
edition, pages, volumes, dates, and Jabref-style comments; fixed edition, pages, volumes, dates, and Jabref-style comments; fixed
abbreviation parsing) abbreviation parsing)
@ -522,9 +512,8 @@ description: |
- Fixed APA bibliography ordering - Fixed APA bibliography ordering
- Drawing additions - Drawing additions
- Added [`polygon`]($func/polygon) function for drawing polygons - Added [`polygon`]($polygon) function for drawing polygons
- Added support for clipping in [boxes]($func/box.clip) and - Added support for clipping in [boxes]($box.clip) and [blocks]($block.clip)
[blocks]($func/block.clip)
- Command line interface - Command line interface
- Now returns with non-zero status code if there is an error - Now returns with non-zero status code if there is an error
@ -534,27 +523,26 @@ description: |
- Added `--open` flag to directly open the PDF - Added `--open` flag to directly open the PDF
- Miscellaneous improvements - Miscellaneous improvements
- Added [`yaml`]($func/yaml) function to load data from YAML files - Added [`yaml`]($yaml) function to load data from YAML files
- Added basic i18n for a few more languages (IT, RU, ZH, FR, PT) - Added basic i18n for a few more languages (IT, RU, ZH, FR, PT)
- Added numbering support for Hebrew - Added numbering support for Hebrew
- Added support for [integers]($type/integer) with base 2, 8, and 16 - Added support for [integers]($int) with base 2, 8, and 16
- Added symbols for double bracket and laplace operator - Added symbols for double bracket and laplace operator
- The [`link`]($func/link) function now accepts [labels]($func/label) - The [`link`]($link) function now accepts [labels]($label)
- The link syntax now allows more characters - The link syntax now allows more characters
- Improved justification of Japanese and Chinese text - Improved justification of Japanese and Chinese text
- Calculation functions behave more consistently w.r.t to non-real results - Calculation functions behave more consistently w.r.t to non-real results
- Replaced deprecated angle brackets - Replaced deprecated angle brackets
- Reduced maximum function call depth from 256 to 64 - Reduced maximum function call depth from 256 to 64
- Fixed [`first-line-indent`]($func/par.first-line-indent) being not applied - Fixed [`first-line-indent`]($par.first-line-indent) being not applied when a
when a paragraph starts with styled text paragraph starts with styled text
- Fixed extraneous spacing in unary operators in equations - Fixed extraneous spacing in unary operators in equations
- Fixed block spacing, e.g. in `{block(above: 1cm, below: 1cm, ..)}` - Fixed block spacing, e.g. in `{block(above: 1cm, below: 1cm, ..)}`
- Fixed styling of text operators in math - Fixed styling of text operators in math
- Fixed invalid parsing of language tag in raw block with a single backtick - Fixed invalid parsing of language tag in raw block with a single backtick
- Fixed bugs with displaying counters and state - Fixed bugs with displaying counters and state
- Fixed crash related to page counter - Fixed crash related to page counter
- Fixed crash when [`symbol`]($func/symbol) function was called without - Fixed crash when [`symbol`]($symbol) function was called without arguments
arguments
- Fixed crash in bibliography generation - Fixed crash in bibliography generation
- Fixed access to label of certain content elements - Fixed access to label of certain content elements
- Fixed line number in error message for CSV parsing - Fixed line number in error message for CSV parsing
@ -562,12 +550,12 @@ description: |
<contributors from="v23-03-28" to="v0.1.0" /> <contributors from="v23-03-28" to="v0.1.0" />
## March 28, 2023 ## March 28, 2023 { #_ }
- **Breaking changes:** - **Breaking changes:**
- Enumerations now require a space after their marker, that is, `[1.ok]` must - Enumerations now require a space after their marker, that is, `[1.ok]` must
now be written as `[1. ok]` now be written as `[1. ok]`
- Changed default style for [term lists]($func/terms): Does not include a - Changed default style for [term lists]($terms): Does not include a colon
colon anymore and has a bit more indent anymore and has a bit more indent
- Command line interface - Command line interface
- Added `--font-path` argument for CLI - Added `--font-path` argument for CLI
@ -575,16 +563,15 @@ description: |
- Fixed build of CLI if `git` is not installed - Fixed build of CLI if `git` is not installed
- Miscellaneous improvements - Miscellaneous improvements
- Added support for disabling [matrix]($func/math.mat) and - Added support for disabling [matrix]($math.mat) and [vector]($math.vec)
[vector]($func/math.vec) delimiters. Generally with delimiters. Generally with `[#set math.mat(delim: none)]` or one-off with
`[#set math.mat(delim: none)]` or one-off with
`[$mat(delim: #none, 1, 2; 3, 4)$]`. `[$mat(delim: #none, 1, 2; 3, 4)$]`.
- Added [`separator`]($func/terms.separator) argument to term lists - Added [`separator`]($terms.separator) argument to term lists
- Added [`round`]($func/math.round) function for equations - Added [`round`]($math.round) function for equations
- Numberings now allow zeros. To reset a counter, you can write - Numberings now allow zeros. To reset a counter, you can write
`[#counter(..).update(0)]` `[#counter(..).update(0)]`
- Added documentation for `{page()}` and `{position()}` methods on - Added documentation for `{page()}` and `{position()}` methods on
[`location`]($func/locate) type [`location`]($location) type
- Added symbols for double, triple, and quadruple dot accent - Added symbols for double, triple, and quadruple dot accent
- Added smart quotes for Norwegian Bokmål - Added smart quotes for Norwegian Bokmål
- Added Nix flake - Added Nix flake
@ -593,92 +580,90 @@ description: |
- Fixed parsing of unbalanced delimiters in fractions: `[$1/(2 (x)$]` - Fixed parsing of unbalanced delimiters in fractions: `[$1/(2 (x)$]`
- Fixed unexpected parsing of numbers as enumerations, e.g. in `[1.2]` - Fixed unexpected parsing of numbers as enumerations, e.g. in `[1.2]`
- Fixed combination of page fill and header - Fixed combination of page fill and header
- Fixed compiler crash if [`repeat`]($func/repeat) is used in page with - Fixed compiler crash if [`repeat`]($repeat) is used in page with automatic
automatic width width
- Fixed [matrices]($func/math.mat) with explicit delimiter - Fixed [matrices]($math.mat) with explicit delimiter
- Fixed [`indent`]($func/terms.indent) property of term lists - Fixed [`indent`]($terms.indent) property of term lists
- Numerous documentation fixes - Numerous documentation fixes
- Links in bibliographies are now affected by link styling - Links in bibliographies are now affected by link styling
- Fixed hovering over comments in web app - Fixed hovering over comments in web app
<contributors from="v23-03-21" to="v23-03-28" /> <contributors from="v23-03-21" to="v23-03-28" />
## March 21, 2023 ## March 21, 2023 { #_ }
- Reference and bibliography management - Reference and bibliography management
- [Bibliographies]($func/bibliography) and [citations]($func/cite) (currently - [Bibliographies]($bibliography) and [citations]($cite) (currently supported
supported styles are APA, Chicago Author Date, IEEE, and MLA) styles are APA, Chicago Author Date, IEEE, and MLA)
- You can now [reference]($func/ref) sections, figures, formulas, and works - You can now [reference]($ref) sections, figures, formulas, and works from
from the bibliography with `[@label]` the bibliography with `[@label]`
- You can make an element referenceable with a label: - You can make an element referenceable with a label:
- `[= Introduction <intro>]` - `[= Introduction <intro>]`
- `[$ A = pi r^2 $ <area>]` - `[$ A = pi r^2 $ <area>]`
- Introspection system for interactions between different parts of the document - Introspection system for interactions between different parts of the document
- [`counter`]($func/counter) function - [`counter`]($counter) function
- Access and modify counters for pages, headings, figures, and equations - Access and modify counters for pages, headings, figures, and equations
- Define and use your own custom counters - Define and use your own custom counters
- Time travel: Find out what the counter value was or will be at some other - 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 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). can determine the value of the figure counter at any given figure).
- Counters count in layout order and not in code order - Counters count in layout order and not in code order
- [`state`]($func/state) function - [`state`]($state) function
- Manage arbitrary state across your document - Manage arbitrary state across your document
- Time travel: Find out the value of your state at any position in the - Time travel: Find out the value of your state at any position in the
document document
- State is modified in layout order and not in code order - State is modified in layout order and not in code order
- [`query`]($func/query) function - [`query`]($query) function
- Find all occurrences of an element or a label, either in the whole document - Find all occurrences of an element or a label, either in the whole
or before/after some location document or before/after some location
- Link to elements, find out their position on the pages and access their - Link to elements, find out their position on the pages and access their
fields fields
- Example use cases: Custom list of figures or page header with current - Example use cases: Custom list of figures or page header with current
chapter title chapter title
- [`locate`]($func/locate) function - [`locate`]($locate) function
- Determines the location of itself in the final layout - Determines the location of itself in the final layout
- Can be accessed to get the `page` and `x`, `y` coordinates - 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 - Can be used with counters and state to find out their values at that
location location
- Can be used with queries to find elements before or after its location - Can be used with queries to find elements before or after its location
- New [`measure`]($func/measure) function - New [`measure`]($measure) function
- Measure the layouted size of elements - Measure the layouted size of elements
- To be used in combination with the new [`style`]($func/style) function that - To be used in combination with the new [`style`]($style) function that lets
lets you generate different content based on the style context something is you generate different content based on the style context something is
inserted into (because that affects the measured size of content) inserted into (because that affects the measured size of content)
- Exposed content representation - Exposed content representation
- Content is not opaque anymore - Content is not opaque anymore
- Content can be compared for equality - Content can be compared for equality
- The tree of content elements can be traversed with code - The tree of content elements can be traversed with code
- Can be observed in hover tooltips or with [`repr`]($func/repr) - Can be observed in hover tooltips or with [`repr`]($repr)
- New [methods]($type/content) on content: `func`, `has`, `at`, and `location` - New [methods]($content) on content: `func`, `has`, `at`, and `location`
- All optional fields on elements are now settable - All optional fields on elements are now settable
- More uniform field names (`heading.title` becomes `heading.body`, - More uniform field names (`heading.title` becomes `heading.body`,
`list.items` becomes `list.children`, and a few more changes) `list.items` becomes `list.children`, and a few more changes)
- Further improvements - Further improvements
- Added [`figure`]($func/figure) function - Added [`figure`]($figure) function
- Added [`numbering`]($func/math.equation.numbering) parameter on equation function - Added [`numbering`]($math.equation.numbering) parameter on equation function
- Added [`numbering`]($func/page.numbering) and - Added [`numbering`]($page.numbering) and
[`number-align`]($func/page.number-align) parameters on page function [`number-align`]($page.number-align) parameters on page function
- The page function's [`header`]($func/page.header) and - The page function's [`header`]($page.header) and [`footer`]($page.footer)
[`footer`]($func/page.footer) parameters do not take functions anymore. If parameters do not take functions anymore. If you want to customize them
you want to customize them based on the page number, use the new based on the page number, use the new [`numbering`]($page.numbering)
[`numbering`]($func/page.numbering) parameter or [`counter`]($func/counter) parameter or [`counter`]($counter) function instead.
function instead. - Added [`footer-descent`]($page.footer-descent) and
- Added [`footer-descent`]($func/page.footer-descent) and [`header-ascent`]($page.header-ascent) parameters
[`header-ascent`]($func/page.header-ascent) parameters
- Better default alignment in header and footer - Better default alignment in header and footer
- Fixed Arabic vowel placement - Fixed Arabic vowel placement
- Fixed PDF font embedding issues - Fixed PDF font embedding issues
- Renamed `math.formula` to [`math.equation`]($func/math.equation) - Renamed `math.formula` to [`math.equation`]($math.equation)
- Font family must be a named argument now: `[#set text(font: "..")]` - Font family must be a named argument now: `[#set text(font: "..")]`
- Added support for [hanging indent]($func/par.hanging-indent) - Added support for [hanging indent]($par.hanging-indent)
- Renamed paragraph `indent` to - Renamed paragraph `indent` to [`first-line-indent`]($par.first-line-indent)
[`first-line-indent`]($func/par.first-line-indent) - More accurate [logarithm]($calc.log) when base is `2` or `10`
- More accurate [logarithm]($func/calc.log) when base is `2` or `10`
- Improved some error messages - Improved some error messages
- Fixed layout of [`terms`]($func/terms) list - Fixed layout of [`terms`]($terms) list
- Web app improvements - Web app improvements
- Added template gallery - Added template gallery
@ -697,76 +682,75 @@ description: |
- New back button instead of four-dots button - New back button instead of four-dots button
- Lots of bug fixes - Lots of bug fixes
## February 25, 2023 ## February 25, 2023 { #_ }
- Font changes - Font changes
- New default font: Linux Libertine - New default font: Linux Libertine
- New default font for raw blocks: DejaVu Sans Mono - New default font for raw blocks: DejaVu Sans Mono
- New default font for math: Book weight of New Computer Modern Math - New default font for math: Book weight of New Computer Modern Math
- Lots of new math fonts available - Lots of new math fonts available
- Removed Latin Modern fonts in favor of New Computer Modern family - Removed Latin Modern fonts in favor of New Computer Modern family
- Removed unnecessary smallcaps fonts which are already accessible through - Removed unnecessary smallcaps fonts which are already accessible through the
the corresponding main font and the [`smallcaps`]($func/smallcaps) function corresponding main font and the [`smallcaps`]($smallcaps) function
- Improved default spacing for headings - Improved default spacing for headings
- Added [`panic`]($func/panic) function - Added [`panic`]($panic) function
- Added [`clusters`]($type/string.clusters) and - Added [`clusters`]($str.clusters) and [`codepoints`]($str.codepoints) methods
[`codepoints`]($type/string.codepoints) for strings
methods for strings - Support for multiple authors in [`set document`]($document.author)
- 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 crash when string is accessed at a position that is not a char boundary
- Fixed semicolon parsing in `[#var ;]` - Fixed semicolon parsing in `[#var ;]`
- Fixed incremental parsing when inserting backslash at end of `[#"abc"]` - Fixed incremental parsing when inserting backslash at end of `[#"abc"]`
- Fixed names of a few font families - Fixed names of a few font families (including Noto Sans Symbols and New
(including Noto Sans Symbols and New Computer Modern families) Computer Modern families)
- Fixed autocompletion for font families - Fixed autocompletion for font families
- Improved incremental compilation for user-defined functions - Improved incremental compilation for user-defined functions
## February 15, 2023 ## February 15, 2023 { #_ }
- [Box]($func/box) and [block]($func/block) have gained `fill`, `stroke`, - [Box]($box) and [block]($block) have gained `fill`, `stroke`, `radius`, and
`radius`, and `inset` properties `inset` properties
- Blocks may now be explicitly sized, fixed-height blocks can still break - Blocks may now be explicitly sized, fixed-height blocks can still break across
across pages pages
- Blocks can now be configured to be [`breakable`]($func/block.breakable) or not - Blocks can now be configured to be [`breakable`]($block.breakable) or not
- [Numbering style]($func/enum.numbering) can now be configured for nested enums - [Numbering style]($enum.numbering) can now be configured for nested enums
- [Markers]($func/list.marker) can now be configured for nested lists - [Markers]($list.marker) can now be configured for nested lists
- The [`eval`]($func/eval) function now expects code instead of markup and - The [`eval`]($eval) function now expects code instead of markup and returns an
returns an arbitrary value. Markup can still be evaluated by surrounding the arbitrary value. Markup can still be evaluated by surrounding the string with
string with brackets. brackets.
- PDFs generated by Typst now contain XMP metadata - PDFs generated by Typst now contain XMP metadata
- Link boxes are now disabled in PDF output - Link boxes are now disabled in PDF output
- Tables don't produce small empty cells before a pagebreak anymore - Tables don't produce small empty cells before a pagebreak anymore
- Fixed raw block highlighting bug - Fixed raw block highlighting bug
## February 12, 2023 ## February 12, 2023 { #_ }
- Shapes, images, and transformations (move/rotate/scale/repeat) are now - Shapes, images, and transformations (move/rotate/scale/repeat) are now
block-level. To integrate them into a paragraph, use a [`box`]($func/box) as block-level. To integrate them into a paragraph, use a [`box`]($box) as with
with other elements. other elements.
- A colon is now required in an "everything" show rule: Write `{show: it => ..}` - A colon is now required in an "everything" show rule: Write `{show: it => ..}`
instead of `{show it => ..}`. This prevents intermediate states that ruin instead of `{show it => ..}`. This prevents intermediate states that ruin your
your whole document. whole document.
- Non-math content like a shape or table in a math formula is now centered - Non-math content like a shape or table in a math formula is now centered
vertically vertically
- Support for widow and orphan prevention within containers - Support for widow and orphan prevention within containers
- Support for [RTL]($func/text.dir) in lists, grids, and tables - Support for [RTL]($text.dir) in lists, grids, and tables
- Support for explicit `{auto}` sizing for boxes and shapes - Support for explicit `{auto}` sizing for boxes and shapes
- Support for fractional (i.e. `{1fr}`) widths for boxes - Support for fractional (i.e. `{1fr}`) widths for boxes
- Fixed bug where columns jump to next page - Fixed bug where columns jump to next page
- Fixed bug where list items have no leading - Fixed bug where list items have no leading
- Fixed relative sizing in lists, squares and grid auto columns - Fixed relative sizing in lists, squares and grid auto columns
- Fixed relative displacement in [`place`]($func/place) function - Fixed relative displacement in [`place`]($place) function
- Fixed that lines don't have a size - Fixed that lines don't have a size
- Fixed bug where `{set document(..)}` complains about being after content - Fixed bug where `{set document(..)}` complains about being after content
- Fixed parsing of `{not in}` operation - Fixed parsing of `{not in}` operation
- Fixed hover tooltips in math - Fixed hover tooltips in math
- Fixed bug where a heading show rule may not contain a pagebreak when an - Fixed bug where a heading show rule may not contain a pagebreak when an
outline is present outline is present
- Added [`baseline`]($func/box.baseline) property on [`box`]($func/box) - Added [`baseline`]($box.baseline) property on [`box`]($box)
- Added [`tg`]($func/math.op) and [`ctg`]($func/math.op) operators in math - Added [`tg`]($math.op) and [`ctg`]($math.op) operators in math
- Added delimiter setting for [`cases`]($func/math.cases) function - Added delimiter setting for [`cases`]($math.cases) function
- Parentheses are now included when accepting a function autocompletion - Parentheses are now included when accepting a function autocompletion
## February 2, 2023 ## February 2, 2023 { #_ }
- Merged text and math symbols, renamed a few symbols - Merged text and math symbols, renamed a few symbols (including `infty` to
(including `infty` to `infinity` with the alias `oo`) `infinity` with the alias `oo`)
- Fixed missing italic mappings - Fixed missing italic mappings
- Math italics correction is now applied properly - Math italics correction is now applied properly
- Parentheses now scale in `[$zeta(x/2)$]` - Parentheses now scale in `[$zeta(x/2)$]`
@ -779,17 +763,17 @@ description: |
- Heading and list markers now parse consistently - Heading and list markers now parse consistently
- Allow arbitrary math directly in content - Allow arbitrary math directly in content
## January 30, 2023 ## January 30, 2023 { #_ }
[Go to the announcement blog post.](https://typst.app/blog/2023/january-update) [Go to the announcement blog post.](https://typst.app/blog/2023/january-update)
- New expression syntax in markup/math - New expression syntax in markup/math
- Blocks cannot be directly embedded in markup anymore - Blocks cannot be directly embedded in markup anymore
- Like other expressions, they now require a leading hashtag - Like other expressions, they now require a leading hashtag
- More expressions available with hashtag, including literals - More expressions available with hashtag, including literals (`[#"string"]`)
(`[#"string"]`) as well as field access and method call as well as field access and method call without space: `[#emoji.face]`
without space: `[#emoji.face]`
- New import syntax - New import syntax
- `[#import "module.typ"]` creates binding named `module` - `[#import "module.typ"]` creates binding named `module`
- `[#import "module.typ": a, b]` or `[#import "module.typ": *]` to import items - `[#import "module.typ": a, b]` or `[#import "module.typ": *]` to import
items
- `[#import emoji: face, turtle]` to import from already bound module - `[#import emoji: face, turtle]` to import from already bound module
- New symbol handling - New symbol handling
- Removed symbol notation - Removed symbol notation
@ -811,8 +795,8 @@ description: |
- To forcibly match two delimiters, use `lr` function - To forcibly match two delimiters, use `lr` function
- Line breaks may occur between matched delimiters - Line breaks may occur between matched delimiters
- Delimiters may also be unbalanced - Delimiters may also be unbalanced
- You can also use the `lr` function to scale the brackets - You can also use the `lr` function to scale the brackets (or just one
(or just one bracket) to a specific size manually bracket) to a specific size manually
- Multi-line math with alignment - Multi-line math with alignment
- The `\` character inserts a line break - The `\` character inserts a line break
- The `&` character defines an alignment point - The `&` character defines an alignment point
@ -835,10 +819,11 @@ description: |
- New shorthands: `[|`, `|]`, and `||` - New shorthands: `[|`, `|]`, and `||`
- New `attach` function, overridable attachments with `script` and `limit` - New `attach` function, overridable attachments with `script` and `limit`
- Manual spacing in math, with `h`, `thin`, `med`, `thick` and `quad` - 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)$]` - Symbols and other content may now be used like a function, e.g.
`[$zeta(x)$]`
- Added Fira Math font, removed Noto Sans Math font - Added Fira Math font, removed Noto Sans Math font
- Support for alternative math fonts through - Support for alternative math fonts through `[#show math.formula: set
`[#show math.formula: set text("Fira Math")]` text("Fira Math")]`
- More library improvements - More library improvements
- New `calc` module, `abs`, `min`, `max`, `even`, `odd` and `mod` moved there - New `calc` module, `abs`, `min`, `max`, `even`, `odd` and `mod` moved there
- New `message` argument on `{assert}` function - New `message` argument on `{assert}` function

View File

@ -6,8 +6,8 @@ description: |
# Community # Community
Hey and welcome to the Community page! We're so glad you're here. Typst is 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 developed by an early-stage startup and is still in its infancy, but it would be
would be pointless without people like you who are interested in it. 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 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 discuss any topic around Typst, typesetting, writing, the sciences, and
@ -22,9 +22,9 @@ Of course, you are also very welcome to connect with us on social media
[GitHub](https://github.com/typst)). [GitHub](https://github.com/typst)).
## What to share? { #want-to-share } ## What to share? { #want-to-share }
For our community, we want to foster versatility and inclusivity. For our community, we want to foster versatility and inclusivity. You are
You are welcome to post about any topic that you think would interest other welcome to post about any topic that you think would interest other community
community members, but if you need a little inspiration, here are a few ideas: 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 - Share and discuss your thoughts and ideas for new features or improvements
you'd like to see in Typst you'd like to see in Typst
@ -33,16 +33,15 @@ community members, but if you need a little inspiration, here are a few ideas:
- Share importable files or templates that you use to style your documents - Share importable files or templates that you use to style your documents
- Alert us of bugs you encounter while using Typst - Alert us of bugs you encounter while using Typst
## Beta test { #beta-test } ## Beta test
We are starting a public beta test of our product on March 21st, 2023. We are starting a public beta test of our product on March 21st, 2023. The Typst
The Typst compiler is still under active development and breaking changes can compiler is still under active development and breaking changes can occur at any
occur at any point. The compiler is developed in the open on point. The compiler is developed in the open on
[GitHub](https://github.com/typst/typst). [GitHub](https://github.com/typst/typst).
We will update the members of our Discord server and our social media followers We will update the members of our Discord server and our social media followers
when new features become available. We'll also update you on the when new features become available. We'll also update you on the development
development progress of large features. A development tracker will become progress of large features.
available on the documentation pages soon.
## How to support Typst { #support-typst } ## How to support Typst { #support-typst }
If you want to support Typst, there are multiple ways to do that! You can If you want to support Typst, there are multiple ways to do that! You can

View File

@ -4,7 +4,7 @@ description: |
similarities between Typst and LaTeX so you can get started quickly. similarities between Typst and LaTeX so you can get started quickly.
--- ---
# Guide for LaTeX users # Guide for LaTeX users { # }
This page is a good starting point if you have used LaTeX before and want to try 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 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 user perspective. Although Typst is not built upon LaTeX and has a different
@ -32,8 +32,8 @@ 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 `.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, 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 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 editor. [Paragraph breaks]($parbreak) work just as they do in LaTeX, just use a
use a blank line. blank line.
```example ```example
Hey there! Hey there!
@ -47,8 +47,8 @@ LaTeX uses the command `\section` to create a section heading. Nested headings
are indicated with `\subsection`, `\subsubsection`, etc. Depending on your are indicated with `\subsection`, `\subsubsection`, etc. Depending on your
document class, there is also `\part` or `\chapter`. document class, there is also `\part` or `\chapter`.
In Typst, [headings]($func/heading) are less verbose: You prefix the line with In Typst, [headings]($heading) are less verbose: You prefix the line with the
the heading on it with an equals sign and a space to get a first-order heading: 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 `[= 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 signs: `[== In this paper]`. You can nest headings as deeply as you'd like by
adding more equals signs. adding more equals signs.
@ -60,23 +60,23 @@ Emphasis (usually rendered as italic text) is expressed by enclosing text in
Here is a list of common markup commands used in LaTeX and their Typst 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). equivalents. You can also check out the [full syntax cheat sheet]($syntax).
| Element | LaTeX | Typst | See | | Element | LaTeX | Typst | See
|:-----------------|:--------------------------|:-----------------------|:-------------------------| |:-----------------|:--------------------------|:-----------------------|:--------------------
| Strong emphasis | `\textbf{strong}` | `[*strong*]` | [`strong`]($func/strong) | | Strong emphasis | `\textbf{strong}` | `[*strong*]` | [`strong`]($strong) |
| Emphasis | `\emph{emphasis}` | `[_emphasis_]` | [`emph`]($func/emph) | | Emphasis | `\emph{emphasis}` | `[_emphasis_]` | [`emph`]($emph) |
| Monospace / code | `\texttt{print(1)}` | ``[`print(1)`]`` | [`raw`]($func/raw) | | Monospace / code | `\texttt{print(1)}` | ``[`print(1)`]`` | [`raw`]($raw) |
| Link | `\url{https://typst.app}` | `[https://typst.app/]` | [`link`]($func/link) | | Link | `\url{https://typst.app}` | `[https://typst.app/]` | [`link`]($link) |
| Label | `\label{intro}` | `[<intro>]` | [`label`]($func/label) | | Label | `\label{intro}` | `[<intro>]` | [`label`]($label) |
| Reference | `\ref{intro}` | `[@intro]` | [`ref`]($func/ref) | | Reference | `\ref{intro}` | `[@intro]` | [`ref`]($ref) |
| Citation | `\cite{humphrey97}` | `[@humphrey97]` | [`cite`]($func/cite) | | Citation | `\cite{humphrey97}` | `[@humphrey97]` | [`cite`]($cite) |
| Bullet list | `itemize` environment | `[- List]` | [`list`]($func/list) | | Bullet list | `itemize` environment | `[- List]` | [`list`]($list) |
| Numbered list | `enumerate` environment | `[+ List]` | [`enum`]($func/enum) | | Numbered list | `enumerate` environment | `[+ List]` | [`enum`]($enum) |
| Term list | `description` environment | `[/ Term: List]` | [`terms`]($func/terms) | | Term list | `description` environment | `[/ Term: List]` | [`terms`]($terms) |
| Figure | `figure` environment | `figure` function | [`figure`]($func/figure) | | Figure | `figure` environment | `figure` function | [`figure`]($figure) |
| Table | `table` environment | `table` function | [`table`]($func/table) | | Table | `table` environment | `table` function | [`table`]($table) |
| Equation | `$x$`, `align` / `equation` environments | `[$x$]`, `[$ x = y $]` | [`equation`]($func/math.equation) | | Equation | `$x$`, `align` / `equation` environments | `[$x$]`, `[$ x = y $]` | [`equation`]($math.equation) |
[Lists]($func/list) do not rely on environments in Typst. Instead, they have [Lists]($list) do not rely on environments in Typst. Instead, they have
lightweight syntax like headings. To create an unordered list (`itemize`), lightweight syntax like headings. To create an unordered list (`itemize`),
prefix each line of an item with a hyphen: prefix each line of an item with a hyphen:
@ -100,11 +100,11 @@ To write this list in Typst...
```` ````
Nesting lists works just by using proper indentation. Adding a blank line in 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. between items results in a more [widely]($list.tight) spaced list.
To get a [numbered list]($func/enum) (`enumerate`) instead, use a `+` instead of To get a [numbered list]($enum) (`enumerate`) instead, use a `+` instead of the
the hyphen. For a [term list]($func/terms) (`description`), write hyphen. For a [term list]($terms) (`description`), write `[/ Term: Description]`
`[/ Term: Description]` instead. instead.
## How do I use a command? { #commands } ## How do I use a command? { #commands }
LaTeX heavily relies on commands (prefixed by backslashes). It uses these LaTeX heavily relies on commands (prefixed by backslashes). It uses these
@ -115,16 +115,16 @@ braces: `\cite{rasmus}`.
Typst differentiates between [markup mode and code mode]($scripting/#blocks). Typst differentiates between [markup mode and code mode]($scripting/#blocks).
The default is markup mode, where you compose text and apply syntactic 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, constructs such as `[*stars for bold text*]`. Code mode, on the other hand,
parallels programming languages like Python, providing the option to input parallels programming languages like Python, providing the option to input and
and execute segments of code. execute segments of code.
Within Typst's markup, you can switch to code mode for a single command (or 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, rather, _expression_) using a hashtag (`#`). This is how you call functions to,
for example, split your project into different [files]($scripting/#modules) for example, split your project into different [files]($scripting/#modules) or
or render text based on some [condition]($scripting/#conditionals). render text based on some [condition]($scripting/#conditionals). Within code
Within code mode, it is possible to include normal markup mode, it is possible to include normal markup [_content_]($content) by using
[_content_]($type/content) by using square brackets. Within code mode, this square brackets. Within code mode, this content is treated just as any other
content is treated just as any other normal value for a variable. normal value for a variable.
```example ```example
First, a rectangle: First, a rectangle:
@ -142,15 +142,14 @@ And finally a little loop:
] ]
``` ```
A function call always involves the name of the function ([`rect`]($func/rect), A function call always involves the name of the function ([`rect`]($rect),
[`underline`]($func/underline), [`calc.max`]($func/calc.max), [`underline`]($underline), [`calc.max`]($calc.max), [`range`]($range)) followed
[`range`]($func/range)) followed by parentheses (as opposed to LaTeX where the by parentheses (as opposed to LaTeX where the square brackets and curly braces
square brackets and curly braces are optional if the macro requires no are optional if the macro requires no arguments). The expected list of arguments
arguments). The expected list of arguments passed within those parentheses passed within those parentheses depends on the concrete function and is
depends on the concrete function and is specified in the specified in the [reference]($reference).
[reference]($reference).
### Arguments { #arguments } ### Arguments
A function can have multiple arguments. Some arguments are positional, i.e., you A function can have multiple arguments. Some arguments are positional, i.e., you
just provide the value: The function `[#lower("SCREAM")]` returns its argument just provide the value: The function `[#lower("SCREAM")]` returns its argument
in all-lowercase. Many functions use named arguments instead of positional in all-lowercase. Many functions use named arguments instead of positional
@ -173,13 +172,13 @@ Named arguments are similar to how some LaTeX environments are configured, for
example, you would type `\begin{enumerate}[label={\alph*)}]` to start a list example, you would type `\begin{enumerate}[label={\alph*)}]` to start a list
with the labels `a)`, `b)`, and so on. with the labels `a)`, `b)`, and so on.
Often, you want to provide some [content]($type/content) to a function. For Often, you want to provide some [content]($content) to a function. For example,
example, the LaTeX command `\underline{Alternative A}` would translate to the LaTeX command `\underline{Alternative A}` would translate to
`[#underline([Alternative A])]` in Typst. The square brackets indicate that a `[#underline([Alternative A])]` in Typst. The square brackets indicate that a
value is [content]($type/content). Within these brackets, you can use normal value is [content]($content). Within these brackets, you can use normal markup.
markup. However, that's a lot of parentheses for a pretty simple construct. However, that's a lot of parentheses for a pretty simple construct. This is why
This is why you can also move trailing content arguments after the parentheses you can also move trailing content arguments after the parentheses (and omit the
(and omit the parentheses if they would end up empty). parentheses if they would end up empty).
```example ```example
Typst is an #underline[alternative] Typst is an #underline[alternative]
@ -188,20 +187,20 @@ to LaTeX.
#rect(fill: aqua)[Get started here!] #rect(fill: aqua)[Get started here!]
``` ```
### Data types { #data-types } ### Data types
You likely already noticed that the arguments have distinctive data types. Typst 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 supports many data types. 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 important ones and how to write them. In order to specify values of any of these
types, you have to be in code mode! types, you have to be in code mode!
| Data type | Example | | Data type | Example |
|:-------------------------------------|:----------------------------------| |:--------------------------------|:----------------------------------|
| [Content]($type/content) | `{[*fast* typesetting]}` | | [Content]($content) | `{[*fast* typesetting]}` |
| [String]($type/string) | `{"Pietro S. Author"}` | | [String]($str) | `{"Pietro S. Author"}` |
| [Integer]($type/integer) | `{23}` | | [Integer]($int) | `{23}` |
| [Floating point number]($type/float) | `{1.459}` | | [Floating point number]($float) | `{1.459}` |
| [Absolute length]($type/length) | `{12pt}`, `{5in}`, `{0.3cm}`, ... | | [Absolute length]($length) | `{12pt}`, `{5in}`, `{0.3cm}`, ... |
| [Relative length]($type/ratio) | `{65%}` | | [Relative length]($ratio) | `{65%}` |
The difference between content and string is that content can contain markup, 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 including function calls, while a string really is just a plain sequence of
@ -219,9 +218,9 @@ braces and only affect that argument. Other commands such as
content within the document or current scope. content within the document or current scope.
In Typst, the same function can be used both to affect the appearance for the 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, remainder of the document, a block (or scope), or just its arguments. For
`[#text(weight: "bold")[bold text]]` will only embolden its argument, while example, `[#text(weight: "bold")[bold text]]` will only embolden its argument,
`[#set text(weight: "bold")]` will embolden any text until the end of the 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 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 immediately obvious based on whether it is used in a call or a
[set rule.]($styling/#set-rules) [set rule.]($styling/#set-rules)
@ -249,9 +248,9 @@ Good results can only be obtained by
``` ```
The `+` is syntactic sugar (think of it as an abbreviation) for a call to the 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 [`{enum}`]($enum) function, to which we apply a set rule above.
syntax is linked to a function in this way.]($syntax) If you need to style an [Most syntax is linked to a function in this way.]($syntax) If you need to style
element beyond what its arguments enable, you can completely redefine its an element beyond what its arguments enable, you can completely redefine its
appearance with a [show rule]($styling/#show-rules) (somewhat comparable to appearance with a [show rule]($styling/#show-rules) (somewhat comparable to
`\renewcommand`). `\renewcommand`).
@ -261,7 +260,7 @@ 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 may have replaced `article` with another value such as `report` and `amsart` to
select a different look. select a different look.
When using Typst, you style your documents with [functions]($type/function). When using Typst, you style your documents with [functions]($function).
Typically, you use a template that provides a function that styles your whole 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 document. First, you import the function from a template file. Then, you apply
it to your whole document. This is accomplished with a it to your whole document. This is accomplished with a
@ -357,7 +356,7 @@ paragraphs right here!
``` ```
The [`{import}`]($scripting/#modules) statement makes The [`{import}`]($scripting/#modules) statement makes
[functions]($type/function) (and other definitions) from another file available. [functions]($function) (and other definitions) from another file available.
In this example, it imports the `conf` function from the `conf.typ` file. This 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 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 it to the document and also configure some metadata of the article. After
@ -393,23 +392,23 @@ 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 is built right-in. Below, we compiled a table with frequently loaded packages
and their corresponding Typst functions. and their corresponding Typst functions.
| LaTeX Package | Typst Alternative | | LaTeX Package | Typst Alternative |
|:--------------------------------|:---------------------------------------------------------------------| |:--------------------------------|:------------------------------------------------------------- |
| graphicx, svg | [`image`]($func/image) function | | graphicx, svg | [`image`]($image) function |
| tabularx | [`table`]($func/table), [`grid`]($func/grid) functions | | tabularx | [`table`]($table), [`grid`]($grid) functions |
| fontenc, inputenc, unicode-math | Just start writing! | | fontenc, inputenc, unicode-math | Just start writing! |
| babel, polyglossia | [`text`]($func/text.lang) function: `[#set text(lang: "zh")]` | | babel, polyglossia | [`text`]($text.lang) function: `[#set text(lang: "zh")]` |
| amsmath | [Math mode]($category/math) | | amsmath | [Math mode]($category/math) |
| amsfonts, amssymb | [`sym`]($category/symbols) module and [syntax]($syntax/#math) | | amsfonts, amssymb | [`sym`]($category/symbols) module and [syntax]($syntax/#math) |
| geometry, fancyhdr | [`page`]($func/page) function | | geometry, fancyhdr | [`page`]($page) function |
| xcolor | [`text`]($func/text.fill) function: `[#set text(fill: rgb("#0178A4"))]` | | xcolor | [`text`]($text.fill) function: `[#set text(fill: rgb("#0178A4"))]` |
| hyperref | [`link`]($func/link) function | | hyperref | [`link`]($link) function |
| bibtex, biblatex, natbib | [`cite`]($func/cite), [`bibliography`]($func/bibliography) functions | | bibtex, biblatex, natbib | [`cite`]($cite), [`bibliography`]($bibliography) functions |
| lstlisting, minted | [`raw`]($func/raw) function and syntax | | lstlisting, minted | [`raw`]($raw) function and syntax |
| parskip | [`block`]($func/block.spacing) and [`par`]($func/par.first-line-indent) functions | | parskip | [`block`]($block.spacing) and [`par`]($par.first-line-indent) functions |
| csquotes | Set the [`text`]($func/text.lang) language and type `["]` or `[']` | | csquotes | Set the [`text`]($text.lang) language and type `["]` or `[']` |
| caption | [`figure`]($func/figure) function | | caption | [`figure`]($figure) function |
| enumitem | [`list`]($func/list), [`enum`]($func/enum), [`terms`]($func/terms) functions | | enumitem | [`list`]($list), [`enum`]($enum), [`terms`]($terms) functions |
If you need to load functions and variables from another file, for example, to 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 use a template, you can use an [`import`]($scripting/#modules) statement. If you
@ -444,12 +443,12 @@ Typst pre-defines a lot of useful variables in math mode. All Greek (`alpha`,
their name. Some symbols are additionally available through shorthands, such as their name. Some symbols are additionally available through shorthands, such as
`<=`, `>=`, and `->`. `<=`, `>=`, and `->`.
Refer to the [symbol page]($func/symbol) for a full list of the symbols. Refer to the [symbol pages]($reference/symbols) for a full list of the symbols.
If a symbol is missing, you can also access it through a If a symbol is missing, you can also access it through a
[Unicode escape sequence]($syntax/#escapes). [Unicode escape sequence]($syntax/#escapes).
Alternate and related forms of symbols can often be selected by Alternate and related forms of symbols can often be selected by
[appending a modifier]($type/symbol) after a period. For example, [appending a modifier]($symbol) after a period. For example,
`arrow.l.squiggly` inserts a squiggly left-pointing arrow. If you want to insert `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: multiletter text in your expression instead, enclose it in double quotes:
@ -459,7 +458,7 @@ $ delta "if" x <= 5 $
In Typst, delimiters will scale automatically for their expressions, just as if In Typst, delimiters will scale automatically for their expressions, just as if
`\left` and `\right` commands were implicitly inserted in LaTeX. You can `\left` and `\right` commands were implicitly inserted in LaTeX. You can
customize delimiter behavior using the [`lr` function]($func/math.lr). To customize delimiter behavior using the [`lr` function]($math.lr). To
prevent a pair of delimiters from scaling, you can escape them with backslashes. 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 Typst will automatically set terms around a slash `/` as a fraction while
@ -470,7 +469,7 @@ fraction will appear in the output.
$ f(x) = (x + 1) / x $ $ f(x) = (x + 1) / x $
``` ```
[Sub- and superscripts]($func/math.attach) work similarly in Typst and LaTeX. [Sub- and superscripts]($math.attach) work similarly in Typst and LaTeX.
`{$x^2$}` will produce a superscript, `{$x_2$}` yields a subscript. If you want `{$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 to include more than one value in a sub- or superscript, enclose their contents
in parentheses: `{$x_(a -> epsilon)$}`. in parentheses: `{$x_(a -> epsilon)$}`.
@ -487,7 +486,7 @@ $ f(x, y) := cases(
) $ ) $
``` ```
The above example uses the [`cases` function]($func/math.cases) to describe f. Within The above example uses the [`cases` function]($math.cases) to describe f. Within
the cases function, arguments are delimited using commas and the arguments are the cases function, arguments are delimited using commas and the arguments are
also interpreted as math. If you need to interpret arguments as Typst also interpreted as math. If you need to interpret arguments as Typst
values instead, prefix them with a `#`: values instead, prefix them with a `#`:
@ -514,7 +513,7 @@ If you'd like to enter your mathematical symbols directly as Unicode, that is
possible, too! possible, too!
Math calls can have two-dimensional argument lists using `;` as a delimiter. The 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 most common use for this is the [`mat` function]($math.mat) that creates
matrices: matrices:
```example ```example
@ -531,13 +530,13 @@ Papers set in LaTeX have an unmistakeable look. This is mostly due to their
font, Computer Modern, justification, narrow line spacing, and wide margins. font, Computer Modern, justification, narrow line spacing, and wide margins.
The example below The example below
- sets wide [margins]($func/page.margin) - sets wide [margins]($page.margin)
- enables [justification]($func/par.justify), [tighter lines]($func/par.leading) - enables [justification]($par.justify), [tighter lines]($par.leading) and
and [first-line-indent]($func/par.first-line-indent) [first-line-indent]($par.first-line-indent)
- [sets the font]($func/text.font) to "New Computer Modern", an OpenType - [sets the font]($text.font) to "New Computer Modern", an OpenType derivate of
derivate of Computer Modern for both text and [code blocks]($func/raw) Computer Modern for both text and [code blocks]($raw)
- disables paragraph [spacing]($func/block.spacing) - disables paragraph [spacing]($block.spacing)
- increases [spacing]($func/block.spacing) around [headings]($func/heading) - increases [spacing]($block.spacing) around [headings]($heading)
```typ ```typ
#set page(margin: 1.75in) #set page(margin: 1.75in)
@ -566,9 +565,9 @@ applicable, contains possible workarounds.
- **Change page margins without a pagebreak.** In LaTeX, margins can always be - **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 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 [`page` function]($page) which will force a page break. If you just want a few
a few paragraphs to stretch into the margins, then reverting to the old paragraphs to stretch into the margins, then reverting to the old margins, you
margins, you can use the [`pad` function]($func/pad) with negative padding. can use the [`pad` function]($pad) with negative padding.
- **Floating figures.** The figure command of LaTeX will smartly choose where to - **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 place a figure, be it on the top or bottom of the page, or a dedicated figure
@ -589,9 +588,9 @@ applicable, contains possible workarounds.
orphans, it uses less sophisticated algorithms to determine page breaks. You orphans, it uses less sophisticated algorithms to determine page breaks. You
can insert custom page breaks in Typst using `[#pagebreak(weak: true)]` before can insert custom page breaks in Typst using `[#pagebreak(weak: true)]` before
submitting your document. The argument `weak` ensures that no double page submitting your document. The argument `weak` ensures that no double page
break will be created if this spot would be a natural page break break will be created if this spot would be a natural page break anyways. You
anyways. You can also use `[#v(1fr)]` to distribute space on your page. It can also use `[#v(1fr)]` to distribute space on your page. It works quite
works quite similar to LaTeX's `\vfill`. similar to LaTeX's `\vfill`.
- **Bibliographies are not customizable.** In LaTeX, the packages `bibtex`, - **Bibliographies are not customizable.** In LaTeX, the packages `bibtex`,
`biblatex`, and `natbib` provide a wide range of reference and bibliography `biblatex`, and `natbib` provide a wide range of reference and bibliography

View File

@ -16,28 +16,29 @@ you can get started with writing.
In Typst, each page has a width, a height, and margins on all four sides. The In Typst, each page has a width, a height, and margins on all four sides. The
top and bottom margins may contain a header and footer. The set rule of the top and bottom margins may contain a header and footer. The set rule of the
[`{page}`]($func/page) element is where you control all of the page setup. If [`{page}`]($page) element is where you control all of the page setup. If you
you make changes with this set rule, Typst will ensure that there is a new and make changes with this set rule, Typst will ensure that there is a new and
conforming empty page afterward, so it may insert a page break. Therefore, it conforming empty page afterward, so it may insert a page break. Therefore, it is
is best to specify your [`{page}`]($func/page) set rule at the start of your best to specify your [`{page}`]($page) set rule at the start of your document or
document or in your template. in your template.
```example ```example
#set rect( #set rect(
width: 100%, width: 100%,
height: 100%, height: 100%,
inset: 4pt inset: 4pt,
) )
>>> #set text(6pt) >>> #set text(6pt)
>>> #set page(margin: auto)
#set page( #set page(
"iso-b7", paper: "iso-b7",
header: rect[Header], header: rect(fill: aqua)[Header],
footer: rect[Footer], footer: rect(fill: aqua)[Footer],
number-align: center, number-align: center,
) )
#rect(fill: rgb("#565565")) #rect(fill: aqua)
``` ```
This example visualizes the dimensions for page content, headers, and footers. This example visualizes the dimensions for page content, headers, and footers.
@ -45,45 +46,46 @@ The page content is the page size (ISO B7) minus each side's default margin. In
the top and the bottom margin, there are stroked rectangles visualizing the the top and the bottom margin, there are stroked rectangles visualizing the
header and footer. They do not touch the main content, instead, they are offset header and footer. They do not touch the main content, instead, they are offset
by 30% of the respective margin. You can control this offset by specifying the by 30% of the respective margin. You can control this offset by specifying the
[`header-ascent`]($func/page.header-ascent) and [`header-ascent`]($page.header-ascent) and
[`footer-descent`]($func/page.footer-descent) arguments. [`footer-descent`]($page.footer-descent) arguments.
Below, the guide will go more into detail on how to accomplish common page setup Below, the guide will go more into detail on how to accomplish common page setup
requirements with examples. requirements with examples.
## Customize page size and margins { #customize-margins } ## Customize page size and margins { #customize-margins }
Typst's default page size is A4 paper. Depending on your region and your Typst's default page size is A4 paper. Depending on your region and your use
use case, you will want to change this. You can do this by using the case, you will want to change this. You can do this by using the
[`{page}`]($func/page) set rule and passing it a string argument to use a common [`{page}`]($page) set rule and passing it a string argument to use a common page
page size. Options include the complete ISO 216 series (e.g. `"iso-a4"`, size. Options include the complete ISO 216 series (e.g. `"iso-a4"`, `"iso-c2"`),
`"iso-c2"`), customary US formats like `"us-legal"` or `"us-letter"`, and more. customary US formats like `"us-legal"` or `"us-letter"`, and more. Check out the
Check out the reference for the [page's paper argument]($func/page.paper) to reference for the [page's paper argument]($page.paper) to learn about all
learn about all available options. available options.
```example ```example
>>> #set page(margin: auto)
#set page("us-letter") #set page("us-letter")
This page likes freedom. This page likes freedom.
``` ```
If you need to customize your page size to some dimensions, you can specify the If you need to customize your page size to some dimensions, you can specify the
named arguments [`width`]($func/page.width) and [`height`]($func/page.height) named arguments [`width`]($page.width) and [`height`]($page.height) instead.
instead.
```example ```example
>>> #set page(margin: auto)
#set page(width: 12cm, height: 12cm) #set page(width: 12cm, height: 12cm)
This page is a square. This page is a square.
``` ```
### Change the page's margins { #change-margins } ### Change the page's margins { #change-margins }
Margins are a vital ingredient for good typography: [Typographers consider lines Margins are a vital ingredient for good typography:
that fit between 45 and 75 characters best length for [Typographers consider lines that fit between 45 and 75 characters best length
legibility](http://webtypography.net/2.1.2) and your margins and for legibility](http://webtypography.net/2.1.2) and your margins and
[columns](#columns) help define line widths. By default, Typst will create [columns](#columns) help define line widths. By default, Typst will create
margins proportional to the page size of your document. To set custom margins, margins proportional to the page size of your document. To set custom margins,
you will use the [`margin`]($func/page.margin) argument in the you will use the [`margin`]($page.margin) argument in the [`{page}`]($page) set
[`{page}`]($func/page) set rule. rule.
The `margin` argument will accept a length if you want to set all margins to the The `margin` argument will accept a length if you want to set all margins to the
same width. However, you often want to set different margins on each side. To do same width. However, you often want to set different margins on each side. To do
@ -119,11 +121,7 @@ the margin dictionary. The `inside` margin points towards the spine, and the
`outside` margin points towards the edge of the bound book. `outside` margin points towards the edge of the bound book.
```typ ```typ
#set page(margin: ( #set page(margin: (inside: 2.5cm, outside: 2cm, y: 1.75cm))
inside: 2.5cm,
outside: 2cm,
y: 1.75cm,
))
``` ```
Typst will assume that documents written in Left-to-Right scripts are bound on Typst will assume that documents written in Left-to-Right scripts are bound on
@ -133,13 +131,12 @@ output by a different app, the binding is reversed from Typst's perspective.
Also, some books, like English-language Mangas are customarily bound on the Also, some books, like English-language Mangas are customarily bound on the
right, despite English using Left-to-Right script. To change the binding side right, despite English using Left-to-Right script. To change the binding side
and explicitly set where the `inside` and `outside` are, set the and explicitly set where the `inside` and `outside` are, set the
[`binding`]($func/page.binding) argument in the [`{page}`]($func/page) set rule. [`binding`]($page.binding) argument in the [`{page}`]($page) set rule.
```typ ```typ
#set text(lang: "es")
// Produce a book bound on the right, // Produce a book bound on the right,
// even though it is set in Spanish. // even though it is set in Spanish.
#set text(lang: "es")
#set page(binding: right) #set page(binding: right)
``` ```
@ -151,9 +148,9 @@ Headers and footers are inserted in the top and bottom margins of every page.
You can add custom headers and footers or just insert a page number. You can add custom headers and footers or just insert a page number.
In case you need more than just a page number, the best way to insert a header In case you need more than just a page number, the best way to insert a header
and a footer are the [`header`]($func/page.header) and and a footer are the [`header`]($page.header) and [`footer`]($page.footer)
[`footer`]($func/page.footer) arguments of the [`{page}`]($func/page) set rule. arguments of the [`{page}`]($page) set rule. You can pass any content as their
You can pass any content as their values: values:
```example ```example
>>> #set page("a5", margin: (x: 2.5cm, y: 3cm)) >>> #set page("a5", margin: (x: 2.5cm, y: 3cm))
@ -168,7 +165,7 @@ You can pass any content as their values:
Headers are bottom-aligned by default so that they do not collide with the top Headers are bottom-aligned by default so that they do not collide with the top
edge of the page. You can change this by wrapping your header in the edge of the page. You can change this by wrapping your header in the
[`{align}`]($func/align) function. [`{align}`]($align) function.
### Different header and footer on specific pages { #specific-pages } ### Different header and footer on specific pages { #specific-pages }
You'll need different headers and footers on some pages. For example, you may You'll need different headers and footers on some pages. For example, you may
@ -191,13 +188,13 @@ conditionally remove the header on the first page:
``` ```
This example may look intimidating, but let's break it down: We are telling This example may look intimidating, but let's break it down: We are telling
Typst that the header depends on the current [location]($func/locate). The `loc` Typst that the header depends on the current [location]($locate). The `loc`
value allows other functions to find out where on the page we currently are. We value allows other functions to find out where on the page we currently are. We
then ask Typst if the page [counter]($func/counter) is larger than one at our then ask Typst if the page [counter]($counter) is larger than one at our current
current position. The page counter starts at one, so we are skipping the header position. The page counter starts at one, so we are skipping the header on a
on a single page. Counters may have multiple levels. This feature is used for single page. Counters may have multiple levels. This feature is used for items
items like headings, but the page counter will always have a single level, so we like headings, but the page counter will always have a single level, so we can
can just look at the first one. just look at the first one.
You can, of course, add an `else` to this example to add a different header to You can, of course, add an `else` to this example to add a different header to
the first page instead. the first page instead.
@ -206,8 +203,8 @@ the first page instead.
The technique described in the previous section can be adapted to perform more The technique described in the previous section can be adapted to perform more
advanced tasks using Typst's labels. For example, pages with big tables could advanced tasks using Typst's labels. For example, pages with big tables could
omit their headers to help keep clutter down. We will mark our tables with a omit their headers to help keep clutter down. We will mark our tables with a
`<big-table>` [label]($type/label) and use the [query system]($func/query) to `<big-table>` [label]($label) and use the [query system]($query) to find out if
find out if such a label exists on the current page: such a label exists on the current page:
```typ ```typ
>>> #set page("a5", margin: (x: 2.5cm, y: 3cm)) >>> #set page("a5", margin: (x: 2.5cm, y: 3cm))
@ -232,8 +229,10 @@ find out if such a label exists on the current page:
#pagebreak() #pagebreak()
#table( #table(
columns: 2 * (1fr, ) columns: 2 * (1fr,),
)[A][B][C][D] <big-table> [A], [B],
[C], [D],
) <big-table>
``` ```
Here, we query for all instances of the `<big-table>` label. We then check that Here, we query for all instances of the `<big-table>` label. We then check that
@ -243,10 +242,10 @@ could add an `else` to add another header instead of deleting it.
## Add and customize page numbers { #page-numbers } ## Add and customize page numbers { #page-numbers }
Page numbers help readers keep track of and reference your document more easily. Page numbers help readers keep track of and reference your document more easily.
The simplest way to insert footnotes is the [`numbering`]($func/page.numbering) The simplest way to insert footnotes is the [`numbering`]($page.numbering)
argument of the [`{page}`]($func/page) set rule. You can pass a [_numbering argument of the [`{page}`]($page) set rule. You can pass a [_numbering
pattern_]($func/numbering.numbering) string that shows how you want your pages pattern_]($numbering.numbering) string that shows how you want your pages to be
to be numbered. numbered.
```example ```example
>>> #set page("iso-b6", margin: 1.75cm) >>> #set page("iso-b6", margin: 1.75cm)
@ -278,21 +277,21 @@ the string.
This is one of many numbered pages. This is one of many numbered pages.
``` ```
Go to the [`{numbering}` function reference]($func/numbering.numbering) to learn Go to the [`{numbering}` function reference]($numbering.numbering) to learn more
more about the arguments you can pass here. about the arguments you can pass here.
In case you need to right- or left-align the page number, use the In case you need to right- or left-align the page number, use the
[`number-align`]($func/page.number-align) argument of the [`{page}`]($func/page) [`number-align`]($page.number-align) argument of the [`{page}`]($page) set rule.
set rule. Alternating alignment between even and odd pages is not currently Alternating alignment between even and odd pages is not currently supported
supported using this property. To do this, you'll need to specify a custom using this property. To do this, you'll need to specify a custom footer with
footer with your footnote and query the page counter as described in the section your footnote and query the page counter as described in the section on
on conditionally omitting headers and footers. conditionally omitting headers and footers.
### Custom footer with page numbers { #custom-footer-with-page-numbers } ### Custom footer with page numbers
Sometimes, you need to add other content than a page number to your footer. Sometimes, you need to add other content than a page number to your footer.
However, once a footer is specified, the [`numbering`]($func/page.numbering) However, once a footer is specified, the [`numbering`]($page.numbering) argument
argument of the [`{page}`]($func/page) set rule is ignored. This section shows of the [`{page}`]($page) set rule is ignored. This section shows you how to add
you how to add a custom footer with page numbers and more. a custom footer with page numbers and more.
```example ```example
>>> #set page("iso-b6", margin: 1.75cm) >>> #set page("iso-b6", margin: 1.75cm)
@ -319,7 +318,7 @@ This page has a custom footer.
The example above shows how to add a custom footer with page numbers. First, we The example above shows how to add a custom footer with page numbers. First, we
need to recover the page number using the page counter. For this, we are using need to recover the page number using the page counter. For this, we are using
the [`{locate}` function]($func/locate) to check the page counter, just like in the [`{locate}` function]($locate) to check the page counter, just like in
the conditional header section. We then store the current and final page number the conditional header section. We then store the current and final page number
in variables. in variables.
@ -328,8 +327,8 @@ insert all the free space on the line, and finally display the current page
number and the page total. This would work just the same in the header and with number and the page total. This would work just the same in the header and with
any content. any content.
We can, of course, use the [`{numbering}` function]($func/numbering) to use We can, of course, use the [`{numbering}` function]($numbering) to use numbering
numbering pattern strings like before: pattern strings like before:
```example ```example
>>> #set page("iso-b6", margin: 1.75cm) >>> #set page("iso-b6", margin: 1.75cm)
@ -395,10 +394,10 @@ This page has a custom footer.
``` ```
In this example, we use the number of pages to create an array of In this example, we use the number of pages to create an array of
[circles]($func/circle). The circles are wrapped in a [box]($func/box) so they [circles]($circle). The circles are wrapped in a [box]($box) so they can all
can all appear on the same line because they are blocks and would otherwise appear on the same line because they are blocks and would otherwise create
create paragraph breaks. The length of this [array]($type/array) depends on the paragraph breaks. The length of this [array]($array) depends on the current page
current page number. number.
We then insert the circles at the right side of the footer, with 1pt of space We then insert the circles at the right side of the footer, with 1pt of space
between them. The join method of an array will attempt to between them. The join method of an array will attempt to
@ -406,8 +405,8 @@ between them. The join method of an array will attempt to
value, interspersed with its argument. In our case, we get a single content value, interspersed with its argument. In our case, we get a single content
value with circles and spaces between them that we can use with the align value with circles and spaces between them that we can use with the align
function. Finally, we use another box to ensure that the text and the circles function. Finally, we use another box to ensure that the text and the circles
can share a line and use the [`inset` argument]($func/box.inset) to raise the can share a line and use the [`inset` argument]($box.inset) to raise the circles
circles a bit so they line up nicely with the text. a bit so they line up nicely with the text.
### Reset the page number and skip pages { #skip-pages } ### Reset the page number and skip pages { #skip-pages }
Do you, at some point in your document, need to reset the page number? Maybe you Do you, at some point in your document, need to reset the page number? Maybe you
@ -416,8 +415,7 @@ to skip a few page numbers because you will insert pages into the final printed
product. product.
The right way to modify the page number is to manipulate the page The right way to modify the page number is to manipulate the page
[counter]($func/counter). The simplest manipulation is to set the counter back [counter]($counter). The simplest manipulation is to set the counter back to 1.
to 1.
```typ ```typ
#counter(page).update(1) #counter(page).update(1)
@ -435,8 +433,8 @@ In this example, we skip five pages. `i` is the current value of the page
counter and `i + 5` is the return value of our function. counter and `i + 5` is the return value of our function.
In case you need to retrieve the actual page number instead of the value of the In case you need to retrieve the actual page number instead of the value of the
page counter, you can use the [`page`]($func/locate) method on the argument of page counter, you can use the [`page`]($locate) method on the argument of the
the `{locate}` closure: `{locate}` closure:
```example ```example
#counter(page).update(i => i + 5) #counter(page).update(i => i + 5)
@ -447,7 +445,7 @@ the `{locate}` closure:
``` ```
You can also obtain the page numbering pattern from the `{locate}` closure You can also obtain the page numbering pattern from the `{locate}` closure
parameter with the [`page-numbering`]($func/locate) method. parameter with the [`page-numbering`]($locate) method.
## Add columns { #columns } ## Add columns { #columns }
Add columns to your document to fit more on a page while maintaining legible Add columns to your document to fit more on a page while maintaining legible
@ -455,7 +453,7 @@ line lengths. Columns are vertical blocks of text which are separated by some
whitespace. This space is called the gutter. whitespace. This space is called the gutter.
If all of your content needs to be laid out in columns, you can just specify the If all of your content needs to be laid out in columns, you can just specify the
desired number of columns in the [`{page}`]($func/page.columns) set rule: desired number of columns in the [`{page}`]($page.columns) set rule:
```example ```example
>>> #set page(height: 120pt) >>> #set page(height: 120pt)
@ -469,8 +467,8 @@ in the next section.
### Use columns anywhere in your document { #columns-anywhere } ### Use columns anywhere in your document { #columns-anywhere }
Very commonly, scientific papers have a single-column title and abstract, while Very commonly, scientific papers have a single-column title and abstract, while
the main body is set in two-columns. To achieve this effect, Typst includes a the main body is set in two-columns. To achieve this effect, Typst includes a
standalone [`{columns}` function]($func/columns) that can be used to insert standalone [`{columns}` function]($columns) that can be used to insert columns
columns anywhere on a page. anywhere on a page.
Conceptually, the `columns` function must wrap the content of the columns: Conceptually, the `columns` function must wrap the content of the columns:
@ -502,8 +500,8 @@ nesting and write more legible Typst markup:
``` ```
The show rule will wrap everything that comes after it in its function. The The show rule will wrap everything that comes after it in its function. The
[`with` mehtod]($type/function.with) allows us to pass arguments, in this case, [`with` mehtod]($function.with) allows us to pass arguments, in this case, the
the column count, to a function without calling it. column count, to a function without calling it.
Another use of the `columns` function is to create columns inside of a container Another use of the `columns` function is to create columns inside of a container
like a rectangle or to customize gutter size: like a rectangle or to customize gutter size:
@ -523,24 +521,23 @@ like a rectangle or to customize gutter size:
) )
``` ```
### Balanced columns { #balanced-columns } ### Balanced columns
If the columns on the last page of a document differ greatly in length, they may If the columns on the last page of a document differ greatly in length, they may
create a lopsided and unappealing layout. That's why typographers will often create a lopsided and unappealing layout. That's why typographers will often
equalize the length of columns on the last page. This effect is called balancing equalize the length of columns on the last page. This effect is called balancing
columns. Typst cannot yet balance columns automatically. However, you can columns. Typst cannot yet balance columns automatically. However, you can
balance columns manually by placing [`[#colbreak()]`]($func/colbreak) at an balance columns manually by placing [`[#colbreak()]`]($colbreak) at an
appropriate spot in your markup, creating the desired column break manually. appropriate spot in your markup, creating the desired column break manually.
## One-off modifications { #one-off-modifications } ## One-off modifications
You do not need to override your page settings if you need to insert a single You do not need to override your page settings if you need to insert a single
page with a different setup. For example, you may want to insert a page that's page with a different setup. For example, you may want to insert a page that's
flipped to landscape to insert a big table or change the margin and columns for flipped to landscape to insert a big table or change the margin and columns for
your title page. In this case, you can call [`{page}`]($func/page) as a function your title page. In this case, you can call [`{page}`]($page) as a function with
with your content as an argument and the overrides as the other arguments. This your content as an argument and the overrides as the other arguments. This will
will insert enough new pages with your overridden settings to place your content insert enough new pages with your overridden settings to place your content on
on them. Typst will revert to the page settings from the set rule after the them. Typst will revert to the page settings from the set rule after the call.
call.
```example ```example
>>> #set page("a6") >>> #set page("a6")

View File

@ -7,6 +7,6 @@ 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 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! to Typst for LaTeX users. Feel free to propose other topics for guides!
## List of Guides { #list-of-guides } ## List of Guides
- [Guide for LaTeX users]($guides/guide-for-latex-users) - [Guide for LaTeX users]($guides/guide-for-latex-users)
- [Page setup guide]($guides/page-setup-guide) - [Page setup guide]($guides/page-setup-guide)

View File

@ -10,6 +10,9 @@ 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 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. 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. 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. 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.

View File

@ -1,33 +1,26 @@
types: | # Descriptions of the documentation categories.
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 foundations: |
programming languages, Typst provides a special type for _content._ A value of Foundational types and functions.
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 Here, you'll find documentation for basic data types like [integers]($int) and
all of them here, they are explained where they are relevant. [strings]($int) as well as details about core computational functions.
text: | text: |
Text styling. Text styling.
The [text function]($func/text) is of particular interest. The [text function]($text) is of particular interest.
math: | math: |
Typst has special [syntax]($syntax/#math) and library functions Typst has special [syntax]($syntax/#math) and library functions to typeset
to typeset mathematical formulas. Math formulas can be displayed inline with mathematical formulas. Math formulas can be displayed inline with text or as
text or as separate blocks. They will be typeset into their own block if they separate blocks. They will be typeset into their own block if they start and
start and end with at least one space (e.g. `[$ x^2 $]`). end with at least one space (e.g. `[$ x^2 $]`).
In math, single letters are always displayed as is. Multiple letters, however, In math, single letters are always displayed as is. Multiple letters, however,
are interpreted as variables and functions. To display multiple letters are interpreted as variables and functions. To display multiple letters
verbatim, you can place them into quotes and to access single letter verbatim, you can place them into quotes and to access single letter
variables, you can use the variables, you can use the [hashtag syntax]($scripting/#expressions).
[hashtag syntax]($scripting/#expressions).
```example ```example
$ A = pi r^2 $ $ A = pi r^2 $
@ -41,7 +34,7 @@ math: |
Math mode makes a wide selection of [symbols]($category/symbols/sym) like Math mode makes a wide selection of [symbols]($category/symbols/sym) like
`pi`, `dot`, or `RR` available. Many mathematical symbols are available in `pi`, `dot`, or `RR` available. Many mathematical symbols are available in
different variants. You can select between different variants by applying different variants. You can select between different variants by applying
[modifiers]($type/symbol) to the symbol. Typst further recognizes a number of [modifiers]($symbol) to the symbol. Typst further recognizes a number of
shorthand sequences like `=>` that approximate a symbol. When such a shorthand shorthand sequences like `=>` that approximate a symbol. When such a shorthand
exists, the symbol's documentation lists it. exists, the symbol's documentation lists it.
@ -51,6 +44,7 @@ math: |
Formulas can also contain line breaks. Each line can contain one or multiple Formulas can also contain line breaks. Each line can contain one or multiple
_alignment points_ (`&`) which are then aligned. _alignment points_ (`&`) which are then aligned.
```example ```example
$ sum_(k=0)^n k $ sum_(k=0)^n k
&= 1 + ... + n \ &= 1 + ... + n \
@ -60,11 +54,11 @@ math: |
Math mode supports special function calls without the hashtag prefix. In these Math mode supports special function calls without the hashtag prefix. In these
"math calls", the argument list works a little differently than in code: "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 - Within them, Typst is still in "math mode". Thus, you can write math
into them, but need to use hashtag syntax to pass code expressions (except directly into them, but need to use hashtag syntax to pass code expressions
for strings, which are available in the math syntax). (except for strings, which are available in the math syntax).
- They support positional and named arguments, but don't support - They support positional and named arguments, but don't support trailing
trailing content blocks and argument spreading. content blocks and argument spreading.
- They provide additional syntax for 2-dimensional argument lists. The - They provide additional syntax for 2-dimensional argument lists. The
semicolon (`;`) merges preceding arguments separated by commas into an array semicolon (`;`) merges preceding arguments separated by commas into an array
argument. argument.
@ -143,27 +137,11 @@ emoji: |
certain emojis, you can also import them from the `emoji` module (`[#import certain emojis, you can also import them from the `emoji` module (`[#import
emoji: face]`) to use them without the `#emoji.` prefix. 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`, `tau`, `e`, `inf`, and `nan`.
construct: |
Construction of and conversions between values of different types.
data-loading: | data-loading: |
Data loading from external files. Data loading from external files.
These functions help you with embedding data from experiments in your These functions help you with loading and embedding data, for example from
documents. the results of an experiment.
utility: |
Useful utility functions.
packages: | packages: |
Typst [packages]($scripting/#packages) encapsulate reusable building blocks Typst [packages]($scripting/#packages) encapsulate reusable building blocks

View File

@ -3,24 +3,27 @@
- name: variants - name: variants
display: Variants display: Variants
category: math
functions: ["serif", "sans", "frak", "mono", "bb", "cal"] functions: ["serif", "sans", "frak", "mono", "bb", "cal"]
description: | description: |
Alternate typefaces within formulas. Alternate typefaces within formulas.
These functions are distinct from the [`text`]($func/text) function because These functions are distinct from the [`text`]($text) function because math
math fonts contain multiple variants of each letter. fonts contain multiple variants of each letter.
- name: styles - name: styles
display: Styles display: Styles
category: math
functions: ["upright", "italic", "bold"] functions: ["upright", "italic", "bold"]
description: | description: |
Alternate letterforms within formulas. Alternate letterforms within formulas.
These functions are distinct from the [`text`]($func/text) function because These functions are distinct from the [`text`]($text) function because math
math fonts contain multiple variants of each letter. fonts contain multiple variants of each letter.
- name: sizes - name: sizes
display: Sizes display: Sizes
category: math
functions: ["display", "inline", "script", "sscript"] functions: ["display", "inline", "script", "sscript"]
description: | description: |
Forced size styles for expressions within formulas. Forced size styles for expressions within formulas.
@ -31,6 +34,7 @@
- name: underover - name: underover
display: Under/Over display: Under/Over
category: math
functions: [ functions: [
"underline", "underline",
"overline", "overline",
@ -47,23 +51,41 @@
- name: roots - name: roots
display: Roots display: Roots
category: math
functions: ["root", "sqrt"] functions: ["root", "sqrt"]
description: Square and non-square roots. description: |
Square and non-square roots.
# Example
```example
$ sqrt(3 - 2 sqrt(2)) = sqrt(2) - 1 $
$ root(3, x) $
```
- name: attach - name: attach
display: Attach display: Attach
category: math
functions: ["attach", "scripts", "limits"] functions: ["attach", "scripts", "limits"]
description: | description: |
Subscript, superscripts, and limits. Subscript, superscripts, and limits.
The `attach` function backs the `[$a_b^c$]` syntax that adds top and bottom Attachments can be displayed either as sub/superscripts, or limits. Typst
attachments to a part of an equation. Attachments can be displayed either as automatically decides which is more suitable depending on the base, but you
sub/superscripts, or limits. Typst automatically decides which is more can also control this manually with the `scripts` and `limits` functions.
suitable depending on the base, but you can also control this manually with
the `scripts` and `limits` functions. # Example
```example
$ sum_(i=0)^n a_i = 2^(1+i) $
```
# Syntax
This function also has dedicated syntax for attachments after the base: Use
the underscore (`_`) to indicate a subscript i.e. bottom attachment and the
hat (`^`) to indicate a superscript i.e. top attachment.
- name: lr - name: lr
display: Left/Right display: Left/Right
category: math
functions: ["lr", "abs", "norm", "floor", "ceil", "round"] functions: ["lr", "abs", "norm", "floor", "ceil", "round"]
description: | description: |
Delimiter matching. Delimiter matching.
@ -74,3 +96,21 @@
and control their size exactly. Apart from the `lr` function, Typst provides and control their size exactly. Apart from the `lr` function, Typst provides
a few more functions that create delimiter pairings for absolute, ceiled, a few more functions that create delimiter pairings for absolute, ceiled,
and floored values as well as norms. and floored values as well as norms.
# Example
```example
$ [a, b/2] $
$ lr(]sum_(x=1)^n] x, size: #50%) $
$ abs((x + y) / 2) $
```
- name: calc
display: Calculation
category: foundations
path: ["calc"]
description: |
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`, `tau`, `e`, `inf`, and `nan`.

View File

@ -7,7 +7,7 @@ Typst embeds a powerful scripting language. You can automate your documents and
create more sophisticated styles with code. Below is an overview over the create more sophisticated styles with code. Below is an overview over the
scripting concepts. scripting concepts.
## Expressions { #expressions } ## Expressions
In Typst, markup and code are fused into one. All but the most common elements 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 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 provides compact syntax to embed a code expression into markup: An expression is
@ -23,14 +23,13 @@ be interpreted as text, the expression can forcibly be ended with a semicolon
``` ```
The example above shows a few of the available expressions, including The example above shows a few of the available expressions, including
[function calls]($type/function), [function calls]($function), [field accesses]($scripting/#fields), and
[field accesses]($scripting/#fields), and
[method calls]($scripting/#methods). More kinds of expressions are [method calls]($scripting/#methods). More kinds of expressions are
discussed in the remainder of this chapter. A few kinds of expressions are not 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 compatible with the hashtag syntax (e.g. binary operator expressions). To embed
these into markup, you can use parentheses, as in `[#(1 + 2)]`. these into markup, you can use parentheses, as in `[#(1 + 2)]`.
## Blocks { #blocks } ## Blocks
To structure your code and embed markup into it, Typst provides two kinds of To structure your code and embed markup into it, Typst provides two kinds of
_blocks:_ _blocks:_
@ -45,9 +44,9 @@ _blocks:_
- **Content block:** `{[*Hey* there!]}` \ - **Content block:** `{[*Hey* there!]}` \
With content blocks, you can handle markup/content as a programmatic value, With content blocks, you can handle markup/content as a programmatic value,
store it in variables and pass it to [functions]($type/function). Content store it in variables and pass it to [functions]($function). Content
blocks are delimited by square brackets and can contain arbitrary markup. A blocks are delimited by square brackets and can contain arbitrary markup. A
content block results in a value of type [content]($type/content). An content block results in a value of type [content]($content). An
arbitrary number of content blocks can be passed as trailing arguments to arbitrary number of content blocks can be passed as trailing arguments to
functions. That is, `{list([A], [B])}` is equivalent to `{list[A][B]}`. functions. That is, `{list([A], [B])}` is equivalent to `{list[A][B]}`.
@ -69,7 +68,7 @@ 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 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 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 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 a [custom named function]($function/#defining-functions). Let bindings can be
accessed for the rest of the containing block or document. accessed for the rest of the containing block or document.
```example ```example
@ -81,8 +80,8 @@ It explains #name.
Sum is #add(2, 3). Sum is #add(2, 3).
``` ```
Let bindings can also be used to destructure [arrays]($type/array) and Let bindings can also be used to destructure [arrays]($array) and
[dictionaries]($type/dictionary). In this case, the left-hand side of the [dictionaries]($dictionary). In this case, the left-hand side of the
assignment should mirror an array or dictionary. The `..` operator can be used 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 once in the pattern to collect the remainder of the array's or dictionary's
items. items.
@ -142,7 +141,7 @@ swap variables among other things.
} }
``` ```
## Conditionals { #conditionals } ## Conditionals
With a conditional, you can display or compute different things depending on With a conditional, you can display or compute different things depending on
whether some condition is fulfilled. Typst supports `{if}`, `{else if}` and whether some condition is fulfilled. Typst supports `{if}`, `{else if}` and
`{else}` expression. When the condition evaluates to `{true}`, the conditional `{else}` expression. When the condition evaluates to `{true}`, the conditional
@ -164,7 +163,7 @@ Each branch can have a code or content block as its body.
- `{if condition [..] else {..}}` - `{if condition [..] else {..}}`
- `{if condition [..] else if condition {..} else [..]}` - `{if condition [..] else if condition {..} else [..]}`
## Loops { #loops } ## Loops
With loops, you can repeat content or compute something iteratively. Typst With loops, you can repeat content or compute something iteratively. Typst
supports two types of loops: `{for}` and `{while}` loops. The former iterate 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 over a specified collection whereas the latter iterate as long as a condition
@ -190,18 +189,18 @@ together into one larger array.
For loops can iterate over a variety of collections: For loops can iterate over a variety of collections:
- `{for letter in "abc" {..}}` \ - `{for letter in "abc" {..}}` \
Iterates over the characters of the [string]($type/string). Iterates over the characters of the [string]($str).
(Technically, iterates over the grapheme clusters of the string. Most of the (Technically, iterates over the grapheme clusters of the string. Most of the
time, a grapheme cluster is just a single character/codepoint. However, some time, a grapheme cluster is just a single character/codepoint. However, some
constructs like flag emojis that consist of multiple codepoints are still only constructs like flag emojis that consist of multiple codepoints are still only
one cluster.) one cluster.)
- `{for value in array {..}}` \ - `{for value in array {..}}` \
Iterates over the items in the [array]($type/array). The destructuring syntax Iterates over the items in the [array]($array). The destructuring syntax
described in [Let binding]($scripting/#bindings) can also be used here. described in [Let binding]($scripting/#bindings) can also be used here.
- `{for pair in dict {..}}` \ - `{for pair in dict {..}}` \
Iterates over the key-value pairs of the [dictionary]($type/dictionary). Iterates over the key-value pairs of the [dictionary]($dictionary).
The pairs can also be destructured by using `{for (key, value) in dict {..}}`. 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 To control the execution of the loop, Typst provides the `{break}` and
@ -225,16 +224,16 @@ The body of a loop can be a code or content block:
- `{while condition {..}}` - `{while condition {..}}`
- `{while condition [..]}` - `{while condition [..]}`
## Fields { #fields } ## Fields
You can use _dot notation_ to access fields on a value. The value in question You can use _dot notation_ to access fields on a value. The value in question
can be either: can be either:
- a [dictionary]($type/dictionary) that has the specified key, - a [dictionary]($dictionary) that has the specified key,
- a [symbol]($type/symbol) that has the specified modifier, - a [symbol]($symbol) that has the specified modifier,
- a [module]($type/module) containing the specified definition, - a [module]($module) containing the specified definition,
- [content]($type/content) consisting of an element that has the specified - [content]($content) consisting of an element that has the specified field. The
field. The available fields match the arguments of the available fields match the arguments of the
[element function]($type/function/#element-functions) that were given when [element function]($function/#element-functions) that were given when the
the element was constructed. element was constructed.
```example ```example
#let dict = (greet: "Hello") #let dict = (greet: "Hello")
@ -246,12 +245,20 @@ can be either:
#it.level #it.level
``` ```
## Methods { #methods } ## Methods
A method is a kind of a [function]($type/function) that is tightly coupled with A _method call_ is a convenient way to call a function that is scoped to a
a specific type. It is called on a value of its type using the same dot notation value's [type]($type). For example, we can call the [`str.len`]($str.len)
that is also used for fields: `{value.method(..)}`. The function in the following two equivalent ways:
[type documentation]($type) lists the available methods for each of the built-in
types. You cannot define your own methods. ```example
#str.len("abc") is the same as
#"abc".len()
```
The structure of a method call is `{value.method(..args)}` and its equivalent
full function call is `{type(value).method(value, ..args)}`. The documentation
of each type lists it's scoped functions. You cannot currently define your own
methods.
```example ```example
#let array = (1, 2, 3, 4) #let array = (1, 2, 3, 4)
@ -261,26 +268,29 @@ types. You cannot define your own methods.
#("a, b, c" #("a, b, c"
.split(", ") .split(", ")
.join[ --- ]) .join[ --- ])
#"abc".len() is the same as
#str.len("abc")
``` ```
Methods are the only functions in Typst that can modify the value they are There are a few special functions that modify the value they are called on (e.g.
called on. In some cases, this means that a method is only called for its side [`array.push`]($array.push)). These functions _must_ be called in method form.
effect and its return value should be ignored (and not participate in joining). In some cases, when the method is only called for its side effect, its return
The canonical way to discard a value is with a let binding: value should be ignored (and not participate in joining). The canonical way to
`{let _ = array.remove(1)}`. discard a value is with a let binding: `{let _ = array.remove(1)}`.
## Modules { #modules } ## Modules
You can split up your Typst projects into multiple files called _modules._ A 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 module can refer to the content and definitions of another module in multiple
ways: ways:
- **Including:** `{include "bar.typ"}` \ - **Including:** `{include "bar.typ"}` \
Evaluates the file at the path `bar.typ` and returns the resulting Evaluates the file at the path `bar.typ` and returns the resulting
[content]($type/content). [content]($content).
- **Import:** `{import "bar.typ"}` \ - **Import:** `{import "bar.typ"}` \
Evaluates the file at the path `bar.typ` and inserts the resulting Evaluates the file at the path `bar.typ` and inserts the resulting
[module]($type/module) into the current scope as `bar` (filename without [module]($module) into the current scope as `bar` (filename without
extension). extension).
- **Import items:** `{import "bar.typ": a, b}` \ - **Import items:** `{import "bar.typ": a, b}` \
@ -289,15 +299,15 @@ ways:
bindings) and defines them in the current file. Replacing `a, b` with `*` loads bindings) and defines them in the current file. Replacing `a, b` with `*` loads
all variables defined in a module. all variables defined in a module.
Instead of a path, you can also use a [module value]($type/module), as shown in Instead of a path, you can also use a [module value]($module), as shown in the
the following example: following example:
```example ```example
#import emoji: face #import emoji: face
#face.grin #face.grin
``` ```
## Packages { #packages } ## Packages
To reuse building blocks across projects, you can also create and import Typst 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, _packages._ A package import is specified as a triple of a namespace, a name,
and a version. and a version.
@ -316,7 +326,7 @@ If you are using Typst locally, you can also create your own system-local
packages. For more details on this, see the packages. For more details on this, see the
[package repository](https://github.com/typst/packages). [package repository](https://github.com/typst/packages).
## Operators { #operators } ## Operators
The following table lists all available unary and binary operators with effect, The following table lists all available unary and binary operators with effect,
arity (unary, binary) and precedence level (higher binds stronger). arity (unary, binary) and precedence level (higher binds stronger).

View File

@ -10,15 +10,14 @@ 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 Typst further supports _show rules_ that can completely redefine the appearance
of elements. of elements.
## Set rules { #set-rules } ## Set rules
With set rules, you can customize the appearance of elements. They are written With set rules, you can customize the appearance of elements. They are written
as a [function call]($type/function) to an as a [function call]($function) to an [element
[element function]($type/function/#element-functions) preceded by the `{set}` function]($function/#element-functions) preceded by the `{set}` keyword (or
keyword (or `[#set]` in markup). Only optional parameters of that function can `[#set]` in markup). Only optional parameters of that function can be provided
be provided to the set rule. Refer to each function's documentation to see which to the set rule. Refer to each function's documentation to see which parameters
parameters are optional. In the example below, we use two set rules to change are optional. In the example below, we use two set rules to change the
the [font family]($func/text.font) and [font family]($text.font) and [heading numbering]($heading.numbering).
[heading numbering]($func/heading.numbering).
```example ```example
#set heading(numbering: "I.") #set heading(numbering: "I.")
@ -60,13 +59,14 @@ a _set-if_ rule.
#task(critical: false)[Work deadline] #task(critical: false)[Work deadline]
``` ```
## Show rules { #show-rules } ## Show rules
With show rules, you can deeply customize the look of a type of element. The 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 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 `{show}` keyword followed by a [selector]($selector), a colon and then a set
[element function]($type/function/#element-functions). This lets the set rule rule. The most basic form of selector is an
only apply to the selected element. In the example below, headings become dark [element function]($function/#element-functions). This lets the set rule only
blue while all other text stays black. apply to the selected element. In the example below, headings become dark blue
while all other text stays black.
```example ```example
#show heading: set text(navy) #show heading: set text(navy)
@ -79,12 +79,11 @@ 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 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 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, defines how to format an element from scratch. To write such a show rule,
replace the set rule after the colon with an arbitrary replace the set rule after the colon with an arbitrary [function]($function).
[function]($type/function). This function receives the element in question and This function receives the element in question and can return arbitrary content.
can return arbitrary content. Different Different [fields]($scripting/#fields) are available on the element passed to
[fields]($scripting/#fields) are available on the element passed the function. Below, we define a show rule that formats headings for a fantasy
to the function. Below, we define a show rule that formats headings for a encyclopedia.
fantasy encyclopedia.
```example ```example
#set heading(numbering: "(I)") #set heading(numbering: "(I)")
@ -125,15 +124,15 @@ to:
- **Regex:** `{show regex("\w+"): ..}` \ - **Regex:** `{show regex("\w+"): ..}` \
Select and transform text with a regular expression for even more flexibility. Select and transform text with a regular expression for even more flexibility.
See the documentation of the [`regex` function]($func/regex) for details. See the documentation of the [`regex` type]($regex) for details.
- **Function with fields:** `{show heading.where(level: 1): ..}` \ - **Function with fields:** `{show heading.where(level: 1): ..}` \
Transform only elements that have the specified fields. For example, you might Transform only elements that have the specified fields. For example, you might
want to only change the style of level-1 headings. want to only change the style of level-1 headings.
- **Label:** `{show <intro>: ..}` \ - **Label:** `{show <intro>: ..}` \
Select and transform elements that have the specified label. Select and transform elements that have the specified label. See the
See the documentation of the [`label` function]($func/label) for more details. documentation of the [`label` type]($label) for more details.
```example ```example
#show "Project": smallcaps #show "Project": smallcaps

View File

@ -11,7 +11,7 @@ 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 All this is backed by a tightly integrated scripting language with built-in and
user-defined functions. user-defined functions.
## Markup { #markup } ## Markup
Typst provides built-in markup for the most common document elements. Most of 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 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 below lists all markup that is available and links to the best place to learn
@ -19,20 +19,20 @@ more about their syntax and usage.
| Name | Example | See | | Name | Example | See |
| ------------------ | ------------------------ | ---------------------------- | | ------------------ | ------------------------ | ---------------------------- |
| Paragraph break | Blank line | [`parbreak`]($func/parbreak) | | Paragraph break | Blank line | [`parbreak`]($parbreak) |
| Strong emphasis | `[*strong*]` | [`strong`]($func/strong) | | Strong emphasis | `[*strong*]` | [`strong`]($strong) |
| Emphasis | `[_emphasis_]` | [`emph`]($func/emph) | | Emphasis | `[_emphasis_]` | [`emph`]($emph) |
| Raw text | ``[`print(1)`]`` | [`raw`]($func/raw) | | Raw text | ``[`print(1)`]`` | [`raw`]($raw) |
| Link | `[https://typst.app/]` | [`link`]($func/link) | | Link | `[https://typst.app/]` | [`link`]($link) |
| Label | `[<intro>]` | [`label`]($func/label) | | Label | `[<intro>]` | [`label`]($label) |
| Reference | `[@intro]` | [`ref`]($func/ref) | | Reference | `[@intro]` | [`ref`]($ref) |
| Heading | `[= Heading]` | [`heading`]($func/heading) | | Heading | `[= Heading]` | [`heading`]($heading) |
| Bullet list | `[- item]` | [`list`]($func/list) | | Bullet list | `[- item]` | [`list`]($list) |
| Numbered list | `[+ item]` | [`enum`]($func/enum) | | Numbered list | `[+ item]` | [`enum`]($enum) |
| Term list | `[/ Term: description]` | [`terms`]($func/terms) | | Term list | `[/ Term: description]` | [`terms`]($terms) |
| Math | `[$x^2$]` | [Math]($category/math) | | Math | `[$x^2$]` | [Math]($category/math) |
| Line break | `[\]` | [`linebreak`]($func/linebreak) | | Line break | `[\]` | [`linebreak`]($linebreak) |
| Smart quote | `['single' or "double"]` | [`smartquote`]($func/smartquote) | | Smart quote | `['single' or "double"]` | [`smartquote`]($smartquote) |
| Symbol shorthand | `[~, ---]` | [Symbols]($category/symbols/sym) | | Symbol shorthand | `[~, ---]` | [Symbols]($category/symbols/sym) |
| Code expression | `[#rect(width: 1cm)]` | [Scripting]($scripting/#expressions) | | Code expression | `[#rect(width: 1cm)]` | [Scripting]($scripting/#expressions) |
| Character escape | `[Tweet at us \#ad]` | [Below](#escapes) | | Character escape | `[Tweet at us \#ad]` | [Below](#escapes) |
@ -52,8 +52,8 @@ follows:
| Block-level math | `[$ x^2 $]` | [Math]($category/math) | | Block-level math | `[$ x^2 $]` | [Math]($category/math) |
| Bottom attachment | `[$x_1$]` | [`attach`]($category/math/attach) | | Bottom attachment | `[$x_1$]` | [`attach`]($category/math/attach) |
| Top attachment | `[$x^2$]` | [`attach`]($category/math/attach) | | Top attachment | `[$x^2$]` | [`attach`]($category/math/attach) |
| Fraction | `[$1 + (a+b)/5$]` | [`frac`]($func/math.frac) | | Fraction | `[$1 + (a+b)/5$]` | [`frac`]($math.frac) |
| Line break | `[$x \ y$]` | [`linebreak`]($func/linebreak) | | Line break | `[$x \ y$]` | [`linebreak`]($linebreak) |
| Alignment point | `[$x &= 2 \ &= 3$]` | [Math]($category/math) | | Alignment point | `[$x &= 2 \ &= 3$]` | [Math]($category/math) |
| Variable access | `[$#x$, $pi$]` | [Math]($category/math) | | Variable access | `[$#x$, $pi$]` | [Math]($category/math) |
| Field access | `[$arrow.r.long$]` | [Scripting]($scripting/#fields) | | Field access | `[$arrow.r.long$]` | [Scripting]($scripting/#fields) |
@ -73,22 +73,22 @@ a table listing all syntax that is available in code mode:
| Name | Example | See | | Name | Example | See |
| ------------------------ | ----------------------------- | ---------------------------------- | | ------------------------ | ----------------------------- | ---------------------------------- |
| Variable access | `{x}` | [Scripting]($scripting/#blocks) | | Variable access | `{x}` | [Scripting]($scripting/#blocks) |
| Any literal | `{1pt, "hey"}` | [Types]($types) | | Any literal | `{1pt, "hey"}` | [Scripting]($scripting/#expressions) |
| Code block | `{{ let x = 1; x + 2 }}` | [Scripting]($scripting/#blocks) | | Code block | `{{ let x = 1; x + 2 }}` | [Scripting]($scripting/#blocks) |
| Content block | `{[*Hello*]}` | [Scripting]($scripting/#blocks) | | Content block | `{[*Hello*]}` | [Scripting]($scripting/#blocks) |
| Parenthesized expression | `{(1 + 2)}` | [Scripting]($scripting/#blocks) | | Parenthesized expression | `{(1 + 2)}` | [Scripting]($scripting/#blocks) |
| Array | `{(1, 2, 3)}` | [Array]($type/array) | | Array | `{(1, 2, 3)}` | [Array]($array) |
| Dictionary | `{(a: "hi", b: 2)}` | [Dictionary]($type/dictionary) | | Dictionary | `{(a: "hi", b: 2)}` | [Dictionary]($dictionary) |
| Unary operator | `{-x}` | [Scripting]($scripting/#operators) | | Unary operator | `{-x}` | [Scripting]($scripting/#operators) |
| Binary operator | `{x + y}` | [Scripting]($scripting/#operators) | | Binary operator | `{x + y}` | [Scripting]($scripting/#operators) |
| Assignment | `{x = 1}` | [Scripting]($scripting/#operators) | | Assignment | `{x = 1}` | [Scripting]($scripting/#operators) |
| Field access | `{x.y}` | [Scripting]($scripting/#fields) | | Field access | `{x.y}` | [Scripting]($scripting/#fields) |
| Method call | `{x.flatten()}` | [Scripting]($scripting/#methods) | | Method call | `{x.flatten()}` | [Scripting]($scripting/#methods) |
| Function call | `{min(x, y)}` | [Function]($type/function) | | Function call | `{min(x, y)}` | [Function]($function) |
| Argument spreading | `{min(..nums)}` | [Arguments]($type/arguments) | | Argument spreading | `{min(..nums)}` | [Arguments]($arguments) |
| Unnamed function | `{(x, y) => x + y}` | [Function]($type/function) | | Unnamed function | `{(x, y) => x + y}` | [Function]($function) |
| Let binding | `{let x = 1}` | [Scripting]($scripting/#bindings) | | Let binding | `{let x = 1}` | [Scripting]($scripting/#bindings) |
| Named function | `{let f(x) = 2 * x}` | [Function]($type/function) | | Named function | `{let f(x) = 2 * x}` | [Function]($function) |
| Set rule | `{set text(14pt)}` | [Styling]($styling/#set-rules) | | Set rule | `{set text(14pt)}` | [Styling]($styling/#set-rules) |
| Set-if rule | `{set text(..) if .. }` | [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-set rule | `{show par: set block(..)}` | [Styling]($styling/#show-rules) |
@ -98,16 +98,16 @@ a table listing all syntax that is available in code mode:
| For loop | `{for x in (1, 2, 3) {..}}` | [Scripting]($scripting/#loops) | | For loop | `{for x in (1, 2, 3) {..}}` | [Scripting]($scripting/#loops) |
| While loop | `{while x < 10 {..}}` | [Scripting]($scripting/#loops) | | While loop | `{while x < 10 {..}}` | [Scripting]($scripting/#loops) |
| Loop control flow | `{break, continue}` | [Scripting]($scripting/#loops) | | Loop control flow | `{break, continue}` | [Scripting]($scripting/#loops) |
| Return from function | `{return x}` | [Function]($type/function) | | Return from function | `{return x}` | [Function]($function) |
| Include module | `{include "bar.typ"}` | [Scripting]($scripting/#modules) | | Include module | `{include "bar.typ"}` | [Scripting]($scripting/#modules) |
| Import module | `{import "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) | | Import items from module | `{import "bar.typ": a, b, c}` | [Scripting]($scripting/#modules) |
| Comment | `[/* block */, // line]` | [Below](#comments) | | Comment | `[/* block */, // line]` | [Below](#comments) |
## Comments { #comments } ## Comments
Comments are ignored by Typst and will not be included in the output. This Comments are ignored by Typst and will not be included in the output. This is
is useful to exclude old versions or to add annotations. useful to exclude old versions or to add annotations. To comment out a single
To comment out a single line, start it with `//`: line, start it with `//`:
```example ```example
// our data barely supports // our data barely supports
// this claim // this claim
@ -129,9 +129,9 @@ Our study design is as follows:
## Escape sequences { #escapes } ## Escape sequences { #escapes }
Escape sequences are used to insert special characters that are hard to type or 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 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 a backslash. To insert any Unicode codepoint, you can write a hexadecimal escape
escape sequence: `[\u{1f600}]`. The same kind of escape sequences also work in sequence: `[\u{1f600}]`. The same kind of escape sequences also work in
[strings]($type/string). [strings]($str).
```example ```example
I got an ice cream for I got an ice cream for

File diff suppressed because it is too large Load Diff

View File

@ -10,14 +10,13 @@ syntax, concepts, types, and functions. If you are completely new to Typst, we
recommend starting with the [tutorial]($tutorial) and then coming back to recommend starting with the [tutorial]($tutorial) and then coming back to
the reference to learn more about Typst's features as you need them. the reference to learn more about Typst's features as you need them.
## Language { #language } ## Language
The reference starts with a language part that gives an overview over [Typst's The reference starts with a language part that gives an overview over
syntax]($syntax) and contains information about concepts involved in [Typst's syntax]($syntax) and contains information about concepts involved in
[styling documents,]($styling) using [styling documents,]($styling) using
[Typst's scripting capabilities,]($scripting) and a detailed documentation of [Typst's scripting capabilities.]($scripting)
all [data types]($types) in Typst.
## Functions { #functions } ## Functions
The second part includes chapters on all functions used to insert, style, transform, 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 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 description of its purpose, a list of its parameters, and examples of how to use

View File

@ -14,7 +14,7 @@ user to plan for and prioritize new features. Get started by filing a new issue
on [GitHub](https://github.com/typst/typst/issues) or discuss your feature on [GitHub](https://github.com/typst/typst/issues) or discuss your feature
request with the [community]($community). request with the [community]($community).
## Language and Compiler { #language-and-compiler } ## Language and Compiler
- **Structure and Styling** - **Structure and Styling**
- Fix show rule recursion - Fix show rule recursion
- Fix show-set order - Fix show-set order
@ -24,7 +24,7 @@ request with the [community]($community).
- Custom elements (that work with set and show rules) - Custom elements (that work with set and show rules)
- Possibly a capability system, e.g. to make your own element referenceable - Possibly a capability system, e.g. to make your own element referenceable
- **Layout** - **Layout**
- Floating layout - Advanced floating layout
- Rework layout engine to a more flexible model that has first-class support - Rework layout engine to a more flexible model that has first-class support
for both "normal" text layout and more canvas-like layout for both "normal" text layout and more canvas-like layout
- Unified layout primitives across normal content and math - Unified layout primitives across normal content and math
@ -36,8 +36,6 @@ request with the [community]($community).
- Layout with collision - Layout with collision
- **Export** - **Export**
- Implement emoji export - Implement emoji export
- Implement transparency
- Fix SVG export issues
- HTML export - HTML export
- EPUB export - EPUB export
- Tagged PDF for Accessibility - Tagged PDF for Accessibility
@ -51,17 +49,11 @@ request with the [community]($community).
- Ruby and Warichu - Ruby and Warichu
- Kashida justification - Kashida justification
- **Scripting** - **Scripting**
- More fields and methods on primitives
- Import renaming with as
- Allow expressions as dictionary keys - Allow expressions as dictionary keys
- Make types first-class values and bring methods and functions closer
together
- Function hoisting if possible - Function hoisting if possible
- Get values of set rules - Get values of set rules
- Doc comments - Doc comments
- Type hints - Type hints
- WebAssembly integration
- Query from CLI
- **Visualization** - **Visualization**
- Arrows - Arrows
- Gradients - Gradients
@ -75,13 +67,12 @@ request with the [community]($community).
- Benchmarking - Benchmarking
- Better contributor documentation - Better contributor documentation
## Library { #library } ## Library
- **Customization** - **Customization**
- Integrate CSL (Citation Style Language) - Integrate CSL (Citation Style Language)
- Bibliography and citation customization - Bibliography and citation customization
- Outline customization - Outline customization
- Table stroke customization - Table stroke customization
- Themes for raw text and more/custom syntaxes
- **Numbering** - **Numbering**
- Relative counters, e.g. for figure numbering per section - Relative counters, e.g. for figure numbering per section
- Improve equation numbering - Improve equation numbering
@ -97,12 +88,11 @@ request with the [community]($community).
- Fix font handling - Fix font handling
- Provide more primitives - Provide more primitives
- Smarter automatic delimiter sizing - Smarter automatic delimiter sizing
- Augmented matrices
- Big fractions - Big fractions
- **Other** - **Other**
- Plotting - Plotting
## Web App { #web-app } ## Web App
- **Editing** - **Editing**
- Smarter & more action buttons - Smarter & more action buttons
- Basic, built-in image editor (cropping, etc.) - Basic, built-in image editor (cropping, etc.)

View File

@ -85,7 +85,7 @@ and emphasized text, respectively. However, having a special symbol for
everything we want to insert into our document would soon become cryptic and 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 unwieldy. For this reason, Typst reserves markup symbols only for the most
common things. Everything else is inserted with _functions._ For our image to 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. show up on the page, we use Typst's [`image`]($image) function.
```example ```example
#image("glacier.jpg") #image("glacier.jpg")
@ -98,8 +98,8 @@ result (the function's _return value_) into the document. In our case, the
function in markup, we first need to type the `#` character, immediately function in markup, we first need to type the `#` character, immediately
followed by the name of the function. Then, we enclose the arguments in followed by the name of the function. Then, we enclose the arguments in
parentheses. Typst recognizes many different data types within argument lists. 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 Our file path is a short [string of text]($str), so we need to enclose it in
it in double quotes. double quotes.
The inserted image uses the whole width of the page. To change that, pass the 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 `width` argument to the `image` function. This is a _named_ argument and
@ -110,14 +110,14 @@ they are separated by commas, so we first need to put a comma behind the path.
#image("glacier.jpg", width: 70%) #image("glacier.jpg", width: 70%)
``` ```
The `width` argument is a [relative length]($type/relative-length). In our case, The `width` argument is a [relative length]($relative). In our case, we
we specified a percentage, determining that the image shall take up `{70%}` of specified a percentage, determining that the image shall take up `{70%}` of the
the page's width. We also could have specified an absolute value like `{1cm}` or page's width. We also could have specified an absolute value like `{1cm}` or
`{0.7in}`. `{0.7in}`.
Just like text, the image is now aligned at the left side of the page by 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 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 [figure]($figure) function. This function takes the figure's contents as a
positional argument and an optional caption as a named argument. 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. 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.
@ -176,9 +176,8 @@ valid kind of content.
## Adding a bibliography { #bibliography } ## Adding a bibliography { #bibliography }
As you write up your report, you need to back up some of your claims. You can 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 add a bibliography to your document with the [`bibliography`]($bibliography)
[`bibliography`]($func/bibliography) function. This function expects a path function. This function expects a path to a bibliography file.
to a bibliography file.
Typst's native bibliography format is Typst's native bibliography format is
[Hayagriva](https://github.com/typst/hayagriva/blob/main/docs/file-format.md), [Hayagriva](https://github.com/typst/hayagriva/blob/main/docs/file-format.md),
@ -190,7 +189,7 @@ 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 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 source for the first time, it will appear in the bibliography section of your
document. Typst supports different citation and bibliography styles. Consult the document. Typst supports different citation and bibliography styles. Consult the
[reference]($func/bibliography.style) for more details. [reference]($bibliography.style) for more details.
```example ```example
= Methods = Methods
@ -200,7 +199,7 @@ established in @glacier-melt.
#bibliography("works.bib") #bibliography("works.bib")
``` ```
## Maths { #maths } ## Maths
After fleshing out the methods section, you move on to the meat of the document: 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 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 math notation. Let's start with a simple equation. We wrap it in `[$]` signs
@ -269,17 +268,17 @@ $ 7.32 beta +
Not all math constructs have special syntax. Instead, we use functions, just 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 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, vector, we can use the [`vec`]($math.vec) function. Within math mode, function
function calls don't need to start with the `#` character. calls don't need to start with the `#` character.
```example ```example
$ v := vec(x_1, x_2, x_3) $ $ v := vec(x_1, x_2, x_3) $
``` ```
Some functions are only available within math mode. For example, the Some functions are only available within math mode. For example, the
[`cal`]($func/math.cal) function is used to typeset calligraphic letters [`cal`]($math.cal) function is used to typeset calligraphic letters commonly
commonly used for sets. The [math section of the reference]($category/math) used for sets. The [math section of the reference]($category/math) provides a
provides a complete list of all functions that math mode makes available. 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 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 select among these variants by appending a dot and a modifier name to a symbol's
@ -293,14 +292,14 @@ 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) preceded with `#sym.` there. See the [symbols section]($category/symbols/sym)
for a list of all available symbols. for a list of all available symbols.
## Review { #review } ## Review
You have now seen how to write a basic document in Typst. You learned how to 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 emphasize text, write lists, insert images, align content, and typeset
mathematical expressions. You also learned about Typst's functions. There are 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 many more kinds of content that Typst lets you insert into your document, such
as [tables]($func/table), [shapes]($category/visualize), and as [tables]($table), [shapes]($category/visualize), and [code blocks]($raw). You
[code blocks]($func/raw). You can peruse the [reference]($reference) to learn can peruse the [reference]($reference) to learn more about these and other
more about these and other features. features.
For the moment, you have completed writing your report. You have already saved a 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 PDF by clicking on the download button in the top right corner. However, you

View File

@ -9,13 +9,13 @@ 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 with the other student's submissions. In this chapter, we will see how to format
your report using Typst's styling system. your report using Typst's styling system.
## Set rules { #set-rules } ## Set rules
As we have seen in the previous chapter, Typst has functions that _insert_ 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 (e.g. the [`image`]($image) function) and others that _manipulate_
content that they received as arguments (e.g. the [`align`]($func/align) content that they received as arguments (e.g. the [`align`]($align) function).
function). The first impulse you might have when you want, for example, to The first impulse you might have when you want, for example, to justify the
justify the report, could be to look for a function that does that and wrap the report, could be to look for a function that does that and wrap the complete
complete document in it. document in it.
```example ```example
#par(justify: true)[ #par(justify: true)[
@ -38,9 +38,9 @@ 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 inside of the argument list, you can write it in square brackets directly after
the normal arguments, saving on punctuation. the normal arguments, saving on punctuation.
As seen above, that works. The [`par`]($func/par) function justifies all As seen above, that works. The [`par`]($par) function justifies all paragraphs
paragraphs within it. However, wrapping the document in countless functions and within it. However, wrapping the document in countless functions and applying
applying styles selectively and in-situ can quickly become cumbersome. styles selectively and in-situ can quickly become cumbersome.
Fortunately, Typst has a more elegant solution. With _set rules,_ you can apply 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 style properties to all occurrences of some kind of content. You write a set
@ -89,15 +89,13 @@ 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 what type of element you want to style. Here is a list of some functions that
are commonly used in set rules: are commonly used in set rules:
- [`text`]($func/text) to set font family, size, color, and other properties of - [`text`]($text) to set font family, size, color, and other properties of text
text - [`page`]($page) to set the page size, margins, headers, enable columns, and
- [`page`]($func/page) to set the page size, margins, headers, enable columns, footers
and footers - [`par`]($par) to justify paragraphs, set line spacing, and more
- [`par`]($func/par) to justify paragraphs, set line spacing, and more - [`heading`]($heading) to set the appearance of headings and enable numbering
- [`heading`]($func/heading) to set the appearance of headings and enable - [`document`]($document) to set the metadata contained in the PDF output, such
numbering as title and author
- [`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 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 a function _how_ to do something can be set, not those that tell it _what_ to
@ -151,23 +149,22 @@ behavior of these natural structures.
There are a few things of note here. There are a few things of note here.
First is the [`page`]($func/page) set rule. It receives two arguments: the page First is the [`page`]($page) set rule. It receives two arguments: the page size
size and margins for the page. The page size is a string. Typst accepts 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 [many standard page sizes,]($page.paper) but you can also specify a custom page
page size. The margins are specified as a [dictionary.]($type/dictionary) size. The margins are specified as a [dictionary.]($dictionary) Dictionaries are
Dictionaries are a collection of key-value pairs. In this case, the keys are `x` a collection of key-value pairs. In this case, the keys are `x` and `y`, and the
and `y`, and the values are the horizontal and vertical margins, respectively. values are the horizontal and vertical margins, respectively. We could also have
We could also have specified separate margins for each side by passing a specified separate margins for each side by passing a dictionary with the keys
dictionary with the keys `{left}`, `{right}`, `{top}`, and `{bottom}`. `{left}`, `{right}`, `{top}`, and `{bottom}`.
Next is the set [`text`]($func/text) set rule. Here, we set the font size to Next is the set [`text`]($text) set rule. Here, we set the font size to `{10pt}`
`{10pt}` and font family to `{"New Computer Modern"}`. The Typst app comes with and font family to `{"New Computer Modern"}`. The Typst app comes with many
many fonts that you can try for your document. When you are in the text fonts that you can try for your document. When you are in the text function's
function's argument list, you can discover the available fonts in the argument list, you can discover the available fonts in the autocomplete panel.
autocomplete panel.
We have also set the spacing between lines (a.k.a. leading): It is specified as 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 a [length]($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 relative to the size of the font: `{1em}` is equivalent to the current font size
(which defaults to `{11pt}`). (which defaults to `{11pt}`).
@ -177,8 +174,8 @@ center alignment. Vertical and horizontal alignments can be combined with the
## A hint of sophistication { #sophistication } ## A hint of sophistication { #sophistication }
To structure our document more clearly, we now want to number our headings. We To structure our document more clearly, we now want to number our headings. We
can do this by setting the `numbering` parameter of the can do this by setting the `numbering` parameter of the [`heading`]($heading)
[`heading`]($func/heading) function. function.
```example ```example
>>> #set text(font: "New Computer Modern") >>> #set text(font: "New Computer Modern")
@ -196,8 +193,8 @@ can do this by setting the `numbering` parameter of the
We specified the string `{"1."}` as the numbering parameter. This tells Typst to 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 number the headings with arabic numerals and to put a dot between the number of
each level. We can also use each level. We can also use [letters, roman numerals, and symbols]($numbering)
[letters, roman numerals, and symbols]($func/numbering) for our headings: for our headings:
```example ```example
>>> #set text(font: "New Computer Modern") >>> #set text(font: "New Computer Modern")
@ -213,7 +210,7 @@ each level. We can also use
#lorem(15) #lorem(15)
``` ```
This example also uses the [`lorem`]($func/lorem) function to generate some This example also uses the [`lorem`]($lorem) function to generate some
placeholder text. This function takes a number as an argument and generates that placeholder text. This function takes a number as an argument and generates that
many words of _Lorem Ipsum_ text. many words of _Lorem Ipsum_ text.
@ -222,13 +219,13 @@ many words of _Lorem Ipsum_ text.
Did you wonder why the headings and text set rules apply to all text and headings, 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? even if they are not produced with the respective functions?
Typst internally calls the `heading` function every time you write `[= Conclusion]`. Typst internally calls the `heading` function every time you write
In fact, the function call `[#heading[Conclusion]]` is equivalent to the heading `[= Conclusion]`. In fact, the function call `[#heading[Conclusion]]` is
markup above. Other markup elements work similarly, they are only equivalent to the heading markup above. Other markup elements work similarly,
_syntax sugar_ for the corresponding function calls. they are only _syntax sugar_ for the corresponding function calls.
</div> </div>
## Show rules { #show-rules } ## Show rules
You are already pretty happy with how this turned out. But one last thing needs 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 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. that project's name should always be accompanied by a logo, even in prose.
@ -236,7 +233,8 @@ 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 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. every instance of the logo using search and replace. That sounds very tedious.
Instead, you could maybe 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: [define a custom function]($function/#defining-functions) that always yields the
logo with its image. However, there is an even easier way:
With show rules, you can redefine how Typst displays certain elements. You With show rules, you can redefine how Typst displays certain elements. You
specify which elements Typst should show differently and how they should look. specify which elements Typst should show differently and how they should look.
@ -272,7 +270,7 @@ expects code instead of markup, the leading `#` is not needed to access
functions, keywords, and variables. This can be observed in parameter lists, functions, keywords, and variables. This can be observed in parameter lists,
function definitions, and [code blocks]($scripting). function definitions, and [code blocks]($scripting).
## Review { #review } ## Review
You now know how to apply basic formatting to your Typst documents. You learned 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 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 add numbering to your headings with set rules. You also learned how to use a

View File

@ -78,7 +78,7 @@ by the conference style guide. We use the `align` function to align the text to
the right. the right.
Last but not least is the `numbering` argument. Here, we can provide a 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 [numbering pattern]($numbering) that defines how to number the pages. By
setting into to `{"1"}`, Typst only displays the bare page number. Setting it to 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 `{"(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 surrounded by parentheses. And we could even have provided a completely custom
@ -126,16 +126,16 @@ supervisor, we'll add our own and their name.
``` ```
The two author blocks are laid out next to each other. We use the 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 [`grid`]($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 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) `columns` argument takes an array of [relative lengths]($relative) or
or [fractions]($type/fraction). In this case, we passed it two equal fractional [fractions]($fraction). In this case, we passed it two equal fractional sizes,
sizes, telling it to split the available space into two equal columns. We then telling it to split the available space into two equal columns. We then passed
passed two content arguments to the grid function. The first with our own two content arguments to the grid function. The first with our own details, and
details, and the second with our supervisors'. We again use the `align` function the second with our supervisors'. We again use the `align` function to center
to center the content within the column. The grid takes an arbitrary number of the content within the column. The grid takes an arbitrary number of content
content arguments specifying the cells. Rows are added automatically, but they arguments specifying the cells. Rows are added automatically, but they can also
can also be manually sized with the `rows` argument. be manually sized with the `rows` argument.
Now, let's add the abstract. Remember that the conference wants the abstract to Now, let's add the abstract. Remember that the conference wants the abstract to
be set ragged and centered. be set ragged and centered.
@ -249,7 +249,7 @@ on another title, we can easily change it in one place.
## Adding columns and headings { #columns-and-headings } ## Adding columns and headings { #columns-and-headings }
The paper above unfortunately looks like a wall of lead. To fix that, let's add 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 some headings and switch our paper to a two-column layout. The
[`columns`]($func/columns) function takes a number and content, and layouts the [`columns`]($columns) function takes a number and content, and layouts the
content into the specified number of columns. Since we want everything after 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 abstract to be in two columns, we need to apply the column function to our whole
document. document.
@ -386,7 +386,8 @@ 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 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 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 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. [`smallcaps`]($smallcaps) function to render the heading's title in small
capitals.
The only remaining problem is that all headings look the same now. The The only remaining problem is that all headings look the same now. The
"Motivation" and "Problem Statement" subsections ought to be italic run in "Motivation" and "Problem Statement" subsections ought to be italic run in
@ -493,9 +494,9 @@ the conference! The finished paper looks like this:
style="box-shadow: 0 4px 12px rgb(89 85 101 / 20%); width: 500px; max-width: 100%; display: block; margin: 24px auto;" style="box-shadow: 0 4px 12px rgb(89 85 101 / 20%); width: 500px; max-width: 100%; display: block; margin: 24px auto;"
> >
## Review { #review } ## Review
You have now learned how to create headers and footers, how to use functions and 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 scopes to locally override styles, how to create more complex layouts with the [`grid`]($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. [`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 paper was a great success! You've met a lot of like-minded researchers at

View File

@ -195,26 +195,26 @@ Next, we copy the code that generates title, abstract and authors from the
previous chapter into the template, replacing the fixed details with the previous chapter into the template, replacing the fixed details with the
parameters. parameters.
The new `authors` parameter expects an [array]($type/array) of The new `authors` parameter expects an [array]($array) of
[dictionaries]($type/dictionary) with the keys `name`, `affiliation` and [dictionaries]($dictionary) with the keys `name`, `affiliation` and `email`.
`email`. Because we can have an arbitrary number of authors, we dynamically Because we can have an arbitrary number of authors, we dynamically determine if
determine if we need one, two or three columns for the author list. First, we we need one, two or three columns for the author list. First, we determine the
determine the number of authors using the [`.len()`]($type/array.len) method on number of authors using the [`.len()`]($array.len) method on the `authors`
the `authors` array. Then, we set the number of columns as the minimum of this array. Then, we set the number of columns as the minimum of this count and
count and three, so that we never create more than three columns. If there are three, so that we never create more than three columns. If there are more than
more than three authors, a new row will be inserted instead. For this purpose, three authors, a new row will be inserted instead. For this purpose, we have
we have also added a `row-gutter` parameter to the `grid` function. Otherwise, also added a `row-gutter` parameter to the `grid` function. Otherwise, the rows
the rows would be too close together. To extract the details about the authors would be too close together. To extract the details about the authors from the
from the dictionary, we use the [field access syntax]($scripting/#fields). 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 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 the array's [`map` method]($array.map) comes in handy. It takes a function as an
as an argument that gets called with each item of the array. We pass it a argument that gets called with each item of the array. We pass it a function
function that formats the details for each author and returns a new array that formats the details for each author and returns a new array containing
containing content values. We've now got one array of values that we'd like to content values. We've now got one array of values that we'd like to use as
use as multiple arguments for the grid. We can do that by using the [`spread` multiple arguments for the grid. We can do that by using the
operator]($type/arguments). It takes an array and applies each of its items as a [`spread` operator]($arguments). It takes an array and applies each of its items
separate argument to the function. as a separate argument to the function.
The resulting template function looks like this: The resulting template function looks like this:
@ -365,7 +365,7 @@ conference! Why not share it on
[Typst's Discord server](https://discord.gg/2uDybryKPe) so that others can use [Typst's Discord server](https://discord.gg/2uDybryKPe) so that others can use
it too? it too?
## Review { #review } ## Review
Congratulations, you have completed Typst's Tutorial! In this section, you have 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 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 that define reusable document styles. You've made it far and learned a lot. You