Compare commits
No commits in common. "4a9a5d2716fc91f60734769eb001aef32fe15403" and "85b0318158cc1f71825f45c5fb7915b764f75776" have entirely different histories.
4a9a5d2716
...
85b0318158
18
Cargo.lock
generated
@ -312,9 +312,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "citationberg"
|
name = "citationberg"
|
||||||
version = "0.5.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e4595e03beafb40235070080b5286d3662525efc622cca599585ff1d63f844fa"
|
checksum = "92fea693c83bd967604be367dc1e1b4895625eabafec2eec66c51092e18e700e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quick-xml 0.36.2",
|
"quick-xml 0.36.2",
|
||||||
"serde",
|
"serde",
|
||||||
@ -398,9 +398,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "codex"
|
name = "codex"
|
||||||
version = "0.1.1"
|
version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "724d27a0ee38b700e5e164350e79aba601a0db673ac47fce1cb74c3e38864036"
|
checksum = "2e0ee2092c3513f63588d51c3f81b98e6b1aa8ddcca3b5892b288f093516497d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "color-print"
|
name = "color-print"
|
||||||
@ -898,9 +898,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hayagriva"
|
name = "hayagriva"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "954907554bb7fcba29a4f917c2d43e289ec21b69d872ccf97db160eca6caeed8"
|
checksum = "7a3635c2577f77499c9dc3dceeef2e64e6c146e711b1861507a0f15b20641348"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"biblatex",
|
"biblatex",
|
||||||
"ciborium",
|
"ciborium",
|
||||||
@ -2718,9 +2718,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "two-face"
|
name = "two-face"
|
||||||
version = "0.4.3"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "384eda438ddf62e2c6f39a174452d952d9d9df5a8ad5ade22198609f8dcaf852"
|
checksum = "0ccd4843ea031c609fe9c16cae00e9657bad8a9f735a3cc2e420955d802b4268"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"serde",
|
"serde",
|
||||||
@ -2822,8 +2822,6 @@ dependencies = [
|
|||||||
"typst-assets",
|
"typst-assets",
|
||||||
"typst-dev-assets",
|
"typst-dev-assets",
|
||||||
"typst-render",
|
"typst-render",
|
||||||
"typst-utils",
|
|
||||||
"unicode-math-class",
|
|
||||||
"unscanny",
|
"unscanny",
|
||||||
"yaml-front-matter",
|
"yaml-front-matter",
|
||||||
]
|
]
|
||||||
|
@ -47,7 +47,7 @@ clap = { version = "4.4", features = ["derive", "env", "wrap_help"] }
|
|||||||
clap_complete = "4.2.1"
|
clap_complete = "4.2.1"
|
||||||
clap_mangen = "0.2.10"
|
clap_mangen = "0.2.10"
|
||||||
codespan-reporting = "0.11"
|
codespan-reporting = "0.11"
|
||||||
codex = "0.1.1"
|
codex = "0.1.0"
|
||||||
color-print = "0.3.6"
|
color-print = "0.3.6"
|
||||||
comemo = "0.4"
|
comemo = "0.4"
|
||||||
csv = "1"
|
csv = "1"
|
||||||
@ -58,7 +58,7 @@ env_proxy = "0.4"
|
|||||||
flate2 = "1"
|
flate2 = "1"
|
||||||
fontdb = { version = "0.21", default-features = false }
|
fontdb = { version = "0.21", default-features = false }
|
||||||
fs_extra = "1.3"
|
fs_extra = "1.3"
|
||||||
hayagriva = "0.8.1"
|
hayagriva = "0.8"
|
||||||
heck = "0.5"
|
heck = "0.5"
|
||||||
hypher = "0.1.4"
|
hypher = "0.1.4"
|
||||||
icu_properties = { version = "1.4", features = ["serde"] }
|
icu_properties = { version = "1.4", features = ["serde"] }
|
||||||
@ -122,7 +122,7 @@ tiny_http = "0.12"
|
|||||||
tiny-skia = "0.11"
|
tiny-skia = "0.11"
|
||||||
toml = { version = "0.8", default-features = false, features = ["parse", "display"] }
|
toml = { version = "0.8", default-features = false, features = ["parse", "display"] }
|
||||||
ttf-parser = "0.24.1"
|
ttf-parser = "0.24.1"
|
||||||
two-face = { version = "0.4.3", default-features = false, features = ["syntect-fancy"] }
|
two-face = { version = "0.4.0", default-features = false, features = ["syntect-fancy"] }
|
||||||
typed-arena = "2"
|
typed-arena = "2"
|
||||||
unicode-bidi = "0.3.18"
|
unicode-bidi = "0.3.18"
|
||||||
unicode-ident = "1.0"
|
unicode-ident = "1.0"
|
||||||
|
@ -85,9 +85,16 @@ use crate::engine::Engine;
|
|||||||
use crate::routines::EvalMode;
|
use crate::routines::EvalMode;
|
||||||
use crate::{Feature, Features};
|
use crate::{Feature, Features};
|
||||||
|
|
||||||
|
/// Foundational types and functions.
|
||||||
|
///
|
||||||
|
/// Here, you'll find documentation for basic data types like [integers]($int)
|
||||||
|
/// and [strings]($str) as well as details about core computational functions.
|
||||||
|
#[category]
|
||||||
|
pub static FOUNDATIONS: Category;
|
||||||
|
|
||||||
/// Hook up all `foundations` definitions.
|
/// Hook up all `foundations` definitions.
|
||||||
pub(super) fn define(global: &mut Scope, inputs: Dict, features: &Features) {
|
pub(super) fn define(global: &mut Scope, inputs: Dict, features: &Features) {
|
||||||
global.start_category(crate::Category::Foundations);
|
global.start_category(FOUNDATIONS);
|
||||||
global.define_type::<bool>();
|
global.define_type::<bool>();
|
||||||
global.define_type::<i64>();
|
global.define_type::<i64>();
|
||||||
global.define_type::<f64>();
|
global.define_type::<f64>();
|
||||||
@ -118,7 +125,6 @@ pub(super) fn define(global: &mut Scope, inputs: Dict, features: &Features) {
|
|||||||
}
|
}
|
||||||
global.define("calc", calc::module());
|
global.define("calc", calc::module());
|
||||||
global.define("sys", sys::module(inputs));
|
global.define("sys", sys::module(inputs));
|
||||||
global.reset_category();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fails with an error.
|
/// Fails with an error.
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
#[doc(inline)]
|
||||||
|
pub use typst_macros::category;
|
||||||
|
|
||||||
use std::fmt::{self, Debug, Formatter};
|
use std::fmt::{self, Debug, Formatter};
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
|
|
||||||
@ -5,13 +8,14 @@ use ecow::{eco_format, EcoString};
|
|||||||
use indexmap::map::Entry;
|
use indexmap::map::Entry;
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use typst_syntax::Span;
|
use typst_syntax::Span;
|
||||||
|
use typst_utils::Static;
|
||||||
|
|
||||||
use crate::diag::{bail, DeprecationSink, HintedStrResult, HintedString, StrResult};
|
use crate::diag::{bail, DeprecationSink, HintedStrResult, HintedString, StrResult};
|
||||||
use crate::foundations::{
|
use crate::foundations::{
|
||||||
Element, Func, IntoValue, NativeElement, NativeFunc, NativeFuncData, NativeType,
|
Element, Func, IntoValue, NativeElement, NativeFunc, NativeFuncData, NativeType,
|
||||||
Type, Value,
|
Type, Value,
|
||||||
};
|
};
|
||||||
use crate::{Category, Library};
|
use crate::Library;
|
||||||
|
|
||||||
/// A stack of scopes.
|
/// A stack of scopes.
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
@ -357,6 +361,46 @@ pub enum Capturer {
|
|||||||
Context,
|
Context,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A group of related definitions.
|
||||||
|
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
||||||
|
pub struct Category(Static<CategoryData>);
|
||||||
|
|
||||||
|
impl Category {
|
||||||
|
/// Create a new category from raw data.
|
||||||
|
pub const fn from_data(data: &'static CategoryData) -> Self {
|
||||||
|
Self(Static(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The category's name.
|
||||||
|
pub fn name(&self) -> &'static str {
|
||||||
|
self.0.name
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The type's title case name, for use in documentation (e.g. `String`).
|
||||||
|
pub fn title(&self) -> &'static str {
|
||||||
|
self.0.title
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Documentation for the category.
|
||||||
|
pub fn docs(&self) -> &'static str {
|
||||||
|
self.0.docs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for Category {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
|
write!(f, "Category({})", self.name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Defines a category.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct CategoryData {
|
||||||
|
pub name: &'static str,
|
||||||
|
pub title: &'static str,
|
||||||
|
pub docs: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
/// The error message when trying to mutate a variable from the standard
|
/// The error message when trying to mutate a variable from the standard
|
||||||
/// library.
|
/// library.
|
||||||
#[cold]
|
#[cold]
|
||||||
|
@ -3,7 +3,7 @@ use comemo::Tracked;
|
|||||||
use crate::diag::HintedStrResult;
|
use crate::diag::HintedStrResult;
|
||||||
use crate::foundations::{elem, func, Cast, Context};
|
use crate::foundations::{elem, func, Cast, Context};
|
||||||
|
|
||||||
/// The export target.
|
/// The compilation target.
|
||||||
#[derive(Debug, Default, Copy, Clone, PartialEq, Hash, Cast)]
|
#[derive(Debug, Default, Copy, Clone, PartialEq, Hash, Cast)]
|
||||||
pub enum Target {
|
pub enum Target {
|
||||||
/// The target that is used for paged, fully laid-out content.
|
/// The target that is used for paged, fully laid-out content.
|
||||||
@ -28,49 +28,7 @@ pub struct TargetElem {
|
|||||||
pub target: Target,
|
pub target: Target,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the current export target.
|
/// Returns the current compilation target.
|
||||||
///
|
|
||||||
/// This function returns either
|
|
||||||
/// - `{"paged"}` (for PDF, PNG, and SVG export), or
|
|
||||||
/// - `{"html"}` (for HTML export).
|
|
||||||
///
|
|
||||||
/// The design of this function is not yet finalized and for this reason it is
|
|
||||||
/// guarded behind the `html` feature. Visit the [HTML documentation
|
|
||||||
/// page]($html) for more details.
|
|
||||||
///
|
|
||||||
/// # When to use it
|
|
||||||
/// This function allows you to format your document properly across both HTML
|
|
||||||
/// and paged export targets. It should primarily be used in templates and show
|
|
||||||
/// rules, rather than directly in content. This way, the document's contents
|
|
||||||
/// can be fully agnostic to the export target and content can be shared between
|
|
||||||
/// PDF and HTML export.
|
|
||||||
///
|
|
||||||
/// # Varying targets
|
|
||||||
/// This function is [contextual]($context) as the target can vary within a
|
|
||||||
/// single compilation: When exporting to HTML, the target will be `{"paged"}`
|
|
||||||
/// while within an [`html.frame`].
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
/// ```example
|
|
||||||
/// #let kbd(it) = context {
|
|
||||||
/// if target() == "html" {
|
|
||||||
/// html.elem("kbd", it)
|
|
||||||
/// } else {
|
|
||||||
/// set text(fill: rgb("#1f2328"))
|
|
||||||
/// let r = 3pt
|
|
||||||
/// box(
|
|
||||||
/// fill: rgb("#f6f8fa"),
|
|
||||||
/// stroke: rgb("#d1d9e0b3"),
|
|
||||||
/// outset: (y: r),
|
|
||||||
/// inset: (x: r),
|
|
||||||
/// radius: r,
|
|
||||||
/// raw(it)
|
|
||||||
/// )
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// Press #kbd("F1") for help.
|
|
||||||
/// ```
|
|
||||||
#[func(contextual)]
|
#[func(contextual)]
|
||||||
pub fn target(context: Tracked<Context>) -> HintedStrResult<Target> {
|
pub fn target(context: Tracked<Context>) -> HintedStrResult<Target> {
|
||||||
Ok(TargetElem::target_in(context.styles()?))
|
Ok(TargetElem::target_in(context.styles()?))
|
||||||
|
@ -6,77 +6,53 @@ pub use self::dom::*;
|
|||||||
|
|
||||||
use ecow::EcoString;
|
use ecow::EcoString;
|
||||||
|
|
||||||
use crate::foundations::{elem, Content, Module, Scope};
|
use crate::foundations::{category, elem, Category, Content, Module, Scope};
|
||||||
|
|
||||||
|
/// HTML output.
|
||||||
|
#[category]
|
||||||
|
pub static HTML: Category;
|
||||||
|
|
||||||
/// Create a module with all HTML definitions.
|
/// Create a module with all HTML definitions.
|
||||||
pub fn module() -> Module {
|
pub fn module() -> Module {
|
||||||
let mut html = Scope::deduplicating();
|
let mut html = Scope::deduplicating();
|
||||||
html.start_category(crate::Category::Html);
|
html.start_category(HTML);
|
||||||
html.define_elem::<HtmlElem>();
|
html.define_elem::<HtmlElem>();
|
||||||
html.define_elem::<FrameElem>();
|
html.define_elem::<FrameElem>();
|
||||||
Module::new("html", html)
|
Module::new("html", html)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An HTML element that can contain Typst content.
|
/// A HTML element that can contain Typst content.
|
||||||
///
|
|
||||||
/// Typst's HTML export automatically generates the appropriate tags for most
|
|
||||||
/// elements. However, sometimes, it is desirable to retain more control. For
|
|
||||||
/// example, when using Typst to generate your blog, you could use this function
|
|
||||||
/// to wrap each article in an `<article>` tag.
|
|
||||||
///
|
|
||||||
/// Typst is aware of what is valid HTML. A tag and its attributes must form
|
|
||||||
/// syntactically valid HTML. Some tags, like `meta` do not accept content.
|
|
||||||
/// Hence, you must not provide a body for them. We may add more checks in the
|
|
||||||
/// future, so be sure that you are generating valid HTML when using this
|
|
||||||
/// function.
|
|
||||||
///
|
|
||||||
/// Normally, Typst will generate `html`, `head`, and `body` tags for you. If
|
|
||||||
/// you instead create them with this function, Typst will omit its own tags.
|
|
||||||
///
|
|
||||||
/// ```typ
|
|
||||||
/// #html.elem("div", attrs: (style: "background: aqua"))[
|
|
||||||
/// A div with _Typst content_ inside!
|
|
||||||
/// ]
|
|
||||||
/// ```
|
|
||||||
#[elem(name = "elem")]
|
#[elem(name = "elem")]
|
||||||
pub struct HtmlElem {
|
pub struct HtmlElem {
|
||||||
/// The element's tag.
|
/// The element's tag.
|
||||||
#[required]
|
#[required]
|
||||||
pub tag: HtmlTag,
|
pub tag: HtmlTag,
|
||||||
|
|
||||||
/// The element's HTML attributes.
|
/// The element's attributes.
|
||||||
#[borrowed]
|
#[borrowed]
|
||||||
pub attrs: HtmlAttrs,
|
pub attrs: HtmlAttrs,
|
||||||
|
|
||||||
/// The contents of the HTML element.
|
/// The contents of the HTML element.
|
||||||
///
|
|
||||||
/// The body can be arbitrary Typst content.
|
|
||||||
#[positional]
|
#[positional]
|
||||||
#[borrowed]
|
#[borrowed]
|
||||||
pub body: Option<Content>,
|
pub body: Option<Content>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HtmlElem {
|
impl HtmlElem {
|
||||||
/// Add an attribute to the element.
|
/// Add an atribute to the element.
|
||||||
pub fn with_attr(mut self, attr: HtmlAttr, value: impl Into<EcoString>) -> Self {
|
pub fn with_attr(mut self, attr: HtmlAttr, value: impl Into<EcoString>) -> Self {
|
||||||
self.attrs.get_or_insert_with(Default::default).push(attr, value);
|
self.attrs.get_or_insert_with(Default::default).push(attr, value);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An element that lays out its content as an inline SVG.
|
/// An element that forces its contents to be laid out.
|
||||||
///
|
///
|
||||||
/// Sometimes, converting Typst content to HTML is not desirable. This can be
|
/// Integrates content that requires layout (e.g. a plot) into HTML output
|
||||||
/// the case for plots and other content that relies on positioning and styling
|
/// by turning it into an inline SVG.
|
||||||
/// to convey its message.
|
|
||||||
///
|
|
||||||
/// This function allows you to use the Typst layout engine that would also be
|
|
||||||
/// used for PDF, SVG, and PNG export to render a part of your document exactly
|
|
||||||
/// how it would appear when exported in one of these formats. It embeds the
|
|
||||||
/// content as an inline SVG.
|
|
||||||
#[elem]
|
#[elem]
|
||||||
pub struct FrameElem {
|
pub struct FrameElem {
|
||||||
/// The content that shall be laid out.
|
/// The contents that shall be laid out.
|
||||||
#[positional]
|
#[positional]
|
||||||
#[required]
|
#[required]
|
||||||
pub body: Content,
|
pub body: Content,
|
||||||
|
@ -25,11 +25,24 @@ pub use self::query_::*;
|
|||||||
pub use self::state::*;
|
pub use self::state::*;
|
||||||
pub use self::tag::*;
|
pub use self::tag::*;
|
||||||
|
|
||||||
use crate::foundations::Scope;
|
use crate::foundations::{category, Category, Scope};
|
||||||
|
|
||||||
|
/// Interactions between document parts.
|
||||||
|
///
|
||||||
|
/// This category is home to Typst's introspection capabilities: With the
|
||||||
|
/// `counter` function, you can access and manipulate page, section, figure, and
|
||||||
|
/// equation counters or create custom ones. Meanwhile, the `query` function
|
||||||
|
/// lets you search for elements in the document to construct things like a list
|
||||||
|
/// of figures or headers which show the current chapter title.
|
||||||
|
///
|
||||||
|
/// Most of the functions are _contextual._ It is recommended to read the chapter
|
||||||
|
/// on [context] before continuing here.
|
||||||
|
#[category]
|
||||||
|
pub static INTROSPECTION: Category;
|
||||||
|
|
||||||
/// Hook up all `introspection` definitions.
|
/// Hook up all `introspection` definitions.
|
||||||
pub fn define(global: &mut Scope) {
|
pub fn define(global: &mut Scope) {
|
||||||
global.start_category(crate::Category::Introspection);
|
global.start_category(INTROSPECTION);
|
||||||
global.define_type::<Location>();
|
global.define_type::<Location>();
|
||||||
global.define_type::<Counter>();
|
global.define_type::<Counter>();
|
||||||
global.define_type::<State>();
|
global.define_type::<State>();
|
||||||
@ -37,5 +50,4 @@ pub fn define(global: &mut Scope) {
|
|||||||
global.define_func::<here>();
|
global.define_func::<here>();
|
||||||
global.define_func::<query>();
|
global.define_func::<query>();
|
||||||
global.define_func::<locate>();
|
global.define_func::<locate>();
|
||||||
global.reset_category();
|
|
||||||
}
|
}
|
||||||
|
@ -64,11 +64,17 @@ pub use self::spacing::*;
|
|||||||
pub use self::stack::*;
|
pub use self::stack::*;
|
||||||
pub use self::transform::*;
|
pub use self::transform::*;
|
||||||
|
|
||||||
use crate::foundations::Scope;
|
use crate::foundations::{category, Category, Scope};
|
||||||
|
|
||||||
|
/// Arranging elements on the page in different ways.
|
||||||
|
///
|
||||||
|
/// By combining layout functions, you can create complex and automatic layouts.
|
||||||
|
#[category]
|
||||||
|
pub static LAYOUT: Category;
|
||||||
|
|
||||||
/// Hook up all `layout` definitions.
|
/// Hook up all `layout` definitions.
|
||||||
pub fn define(global: &mut Scope) {
|
pub fn define(global: &mut Scope) {
|
||||||
global.start_category(crate::Category::Layout);
|
global.start_category(LAYOUT);
|
||||||
global.define_type::<Length>();
|
global.define_type::<Length>();
|
||||||
global.define_type::<Angle>();
|
global.define_type::<Angle>();
|
||||||
global.define_type::<Ratio>();
|
global.define_type::<Ratio>();
|
||||||
@ -97,5 +103,4 @@ pub fn define(global: &mut Scope) {
|
|||||||
global.define_elem::<HideElem>();
|
global.define_elem::<HideElem>();
|
||||||
global.define_func::<measure>();
|
global.define_func::<measure>();
|
||||||
global.define_func::<layout>();
|
global.define_func::<layout>();
|
||||||
global.reset_category();
|
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,6 @@ pub mod visualize;
|
|||||||
|
|
||||||
use std::ops::{Deref, Range};
|
use std::ops::{Deref, Range};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use typst_syntax::{FileId, Source, Span};
|
use typst_syntax::{FileId, Source, Span};
|
||||||
use typst_utils::{LazyHash, SmallBitSet};
|
use typst_utils::{LazyHash, SmallBitSet};
|
||||||
|
|
||||||
@ -237,72 +236,31 @@ pub enum Feature {
|
|||||||
Html,
|
Html,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A group of related standard library definitions.
|
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
|
|
||||||
#[serde(rename_all = "kebab-case")]
|
|
||||||
pub enum Category {
|
|
||||||
Foundations,
|
|
||||||
Introspection,
|
|
||||||
Layout,
|
|
||||||
DataLoading,
|
|
||||||
Math,
|
|
||||||
Model,
|
|
||||||
Symbols,
|
|
||||||
Text,
|
|
||||||
Visualize,
|
|
||||||
Pdf,
|
|
||||||
Html,
|
|
||||||
Svg,
|
|
||||||
Png,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Category {
|
|
||||||
/// The kebab-case name of the category.
|
|
||||||
pub fn name(&self) -> &'static str {
|
|
||||||
match self {
|
|
||||||
Self::Foundations => "foundations",
|
|
||||||
Self::Introspection => "introspection",
|
|
||||||
Self::Layout => "layout",
|
|
||||||
Self::DataLoading => "data-loading",
|
|
||||||
Self::Math => "math",
|
|
||||||
Self::Model => "model",
|
|
||||||
Self::Symbols => "symbols",
|
|
||||||
Self::Text => "text",
|
|
||||||
Self::Visualize => "visualize",
|
|
||||||
Self::Pdf => "pdf",
|
|
||||||
Self::Html => "html",
|
|
||||||
Self::Svg => "svg",
|
|
||||||
Self::Png => "png",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Construct the module with global definitions.
|
/// Construct the module with global definitions.
|
||||||
fn global(math: Module, inputs: Dict, features: &Features) -> Module {
|
fn global(math: Module, inputs: Dict, features: &Features) -> Module {
|
||||||
let mut global = Scope::deduplicating();
|
let mut global = Scope::deduplicating();
|
||||||
|
|
||||||
self::foundations::define(&mut global, inputs, features);
|
self::foundations::define(&mut global, inputs, features);
|
||||||
self::model::define(&mut global);
|
self::model::define(&mut global);
|
||||||
self::text::define(&mut global);
|
self::text::define(&mut global);
|
||||||
|
global.reset_category();
|
||||||
|
global.define("math", math);
|
||||||
self::layout::define(&mut global);
|
self::layout::define(&mut global);
|
||||||
self::visualize::define(&mut global);
|
self::visualize::define(&mut global);
|
||||||
self::introspection::define(&mut global);
|
self::introspection::define(&mut global);
|
||||||
self::loading::define(&mut global);
|
self::loading::define(&mut global);
|
||||||
self::symbols::define(&mut global);
|
self::symbols::define(&mut global);
|
||||||
|
self::pdf::define(&mut global);
|
||||||
global.define("math", math);
|
global.reset_category();
|
||||||
global.define("pdf", self::pdf::module());
|
|
||||||
if features.is_enabled(Feature::Html) {
|
if features.is_enabled(Feature::Html) {
|
||||||
global.define("html", self::html::module());
|
global.define("html", self::html::module());
|
||||||
}
|
}
|
||||||
|
|
||||||
prelude(&mut global);
|
prelude(&mut global);
|
||||||
|
|
||||||
Module::new("global", global)
|
Module::new("global", global)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defines scoped values that are globally available, too.
|
/// Defines scoped values that are globally available, too.
|
||||||
fn prelude(global: &mut Scope) {
|
fn prelude(global: &mut Scope) {
|
||||||
|
global.reset_category();
|
||||||
global.define("black", Color::BLACK);
|
global.define("black", Color::BLACK);
|
||||||
global.define("gray", Color::GRAY);
|
global.define("gray", Color::GRAY);
|
||||||
global.define("silver", Color::SILVER);
|
global.define("silver", Color::SILVER);
|
||||||
|
@ -34,6 +34,9 @@ pub fn cbor(
|
|||||||
#[scope]
|
#[scope]
|
||||||
impl cbor {
|
impl cbor {
|
||||||
/// Reads structured data from CBOR bytes.
|
/// Reads structured data from CBOR bytes.
|
||||||
|
///
|
||||||
|
/// This function is deprecated. The [`cbor`] function now accepts bytes
|
||||||
|
/// directly.
|
||||||
#[func(title = "Decode CBOR")]
|
#[func(title = "Decode CBOR")]
|
||||||
#[deprecated = "`cbor.decode` is deprecated, directly pass bytes to `cbor` instead"]
|
#[deprecated = "`cbor.decode` is deprecated, directly pass bytes to `cbor` instead"]
|
||||||
pub fn decode(
|
pub fn decode(
|
||||||
|
@ -96,6 +96,9 @@ pub fn csv(
|
|||||||
#[scope]
|
#[scope]
|
||||||
impl csv {
|
impl csv {
|
||||||
/// Reads structured data from a CSV string/bytes.
|
/// Reads structured data from a CSV string/bytes.
|
||||||
|
///
|
||||||
|
/// This function is deprecated. The [`csv`] function now accepts bytes
|
||||||
|
/// directly.
|
||||||
#[func(title = "Decode CSV")]
|
#[func(title = "Decode CSV")]
|
||||||
#[deprecated = "`csv.decode` is deprecated, directly pass bytes to `csv` instead"]
|
#[deprecated = "`csv.decode` is deprecated, directly pass bytes to `csv` instead"]
|
||||||
pub fn decode(
|
pub fn decode(
|
||||||
|
@ -65,6 +65,9 @@ pub fn json(
|
|||||||
#[scope]
|
#[scope]
|
||||||
impl json {
|
impl json {
|
||||||
/// Reads structured data from a JSON string/bytes.
|
/// Reads structured data from a JSON string/bytes.
|
||||||
|
///
|
||||||
|
/// This function is deprecated. The [`json`] function now accepts bytes
|
||||||
|
/// directly.
|
||||||
#[func(title = "Decode JSON")]
|
#[func(title = "Decode JSON")]
|
||||||
#[deprecated = "`json.decode` is deprecated, directly pass bytes to `json` instead"]
|
#[deprecated = "`json.decode` is deprecated, directly pass bytes to `json` instead"]
|
||||||
pub fn decode(
|
pub fn decode(
|
||||||
|
@ -29,12 +29,19 @@ pub use self::yaml_::*;
|
|||||||
|
|
||||||
use crate::diag::{At, SourceResult};
|
use crate::diag::{At, SourceResult};
|
||||||
use crate::foundations::OneOrMultiple;
|
use crate::foundations::OneOrMultiple;
|
||||||
use crate::foundations::{cast, Bytes, Scope, Str};
|
use crate::foundations::{cast, category, Bytes, Category, Scope, Str};
|
||||||
use crate::World;
|
use crate::World;
|
||||||
|
|
||||||
|
/// Data loading from external files.
|
||||||
|
///
|
||||||
|
/// These functions help you with loading and embedding data, for example from
|
||||||
|
/// the results of an experiment.
|
||||||
|
#[category]
|
||||||
|
pub static DATA_LOADING: Category;
|
||||||
|
|
||||||
/// Hook up all `data-loading` definitions.
|
/// Hook up all `data-loading` definitions.
|
||||||
pub(super) fn define(global: &mut Scope) {
|
pub(super) fn define(global: &mut Scope) {
|
||||||
global.start_category(crate::Category::DataLoading);
|
global.start_category(DATA_LOADING);
|
||||||
global.define_func::<read>();
|
global.define_func::<read>();
|
||||||
global.define_func::<csv>();
|
global.define_func::<csv>();
|
||||||
global.define_func::<json>();
|
global.define_func::<json>();
|
||||||
@ -42,7 +49,6 @@ pub(super) fn define(global: &mut Scope) {
|
|||||||
global.define_func::<yaml>();
|
global.define_func::<yaml>();
|
||||||
global.define_func::<cbor>();
|
global.define_func::<cbor>();
|
||||||
global.define_func::<xml>();
|
global.define_func::<xml>();
|
||||||
global.reset_category();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Something we can retrieve byte data from.
|
/// Something we can retrieve byte data from.
|
||||||
|
@ -44,6 +44,9 @@ pub fn toml(
|
|||||||
#[scope]
|
#[scope]
|
||||||
impl toml {
|
impl toml {
|
||||||
/// Reads structured data from a TOML string/bytes.
|
/// Reads structured data from a TOML string/bytes.
|
||||||
|
///
|
||||||
|
/// This function is deprecated. The [`toml`] function now accepts bytes
|
||||||
|
/// directly.
|
||||||
#[func(title = "Decode TOML")]
|
#[func(title = "Decode TOML")]
|
||||||
#[deprecated = "`toml.decode` is deprecated, directly pass bytes to `toml` instead"]
|
#[deprecated = "`toml.decode` is deprecated, directly pass bytes to `toml` instead"]
|
||||||
pub fn decode(
|
pub fn decode(
|
||||||
|
@ -77,6 +77,9 @@ pub fn xml(
|
|||||||
#[scope]
|
#[scope]
|
||||||
impl xml {
|
impl xml {
|
||||||
/// Reads structured data from an XML string/bytes.
|
/// Reads structured data from an XML string/bytes.
|
||||||
|
///
|
||||||
|
/// This function is deprecated. The [`xml`] function now accepts bytes
|
||||||
|
/// directly.
|
||||||
#[func(title = "Decode XML")]
|
#[func(title = "Decode XML")]
|
||||||
#[deprecated = "`xml.decode` is deprecated, directly pass bytes to `xml` instead"]
|
#[deprecated = "`xml.decode` is deprecated, directly pass bytes to `xml` instead"]
|
||||||
pub fn decode(
|
pub fn decode(
|
||||||
|
@ -55,6 +55,9 @@ pub fn yaml(
|
|||||||
#[scope]
|
#[scope]
|
||||||
impl yaml {
|
impl yaml {
|
||||||
/// Reads structured data from a YAML string/bytes.
|
/// Reads structured data from a YAML string/bytes.
|
||||||
|
///
|
||||||
|
/// This function is deprecated. The [`yaml`] function now accepts bytes
|
||||||
|
/// directly.
|
||||||
#[func(title = "Decode YAML")]
|
#[func(title = "Decode YAML")]
|
||||||
#[deprecated = "`yaml.decode` is deprecated, directly pass bytes to `yaml` instead"]
|
#[deprecated = "`yaml.decode` is deprecated, directly pass bytes to `yaml` instead"]
|
||||||
pub fn decode(
|
pub fn decode(
|
||||||
|
@ -27,10 +27,119 @@ pub use self::underover::*;
|
|||||||
use typst_utils::singleton;
|
use typst_utils::singleton;
|
||||||
use unicode_math_class::MathClass;
|
use unicode_math_class::MathClass;
|
||||||
|
|
||||||
use crate::foundations::{elem, Content, Module, NativeElement, Scope};
|
use crate::foundations::{
|
||||||
|
category, elem, Category, Content, Module, NativeElement, Scope,
|
||||||
|
};
|
||||||
use crate::layout::{Em, HElem};
|
use crate::layout::{Em, HElem};
|
||||||
use crate::text::TextElem;
|
use crate::text::TextElem;
|
||||||
|
|
||||||
|
/// Typst has special [syntax]($syntax/#math) and library functions to typeset
|
||||||
|
/// mathematical formulas. Math formulas can be displayed inline with text or as
|
||||||
|
/// separate blocks. They will be typeset into their own block if they start and
|
||||||
|
/// end with at least one space (e.g. `[$ x^2 $]`).
|
||||||
|
///
|
||||||
|
/// # Variables
|
||||||
|
/// In math, single letters are always displayed as is. Multiple letters,
|
||||||
|
/// however, are interpreted as variables and functions. To display multiple
|
||||||
|
/// letters verbatim, you can place them into quotes and to access single letter
|
||||||
|
/// variables, you can use the [hash syntax]($scripting/#expressions).
|
||||||
|
///
|
||||||
|
/// ```example
|
||||||
|
/// $ A = pi r^2 $
|
||||||
|
/// $ "area" = pi dot "radius"^2 $
|
||||||
|
/// $ cal(A) :=
|
||||||
|
/// { x in RR | x "is natural" } $
|
||||||
|
/// #let x = 5
|
||||||
|
/// $ #x < 17 $
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Symbols
|
||||||
|
/// Math mode makes a wide selection of [symbols]($category/symbols/sym) like
|
||||||
|
/// `pi`, `dot`, or `RR` available. Many mathematical symbols are available in
|
||||||
|
/// different variants. You can select between different variants by applying
|
||||||
|
/// [modifiers]($symbol) to the symbol. Typst further recognizes a number of
|
||||||
|
/// shorthand sequences like `=>` that approximate a symbol. When such a
|
||||||
|
/// shorthand exists, the symbol's documentation lists it.
|
||||||
|
///
|
||||||
|
/// ```example
|
||||||
|
/// $ x < y => x gt.eq.not y $
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Line Breaks
|
||||||
|
/// Formulas can also contain line breaks. Each line can contain one or multiple
|
||||||
|
/// _alignment points_ (`&`) which are then aligned.
|
||||||
|
///
|
||||||
|
/// ```example
|
||||||
|
/// $ sum_(k=0)^n k
|
||||||
|
/// &= 1 + ... + n \
|
||||||
|
/// &= (n(n+1)) / 2 $
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Function calls
|
||||||
|
/// Math mode supports special function calls without the hash prefix. In these
|
||||||
|
/// "math calls", the argument list works a little differently than in code:
|
||||||
|
///
|
||||||
|
/// - Within them, Typst is still in "math mode". Thus, you can write math
|
||||||
|
/// directly into them, but need to use hash syntax to pass code expressions
|
||||||
|
/// (except for strings, which are available in the math syntax).
|
||||||
|
/// - They support positional and named arguments, as well as argument
|
||||||
|
/// spreading.
|
||||||
|
/// - They don't support trailing content blocks.
|
||||||
|
/// - They provide additional syntax for 2-dimensional argument lists. The
|
||||||
|
/// semicolon (`;`) merges preceding arguments separated by commas into an
|
||||||
|
/// array argument.
|
||||||
|
///
|
||||||
|
/// ```example
|
||||||
|
/// $ frac(a^2, 2) $
|
||||||
|
/// $ vec(1, 2, delim: "[") $
|
||||||
|
/// $ mat(1, 2; 3, 4) $
|
||||||
|
/// $ mat(..#range(1, 5).chunks(2)) $
|
||||||
|
/// $ lim_x =
|
||||||
|
/// op("lim", limits: #true)_x $
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// To write a verbatim comma or semicolon in a math call, escape it with a
|
||||||
|
/// backslash. The colon on the other hand is only recognized in a special way
|
||||||
|
/// if directly preceded by an identifier, so to display it verbatim in those
|
||||||
|
/// cases, you can just insert a space before it.
|
||||||
|
///
|
||||||
|
/// Functions calls preceded by a hash are normal code function calls and not
|
||||||
|
/// affected by these rules.
|
||||||
|
///
|
||||||
|
/// # Alignment
|
||||||
|
/// When equations include multiple _alignment points_ (`&`), this creates
|
||||||
|
/// blocks of alternatingly right- and left-aligned columns. In the example
|
||||||
|
/// below, the expression `(3x + y) / 7` is right-aligned and `= 9` is
|
||||||
|
/// left-aligned. The word "given" is also left-aligned because `&&` creates two
|
||||||
|
/// alignment points in a row, alternating the alignment twice. `& &` and `&&`
|
||||||
|
/// behave exactly the same way. Meanwhile, "multiply by 7" is right-aligned
|
||||||
|
/// because just one `&` precedes it. Each alignment point simply alternates
|
||||||
|
/// between right-aligned/left-aligned.
|
||||||
|
///
|
||||||
|
/// ```example
|
||||||
|
/// $ (3x + y) / 7 &= 9 && "given" \
|
||||||
|
/// 3x + y &= 63 & "multiply by 7" \
|
||||||
|
/// 3x &= 63 - y && "subtract y" \
|
||||||
|
/// x &= 21 - y/3 & "divide by 3" $
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Math fonts
|
||||||
|
/// You can set the math font by with a [show-set rule]($styling/#show-rules) as
|
||||||
|
/// demonstrated below. Note that only special OpenType math fonts are suitable
|
||||||
|
/// for typesetting maths.
|
||||||
|
///
|
||||||
|
/// ```example
|
||||||
|
/// #show math.equation: set text(font: "Fira Math")
|
||||||
|
/// $ sum_(i in NN) 1 + i $
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Math module
|
||||||
|
/// All math functions are part of the `math` [module]($scripting/#modules),
|
||||||
|
/// which is available by default in equations. Outside of equations, they can
|
||||||
|
/// be accessed with the `math.` prefix.
|
||||||
|
#[category]
|
||||||
|
pub static MATH: Category;
|
||||||
|
|
||||||
// Spacings.
|
// Spacings.
|
||||||
pub const THIN: Em = Em::new(1.0 / 6.0);
|
pub const THIN: Em = Em::new(1.0 / 6.0);
|
||||||
pub const MEDIUM: Em = Em::new(2.0 / 9.0);
|
pub const MEDIUM: Em = Em::new(2.0 / 9.0);
|
||||||
@ -41,7 +150,7 @@ pub const WIDE: Em = Em::new(2.0);
|
|||||||
/// Create a module with all math definitions.
|
/// Create a module with all math definitions.
|
||||||
pub fn module() -> Module {
|
pub fn module() -> Module {
|
||||||
let mut math = Scope::deduplicating();
|
let mut math = Scope::deduplicating();
|
||||||
math.start_category(crate::Category::Math);
|
math.start_category(MATH);
|
||||||
math.define_elem::<EquationElem>();
|
math.define_elem::<EquationElem>();
|
||||||
math.define_elem::<TextElem>();
|
math.define_elem::<TextElem>();
|
||||||
math.define_elem::<LrElem>();
|
math.define_elem::<LrElem>();
|
||||||
|
@ -40,11 +40,19 @@ pub use self::strong::*;
|
|||||||
pub use self::table::*;
|
pub use self::table::*;
|
||||||
pub use self::terms::*;
|
pub use self::terms::*;
|
||||||
|
|
||||||
use crate::foundations::Scope;
|
use crate::foundations::{category, Category, Scope};
|
||||||
|
|
||||||
|
/// Document structuring.
|
||||||
|
///
|
||||||
|
/// Here, you can find functions to structure your document and interact with
|
||||||
|
/// that structure. This includes section headings, figures, bibliography
|
||||||
|
/// management, cross-referencing and more.
|
||||||
|
#[category]
|
||||||
|
pub static MODEL: Category;
|
||||||
|
|
||||||
/// Hook up all `model` definitions.
|
/// Hook up all `model` definitions.
|
||||||
pub fn define(global: &mut Scope) {
|
pub fn define(global: &mut Scope) {
|
||||||
global.start_category(crate::Category::Model);
|
global.start_category(MODEL);
|
||||||
global.define_elem::<DocumentElem>();
|
global.define_elem::<DocumentElem>();
|
||||||
global.define_elem::<RefElem>();
|
global.define_elem::<RefElem>();
|
||||||
global.define_elem::<LinkElem>();
|
global.define_elem::<LinkElem>();
|
||||||
@ -64,5 +72,4 @@ pub fn define(global: &mut Scope) {
|
|||||||
global.define_elem::<EmphElem>();
|
global.define_elem::<EmphElem>();
|
||||||
global.define_elem::<StrongElem>();
|
global.define_elem::<StrongElem>();
|
||||||
global.define_func::<numbering>();
|
global.define_func::<numbering>();
|
||||||
global.reset_category();
|
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,21 @@ mod embed;
|
|||||||
|
|
||||||
pub use self::embed::*;
|
pub use self::embed::*;
|
||||||
|
|
||||||
use crate::foundations::{Module, Scope};
|
use crate::foundations::{category, Category, Module, Scope};
|
||||||
|
|
||||||
|
/// PDF-specific functionality.
|
||||||
|
#[category]
|
||||||
|
pub static PDF: Category;
|
||||||
|
|
||||||
|
/// Hook up the `pdf` module.
|
||||||
|
pub(super) fn define(global: &mut Scope) {
|
||||||
|
global.start_category(PDF);
|
||||||
|
global.define("pdf", module());
|
||||||
|
}
|
||||||
|
|
||||||
/// Hook up all `pdf` definitions.
|
/// Hook up all `pdf` definitions.
|
||||||
pub fn module() -> Module {
|
pub fn module() -> Module {
|
||||||
let mut pdf = Scope::deduplicating();
|
let mut scope = Scope::deduplicating();
|
||||||
pdf.start_category(crate::Category::Pdf);
|
scope.define_elem::<EmbedElem>();
|
||||||
pdf.define_elem::<EmbedElem>();
|
Module::new("pdf", scope)
|
||||||
Module::new("pdf", pdf)
|
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,19 @@
|
|||||||
//! Modifiable symbols.
|
//! Modifiable symbols.
|
||||||
|
|
||||||
use crate::foundations::{Module, Scope, Symbol, Value};
|
use crate::foundations::{category, Category, Module, Scope, Symbol, Value};
|
||||||
|
|
||||||
|
/// These two modules give names to symbols and emoji to make them easy to
|
||||||
|
/// insert with a normal keyboard. Alternatively, you can also always directly
|
||||||
|
/// enter Unicode symbols into your text and formulas. In addition to the
|
||||||
|
/// symbols listed below, math mode defines `dif` and `Dif`. These are not
|
||||||
|
/// normal symbol values because they also affect spacing and font style.
|
||||||
|
#[category]
|
||||||
|
pub static SYMBOLS: Category;
|
||||||
|
|
||||||
/// Hook up all `symbol` definitions.
|
/// Hook up all `symbol` definitions.
|
||||||
pub(super) fn define(global: &mut Scope) {
|
pub(super) fn define(global: &mut Scope) {
|
||||||
global.start_category(crate::Category::Symbols);
|
global.start_category(SYMBOLS);
|
||||||
extend_scope_from_codex_module(global, codex::ROOT);
|
extend_scope_from_codex_module(global, codex::ROOT);
|
||||||
global.reset_category();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Hook up all math `symbol` definitions, i.e., elements of the `sym` module.
|
/// Hook up all math `symbol` definitions, i.e., elements of the `sym` module.
|
||||||
|
@ -45,9 +45,9 @@ use typst_utils::singleton;
|
|||||||
use crate::diag::{bail, warning, HintedStrResult, SourceResult};
|
use crate::diag::{bail, warning, HintedStrResult, SourceResult};
|
||||||
use crate::engine::Engine;
|
use crate::engine::Engine;
|
||||||
use crate::foundations::{
|
use crate::foundations::{
|
||||||
cast, dict, elem, Args, Array, Cast, Construct, Content, Dict, Fold, IntoValue,
|
cast, category, dict, elem, Args, Array, Cast, Category, Construct, Content, Dict,
|
||||||
NativeElement, Never, NoneValue, Packed, PlainText, Regex, Repr, Resolve, Scope, Set,
|
Fold, IntoValue, NativeElement, Never, NoneValue, Packed, PlainText, Regex, Repr,
|
||||||
Smart, StyleChain,
|
Resolve, Scope, Set, Smart, StyleChain,
|
||||||
};
|
};
|
||||||
use crate::layout::{Abs, Axis, Dir, Em, Length, Ratio, Rel};
|
use crate::layout::{Abs, Axis, Dir, Em, Length, Ratio, Rel};
|
||||||
use crate::math::{EquationElem, MathSize};
|
use crate::math::{EquationElem, MathSize};
|
||||||
@ -55,9 +55,15 @@ use crate::model::ParElem;
|
|||||||
use crate::visualize::{Color, Paint, RelativeTo, Stroke};
|
use crate::visualize::{Color, Paint, RelativeTo, Stroke};
|
||||||
use crate::World;
|
use crate::World;
|
||||||
|
|
||||||
|
/// Text styling.
|
||||||
|
///
|
||||||
|
/// The [text function]($text) is of particular interest.
|
||||||
|
#[category]
|
||||||
|
pub static TEXT: Category;
|
||||||
|
|
||||||
/// Hook up all `text` definitions.
|
/// Hook up all `text` definitions.
|
||||||
pub(super) fn define(global: &mut Scope) {
|
pub(super) fn define(global: &mut Scope) {
|
||||||
global.start_category(crate::Category::Text);
|
global.start_category(TEXT);
|
||||||
global.define_elem::<TextElem>();
|
global.define_elem::<TextElem>();
|
||||||
global.define_elem::<LinebreakElem>();
|
global.define_elem::<LinebreakElem>();
|
||||||
global.define_elem::<SmartQuoteElem>();
|
global.define_elem::<SmartQuoteElem>();
|
||||||
@ -72,7 +78,6 @@ pub(super) fn define(global: &mut Scope) {
|
|||||||
global.define_func::<lower>();
|
global.define_func::<lower>();
|
||||||
global.define_func::<upper>();
|
global.define_func::<upper>();
|
||||||
global.define_func::<lorem>();
|
global.define_func::<lorem>();
|
||||||
global.reset_category();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Customizes the look and layout of text in a variety of ways.
|
/// Customizes the look and layout of text in a variety of ways.
|
||||||
|
@ -50,17 +50,6 @@ pub struct ImageElem {
|
|||||||
/// supported [formats]($image.format).
|
/// supported [formats]($image.format).
|
||||||
///
|
///
|
||||||
/// For more details about paths, see the [Paths section]($syntax/#paths).
|
/// For more details about paths, see the [Paths section]($syntax/#paths).
|
||||||
///
|
|
||||||
/// ```example
|
|
||||||
/// #let original = read("diagram.svg")
|
|
||||||
/// #let changed = original.replace(
|
|
||||||
/// "#2B80FF", // blue
|
|
||||||
/// green.to-hex(),
|
|
||||||
/// )
|
|
||||||
///
|
|
||||||
/// #image(bytes(original))
|
|
||||||
/// #image(bytes(changed))
|
|
||||||
/// ```
|
|
||||||
#[required]
|
#[required]
|
||||||
#[parse(
|
#[parse(
|
||||||
let source = args.expect::<Spanned<DataSource>>("source")?;
|
let source = args.expect::<Spanned<DataSource>>("source")?;
|
||||||
@ -167,6 +156,20 @@ pub struct ImageElem {
|
|||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
impl ImageElem {
|
impl ImageElem {
|
||||||
/// Decode a raster or vector graphic from bytes or a string.
|
/// Decode a raster or vector graphic from bytes or a string.
|
||||||
|
///
|
||||||
|
/// This function is deprecated. The [`image`] function now accepts bytes
|
||||||
|
/// directly.
|
||||||
|
///
|
||||||
|
/// ```example
|
||||||
|
/// #let original = read("diagram.svg")
|
||||||
|
/// #let changed = original.replace(
|
||||||
|
/// "#2B80FF", // blue
|
||||||
|
/// green.to-hex(),
|
||||||
|
/// )
|
||||||
|
///
|
||||||
|
/// #image.decode(original)
|
||||||
|
/// #image.decode(changed)
|
||||||
|
/// ```
|
||||||
#[func(title = "Decode Image")]
|
#[func(title = "Decode Image")]
|
||||||
#[deprecated = "`image.decode` is deprecated, directly pass bytes to `image` instead"]
|
#[deprecated = "`image.decode` is deprecated, directly pass bytes to `image` instead"]
|
||||||
pub fn decode(
|
pub fn decode(
|
||||||
|
@ -24,11 +24,19 @@ pub use self::shape::*;
|
|||||||
pub use self::stroke::*;
|
pub use self::stroke::*;
|
||||||
pub use self::tiling::*;
|
pub use self::tiling::*;
|
||||||
|
|
||||||
use crate::foundations::{Element, Scope, Type};
|
use crate::foundations::{category, Category, Element, Scope, Type};
|
||||||
|
|
||||||
|
/// Drawing and data visualization.
|
||||||
|
///
|
||||||
|
/// If you want to create more advanced drawings or plots, also have a look at
|
||||||
|
/// the [CetZ](https://github.com/johannes-wolf/cetz) package as well as more
|
||||||
|
/// specialized [packages]($universe) for your use case.
|
||||||
|
#[category]
|
||||||
|
pub static VISUALIZE: Category;
|
||||||
|
|
||||||
/// Hook up all visualize definitions.
|
/// Hook up all visualize definitions.
|
||||||
pub(super) fn define(global: &mut Scope) {
|
pub(super) fn define(global: &mut Scope) {
|
||||||
global.start_category(crate::Category::Visualize);
|
global.start_category(VISUALIZE);
|
||||||
global.define_type::<Color>();
|
global.define_type::<Color>();
|
||||||
global.define_type::<Gradient>();
|
global.define_type::<Gradient>();
|
||||||
global.define_type::<Tiling>();
|
global.define_type::<Tiling>();
|
||||||
@ -47,5 +55,4 @@ pub(super) fn define(global: &mut Scope) {
|
|||||||
global
|
global
|
||||||
.define("pattern", Type::of::<Tiling>())
|
.define("pattern", Type::of::<Tiling>())
|
||||||
.deprecated("the name `pattern` is deprecated, use `tiling` instead");
|
.deprecated("the name `pattern` is deprecated, use `tiling` instead");
|
||||||
global.reset_category();
|
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,9 @@ use crate::visualize::{FillRule, Paint, Stroke};
|
|||||||
/// ((50%, 0pt), (40pt, 0pt)),
|
/// ((50%, 0pt), (40pt, 0pt)),
|
||||||
/// )
|
/// )
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Deprecation
|
||||||
|
/// This function is deprecated. The [`curve`] function should be used instead.
|
||||||
#[elem(Show)]
|
#[elem(Show)]
|
||||||
pub struct PathElem {
|
pub struct PathElem {
|
||||||
/// How to fill the path.
|
/// How to fill the path.
|
||||||
|
59
crates/typst-macros/src/category.rs
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
use heck::{ToKebabCase, ToTitleCase};
|
||||||
|
use proc_macro2::TokenStream;
|
||||||
|
use quote::quote;
|
||||||
|
use syn::parse::{Parse, ParseStream};
|
||||||
|
use syn::{Attribute, Ident, Result, Token, Type, Visibility};
|
||||||
|
|
||||||
|
use crate::util::{documentation, foundations};
|
||||||
|
|
||||||
|
/// Expand the `#[category]` macro.
|
||||||
|
pub fn category(_: TokenStream, item: syn::Item) -> Result<TokenStream> {
|
||||||
|
let syn::Item::Verbatim(stream) = item else {
|
||||||
|
bail!(item, "expected bare static");
|
||||||
|
};
|
||||||
|
|
||||||
|
let BareStatic { attrs, vis, ident, ty, .. } = syn::parse2(stream)?;
|
||||||
|
|
||||||
|
let name = ident.to_string().to_kebab_case();
|
||||||
|
let title = name.to_title_case();
|
||||||
|
let docs = documentation(&attrs);
|
||||||
|
|
||||||
|
Ok(quote! {
|
||||||
|
#(#attrs)*
|
||||||
|
#[allow(rustdoc::broken_intra_doc_links)]
|
||||||
|
#vis static #ident: #ty = {
|
||||||
|
static DATA: #foundations::CategoryData = #foundations::CategoryData {
|
||||||
|
name: #name,
|
||||||
|
title: #title,
|
||||||
|
docs: #docs,
|
||||||
|
};
|
||||||
|
#foundations::Category::from_data(&DATA)
|
||||||
|
};
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parse a bare `pub static CATEGORY: Category;` item.
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub struct BareStatic {
|
||||||
|
pub attrs: Vec<Attribute>,
|
||||||
|
pub vis: Visibility,
|
||||||
|
pub static_token: Token![static],
|
||||||
|
pub ident: Ident,
|
||||||
|
pub colon_token: Token![:],
|
||||||
|
pub ty: Type,
|
||||||
|
pub semi_token: Token![;],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Parse for BareStatic {
|
||||||
|
fn parse(input: ParseStream) -> Result<Self> {
|
||||||
|
Ok(Self {
|
||||||
|
attrs: input.call(Attribute::parse_outer)?,
|
||||||
|
vis: input.parse()?,
|
||||||
|
static_token: input.parse()?,
|
||||||
|
ident: input.parse()?,
|
||||||
|
colon_token: input.parse()?,
|
||||||
|
ty: input.parse()?,
|
||||||
|
semi_token: input.parse()?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ extern crate proc_macro;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod util;
|
mod util;
|
||||||
mod cast;
|
mod cast;
|
||||||
|
mod category;
|
||||||
mod elem;
|
mod elem;
|
||||||
mod func;
|
mod func;
|
||||||
mod scope;
|
mod scope;
|
||||||
@ -265,6 +266,15 @@ pub fn scope(stream: BoundaryStream, item: BoundaryStream) -> BoundaryStream {
|
|||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Defines a category of definitions.
|
||||||
|
#[proc_macro_attribute]
|
||||||
|
pub fn category(stream: BoundaryStream, item: BoundaryStream) -> BoundaryStream {
|
||||||
|
let item = syn::parse_macro_input!(item as syn::Item);
|
||||||
|
category::category(stream.into(), item)
|
||||||
|
.unwrap_or_else(|err| err.to_compile_error())
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
/// Implements `Reflect`, `FromValue`, and `IntoValue` for a type.
|
/// Implements `Reflect`, `FromValue`, and `IntoValue` for a type.
|
||||||
///
|
///
|
||||||
/// - `Reflect` makes Typst's runtime aware of the type's characteristics.
|
/// - `Reflect` makes Typst's runtime aware of the type's characteristics.
|
||||||
|
@ -17,8 +17,6 @@ cli = ["clap", "typst-render", "serde_json"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
typst = { workspace = true }
|
typst = { workspace = true }
|
||||||
typst-render = { workspace = true, optional = true }
|
|
||||||
typst-utils = { workspace = true }
|
|
||||||
typst-assets = { workspace = true, features = ["fonts"] }
|
typst-assets = { workspace = true, features = ["fonts"] }
|
||||||
typst-dev-assets = { workspace = true }
|
typst-dev-assets = { workspace = true }
|
||||||
clap = { workspace = true, optional = true }
|
clap = { workspace = true, optional = true }
|
||||||
@ -30,7 +28,7 @@ serde_json = { workspace = true, optional = true }
|
|||||||
serde_yaml = { workspace = true }
|
serde_yaml = { workspace = true }
|
||||||
syntect = { workspace = true, features = ["html"] }
|
syntect = { workspace = true, features = ["html"] }
|
||||||
typed-arena = { workspace = true }
|
typed-arena = { workspace = true }
|
||||||
unicode-math-class = { workspace = true }
|
typst-render = { workspace = true, optional = true }
|
||||||
unscanny = { workspace = true }
|
unscanny = { workspace = true }
|
||||||
yaml-front-matter = { workspace = true }
|
yaml-front-matter = { workspace = true }
|
||||||
|
|
||||||
|
@ -1,324 +0,0 @@
|
|||||||
---
|
|
||||||
title: Unreleased changes planned for 0.13.0
|
|
||||||
description: Changes slated to appear in Typst 0.13.0
|
|
||||||
---
|
|
||||||
|
|
||||||
# Unreleased
|
|
||||||
|
|
||||||
## Highlights
|
|
||||||
- There is now a distinction between [proper paragraphs]($par) and just
|
|
||||||
inline-level content. This is important for future work on accessibility and
|
|
||||||
means that [first line indent]($par.first-line-indent) can now be enabled for
|
|
||||||
all paragraphs instead of just consecutive ones.
|
|
||||||
- The [`outline`] has a better out-of-the-box look and is more customizable
|
|
||||||
- The new [`curve`] function (that supersedes the `path` function) provides a
|
|
||||||
simpler and more flexible interface for creating Bézier curves
|
|
||||||
- The `image` function now supports raw [pixel raster formats]($image.format)
|
|
||||||
for generating images from within Typst
|
|
||||||
- Functions that accept [file paths]($syntax/#paths) now also accept raw
|
|
||||||
[bytes] instead, for full flexibility
|
|
||||||
- WebAssembly [plugins]($plugin) are more flexible and automatically run
|
|
||||||
multi-threaded
|
|
||||||
- Fixed a long-standing bug where single-letter strings in math (`[$"a"$]`)
|
|
||||||
would be displayed in italics
|
|
||||||
- You can now specify which charset should be [covered]($text.font) by which
|
|
||||||
font family
|
|
||||||
- The [`pdf.embed`] function lets you embed arbitrary files in the exported
|
|
||||||
PDF
|
|
||||||
- HTML export is currently under active development. The feature is still _very_
|
|
||||||
incomplete, but already available for experimentation behind a feature flag.
|
|
||||||
|
|
||||||
## Model
|
|
||||||
- There is now a distinction between [proper paragraphs]($par) and just
|
|
||||||
inline-level content **(Breaking change)**
|
|
||||||
- All text at the root of a document is wrapped in paragraphs. Meanwhile, text
|
|
||||||
in a container (like a block) is only wrapped in a paragraph if the
|
|
||||||
container holds any block-level content. If all of the content is
|
|
||||||
inline-level, no paragraph is created.
|
|
||||||
- In the laid-out document, it's not immediately visible whether text became
|
|
||||||
part of a paragraph. However, it is still important for accessibility, HTML
|
|
||||||
export, and for properties like `first-line-indent`.
|
|
||||||
- Show rules on `par` now only affect proper paragraphs
|
|
||||||
- The `first-line-indent` and `hanging-indent` properties also only affect
|
|
||||||
proper paragraphs
|
|
||||||
- Creating a `{par[..]}` with body content that is not fully inline-level will
|
|
||||||
result in a warning
|
|
||||||
- The default show rules of various built-in elements like lists, quotes, etc.
|
|
||||||
were adjusted to ensure they produce/don't produce paragraphs as appropriate
|
|
||||||
- The [`outline`] function was fully reworked to improve its out-of-the-box
|
|
||||||
behavior **(Breaking change)**
|
|
||||||
- [Outline entries]($outline.entry) are now [blocks]($block) and are thus
|
|
||||||
affected by block spacing
|
|
||||||
- The `{auto}` indentation mode now aligns numberings and titles outline-wide
|
|
||||||
for a grid-like look
|
|
||||||
- Automatic indentation now also indents entries without a numbering
|
|
||||||
- Titles wrapping over multiple lines now have hanging indent
|
|
||||||
- The page number won't appear alone on its own line anymore
|
|
||||||
- The link now spans the full entry instead of just the title and page number
|
|
||||||
- The default spacing between outline leader dots was increased
|
|
||||||
- The [`fill`]($outline.entry.fill) parameter was moved from `outline` to
|
|
||||||
`outline.entry` and can thus be configured through show-set rules
|
|
||||||
- Removed `body` and `page` fields from outline entry
|
|
||||||
- Added `indented`, `prefix`, `inner`, `body`, and `page` methods on outline
|
|
||||||
entries to simplify writing of show rules
|
|
||||||
- Added configuration to [`par.first-line-indent`] for indenting all paragraphs
|
|
||||||
instead of just consecutive ones
|
|
||||||
- Added [`form`]($ref.form) parameter to `ref` function. Setting the form to
|
|
||||||
`{"page"}` will produce a page reference instead of a textual one.
|
|
||||||
- Added [`document.description`] field, which results in corresponding PDF and
|
|
||||||
HTML metadata
|
|
||||||
- Added [`enum.reversed`] parameter
|
|
||||||
- Added support for Greek [numbering]
|
|
||||||
- When the [`link`] function wraps around a container like a [block], it will
|
|
||||||
now generate only one link for the whole block instead of individual links for
|
|
||||||
all the visible leaf elements. This significantly reduces PDF file sizes when
|
|
||||||
combining `link` and [`repeat`].
|
|
||||||
- The [`link`] function will now only strip one prefix (like `mailto:` or
|
|
||||||
`tel:`) instead of multiple
|
|
||||||
- The link function now suppresses hyphenation via a built-in show-set rule
|
|
||||||
rather than through its default show rule
|
|
||||||
- Displaying the page counter without a specified numbering will now take the
|
|
||||||
page numbering into account
|
|
||||||
|
|
||||||
## Visualization
|
|
||||||
- Added new [`curve`] function that supersedes the [`path`] function and
|
|
||||||
provides a simpler and more flexible interface. The `path` function is now
|
|
||||||
deprecated.
|
|
||||||
- The `image` function now supports raw [pixel raster formats]($image.format).
|
|
||||||
This can be used to generate images from within Typst without the need for
|
|
||||||
encoding in an image exchange format.
|
|
||||||
- Added [`image.scaling`] parameter for configuring how an image is scaled by
|
|
||||||
PNG export and PDF viewers (smooth or pixelated)
|
|
||||||
- Added [`image.icc`] parameter for providing or overriding the ICC profile of
|
|
||||||
an image
|
|
||||||
- Renamed `pattern` to [`tiling`]. The name `pattern` remains as a deprecated
|
|
||||||
alias.
|
|
||||||
- Added [`gradient.center`], [`gradient.radius`], [`gradient.focal-center`], and
|
|
||||||
[`gradient.focal-radius`] methods
|
|
||||||
- Fixed interaction of clipping and outset on [`box`] and [`block`]
|
|
||||||
- Fixed panic with [`path`] of infinite length
|
|
||||||
- Fixed non-solid (e.g. tiling) text fills in clipped blocks
|
|
||||||
- Auto-detection of image formats from a raw buffer now has basic support for
|
|
||||||
SVGs
|
|
||||||
|
|
||||||
## Scripting
|
|
||||||
- Functions that accept [file paths]($syntax/#paths) now also accept raw
|
|
||||||
[bytes]
|
|
||||||
- [`image`], [`cbor`], [`csv`], [`json`], [`toml`], [`xml`], and [`yaml`] now
|
|
||||||
support a path string or bytes and their `.decode` variants are deprecated
|
|
||||||
- [`plugin`], [`bibliography`], [`bibliography.style`], [`cite.style`],
|
|
||||||
[`raw.theme`], and [`raw.syntaxes`] now accept bytes in addition to path
|
|
||||||
strings. These did not have `.decode` variants, so this adds new
|
|
||||||
flexibility.
|
|
||||||
- The `path` argument/field of [`image`] and [`bibliography`] was renamed to
|
|
||||||
`source` and `sources`, respectively **(Minor breaking change)**
|
|
||||||
- Improved WebAssembly [plugins]($plugin)
|
|
||||||
- The `plugin` type is replaced by a [`plugin` function]($plugin) that returns
|
|
||||||
a [module] containing normal Typst functions. This module can be used with
|
|
||||||
import syntax. **(Breaking change)**
|
|
||||||
- Plugins now automatically run in multiple threads without any changes by
|
|
||||||
plugin authors
|
|
||||||
- A new [`plugin.transition`] API is introduced which allows plugins to run
|
|
||||||
impure initialization in a way that doesn't break Typst's purity guarantees
|
|
||||||
- The variable name bound by a bare import (no renaming, no import list) is now
|
|
||||||
determined statically and dynamic imports without `{as}` renaming (e.g.
|
|
||||||
`{import "ot" + "her.typ"}`) are a hard error **(Breaking change)**
|
|
||||||
- Values of the [`arguments`] type can now be added with `+` and
|
|
||||||
[joined]($scripting/#blocks) in curly-braced code blocks
|
|
||||||
- Functions in an element function's scope can now be called with method syntax,
|
|
||||||
bringing elements and types closer (in anticipation of a future full
|
|
||||||
unification of the two). Currently, this is only useful for [`outline.entry`]
|
|
||||||
as no other element function defines methods.
|
|
||||||
- Added [`calc.norm`] function
|
|
||||||
- Added support for 32-bit floats in [`float.from-bytes`] and [`float.to-bytes`]
|
|
||||||
- The [`decimal`] constructor now also accepts decimal values
|
|
||||||
- Improved `repr` of [symbols]($symbol), [arguments], and [types]($type)
|
|
||||||
- Duplicate [symbol] variants and modifiers are now a hard error
|
|
||||||
**(Breaking change)**
|
|
||||||
|
|
||||||
## Math
|
|
||||||
- Fixed a bug where single letter strings in math (`[$"a"$]`) would be displayed
|
|
||||||
in italics
|
|
||||||
- Math function calls can now have hyphenated named arguments and support
|
|
||||||
[argument spreading]($arguments/#spreading)
|
|
||||||
- Better looking accents thanks to support for the `flac` (Flattened Accent
|
|
||||||
Forms) and `dtls` (Dotless Forms) OpenType features
|
|
||||||
- Added `lcm` [text operator]($math.op)
|
|
||||||
- The [`bold`]($math.bold) function now works with ϝ and Ϝ
|
|
||||||
- The [`italic`]($math.italic) function now works with ħ
|
|
||||||
- Fixed a bug where the extent of a math equation was wrongly affected by
|
|
||||||
internal metadata
|
|
||||||
- Fixed interaction of [`lr`]($math.lr) and [context] expressions
|
|
||||||
- Fixed weak spacing being unconditionally ignored in [`lr`]($math.lr)
|
|
||||||
- Fixed sub/superscripts sometimes being in the wrong position with
|
|
||||||
[`lr`]($math.lr)
|
|
||||||
- Fixed multi-line annotations (e.g. overbrace) changing the math baseline
|
|
||||||
- Fixed merging of attachments when the base is a nested equation
|
|
||||||
- Fixed resolving of contextual (em-based) text sizes within math
|
|
||||||
- Fixed spacing around ⊥
|
|
||||||
|
|
||||||
## Bibliography
|
|
||||||
- Prose and author-only citations now use editor names if the author names are
|
|
||||||
unavailable
|
|
||||||
- Some non-standard but widely used BibLaTeX `editortype`s like `producer`,
|
|
||||||
`writer`, `scriptwriter`, and `none` (defined by widespread style
|
|
||||||
`biblatex-chicago` to mean performers within `music` and `video` entries) are
|
|
||||||
now recognized
|
|
||||||
- CSL styles can now render affixes around the bibliography
|
|
||||||
- For BibTeX entries with `eprinttype = {pubmed}`, the PubMed ID will now be
|
|
||||||
correctly processed
|
|
||||||
- Whitespace handling for strings delimiting initialized names has been improved
|
|
||||||
- Uppercase spelling after apostrophes used as quotation marks is now possible
|
|
||||||
- Fixed bugs around the handling of CSL delimiting characters
|
|
||||||
- Fixed a problem with parsing multibyte characters in page ranges that could
|
|
||||||
prevent Hayagriva from parsing some BibTeX page ranges
|
|
||||||
- Updated CSL APA style
|
|
||||||
- Updated CSL locales for Finnish, Swiss German, Austrian German, German, and
|
|
||||||
Arabic
|
|
||||||
|
|
||||||
## Text
|
|
||||||
- Added support for specifying which charset should be [covered]($text.font) by
|
|
||||||
which font family
|
|
||||||
- Added [`all`]($smallcaps.all) parameter to `smallcaps` function that also
|
|
||||||
enables small capitals on uppercase letters
|
|
||||||
- Added basic i18n for Basque and Bulgarian
|
|
||||||
- [Justification]($par.justify) does not affect [raw] blocks anymore
|
|
||||||
- [CJK-Latin-spacing]($text.cjk-latin-spacing) does not affect [raw] text
|
|
||||||
anymore
|
|
||||||
- Fixed wrong language codes being used for Greek and Ukrainian
|
|
||||||
- Fixed default quotes for Croatian
|
|
||||||
- Fixed crash in RTL text handling
|
|
||||||
- Added support for [`raw`] syntax highlighting for a few new languages: CFML,
|
|
||||||
NSIS, and WGSL
|
|
||||||
- New font metadata exception for New Computer Modern Sans Math
|
|
||||||
- Updated bundled New Computer Modern fonts to version 7.0
|
|
||||||
|
|
||||||
## Layout
|
|
||||||
- Fixed various bugs with footnotes
|
|
||||||
- Fixed footnotes getting lost when multiple footnotes were nested within
|
|
||||||
another footnote
|
|
||||||
- Fixed endless loops with empty and overlarge footnotes
|
|
||||||
- Fixed crash with overlarge footnotes within a floating placement
|
|
||||||
- Fixed sizing of quadratic shapes ([`square`] and [`circle`])
|
|
||||||
- Fixed [`block.sticky`] not working properly at the top of a container
|
|
||||||
- Fixed crash due to consecutive weak spacing
|
|
||||||
- Fixed crash when a [block] or text have negative sizes
|
|
||||||
- Fixed unnecessary hyphenations occurring in rare scenarios due to a bad
|
|
||||||
interaction between padding and paragraph optimization
|
|
||||||
- Fixed lone [citations]($cite) in [`align`] not becoming their own paragraph
|
|
||||||
|
|
||||||
## Syntax
|
|
||||||
- Top-level closing square brackets that do not have a matching opening square
|
|
||||||
bracket are now a hard error **(Minor breaking change)**
|
|
||||||
- Adding a space between the identifier and the parentheses in a set rule is not
|
|
||||||
allowed anymore **(Minor breaking change)**
|
|
||||||
- Numbers with a unit cannot have a base prefix anymore, e.g. `0b100000pt` is
|
|
||||||
not allowed anymore. Previously, it was syntactically allowed but always
|
|
||||||
resolved to a value of zero. **(Minor breaking change)**
|
|
||||||
- Using `is` as an identifier will now warn as it might become a keyword in the
|
|
||||||
future
|
|
||||||
- Fixed minor whitespace handling bugs
|
|
||||||
- in math mode argument lists
|
|
||||||
- at the end of headings
|
|
||||||
- between a term list's term and description
|
|
||||||
- Fixed parsing of empty single line raw blocks with 3+ backticks and a language
|
|
||||||
tag
|
|
||||||
- Fixed minor bug with parentheses parsing in math
|
|
||||||
- Markup that can only appear at the start of the line (headings, lists) can now
|
|
||||||
also appear at the start of a list item
|
|
||||||
- A shebang `#!` at the very start of a file is now ignored
|
|
||||||
|
|
||||||
## PDF export
|
|
||||||
- Added `pdf.embed` function for embedding arbitrary files in the exported PDF
|
|
||||||
- Added support for PDF/A-3b export
|
|
||||||
- The PDF timestamp will now contain the timezone by default
|
|
||||||
|
|
||||||
## HTML export
|
|
||||||
**Note:** HTML export is currently under active development. The feature is
|
|
||||||
still _very_ incomplete, but already available for experimentation behind a
|
|
||||||
feature flag.
|
|
||||||
|
|
||||||
- Added HTML output support for some (but not all) of the built-in elements
|
|
||||||
- Added [`html.elem`] function for outputting an arbitrary HTML element
|
|
||||||
- Added [`html.frame`] function for integrating content that requires layout
|
|
||||||
into HTML (by embedding an SVG)
|
|
||||||
- Added [`target`] function which returns either `{"paged"}` or `{"html"}`
|
|
||||||
depending on the export target
|
|
||||||
|
|
||||||
## Tooling and Diagnostics
|
|
||||||
- Autocompletion improvements
|
|
||||||
- Added autocompletion for file paths
|
|
||||||
- Smarter autocompletion of variables: Completing `{rect(fill: |)}` will now
|
|
||||||
only show variables which contain a valid fill (either directly or nested,
|
|
||||||
e.g. a dictionary containing a valid fill)
|
|
||||||
- Different functions will now autocomplete with different brackets (round vs
|
|
||||||
square) depending on which kind is more useful
|
|
||||||
- Positional parameters which are already provided aren't autocompleted again
|
|
||||||
anymore
|
|
||||||
- Fixed variable autocompletion not considering parameters
|
|
||||||
- Added autocompletion snippets for common figure usages
|
|
||||||
- Fixed autocompletion after half-completed import item
|
|
||||||
- Fixed autocompletion for `cite` function
|
|
||||||
- Added warning when an unconditional return in a code block discards joined
|
|
||||||
content
|
|
||||||
- Fixed error message when accessing non-existent label
|
|
||||||
- Fixed handling of nested imports in IDE functionality
|
|
||||||
|
|
||||||
## Command Line Interface
|
|
||||||
- Added `--features` argument and `TYPST_FEATURES` environment variable for
|
|
||||||
opting into experimental features. The only feature so far is `html`.
|
|
||||||
- Added a live reloading HTTP server to `typst watch` when targeting HTML
|
|
||||||
- Fixed self-update not being aware about certain target architectures
|
|
||||||
- Fixed crash when piping `typst fonts` output to another command
|
|
||||||
|
|
||||||
## Symbols
|
|
||||||
- New
|
|
||||||
- `inter`, `inter.and`, `inter.big`, `inter.dot`, `inter.double`, `inter.sq`,
|
|
||||||
`inter.sq.big`, `inter.sq.double`, `integral.inter`
|
|
||||||
- `asymp`, `asymp.not`
|
|
||||||
- `mapsto`, `mapsto.long`
|
|
||||||
- `divides.not.rev`, `divides.struck`
|
|
||||||
- `interleave`, `interleave.big`, `interleave.struck`
|
|
||||||
- `eq.triple.not`, `eq.dots`, `eq.dots.down`, `eq.dots.up`
|
|
||||||
- `smt`, `smt.eq`, `lat`, `lat.eq`
|
|
||||||
- `colon.tri`, `colon.tri.op`
|
|
||||||
- `dagger.triple`, `dagger.l`, `dagger.r`, `dagger.inv`
|
|
||||||
- `hourglass.stroked`, `hourglass.filled`
|
|
||||||
- `die.six`, `die.five`, `die.four`, `die.three`, `die.two`, `die.one`
|
|
||||||
- `errorbar.square.stroked`, `errorbar.square.filled`,
|
|
||||||
`errorbar.diamond.stroked`, `errorbar.diamond.filled`,
|
|
||||||
`errorbar.circle.stroked`, `errorbar.circle.filled`
|
|
||||||
- `numero`
|
|
||||||
- `Omega.inv`
|
|
||||||
- Renamed
|
|
||||||
- `ohm.inv` to `Omega.inv`
|
|
||||||
- Changed codepoint
|
|
||||||
- `angle.l.double` from `《` to `⟪`
|
|
||||||
- `angle.r.double` from `》` to `⟫`
|
|
||||||
- `angstrom` from U+212B (`Å`) to U+00C5 (`Å`)
|
|
||||||
- Deprecated
|
|
||||||
- `sect` and all its variants in favor of `inter`
|
|
||||||
- `integral.sect` in favor of `integral.inter`
|
|
||||||
- Removed
|
|
||||||
- `degree.c` in favor of `°C` (`[$upright(°C)$]` or `[$upright(degree C)$]` in math)
|
|
||||||
- `degree.f` in favor of `°F` (`[$upright(°F)$]` or `[$upright(degree F)$]` in math)
|
|
||||||
- `kelvin` in favor of just K (`[$upright(K)$]` in math)
|
|
||||||
|
|
||||||
## Deprecations
|
|
||||||
- The [`path`] function in favor of the [`curve`] function
|
|
||||||
- The name `pattern` for tiling patterns in favor of the new name [`tiling`]
|
|
||||||
- [`image.decode`], [`cbor.decode`], [`csv.decode`], [`json.decode`],
|
|
||||||
[`toml.decode`], [`xml.decode`], [`yaml.decode`] in favor of the top-level
|
|
||||||
functions directly accepting both paths and bytes
|
|
||||||
- The `sect` and its variants in favor of `inter`, and `integral.sect` in favor
|
|
||||||
of `integral.inter`
|
|
||||||
- Fully removed type/str compatibility behavior (e.g. `{int == "integer"}`)
|
|
||||||
which was temporarily introduced in Typst 0.8 **(Breaking change)**
|
|
||||||
|
|
||||||
## Development
|
|
||||||
- The `typst::compile` function is now generic and can return either a
|
|
||||||
`PagedDocument` or an `HtmlDocument`
|
|
||||||
- `typst-timing` now supports WebAssembly targets via `web-sys` when the `wasm`
|
|
||||||
feature is enabled
|
|
||||||
- Increased minimum supported Rust version to 1.80
|
|
||||||
- Fixed linux/arm64 Docker image
|
|
@ -10,7 +10,6 @@ forward. This section documents all changes to Typst since its initial public
|
|||||||
release.
|
release.
|
||||||
|
|
||||||
## Versions
|
## Versions
|
||||||
- [Unreleased changes planned for Typst 0.13.0]($changelog/0.13.0)
|
|
||||||
- [Typst 0.12.0]($changelog/0.12.0)
|
- [Typst 0.12.0]($changelog/0.12.0)
|
||||||
- [Typst 0.11.1]($changelog/0.11.1)
|
- [Typst 0.11.1]($changelog/0.11.1)
|
||||||
- [Typst 0.11.0]($changelog/0.11.0)
|
- [Typst 0.11.0]($changelog/0.11.0)
|
||||||
|
@ -657,8 +657,7 @@ applicable, contains possible workarounds.
|
|||||||
- **Well-established plotting ecosystem.** LaTeX users often create elaborate
|
- **Well-established plotting ecosystem.** LaTeX users often create elaborate
|
||||||
charts along with their documents in PGF/TikZ. The Typst ecosystem does not
|
charts along with their documents in PGF/TikZ. The Typst ecosystem does not
|
||||||
yet offer the same breadth of available options, but the ecosystem around the
|
yet offer the same breadth of available options, but the ecosystem around the
|
||||||
[`cetz` package](https://typst.app/universe/package/cetz) is catching up
|
[`cetz`](https://github.com/cetz-package/cetz) package is catching up quickly.
|
||||||
quickly.
|
|
||||||
|
|
||||||
- **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
|
||||||
@ -671,6 +670,4 @@ applicable, contains possible workarounds.
|
|||||||
format, but you can easily convert both into SVG files with [online
|
format, but you can easily convert both into SVG files with [online
|
||||||
tools](https://cloudconvert.com/pdf-to-svg) or
|
tools](https://cloudconvert.com/pdf-to-svg) or
|
||||||
[Inkscape](https://inkscape.org/). The web app will automatically convert PDF
|
[Inkscape](https://inkscape.org/). The web app will automatically convert PDF
|
||||||
files to SVG files upon uploading them. You can also use the
|
files to SVG files upon uploading them.
|
||||||
community-provided [`muchpdf` package](https://typst.app/universe/package/muchpdf)
|
|
||||||
to embed PDFs. It internally converts PDFs to SVGs on-the-fly.
|
|
||||||
|
@ -1,61 +0,0 @@
|
|||||||
<div class="info-box">
|
|
||||||
|
|
||||||
Typst's HTML export is currently under active development. The feature is still
|
|
||||||
very incomplete and only available for experimentation behind a feature flag. Do
|
|
||||||
not use this feature for production use cases. In the CLI, you can experiment
|
|
||||||
with HTML export by passing `--features html` or setting the `TYPST_FEATURES`
|
|
||||||
environment variables to `html`. In the web app, HTML export is not available at
|
|
||||||
this time. Visit the [tracking issue](https://github.com/typst/typst/issues/5512)
|
|
||||||
to follow progress on HTML export and learn more about planned features.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
HTML files describe a document structurally. The aim of Typst's HTML export is
|
|
||||||
to capture the structure of an input document and produce semantically rich HTML
|
|
||||||
that retains this structure. The resulting HTML should be accessible,
|
|
||||||
human-readable, and editable by hand and downstream tools.
|
|
||||||
|
|
||||||
PDF, PNG, and SVG export, in contrast, all produce _visual_ representations of a
|
|
||||||
fully-laid out document. This divergence in the formats' intents means that
|
|
||||||
Typst cannot simply produce perfect HTML for your existing Typst documents. It
|
|
||||||
cannot always know what the best semantic HTML representation of your content
|
|
||||||
is.
|
|
||||||
|
|
||||||
Instead, it gives _you_ full control: You can check the current export format
|
|
||||||
through the [`target`] function and when it is set to HTML, generate [raw HTML
|
|
||||||
elements]($html.elem). The primary intended use of these elements is in
|
|
||||||
templates and show rules. This way, the document's contents can be fully
|
|
||||||
agnostic to the export target and content can be shared between PDF and HTML
|
|
||||||
export.
|
|
||||||
|
|
||||||
Currently, Typst will always output a single HTML file. Support for outputting
|
|
||||||
directories with multiple HTML documents and assets, as well as support for
|
|
||||||
outputting fragments that can be integrated into other HTML documents is
|
|
||||||
planned.
|
|
||||||
|
|
||||||
Typst currently does not output CSS style sheets, instead focussing on emitting
|
|
||||||
semantic markup. You can of course write your own CSS styles and still benefit
|
|
||||||
from sharing your _content_ between PDF and HTML. For the future, we plan to
|
|
||||||
give you the option of automatically emitting CSS, taking more of your existing
|
|
||||||
set rules into account.
|
|
||||||
|
|
||||||
# Exporting as HTML
|
|
||||||
## Command Line
|
|
||||||
Pass `--format html` to the `compile` or `watch` subcommand or provide an output
|
|
||||||
file name that ends with `.html`. Note that you must also pass `--features html`
|
|
||||||
or set `TYPST_FEATURES=html` to enable this experimental export target.
|
|
||||||
|
|
||||||
When using `typst watch`, Typst will spin up a live-reloading HTTP server. You
|
|
||||||
can configure it as follows:
|
|
||||||
|
|
||||||
- Pass `--port` to change the port. (Defaults to the first free port in the
|
|
||||||
range 3000-3005.)
|
|
||||||
- Pass `--no-reload` to disable injection of a live reload script. (The HTML
|
|
||||||
that is written to disk isn't affected either way.)
|
|
||||||
- Pass `--no-serve` to disable the server altogether.
|
|
||||||
|
|
||||||
## Web App
|
|
||||||
Not currently available.
|
|
||||||
|
|
||||||
# HTML-specific functionality
|
|
||||||
Typst exposes HTML-specific functionality in the global `html` module. See below
|
|
||||||
for the definitions it contains.
|
|
@ -1,71 +0,0 @@
|
|||||||
PDF files focus on accurately describing documents visually, but also have
|
|
||||||
facilities for annotating their structure. This hybrid approach makes
|
|
||||||
them a good fit for document exchange: They render exactly the same on every
|
|
||||||
device, but also support extraction of a document's content and structure (at
|
|
||||||
least to an extent). Unlike PNG files, PDFs are not bound to a specific
|
|
||||||
resolution. Hence, you can view them at any size without incurring a loss of
|
|
||||||
quality.
|
|
||||||
|
|
||||||
# PDF standards
|
|
||||||
The International Standards Organization (ISO) has published the base PDF
|
|
||||||
standard and various standards that extend it to make PDFs more suitable for
|
|
||||||
specific use-cases. By default, Typst exports PDF 1.7 files. Adobe Acrobat 8 and
|
|
||||||
later as well as all other commonly used PDF viewers are compatible with this
|
|
||||||
PDF version.
|
|
||||||
|
|
||||||
## PDF/A
|
|
||||||
Typst optionally supports emitting PDF/A-conformant files. PDF/A files are
|
|
||||||
geared towards maximum compatibility with current and future PDF tooling. They
|
|
||||||
do not rely on difficult-to-implement or proprietary features and contain
|
|
||||||
exhaustive metadata. This makes them suitable for long-term archival.
|
|
||||||
|
|
||||||
The PDF/A Standard has multiple versions (_parts_ in ISO terminology) and most
|
|
||||||
parts have multiple profiles that indicate the file's conformance level.
|
|
||||||
Currently, Typst supports these PDF/A output profiles:
|
|
||||||
|
|
||||||
- PDF/A-2b: The basic conformance level of ISO 19005-2. This version of PDF/A is
|
|
||||||
based on PDF 1.7 and results in self-contained, archivable PDF files.
|
|
||||||
|
|
||||||
- PDF/A-3b: The basic conformance level of ISO 19005-3. This version of PDF/A is
|
|
||||||
based on PDF 1.7 and results in archivable PDF files that can contain
|
|
||||||
arbitrary other related files as [attachments]($pdf.embed). The only
|
|
||||||
difference between it and PDF/A-2b is the capability to embed
|
|
||||||
non-PDF/A-conformant files within.
|
|
||||||
|
|
||||||
When choosing between exporting PDF/A and regular PDF, keep in mind that PDF/A
|
|
||||||
files contain additional metadata, and that some readers will prevent the user
|
|
||||||
from modifying a PDF/A file. Some features of Typst may be disabled depending on
|
|
||||||
the PDF standard you choose.
|
|
||||||
|
|
||||||
# Exporting as PDF
|
|
||||||
## Command Line
|
|
||||||
PDF is Typst's default export format. Running the `compile` or `watch`
|
|
||||||
subcommand without specifying a format will create a PDF. When exporting to PDF,
|
|
||||||
you have the following configuration options:
|
|
||||||
|
|
||||||
- Which PDF standards Typst should enforce conformance with by specifying
|
|
||||||
`--pdf-standard` followed by one or multiple comma-separated standards. Valid
|
|
||||||
standards are `1.7`, `a-2b`, and `a-3b`. By default, Typst outputs
|
|
||||||
PDF-1.7-compliant files.
|
|
||||||
|
|
||||||
- Which pages to export by specifying `--pages` followed by a comma-separated
|
|
||||||
list of numbers or dash-separated number ranges. Ranges can be half-open.
|
|
||||||
Example: `2,3,7-9,11-`.
|
|
||||||
|
|
||||||
## Web App
|
|
||||||
Click the quick download button at the top right to export a PDF with default
|
|
||||||
settings. For further configuration, click "File" > "Export as" > "PDF" or click
|
|
||||||
the downwards-facing arrow next to the quick download button and select "Export
|
|
||||||
as PDF". When exporting to PDF, you have the following configuration options:
|
|
||||||
|
|
||||||
- Which PDF standards Typst should enforce conformance with. By default, Typst
|
|
||||||
outputs PDF-1.7-compliant files. Valid additional standards are `A-2b` and
|
|
||||||
`A-3b`.
|
|
||||||
|
|
||||||
- Which pages to export. Valid options are "All pages", "Current page", and
|
|
||||||
"Custom ranges". Custom ranges are a comma-separated list of numbers or
|
|
||||||
dash-separated number ranges. Ranges can be half-open. Example: `2,3,7-9,11-`.
|
|
||||||
|
|
||||||
# PDF-specific functionality
|
|
||||||
Typst exposes PDF-specific functionality in the global `pdf` module. See below
|
|
||||||
for the definitions it contains.
|
|
@ -1,61 +0,0 @@
|
|||||||
Instead of creating a PDF, Typst can also directly render pages to PNG raster
|
|
||||||
graphics. PNGs are losslessly compressed images that can contain one page at a
|
|
||||||
time. When exporting a multi-page document, Typst will emit multiple PNGs. PNGs
|
|
||||||
are a good choice when you want to use Typst's output in an image editing
|
|
||||||
software or when you can use none of Typst's other export formats.
|
|
||||||
|
|
||||||
In contrast to Typst's other export formats, PNGs are bound to a specific
|
|
||||||
resolution. When exporting to PNG, you can configure the resolution as pixels
|
|
||||||
per inch (PPI). If the medium you view the PNG on has a finer resolution than
|
|
||||||
the PNG you exported, you will notice a loss of quality. Typst calculates the
|
|
||||||
resolution of your PNGs based on each page's physical dimensions and the PPI. If
|
|
||||||
you need guidance for choosing a PPI value, consider the following:
|
|
||||||
|
|
||||||
- A DPI value of 300 or 600 is typical for desktop printing.
|
|
||||||
- Professional prints of detailed graphics can go up to 1200 PPI.
|
|
||||||
- If your document is only viewed at a distance, e.g. a poster, you may choose a
|
|
||||||
smaller value than 300.
|
|
||||||
- If your document is viewed on screens, a typical PPI value for a smartphone is
|
|
||||||
400-500.
|
|
||||||
|
|
||||||
Because PNGs only contain a pixel raster, the text within cannot be extracted
|
|
||||||
automatically (without OCR), for example by copy/paste or a screen reader. If
|
|
||||||
you need the text to be accessible, export a PDF or HTML file instead.
|
|
||||||
|
|
||||||
PNGs can have transparent backgrounds. By default, Typst will output a PNG with
|
|
||||||
an opaque white background. You can make the background transparent using
|
|
||||||
`[#set page(fill: none)]`. Learn more on the
|
|
||||||
[`page` function's reference page]($page.fill).
|
|
||||||
|
|
||||||
# Exporting as PNG
|
|
||||||
## Command Line
|
|
||||||
Pass `--format png` to the `compile` or `watch` subcommand or provide an output
|
|
||||||
file name that ends with `.png`.
|
|
||||||
|
|
||||||
If your document has more than one page, Typst will create multiple image files.
|
|
||||||
The output file name must then be a template string containing at least one of
|
|
||||||
- `[{p}]`, which will be replaced by the page number
|
|
||||||
- `[{0p}]`, which will be replaced by the zero-padded page number (so that all
|
|
||||||
numbers have the same length)
|
|
||||||
- `[{t}]`, which will be replaced by the total number of pages
|
|
||||||
|
|
||||||
When exporting to PNG, you have the following configuration options:
|
|
||||||
|
|
||||||
- Which resolution to render at by specifying `--ppi` followed by a number of
|
|
||||||
pixels per inch. The default is `144`.
|
|
||||||
|
|
||||||
- Which pages to export by specifying `--pages` followed by a comma-separated
|
|
||||||
list of numbers or dash-separated number ranges. Ranges can be half-open.
|
|
||||||
Example: `2,3,7-9,11-`.
|
|
||||||
|
|
||||||
## Web App
|
|
||||||
Click "File" > "Export as" > "PNG" or click the downwards-facing arrow next to
|
|
||||||
the quick download button and select "Export as PNG". When exporting to PNG, you
|
|
||||||
have the following configuration options:
|
|
||||||
|
|
||||||
- The resolution at which the pages should be rendered, as a number of pixels
|
|
||||||
per inch. The default is `144`.
|
|
||||||
|
|
||||||
- Which pages to export. Valid options are "All pages", "Current page", and
|
|
||||||
"Custom ranges". Custom ranges are a comma-separated list of numbers or
|
|
||||||
dash-separated number ranges. Ranges can be half-open. Example: `2,3,7-9,11-`.
|
|
@ -1,48 +0,0 @@
|
|||||||
Instead of creating a PDF, Typst can also directly render pages to scalable
|
|
||||||
vector graphics (SVGs), which are the preferred format for embedding vector
|
|
||||||
graphics in web pages. Like PDF files, SVGs display your document exactly how
|
|
||||||
you have laid it out in Typst. Likewise, they share the benefit of not being
|
|
||||||
bound to a specific resolution. Hence, you can print or view SVG files on any
|
|
||||||
device without incurring a loss of quality. (Note that font printing quality may
|
|
||||||
be better with a PDF.) In contrast to a PDF, an SVG cannot contain multiple
|
|
||||||
pages. When exporting a multi-page document, Typst will emit multiple SVGs.
|
|
||||||
|
|
||||||
SVGs can represent text in two ways: By embedding the text itself and rendering
|
|
||||||
it with the fonts available on the viewer's computer or by embedding the shapes
|
|
||||||
of each glyph in the font used to create the document. To ensure that the SVG
|
|
||||||
file looks the same across all devices it is viewed on, Typst chooses the latter
|
|
||||||
method. This means that the text in the SVG cannot be extracted automatically,
|
|
||||||
for example by copy/paste or a screen reader. If you need the text to be
|
|
||||||
accessible, export a PDF or HTML file instead.
|
|
||||||
|
|
||||||
SVGs can have transparent backgrounds. By default, Typst will output an SVG with
|
|
||||||
an opaque white background. You can make the background transparent using
|
|
||||||
`[#set page(fill: none)]`. Learn more on the
|
|
||||||
[`page` function's reference page]($page.fill).
|
|
||||||
|
|
||||||
# Exporting as SVG
|
|
||||||
## Command Line
|
|
||||||
Pass `--format svg` to the `compile` or `watch` subcommand or provide an output
|
|
||||||
file name that ends with `.svg`.
|
|
||||||
|
|
||||||
If your document has more than one page, Typst will create multiple image files.
|
|
||||||
The output file name must then be a template string containing at least one of
|
|
||||||
- `[{p}]`, which will be replaced by the page number
|
|
||||||
- `[{0p}]`, which will be replaced by the zero-padded page number (so that all
|
|
||||||
numbers have the same length)
|
|
||||||
- `[{t}]`, which will be replaced by the total number of pages
|
|
||||||
|
|
||||||
When exporting to SVG, you have the following configuration options:
|
|
||||||
|
|
||||||
- Which pages to export by specifying `--pages` followed by a comma-separated
|
|
||||||
list of numbers or dash-separated number ranges. Ranges can be half-open.
|
|
||||||
Example: `2,3,7-9,11-`.
|
|
||||||
|
|
||||||
## Web App
|
|
||||||
Click "File" > "Export as" > "SVG" or click the downwards-facing arrow next to
|
|
||||||
the quick download button and select "Export as SVG". When exporting to SVG, you
|
|
||||||
have the following configuration options:
|
|
||||||
|
|
||||||
- Which pages to export. Valid options are "All pages", "Current page", and
|
|
||||||
"Custom ranges". Custom ranges are a comma-separated list of numbers or
|
|
||||||
dash-separated number ranges. Ranges can be half-open. Example: `2,3,7-9,11-`.
|
|
@ -1,4 +0,0 @@
|
|||||||
Data loading from external files.
|
|
||||||
|
|
||||||
These functions help you with loading and embedding data, for example from the
|
|
||||||
results of an experiment.
|
|
@ -1,4 +0,0 @@
|
|||||||
Foundational types and functions.
|
|
||||||
|
|
||||||
Here, you'll find documentation for basic data types like [integers]($int) and
|
|
||||||
[strings]($str) as well as details about core computational functions.
|
|
@ -1,10 +0,0 @@
|
|||||||
Interactions between document parts.
|
|
||||||
|
|
||||||
This category is home to Typst's introspection capabilities: With the `counter`
|
|
||||||
function, you can access and manipulate page, section, figure, and equation
|
|
||||||
counters or create custom ones. Meanwhile, the `query` function lets you search
|
|
||||||
for elements in the document to construct things like a list of figures or
|
|
||||||
headers which show the current chapter title.
|
|
||||||
|
|
||||||
Most of the functions are _contextual._ It is recommended to read the chapter on
|
|
||||||
[context] before continuing here.
|
|
@ -1,3 +0,0 @@
|
|||||||
Arranging elements on the page in different ways.
|
|
||||||
|
|
||||||
By combining layout functions, you can create complex and automatic layouts.
|
|
@ -1,101 +0,0 @@
|
|||||||
Typst has special [syntax]($syntax/#math) and library functions to typeset
|
|
||||||
mathematical formulas. Math formulas can be displayed inline with text or as
|
|
||||||
separate blocks. They will be typeset into their own block if they start and end
|
|
||||||
with at least one space (e.g. `[$ x^2 $]`).
|
|
||||||
|
|
||||||
# Variables
|
|
||||||
In math, single letters are always displayed as is. Multiple letters, however,
|
|
||||||
are interpreted as variables and functions. To display multiple letters
|
|
||||||
verbatim, you can place them into quotes and to access single letter variables,
|
|
||||||
you can use the [hash syntax]($scripting/#expressions).
|
|
||||||
|
|
||||||
```example
|
|
||||||
$ A = pi r^2 $
|
|
||||||
$ "area" = pi dot "radius"^2 $
|
|
||||||
$ cal(A) :=
|
|
||||||
{ x in RR | x "is natural" } $
|
|
||||||
#let x = 5
|
|
||||||
$ #x < 17 $
|
|
||||||
```
|
|
||||||
|
|
||||||
# Symbols
|
|
||||||
Math mode makes a wide selection of [symbols]($category/symbols/sym) like `pi`,
|
|
||||||
`dot`, or `RR` available. Many mathematical symbols are available in different
|
|
||||||
variants. You can select between different variants by applying
|
|
||||||
[modifiers]($symbol) to the symbol. Typst further recognizes a number of
|
|
||||||
shorthand sequences like `=>` that approximate a symbol. When such a shorthand
|
|
||||||
exists, the symbol's documentation lists it.
|
|
||||||
|
|
||||||
```example
|
|
||||||
$ x < y => x gt.eq.not y $
|
|
||||||
```
|
|
||||||
|
|
||||||
# Line Breaks
|
|
||||||
Formulas can also contain line breaks. Each line can contain one or multiple
|
|
||||||
_alignment points_ (`&`) which are then aligned.
|
|
||||||
|
|
||||||
```example
|
|
||||||
$ sum_(k=0)^n k
|
|
||||||
&= 1 + ... + n \
|
|
||||||
&= (n(n+1)) / 2 $
|
|
||||||
```
|
|
||||||
|
|
||||||
# Function calls
|
|
||||||
Math mode supports special function calls without the hash prefix. In these
|
|
||||||
"math calls", the argument list works a little differently than in code:
|
|
||||||
|
|
||||||
- Within them, Typst is still in "math mode". Thus, you can write math directly
|
|
||||||
into them, but need to use hash syntax to pass code expressions (except for
|
|
||||||
strings, which are available in the math syntax).
|
|
||||||
- They support positional and named arguments, as well as argument spreading.
|
|
||||||
- They don't support trailing content blocks.
|
|
||||||
- They provide additional syntax for 2-dimensional argument lists. The semicolon
|
|
||||||
(`;`) merges preceding arguments separated by commas into an array argument.
|
|
||||||
|
|
||||||
```example
|
|
||||||
$ frac(a^2, 2) $
|
|
||||||
$ vec(1, 2, delim: "[") $
|
|
||||||
$ mat(1, 2; 3, 4) $
|
|
||||||
$ mat(..#range(1, 5).chunks(2)) $
|
|
||||||
$ lim_x =
|
|
||||||
op("lim", limits: #true)_x $
|
|
||||||
```
|
|
||||||
|
|
||||||
To write a verbatim comma or semicolon in a math call, escape it with a
|
|
||||||
backslash. The colon on the other hand is only recognized in a special way if
|
|
||||||
directly preceded by an identifier, so to display it verbatim in those cases,
|
|
||||||
you can just insert a space before it.
|
|
||||||
|
|
||||||
Functions calls preceded by a hash are normal code function calls and not
|
|
||||||
affected by these rules.
|
|
||||||
|
|
||||||
# Alignment
|
|
||||||
When equations include multiple _alignment points_ (`&`), this creates blocks of
|
|
||||||
alternatingly right- and left-aligned columns. In the example below, the
|
|
||||||
expression `(3x + y) / 7` is right-aligned and `= 9` is left-aligned. The word
|
|
||||||
"given" is also left-aligned because `&&` creates two alignment points in a row,
|
|
||||||
alternating the alignment twice. `& &` and `&&` behave exactly the same way.
|
|
||||||
Meanwhile, "multiply by 7" is right-aligned because just one `&` precedes it.
|
|
||||||
Each alignment point simply alternates between right-aligned/left-aligned.
|
|
||||||
|
|
||||||
```example
|
|
||||||
$ (3x + y) / 7 &= 9 && "given" \
|
|
||||||
3x + y &= 63 & "multiply by 7" \
|
|
||||||
3x &= 63 - y && "subtract y" \
|
|
||||||
x &= 21 - y/3 & "divide by 3" $
|
|
||||||
```
|
|
||||||
|
|
||||||
# Math fonts
|
|
||||||
You can set the math font by with a [show-set rule]($styling/#show-rules) as
|
|
||||||
demonstrated below. Note that only special OpenType math fonts are suitable for
|
|
||||||
typesetting maths.
|
|
||||||
|
|
||||||
```example
|
|
||||||
#show math.equation: set text(font: "Fira Math")
|
|
||||||
$ sum_(i in NN) 1 + i $
|
|
||||||
```
|
|
||||||
|
|
||||||
# Math module
|
|
||||||
All math functions are part of the `math` [module]($scripting/#modules), which
|
|
||||||
is available by default in equations. Outside of equations, they can be accessed
|
|
||||||
with the `math.` prefix.
|
|
@ -1,5 +0,0 @@
|
|||||||
Document structuring.
|
|
||||||
|
|
||||||
Here, you can find functions to structure your document and interact with that
|
|
||||||
structure. This includes section headings, figures, bibliography management,
|
|
||||||
cross-referencing and more.
|
|
@ -1,5 +0,0 @@
|
|||||||
These two modules give names to symbols and emoji to make them easy to insert
|
|
||||||
with a normal keyboard. Alternatively, you can also always directly enter
|
|
||||||
Unicode symbols into your text and formulas. In addition to the symbols listed
|
|
||||||
below, math mode defines `dif` and `Dif`. These are not normal symbol values
|
|
||||||
because they also affect spacing and font style.
|
|
@ -1,3 +0,0 @@
|
|||||||
Text styling.
|
|
||||||
|
|
||||||
The [text function]($text) is of particular interest.
|
|
@ -1,5 +0,0 @@
|
|||||||
Drawing and data visualization.
|
|
||||||
|
|
||||||
If you want to create more advanced drawings or plots, also have a look at the
|
|
||||||
[CetZ](https://github.com/johannes-wolf/cetz) package as well as more
|
|
||||||
specialized [packages]($universe) for your use case.
|
|
6
docs/reference/packages.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
Typst [packages]($scripting/#packages) encapsulate reusable building blocks
|
||||||
|
and make them reusable across projects. Below is a list of Typst packages
|
||||||
|
created by the community. Due to the early and experimental nature of Typst's
|
||||||
|
package management, they all live in a `preview` namespace. Click on a package's
|
||||||
|
name to view its documentation and use the copy button on the right to get a
|
||||||
|
full import statement for it.
|
@ -301,10 +301,7 @@ impl<'a> Handler<'a> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let body = self.peeked.as_ref();
|
let default = self.peeked.as_ref().map(|text| text.to_kebab_case());
|
||||||
let default = body.map(|text| text.to_kebab_case());
|
|
||||||
let has_id = id_slot.is_some();
|
|
||||||
|
|
||||||
let id: &'a str = match (&id_slot, default) {
|
let id: &'a str = match (&id_slot, default) {
|
||||||
(Some(id), default) => {
|
(Some(id), default) => {
|
||||||
if Some(*id) == default.as_deref() {
|
if Some(*id) == default.as_deref() {
|
||||||
@ -319,10 +316,10 @@ impl<'a> Handler<'a> {
|
|||||||
*id_slot = (!id.is_empty()).then_some(id);
|
*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 = match &body {
|
let name = if id.starts_with('v') && id.contains('.') {
|
||||||
_ if id.starts_with('v') && id.contains('.') => id.into(),
|
id.into()
|
||||||
Some(body) if !has_id => body.as_ref().into(),
|
} else {
|
||||||
_ => id.to_title_case().into(),
|
id.to_title_case().into()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut children = &mut self.outline;
|
let mut children = &mut self.outline;
|
||||||
|
185
docs/src/lib.rs
@ -12,20 +12,27 @@ pub use self::model::*;
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use ecow::{eco_format, EcoString};
|
use ecow::{eco_format, EcoString};
|
||||||
use heck::ToTitleCase;
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde_yaml as yaml;
|
use serde_yaml as yaml;
|
||||||
use std::sync::LazyLock;
|
use std::sync::LazyLock;
|
||||||
use typst::diag::{bail, StrResult};
|
use typst::diag::{bail, StrResult};
|
||||||
|
use typst::foundations::Binding;
|
||||||
use typst::foundations::{
|
use typst::foundations::{
|
||||||
AutoValue, Binding, Bytes, CastInfo, Func, Module, NoneValue, ParamInfo, Repr, Scope,
|
AutoValue, Bytes, CastInfo, Category, Func, Module, NoneValue, ParamInfo, Repr,
|
||||||
Smart, Type, Value,
|
Scope, Smart, Type, Value, FOUNDATIONS,
|
||||||
};
|
};
|
||||||
use typst::layout::{Abs, Margin, PageElem, PagedDocument};
|
use typst::html::HTML;
|
||||||
use typst::text::{Font, FontBook};
|
use typst::introspection::INTROSPECTION;
|
||||||
|
use typst::layout::{Abs, Margin, PageElem, PagedDocument, LAYOUT};
|
||||||
|
use typst::loading::DATA_LOADING;
|
||||||
|
use typst::math::MATH;
|
||||||
|
use typst::model::MODEL;
|
||||||
|
use typst::pdf::PDF;
|
||||||
|
use typst::symbols::SYMBOLS;
|
||||||
|
use typst::text::{Font, FontBook, TEXT};
|
||||||
use typst::utils::LazyHash;
|
use typst::utils::LazyHash;
|
||||||
use typst::{Category, Feature, Library, LibraryBuilder};
|
use typst::visualize::VISUALIZE;
|
||||||
use unicode_math_class::MathClass;
|
use typst::{Feature, Library, LibraryBuilder};
|
||||||
|
|
||||||
macro_rules! load {
|
macro_rules! load {
|
||||||
($path:literal) => {
|
($path:literal) => {
|
||||||
@ -57,10 +64,9 @@ static LIBRARY: LazyLock<LazyHash<Library>> = LazyLock::new(|| {
|
|||||||
let scope = lib.global.scope_mut();
|
let scope = lib.global.scope_mut();
|
||||||
|
|
||||||
// Add those types, so that they show up in the docs.
|
// Add those types, so that they show up in the docs.
|
||||||
scope.start_category(Category::Foundations);
|
scope.start_category(FOUNDATIONS);
|
||||||
scope.define_type::<NoneValue>();
|
scope.define_type::<NoneValue>();
|
||||||
scope.define_type::<AutoValue>();
|
scope.define_type::<AutoValue>();
|
||||||
scope.reset_category();
|
|
||||||
|
|
||||||
// Adjust the default look.
|
// Adjust the default look.
|
||||||
lib.styles
|
lib.styles
|
||||||
@ -149,24 +155,21 @@ fn reference_pages(resolver: &dyn Resolver) -> PageModel {
|
|||||||
let mut page = md_page(resolver, resolver.base(), load!("reference/welcome.md"));
|
let mut page = md_page(resolver, resolver.base(), load!("reference/welcome.md"));
|
||||||
let base = format!("{}reference/", resolver.base());
|
let base = format!("{}reference/", resolver.base());
|
||||||
page.children = vec![
|
page.children = vec![
|
||||||
md_page(resolver, &base, load!("reference/language/syntax.md"))
|
md_page(resolver, &base, load!("reference/syntax.md")).with_part("Language"),
|
||||||
.with_part("Language"),
|
md_page(resolver, &base, load!("reference/styling.md")),
|
||||||
md_page(resolver, &base, load!("reference/language/styling.md")),
|
md_page(resolver, &base, load!("reference/scripting.md")),
|
||||||
md_page(resolver, &base, load!("reference/language/scripting.md")),
|
md_page(resolver, &base, load!("reference/context.md")),
|
||||||
md_page(resolver, &base, load!("reference/language/context.md")),
|
category_page(resolver, FOUNDATIONS).with_part("Library"),
|
||||||
category_page(resolver, Category::Foundations).with_part("Library"),
|
category_page(resolver, MODEL),
|
||||||
category_page(resolver, Category::Model),
|
category_page(resolver, TEXT),
|
||||||
category_page(resolver, Category::Text),
|
category_page(resolver, MATH),
|
||||||
category_page(resolver, Category::Math),
|
category_page(resolver, SYMBOLS),
|
||||||
category_page(resolver, Category::Symbols),
|
category_page(resolver, LAYOUT),
|
||||||
category_page(resolver, Category::Layout),
|
category_page(resolver, VISUALIZE),
|
||||||
category_page(resolver, Category::Visualize),
|
category_page(resolver, INTROSPECTION),
|
||||||
category_page(resolver, Category::Introspection),
|
category_page(resolver, DATA_LOADING),
|
||||||
category_page(resolver, Category::DataLoading),
|
category_page(resolver, PDF),
|
||||||
category_page(resolver, Category::Pdf).with_part("Export"),
|
category_page(resolver, HTML),
|
||||||
category_page(resolver, Category::Html),
|
|
||||||
category_page(resolver, Category::Png),
|
|
||||||
category_page(resolver, Category::Svg),
|
|
||||||
];
|
];
|
||||||
page
|
page
|
||||||
}
|
}
|
||||||
@ -188,7 +191,6 @@ fn changelog_pages(resolver: &dyn Resolver) -> PageModel {
|
|||||||
let mut page = md_page(resolver, resolver.base(), load!("changelog/welcome.md"));
|
let mut page = md_page(resolver, resolver.base(), load!("changelog/welcome.md"));
|
||||||
let base = format!("{}changelog/", resolver.base());
|
let base = format!("{}changelog/", resolver.base());
|
||||||
page.children = vec![
|
page.children = vec![
|
||||||
md_page(resolver, &base, load!("changelog/0.13.0.md")),
|
|
||||||
md_page(resolver, &base, load!("changelog/0.12.0.md")),
|
md_page(resolver, &base, load!("changelog/0.12.0.md")),
|
||||||
md_page(resolver, &base, load!("changelog/0.11.1.md")),
|
md_page(resolver, &base, load!("changelog/0.11.1.md")),
|
||||||
md_page(resolver, &base, load!("changelog/0.11.0.md")),
|
md_page(resolver, &base, load!("changelog/0.11.0.md")),
|
||||||
@ -217,16 +219,14 @@ fn category_page(resolver: &dyn Resolver, category: Category) -> PageModel {
|
|||||||
let mut markup = vec![];
|
let mut markup = vec![];
|
||||||
let mut math = vec![];
|
let mut math = vec![];
|
||||||
|
|
||||||
let docs = category_docs(category);
|
let (module, path): (&Module, &[&str]) = if category == MATH {
|
||||||
let (module, path): (&Module, &[&str]) = match category {
|
(&LIBRARY.math, &["math"])
|
||||||
Category::Math => (&LIBRARY.math, &["math"]),
|
} else {
|
||||||
Category::Pdf => (get_module(&LIBRARY.global, "pdf").unwrap(), &["pdf"]),
|
(&LIBRARY.global, &[])
|
||||||
Category::Html => (get_module(&LIBRARY.global, "html").unwrap(), &["html"]),
|
|
||||||
_ => (&LIBRARY.global, &[]),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add groups.
|
// Add groups.
|
||||||
for group in GROUPS.iter().filter(|g| g.category == category).cloned() {
|
for group in GROUPS.iter().filter(|g| g.category == category.name()).cloned() {
|
||||||
if matches!(group.name.as_str(), "sym" | "emoji") {
|
if matches!(group.name.as_str(), "sym" | "emoji") {
|
||||||
let subpage = symbols_page(resolver, &route, &group);
|
let subpage = symbols_page(resolver, &route, &group);
|
||||||
let BodyModel::Symbols(model) = &subpage.body else { continue };
|
let BodyModel::Symbols(model) = &subpage.body else { continue };
|
||||||
@ -243,7 +243,7 @@ fn category_page(resolver: &dyn Resolver, category: Category) -> PageModel {
|
|||||||
items.push(CategoryItem {
|
items.push(CategoryItem {
|
||||||
name: group.name.clone(),
|
name: group.name.clone(),
|
||||||
route: subpage.route.clone(),
|
route: subpage.route.clone(),
|
||||||
oneliner: oneliner(docs).into(),
|
oneliner: oneliner(category.docs()).into(),
|
||||||
code: true,
|
code: true,
|
||||||
});
|
});
|
||||||
children.push(subpage);
|
children.push(subpage);
|
||||||
@ -256,15 +256,15 @@ fn category_page(resolver: &dyn Resolver, category: Category) -> PageModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add symbol pages. These are ordered manually.
|
// Add symbol pages. These are ordered manually.
|
||||||
if category == Category::Symbols {
|
if category == SYMBOLS {
|
||||||
shorthands = Some(ShorthandsModel { markup, math });
|
shorthands = Some(ShorthandsModel { markup, math });
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut skip = HashSet::new();
|
let mut skip = HashSet::new();
|
||||||
if category == Category::Math {
|
if category == MATH {
|
||||||
skip = GROUPS
|
skip = GROUPS
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|g| g.category == category)
|
.filter(|g| g.category == category.name())
|
||||||
.flat_map(|g| &g.filter)
|
.flat_map(|g| &g.filter)
|
||||||
.map(|s| s.as_str())
|
.map(|s| s.as_str())
|
||||||
.collect();
|
.collect();
|
||||||
@ -273,11 +273,6 @@ fn category_page(resolver: &dyn Resolver, category: Category) -> PageModel {
|
|||||||
skip.insert("text");
|
skip.insert("text");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tiling would be duplicate otherwise.
|
|
||||||
if category == Category::Visualize {
|
|
||||||
skip.insert("pattern");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add values and types.
|
// Add values and types.
|
||||||
let scope = module.scope();
|
let scope = module.scope();
|
||||||
for (name, binding) in scope.iter() {
|
for (name, binding) in scope.iter() {
|
||||||
@ -292,8 +287,8 @@ fn category_page(resolver: &dyn Resolver, category: Category) -> PageModel {
|
|||||||
match binding.read() {
|
match binding.read() {
|
||||||
Value::Func(func) => {
|
Value::Func(func) => {
|
||||||
let name = func.name().unwrap();
|
let name = func.name().unwrap();
|
||||||
let subpage =
|
|
||||||
func_page(resolver, &route, func, path, binding.deprecation());
|
let subpage = func_page(resolver, &route, func, path);
|
||||||
items.push(CategoryItem {
|
items.push(CategoryItem {
|
||||||
name: name.into(),
|
name: name.into(),
|
||||||
route: subpage.route.clone(),
|
route: subpage.route.clone(),
|
||||||
@ -316,39 +311,31 @@ fn category_page(resolver: &dyn Resolver, category: Category) -> PageModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if category != Category::Symbols {
|
if category != SYMBOLS {
|
||||||
children.sort_by_cached_key(|child| child.title.clone());
|
children.sort_by_cached_key(|child| child.title.clone());
|
||||||
items.sort_by_cached_key(|item| item.name.clone());
|
items.sort_by_cached_key(|item| item.name.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
let title = EcoString::from(match category {
|
let name = category.title();
|
||||||
Category::Pdf | Category::Html | Category::Png | Category::Svg => {
|
let details = Html::markdown(resolver, category.docs(), Some(1));
|
||||||
category.name().to_uppercase()
|
|
||||||
}
|
|
||||||
_ => category.name().to_title_case(),
|
|
||||||
});
|
|
||||||
|
|
||||||
let details = Html::markdown(resolver, docs, Some(1));
|
|
||||||
let mut outline = vec![OutlineItem::from_name("Summary")];
|
let mut outline = vec![OutlineItem::from_name("Summary")];
|
||||||
outline.extend(details.outline());
|
outline.extend(details.outline());
|
||||||
if !items.is_empty() {
|
outline.push(OutlineItem::from_name("Definitions"));
|
||||||
outline.push(OutlineItem::from_name("Definitions"));
|
|
||||||
}
|
|
||||||
if shorthands.is_some() {
|
if shorthands.is_some() {
|
||||||
outline.push(OutlineItem::from_name("Shorthands"));
|
outline.push(OutlineItem::from_name("Shorthands"));
|
||||||
}
|
}
|
||||||
|
|
||||||
PageModel {
|
PageModel {
|
||||||
route,
|
route,
|
||||||
title: title.clone(),
|
title: name.into(),
|
||||||
description: eco_format!(
|
description: eco_format!(
|
||||||
"Documentation for functions related to {title} in Typst."
|
"Documentation for functions related to {name} in Typst."
|
||||||
),
|
),
|
||||||
part: None,
|
part: None,
|
||||||
outline,
|
outline,
|
||||||
body: BodyModel::Category(CategoryModel {
|
body: BodyModel::Category(CategoryModel {
|
||||||
name: category.name(),
|
name: category.name(),
|
||||||
title,
|
title: category.title(),
|
||||||
details,
|
details,
|
||||||
items,
|
items,
|
||||||
shorthands,
|
shorthands,
|
||||||
@ -357,34 +344,14 @@ fn category_page(resolver: &dyn Resolver, category: Category) -> PageModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieve the docs for a category.
|
|
||||||
fn category_docs(category: Category) -> &'static str {
|
|
||||||
match category {
|
|
||||||
Category::Foundations => load!("reference/library/foundations.md"),
|
|
||||||
Category::Introspection => load!("reference/library/introspection.md"),
|
|
||||||
Category::Layout => load!("reference/library/layout.md"),
|
|
||||||
Category::DataLoading => load!("reference/library/data-loading.md"),
|
|
||||||
Category::Math => load!("reference/library/math.md"),
|
|
||||||
Category::Model => load!("reference/library/model.md"),
|
|
||||||
Category::Symbols => load!("reference/library/symbols.md"),
|
|
||||||
Category::Text => load!("reference/library/text.md"),
|
|
||||||
Category::Visualize => load!("reference/library/visualize.md"),
|
|
||||||
Category::Pdf => load!("reference/export/pdf.md"),
|
|
||||||
Category::Html => load!("reference/export/html.md"),
|
|
||||||
Category::Svg => load!("reference/export/svg.md"),
|
|
||||||
Category::Png => load!("reference/export/png.md"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a page for a function.
|
/// Create a page for a function.
|
||||||
fn func_page(
|
fn func_page(
|
||||||
resolver: &dyn Resolver,
|
resolver: &dyn Resolver,
|
||||||
parent: &str,
|
parent: &str,
|
||||||
func: &Func,
|
func: &Func,
|
||||||
path: &[&str],
|
path: &[&str],
|
||||||
deprecation: Option<&'static str>,
|
|
||||||
) -> PageModel {
|
) -> PageModel {
|
||||||
let model = func_model(resolver, func, path, false, deprecation);
|
let model = func_model(resolver, func, path, false);
|
||||||
let name = func.name().unwrap();
|
let name = func.name().unwrap();
|
||||||
PageModel {
|
PageModel {
|
||||||
route: eco_format!("{parent}{}/", urlify(name)),
|
route: eco_format!("{parent}{}/", urlify(name)),
|
||||||
@ -403,7 +370,6 @@ fn func_model(
|
|||||||
func: &Func,
|
func: &Func,
|
||||||
path: &[&str],
|
path: &[&str],
|
||||||
nested: bool,
|
nested: bool,
|
||||||
deprecation: Option<&'static str>,
|
|
||||||
) -> FuncModel {
|
) -> FuncModel {
|
||||||
let name = func.name().unwrap();
|
let name = func.name().unwrap();
|
||||||
let scope = func.scope().unwrap();
|
let scope = func.scope().unwrap();
|
||||||
@ -417,11 +383,7 @@ fn func_model(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut returns = vec![];
|
let mut returns = vec![];
|
||||||
let mut strings = vec![];
|
casts(resolver, &mut returns, &mut vec![], func.returns().unwrap());
|
||||||
casts(resolver, &mut returns, &mut strings, func.returns().unwrap());
|
|
||||||
if !strings.is_empty() && !returns.contains(&"str") {
|
|
||||||
returns.push("str");
|
|
||||||
}
|
|
||||||
returns.sort_by_key(|ty| type_index(ty));
|
returns.sort_by_key(|ty| type_index(ty));
|
||||||
if returns == ["none"] {
|
if returns == ["none"] {
|
||||||
returns.clear();
|
returns.clear();
|
||||||
@ -439,7 +401,6 @@ fn func_model(
|
|||||||
oneliner: oneliner(details),
|
oneliner: oneliner(details),
|
||||||
element: func.element().is_some(),
|
element: func.element().is_some(),
|
||||||
contextual: func.contextual().unwrap_or(false),
|
contextual: func.contextual().unwrap_or(false),
|
||||||
deprecation,
|
|
||||||
details: Html::markdown(resolver, details, nesting),
|
details: Html::markdown(resolver, details, nesting),
|
||||||
example: example.map(|md| Html::markdown(resolver, md, None)),
|
example: example.map(|md| Html::markdown(resolver, md, None)),
|
||||||
self_,
|
self_,
|
||||||
@ -522,7 +483,7 @@ fn scope_models(resolver: &dyn Resolver, name: &str, scope: &Scope) -> Vec<FuncM
|
|||||||
.iter()
|
.iter()
|
||||||
.filter_map(|(_, binding)| {
|
.filter_map(|(_, binding)| {
|
||||||
let Value::Func(func) = binding.read() else { return None };
|
let Value::Func(func) = binding.read() else { return None };
|
||||||
Some(func_model(resolver, func, &[name], true, binding.deprecation()))
|
Some(func_model(resolver, func, &[name], true))
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
@ -598,11 +559,9 @@ fn group_page(
|
|||||||
|
|
||||||
let mut outline_items = vec![];
|
let mut outline_items = vec![];
|
||||||
for name in &group.filter {
|
for name in &group.filter {
|
||||||
let binding = group.module().scope().get(name).unwrap();
|
let value = group.module().scope().get(name).unwrap().read();
|
||||||
let Ok(ref func) = binding.read().clone().cast::<Func>() else {
|
let Ok(ref func) = value.clone().cast::<Func>() else { panic!("not a function") };
|
||||||
panic!("not a function")
|
let func = func_model(resolver, func, &path, true);
|
||||||
};
|
|
||||||
let func = func_model(resolver, func, &path, true, binding.deprecation());
|
|
||||||
let id_base = urlify(&eco_format!("functions-{}", func.name));
|
let id_base = urlify(&eco_format!("functions-{}", func.name));
|
||||||
let children = func_outline(&func, &id_base);
|
let children = func_outline(&func, &id_base);
|
||||||
outline_items.push(OutlineItem {
|
outline_items.push(OutlineItem {
|
||||||
@ -669,7 +628,7 @@ fn type_model(resolver: &dyn Resolver, ty: &Type) -> TypeModel {
|
|||||||
constructor: ty
|
constructor: ty
|
||||||
.constructor()
|
.constructor()
|
||||||
.ok()
|
.ok()
|
||||||
.map(|func| func_model(resolver, &func, &[], true, None)),
|
.map(|func| func_model(resolver, &func, &[], true)),
|
||||||
scope: scope_models(resolver, ty.short_name(), ty.scope()),
|
scope: scope_models(resolver, ty.short_name(), ty.scope()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -723,19 +682,10 @@ fn symbols_model(resolver: &dyn Resolver, group: &GroupData) -> SymbolsModel {
|
|||||||
list.iter().copied().find(|&(_, x)| x == c).map(|(s, _)| s)
|
list.iter().copied().find(|&(_, x)| x == c).map(|(s, _)| s)
|
||||||
};
|
};
|
||||||
|
|
||||||
let name = complete(variant);
|
|
||||||
let deprecation = match name.as_str() {
|
|
||||||
"integral.sect" => {
|
|
||||||
Some("`integral.sect` is deprecated, use `integral.inter` instead")
|
|
||||||
}
|
|
||||||
_ => binding.deprecation(),
|
|
||||||
};
|
|
||||||
|
|
||||||
list.push(SymbolModel {
|
list.push(SymbolModel {
|
||||||
name,
|
name: complete(variant),
|
||||||
markup_shorthand: shorthand(typst::syntax::ast::Shorthand::LIST),
|
markup_shorthand: shorthand(typst::syntax::ast::Shorthand::LIST),
|
||||||
math_shorthand: shorthand(typst::syntax::ast::MathShorthand::LIST),
|
math_shorthand: shorthand(typst::syntax::ast::MathShorthand::LIST),
|
||||||
math_class: typst_utils::default_math_class(c).map(math_class_name),
|
|
||||||
codepoint: c as _,
|
codepoint: c as _,
|
||||||
accent: typst::math::Accent::combine(c).is_some(),
|
accent: typst::math::Accent::combine(c).is_some(),
|
||||||
alternates: symbol
|
alternates: symbol
|
||||||
@ -743,7 +693,6 @@ fn symbols_model(resolver: &dyn Resolver, group: &GroupData) -> SymbolsModel {
|
|||||||
.filter(|(other, _)| other != &variant)
|
.filter(|(other, _)| other != &variant)
|
||||||
.map(|(other, _)| complete(other))
|
.map(|(other, _)| complete(other))
|
||||||
.collect(),
|
.collect(),
|
||||||
deprecation,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -820,32 +769,12 @@ const TYPE_ORDER: &[&str] = &[
|
|||||||
"stroke",
|
"stroke",
|
||||||
];
|
];
|
||||||
|
|
||||||
fn math_class_name(class: MathClass) -> &'static str {
|
|
||||||
match class {
|
|
||||||
MathClass::Normal => "Normal",
|
|
||||||
MathClass::Alphabetic => "Alphabetic",
|
|
||||||
MathClass::Binary => "Binary",
|
|
||||||
MathClass::Closing => "Closing",
|
|
||||||
MathClass::Diacritic => "Diacritic",
|
|
||||||
MathClass::Fence => "Fence",
|
|
||||||
MathClass::GlyphPart => "Glyph Part",
|
|
||||||
MathClass::Large => "Large",
|
|
||||||
MathClass::Opening => "Opening",
|
|
||||||
MathClass::Punctuation => "Punctuation",
|
|
||||||
MathClass::Relation => "Relation",
|
|
||||||
MathClass::Space => "Space",
|
|
||||||
MathClass::Unary => "Unary",
|
|
||||||
MathClass::Vary => "Vary",
|
|
||||||
MathClass::Special => "Special",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Data about a collection of functions.
|
/// Data about a collection of functions.
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
struct GroupData {
|
struct GroupData {
|
||||||
name: EcoString,
|
name: EcoString,
|
||||||
title: EcoString,
|
title: EcoString,
|
||||||
category: Category,
|
category: EcoString,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
path: Vec<EcoString>,
|
path: Vec<EcoString>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
@ -44,8 +44,6 @@ fn resolve_known(head: &str, base: &str) -> Option<String> {
|
|||||||
"$styling" => format!("{base}reference/styling"),
|
"$styling" => format!("{base}reference/styling"),
|
||||||
"$scripting" => format!("{base}reference/scripting"),
|
"$scripting" => format!("{base}reference/scripting"),
|
||||||
"$context" => format!("{base}reference/context"),
|
"$context" => format!("{base}reference/context"),
|
||||||
"$html" => format!("{base}reference/html"),
|
|
||||||
"$pdf" => format!("{base}reference/pdf"),
|
|
||||||
"$guides" => format!("{base}guides"),
|
"$guides" => format!("{base}guides"),
|
||||||
"$changelog" => format!("{base}changelog"),
|
"$changelog" => format!("{base}changelog"),
|
||||||
"$universe" => "https://typst.app/universe".into(),
|
"$universe" => "https://typst.app/universe".into(),
|
||||||
@ -75,14 +73,11 @@ fn resolve_definition(head: &str, base: &str) -> StrResult<String> {
|
|||||||
|
|
||||||
// Handle grouped functions.
|
// Handle grouped functions.
|
||||||
if let Some(group) = GROUPS.iter().find(|group| {
|
if let Some(group) = GROUPS.iter().find(|group| {
|
||||||
group.category == category && group.filter.iter().any(|func| func == name)
|
group.category == category.name() && group.filter.iter().any(|func| func == name)
|
||||||
}) {
|
}) {
|
||||||
let mut route = format!(
|
let mut route = format!(
|
||||||
"{}reference/{}/{}/#functions-{}",
|
"{}reference/{}/{}/#functions-{}",
|
||||||
base,
|
base, group.category, group.name, name
|
||||||
group.category.name(),
|
|
||||||
group.name,
|
|
||||||
name
|
|
||||||
);
|
);
|
||||||
if let Some(param) = parts.next() {
|
if let Some(param) = parts.next() {
|
||||||
route.push('-');
|
route.push('-');
|
||||||
|
@ -64,7 +64,7 @@ pub enum BodyModel {
|
|||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
pub struct CategoryModel {
|
pub struct CategoryModel {
|
||||||
pub name: &'static str,
|
pub name: &'static str,
|
||||||
pub title: EcoString,
|
pub title: &'static str,
|
||||||
pub details: Html,
|
pub details: Html,
|
||||||
pub items: Vec<CategoryItem>,
|
pub items: Vec<CategoryItem>,
|
||||||
pub shorthands: Option<ShorthandsModel>,
|
pub shorthands: Option<ShorthandsModel>,
|
||||||
@ -89,7 +89,6 @@ pub struct FuncModel {
|
|||||||
pub oneliner: &'static str,
|
pub oneliner: &'static str,
|
||||||
pub element: bool,
|
pub element: bool,
|
||||||
pub contextual: bool,
|
pub contextual: bool,
|
||||||
pub deprecation: Option<&'static str>,
|
|
||||||
pub details: Html,
|
pub details: Html,
|
||||||
/// This example is only for nested function models. Others can have
|
/// This example is only for nested function models. Others can have
|
||||||
/// their example directly in their details.
|
/// their example directly in their details.
|
||||||
@ -164,8 +163,6 @@ pub struct SymbolModel {
|
|||||||
pub alternates: Vec<EcoString>,
|
pub alternates: Vec<EcoString>,
|
||||||
pub markup_shorthand: Option<&'static str>,
|
pub markup_shorthand: Option<&'static str>,
|
||||||
pub math_shorthand: Option<&'static str>,
|
pub math_shorthand: Option<&'static str>,
|
||||||
pub math_class: Option<&'static str>,
|
|
||||||
pub deprecation: Option<&'static str>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Shorthands listed on a category page.
|
/// Shorthands listed on a category page.
|
||||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 8.9 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |