diff --git a/Cargo.lock b/Cargo.lock index bfd1ccda6..78ab71c59 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -395,6 +395,11 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "codex" +version = "0.1.0" +source = "git+https://github.com/typst/codex?rev=343a9b1#343a9b199430681ba3ca0e2242097c6419492d55" + [[package]] name = "color-print" version = "0.3.6" @@ -2849,6 +2854,7 @@ dependencies = [ "bumpalo", "chinese-number", "ciborium", + "codex", "comemo", "csv", "ecow", diff --git a/Cargo.toml b/Cargo.toml index e1f6dccb4..cebc2e972 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,6 +46,7 @@ clap = { version = "4.4", features = ["derive", "env", "wrap_help"] } clap_complete = "4.2.1" clap_mangen = "0.2.10" codespan-reporting = "0.11" +codex = { git = "https://github.com/typst/codex", rev = "343a9b1" } color-print = "0.3.6" comemo = "0.4" csv = "1" diff --git a/crates/typst-eval/src/markup.rs b/crates/typst-eval/src/markup.rs index e28eb9ddb..25ea5751a 100644 --- a/crates/typst-eval/src/markup.rs +++ b/crates/typst-eval/src/markup.rs @@ -122,7 +122,7 @@ impl Eval for ast::Escape<'_> { type Output = Value; fn eval(self, _: &mut Vm) -> SourceResult { - Ok(Value::Symbol(Symbol::single(self.get().into()))) + Ok(Value::Symbol(Symbol::single(self.get()))) } } @@ -130,7 +130,7 @@ impl Eval for ast::Shorthand<'_> { type Output = Value; fn eval(self, _: &mut Vm) -> SourceResult { - Ok(Value::Symbol(Symbol::single(self.get().into()))) + Ok(Value::Symbol(Symbol::single(self.get()))) } } diff --git a/crates/typst-eval/src/math.rs b/crates/typst-eval/src/math.rs index c61a32514..51dc0a3d5 100644 --- a/crates/typst-eval/src/math.rs +++ b/crates/typst-eval/src/math.rs @@ -32,7 +32,7 @@ impl Eval for ast::MathShorthand<'_> { type Output = Value; fn eval(self, _: &mut Vm) -> SourceResult { - Ok(Value::Symbol(Symbol::single(self.get().into()))) + Ok(Value::Symbol(Symbol::single(self.get()))) } } diff --git a/crates/typst-library/Cargo.toml b/crates/typst-library/Cargo.toml index a1fb1033f..d854e4d53 100644 --- a/crates/typst-library/Cargo.toml +++ b/crates/typst-library/Cargo.toml @@ -23,6 +23,7 @@ bitflags = { workspace = true } bumpalo = { workspace = true } chinese-number = { workspace = true } ciborium = { workspace = true } +codex = { workspace = true } comemo = { workspace = true } csv = { workspace = true } ecow = { workspace = true } diff --git a/crates/typst-library/src/foundations/symbol.rs b/crates/typst-library/src/foundations/symbol.rs index 86676fa22..fcb3a3ce5 100644 --- a/crates/typst-library/src/foundations/symbol.rs +++ b/crates/typst-library/src/foundations/symbol.rs @@ -1,6 +1,3 @@ -#[doc(inline)] -pub use typst_macros::symbols; - use std::cmp::Reverse; use std::collections::BTreeSet; use std::fmt::{self, Debug, Display, Formatter, Write}; @@ -8,10 +5,10 @@ use std::sync::Arc; use ecow::{eco_format, EcoString}; use serde::{Serialize, Serializer}; -use typst_syntax::{Span, Spanned}; +use typst_syntax::{is_ident, Span, Spanned}; use crate::diag::{bail, SourceResult, StrResult}; -use crate::foundations::{cast, func, scope, ty, Array, Func}; +use crate::foundations::{cast, func, scope, ty, Array, Func, NativeFunc, Repr as _}; /// A Unicode symbol. /// @@ -46,73 +43,90 @@ use crate::foundations::{cast, func, scope, ty, Array, Func}; #[derive(Debug, Clone, Eq, PartialEq, Hash)] pub struct Symbol(Repr); -/// The character of a symbol, possibly with a function. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub struct SymChar(char, Option Func>); - /// The internal representation. #[derive(Clone, Eq, PartialEq, Hash)] enum Repr { - Single(SymChar), - Const(&'static [(&'static str, SymChar)]), - Multi(Arc<(List, EcoString)>), + /// A native symbol that has no named variant. + Single(char), + /// A native symbol with multiple named variants. + Complex(&'static [(&'static str, char)]), + /// A symbol with multiple named variants, where some modifiers may have + /// been applied. Also used for symbols defined at runtime by the user with + /// no modifier applied. + Modified(Arc<(List, EcoString)>), } /// A collection of symbols. #[derive(Clone, Eq, PartialEq, Hash)] enum List { - Static(&'static [(&'static str, SymChar)]), - Runtime(Box<[(EcoString, SymChar)]>), + Static(&'static [(&'static str, char)]), + Runtime(Box<[(EcoString, char)]>), } impl Symbol { /// Create a new symbol from a single character. - pub const fn single(c: SymChar) -> Self { + pub const fn single(c: char) -> Self { Self(Repr::Single(c)) } /// Create a symbol with a static variant list. #[track_caller] - pub const fn list(list: &'static [(&'static str, SymChar)]) -> Self { + pub const fn list(list: &'static [(&'static str, char)]) -> Self { debug_assert!(!list.is_empty()); - Self(Repr::Const(list)) + Self(Repr::Complex(list)) } /// Create a symbol with a runtime variant list. #[track_caller] - pub fn runtime(list: Box<[(EcoString, SymChar)]>) -> Self { + pub fn runtime(list: Box<[(EcoString, char)]>) -> Self { debug_assert!(!list.is_empty()); - Self(Repr::Multi(Arc::new((List::Runtime(list), EcoString::new())))) + Self(Repr::Modified(Arc::new((List::Runtime(list), EcoString::new())))) } - /// Get the symbol's char. + /// Get the symbol's character. pub fn get(&self) -> char { - self.sym().char() - } - - /// Resolve the symbol's `SymChar`. - pub fn sym(&self) -> SymChar { match &self.0 { Repr::Single(c) => *c, - Repr::Const(_) => find(self.variants(), "").unwrap(), - Repr::Multi(arc) => find(self.variants(), &arc.1).unwrap(), + Repr::Complex(_) => find(self.variants(), "").unwrap(), + Repr::Modified(arc) => find(self.variants(), &arc.1).unwrap(), } } /// Try to get the function associated with the symbol, if any. pub fn func(&self) -> StrResult { - self.sym() - .func() - .ok_or_else(|| eco_format!("symbol {self} is not callable")) + match self.get() { + '⌈' => Ok(crate::math::ceil::func()), + '⌊' => Ok(crate::math::floor::func()), + '–' => Ok(crate::math::accent::dash::func()), + '⋅' | '\u{0307}' => Ok(crate::math::accent::dot::func()), + '¨' => Ok(crate::math::accent::dot_double::func()), + '\u{20db}' => Ok(crate::math::accent::dot_triple::func()), + '\u{20dc}' => Ok(crate::math::accent::dot_quad::func()), + '∼' => Ok(crate::math::accent::tilde::func()), + '´' => Ok(crate::math::accent::acute::func()), + '˝' => Ok(crate::math::accent::acute_double::func()), + '˘' => Ok(crate::math::accent::breve::func()), + 'ˇ' => Ok(crate::math::accent::caron::func()), + '^' => Ok(crate::math::accent::hat::func()), + '`' => Ok(crate::math::accent::grave::func()), + '¯' => Ok(crate::math::accent::macron::func()), + '○' => Ok(crate::math::accent::circle::func()), + '→' => Ok(crate::math::accent::arrow::func()), + '←' => Ok(crate::math::accent::arrow_l::func()), + '↔' => Ok(crate::math::accent::arrow_l_r::func()), + '⇀' => Ok(crate::math::accent::harpoon::func()), + '↼' => Ok(crate::math::accent::harpoon_lt::func()), + _ => bail!("symbol {self} is not callable"), + } } /// Apply a modifier to the symbol. pub fn modified(mut self, modifier: &str) -> StrResult { - if let Repr::Const(list) = self.0 { - self.0 = Repr::Multi(Arc::new((List::Static(list), EcoString::new()))); + if let Repr::Complex(list) = self.0 { + self.0 = Repr::Modified(Arc::new((List::Static(list), EcoString::new()))); } - if let Repr::Multi(arc) = &mut self.0 { + if let Repr::Modified(arc) = &mut self.0 { let (list, modifiers) = Arc::make_mut(arc); if !modifiers.is_empty() { modifiers.push('.'); @@ -127,11 +141,11 @@ impl Symbol { } /// The characters that are covered by this symbol. - pub fn variants(&self) -> impl Iterator { + pub fn variants(&self) -> impl Iterator { match &self.0 { Repr::Single(c) => Variants::Single(Some(*c).into_iter()), - Repr::Const(list) => Variants::Static(list.iter()), - Repr::Multi(arc) => arc.0.variants(), + Repr::Complex(list) => Variants::Static(list.iter()), + Repr::Modified(arc) => arc.0.variants(), } } @@ -139,7 +153,7 @@ impl Symbol { pub fn modifiers(&self) -> impl Iterator + '_ { let mut set = BTreeSet::new(); let modifiers = match &self.0 { - Repr::Multi(arc) => arc.1.as_str(), + Repr::Modified(arc) => arc.1.as_str(), _ => "", }; for modifier in self.variants().flat_map(|(name, _)| name.split('.')) { @@ -192,7 +206,14 @@ impl Symbol { if list.iter().any(|(prev, _)| &v.0 == prev) { bail!(span, "duplicate variant"); } - list.push((v.0, SymChar::pure(v.1))); + if !v.0.is_empty() { + for modifier in v.0.split('.') { + if !is_ident(modifier) { + bail!(span, "invalid symbol modifier: {}", modifier.repr()); + } + } + } + list.push((v.0, v.1)); } Ok(Symbol::runtime(list.into_boxed_slice())) } @@ -204,40 +225,12 @@ impl Display for Symbol { } } -impl SymChar { - /// Create a symbol character without a function. - pub const fn pure(c: char) -> Self { - Self(c, None) - } - - /// Create a symbol character with a function. - pub const fn with_func(c: char, func: fn() -> Func) -> Self { - Self(c, Some(func)) - } - - /// Get the character of the symbol. - pub const fn char(&self) -> char { - self.0 - } - - /// Get the function associated with the symbol. - pub fn func(&self) -> Option { - self.1.map(|f| f()) - } -} - -impl From for SymChar { - fn from(c: char) -> Self { - SymChar(c, None) - } -} - impl Debug for Repr { fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { Self::Single(c) => Debug::fmt(c, f), - Self::Const(list) => list.fmt(f), - Self::Multi(lists) => lists.fmt(f), + Self::Complex(list) => list.fmt(f), + Self::Modified(lists) => lists.fmt(f), } } } @@ -286,20 +279,20 @@ cast! { let mut iter = array.into_iter(); match (iter.next(), iter.next(), iter.next()) { (Some(a), Some(b), None) => Self(a.cast()?, b.cast()?), - _ => Err("point array must contain exactly two entries")?, + _ => Err("variant array must contain exactly two entries")?, } }, } /// Iterator over variants. enum Variants<'a> { - Single(std::option::IntoIter), - Static(std::slice::Iter<'static, (&'static str, SymChar)>), - Runtime(std::slice::Iter<'a, (EcoString, SymChar)>), + Single(std::option::IntoIter), + Static(std::slice::Iter<'static, (&'static str, char)>), + Runtime(std::slice::Iter<'a, (EcoString, char)>), } impl<'a> Iterator for Variants<'a> { - type Item = (&'a str, SymChar); + type Item = (&'a str, char); fn next(&mut self) -> Option { match self { @@ -312,9 +305,9 @@ impl<'a> Iterator for Variants<'a> { /// Find the best symbol from the list. fn find<'a>( - variants: impl Iterator, + variants: impl Iterator, modifiers: &str, -) -> Option { +) -> Option { let mut best = None; let mut best_score = None; diff --git a/crates/typst-library/src/math/mod.rs b/crates/typst-library/src/math/mod.rs index 53b1f0724..5a83c854f 100644 --- a/crates/typst-library/src/math/mod.rs +++ b/crates/typst-library/src/math/mod.rs @@ -207,9 +207,7 @@ pub fn module() -> Module { math.define("wide", HElem::new(WIDE.into()).pack()); // Symbols. - for (name, symbol) in crate::symbols::SYM { - math.define(*name, symbol.clone()); - } + crate::symbols::define_math(&mut math); Module::new("math", math) } diff --git a/crates/typst-library/src/symbols.rs b/crates/typst-library/src/symbols.rs new file mode 100644 index 000000000..1617d3aa8 --- /dev/null +++ b/crates/typst-library/src/symbols.rs @@ -0,0 +1,49 @@ +//! Modifiable symbols. + +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; + +impl From for Scope { + fn from(module: codex::Module) -> Scope { + let mut scope = Self::new(); + extend_scope_from_codex_module(&mut scope, module); + scope + } +} + +impl From for Symbol { + fn from(symbol: codex::Symbol) -> Self { + match symbol { + codex::Symbol::Single(c) => Symbol::single(c), + codex::Symbol::Multi(list) => Symbol::list(list), + } + } +} + +fn extend_scope_from_codex_module(scope: &mut Scope, module: codex::Module) { + for (name, definition) in module.iter() { + let value = match definition { + codex::Def::Symbol(s) => Value::Symbol(s.into()), + codex::Def::Module(m) => Value::Module(Module::new(name, m.into())), + }; + scope.define(name, value); + } +} + +/// Hook up all `symbol` definitions. +pub(super) fn define(global: &mut Scope) { + global.category(SYMBOLS); + extend_scope_from_codex_module(global, codex::ROOT); +} + +/// Hook up all math `symbol` definitions, i.e., elements of the `sym` module. +pub(super) fn define_math(math: &mut Scope) { + extend_scope_from_codex_module(math, codex::SYM); +} diff --git a/crates/typst-library/src/symbols/emoji.rs b/crates/typst-library/src/symbols/emoji.rs deleted file mode 100644 index 1bd57ec0b..000000000 --- a/crates/typst-library/src/symbols/emoji.rs +++ /dev/null @@ -1,1363 +0,0 @@ -use crate::foundations::{Module, Scope, Symbol}; - -/// A module with all emoji. -pub fn emoji() -> Module { - let mut scope = Scope::new(); - for (name, symbol) in EMOJI { - scope.define(*name, symbol.clone()); - } - Module::new("emoji", scope) -} - -/// A list of named emoji. -const EMOJI: &[(&str, Symbol)] = typst_macros::symbols! { - abacus: '🧮', - abc: '🔤', - abcd: '🔡', - ABCD: '🔠', - accordion: '🪗', - aesculapius: '⚕', - airplane: [ - '✈', - landing: '🛬', - small: '🛩', - takeoff: '🛫', - ], - alembic: '⚗', - alien: ['👽', monster: '👾'], - ambulance: '🚑', - amphora: '🏺', - anchor: '⚓', - anger: '💢', - ant: '🐜', - apple: [green: '🍏', red: '🍎'], - arm: [mech: '🦾', muscle: '💪', selfie: '🤳'], - arrow: [ - r.filled: '➡', - r.hook: '↪', - r.soon: '🔜', - l.filled: '⬅', - l.hook: '↩', - l.back: '🔙', - l.end: '🔚', - t.filled: '⬆', - t.curve: '⤴', - t.top: '🔝', - b.filled: '⬇', - b.curve: '⤵', - l.r: '↔', - l.r.on: '🔛', - t.b: '↕', - bl: '↙', - br: '↘', - tl: '↖', - tr: '↗', - ], - arrows: [cycle: '🔄'], - ast: ['*', box: '✳'], - atm: '🏧', - atom: '⚛', - aubergine: '🍆', - avocado: '🥑', - axe: '🪓', - baby: ['👶', angel: '👼', box: '🚼'], - babybottle: '🍼', - backpack: '🎒', - bacon: '🥓', - badger: '🦡', - badminton: '🏸', - bagel: '🥯', - baggageclaim: '🛄', - baguette: '🥖', - balloon: '🎈', - ballot: [check: '☑'], - ballotbox: '🗳', - banana: '🍌', - banjo: '🪕', - bank: '🏦', - barberpole: '💈', - baseball: '⚾', - basecap: '🧢', - basket: '🧺', - basketball: ['⛹', ball: '🏀'], - bat: '🦇', - bathtub: ['🛀', foam: '🛁'], - battery: ['🔋', low: '🪫'], - beach: [palm: '🏝', umbrella: '🏖'], - beads: '📿', - beans: '🫘', - bear: '🐻', - beaver: '🦫', - bed: ['🛏', person: '🛌'], - bee: '🐝', - beer: ['🍺', clink: '🍻'], - beet: '🫜', - beetle: ['🪲', lady: '🐞'], - bell: ['🔔', ding: '🛎', not: '🔕'], - bento: '🍱', - bicyclist: ['🚴', mountain: '🚵'], - bike: ['🚲', not: '🚳'], - bikini: '👙', - billiards: '🎱', - bin: '🗑', - biohazard: '☣', - bird: '🐦', - bison: '🦬', - blood: '🩸', - blouse: '👚', - blowfish: '🐡', - blueberries: '🫐', - boar: '🐗', - boat: [ - sail: '⛵', - row: '🚣', - motor: '🛥', - speed: '🚤', - canoe: '🛶', - ], - bolt: '🔩', - bomb: '💣', - bone: '🦴', - book: [ - red: '📕', - blue: '📘', - green: '📗', - orange: '📙', - spiral: '📒', - open: '📖', - ], - bookmark: '🔖', - books: '📚', - boomerang: '🪃', - bordercontrol: '🛂', - bouquet: '💐', - bow: '🏹', - bowl: [spoon: '🥣', steam: '🍜'], - bowling: '🎳', - boxing: '🥊', - boy: '👦', - brain: '🧠', - bread: '🍞', - brick: '🧱', - bride: '👰', - bridge: [fog: '🌁', night: '🌉'], - briefcase: '💼', - briefs: '🩲', - brightness: [high: '🔆', low: '🔅'], - broccoli: '🥦', - broom: '🧹', - brush: '🖌', - bubble: [ - speech.r: '💬', - speech.l: '🗨', - thought: '💭', - anger.r: '🗯', - ], - bubbles: '🫧', - bubbletea: '🧋', - bucket: '🪣', - buffalo: [water: '🐃'], - bug: '🐛', - builder: '👷', - burger: '🍔', - burrito: '🌯', - bus: [ - '🚌', - front: '🚍', - small: '🚐', - stop: '🚏', - trolley: '🚎', - ], - butter: '🧈', - butterfly: '🦋', - button: ['🔲', alt: '🔳', radio: '🔘'], - cabinet: [file: '🗄'], - cablecar: ['🚠', small: '🚡'], - cactus: '🌵', - cake: [ - '🎂', - fish: '🍥', - moon: '🥮', - slice: '🍰', - ], - calendar: ['📅', spiral: '🗓', tearoff: '📆'], - camel: ['🐫', dromedar: '🐪'], - camera: [ - '📷', - flash: '📸', - movie: '🎥', - movie.box: '🎦', - video: '📹', - ], - camping: '🏕', - can: '🥫', - candle: '🕯', - candy: '🍬', - cane: '🦯', - car: [ - '🚗', - front: '🚘', - pickup: '🛻', - police: '🚓', - police.front: '🚔', - racing: '🏎', - rickshaw: '🛺', - suv: '🚙', - ], - card: [credit: '💳', id: '🪪'], - cardindex: '📇', - carrot: '🥕', - cart: '🛒', - cassette: '📼', - castle: [eu: '🏰', jp: '🏯'], - cat: [ - '🐈', - face: '🐱', - face.angry: '😾', - face.cry: '😿', - face.heart: '😻', - face.joy: '😹', - face.kiss: '😽', - face.laugh: '😸', - face.shock: '🙀', - face.smile: '😺', - face.smirk: '😼', - ], - chain: '🔗', - chains: '⛓', - chair: '🪑', - champagne: '🍾', - chart: [ - bar: '📊', - up: '📈', - down: '📉', - yen.up: '💹', - ], - checkmark: [heavy: '✔', box: '✅'], - cheese: '🧀', - cherries: '🍒', - chess: '♟', - chestnut: '🌰', - chicken: [ - '🐔', - baby: '🐥', - baby.egg: '🐣', - baby.head: '🐤', - leg: '🍗', - male: '🐓', - ], - child: '🧒', - chipmunk: '🐿', - chocolate: '🍫', - chopsticks: '🥢', - church: ['⛪', love: '💒'], - cigarette: ['🚬', not: '🚭'], - circle: [ - black: '⚫', - blue: '🔵', - brown: '🟤', - green: '🟢', - orange: '🟠', - purple: '🟣', - white: '⚪', - red: '🔴', - yellow: '🟡', - stroked: '⭕', - ], - circus: '🎪', - city: [ - '🏙', - dusk: '🌆', - night: '🌃', - sunset: '🌇', - ], - clamp: '🗜', - clapperboard: '🎬', - climbing: '🧗', - clip: '📎', - clipboard: '📋', - clips: '🖇', - clock: [ - one: '🕐', - one.thirty: '🕜', - two: '🕑', - two.thirty: '🕝', - three: '🕒', - three.thirty: '🕞', - four: '🕓', - four.thirty: '🕟', - five: '🕔', - five.thirty: '🕠', - six: '🕕', - six.thirty: '🕡', - seven: '🕖', - seven.thirty: '🕢', - eight: '🕗', - eight.thirty: '🕣', - nine: '🕘', - nine.thirty: '🕤', - ten: '🕙', - ten.thirty: '🕥', - eleven: '🕚', - eleven.thirty: '🕦', - twelve: '🕛', - twelve.thirty: '🕧', - alarm: '⏰', - old: '🕰', - timer: '⏲', - ], - cloud: [ - '☁', - dust: '💨', - rain: '🌧', - snow: '🌨', - storm: '⛈', - sun: '⛅', - sun.hidden: '🌥', - sun.rain: '🌦', - thunder: '🌩', - ], - coat: ['🧥', lab: '🥼'], - cockroach: '🪳', - cocktail: [martini: '🍸', tropical: '🍹'], - coconut: '🥥', - coffee: '☕', - coffin: '⚰', - coin: '🪙', - comet: '☄', - compass: '🧭', - computer: '🖥', - computermouse: '🖱', - confetti: '🎊', - construction: '🚧', - controller: '🎮', - cookie: ['🍪', fortune: '🥠'], - cooking: '🍳', - cool: '🆒', - copyright: '©', - coral: '🪸', - corn: '🌽', - couch: '🛋', - couple: '💑', - cow: ['🐄', face: '🐮'], - crab: '🦀', - crane: '🏗', - crayon: '🖍', - cricket: '🦗', - cricketbat: '🏏', - crocodile: '🐊', - croissant: '🥐', - crossmark: ['❌', box: '❎'], - crown: '👑', - crutch: '🩼', - crystal: '🔮', - cucumber: '🥒', - cup: [straw: '🥤'], - cupcake: '🧁', - curling: '🥌', - curry: '🍛', - custard: '🍮', - customs: '🛃', - cutlery: '🍴', - cyclone: '🌀', - dancing: [man: '🕺', woman: '💃', women.bunny: '👯'], - darts: '🎯', - dash: [wave.double: '〰'], - deer: '🦌', - desert: '🏜', - detective: '🕵', - diamond: [ - blue: '🔷', - blue.small: '🔹', - orange: '🔶', - orange.small: '🔸', - dot: '💠', - ], - die: '🎲', - dino: [pod: '🦕', rex: '🦖'], - disc: [cd: '💿', dvd: '📀', mini: '💽'], - discoball: '🪩', - diving: '🤿', - dodo: '🦤', - dog: [ - '🐕', - face: '🐶', - guide: '🦮', - poodle: '🐩', - ], - dollar: '💲', - dolphin: '🐬', - donut: '🍩', - door: '🚪', - dove: [peace: '🕊'], - dragon: ['🐉', face: '🐲'], - dress: ['👗', kimono: '👘', sari: '🥻'], - drop: '💧', - drops: '💦', - drum: ['🥁', big: '🪘'], - duck: '🦆', - dumpling: '🥟', - eagle: '🦅', - ear: ['👂', aid: '🦻'], - egg: '🥚', - eighteen: [not: '🔞'], - elephant: '🐘', - elevator: '🛗', - elf: '🧝', - email: '📧', - excl: [ - '❗', - white: '❕', - double: '‼', - quest: '⁉', - ], - explosion: '💥', - extinguisher: '🧯', - eye: '👁', - eyes: '👀', - face: [ - grin: '😀', - angry: '😠', - angry.red: '😡', - anguish: '😧', - astonish: '😲', - bandage: '🤕', - beam: '😁', - blank: '😶', - clown: '🤡', - cold: '🥶', - concern: '😦', - cool: '😎', - cover: '🤭', - cowboy: '🤠', - cry: '😭', - devil.smile: '😈', - devil.frown: '👿', - diagonal: '🫤', - disguise: '🥸', - distress: '😫', - dizzy: '😵', - dotted: '🫥', - down: '😞', - down.sweat: '😓', - drool: '🤤', - explode: '🤯', - eyeroll: '🙄', - friendly: '☺', - fear: '😨', - fear.sweat: '😰', - fever: '🤒', - flush: '😳', - frown: '☹', - frown.slight: '🙁', - frust: '😣', - goofy: '🤪', - halo: '😇', - happy: '😊', - heart: '😍', - hearts: '🥰', - heat: '🥵', - hug: '🤗', - inv: '🙃', - joy: '😂', - kiss: '😗', - kiss.smile: '😙', - kiss.heart: '😘', - kiss.blush: '😚', - lick: '😋', - lie: '🤥', - mask: '😷', - meh: '😒', - melt: '🫠', - money: '🤑', - monocle: '🧐', - nausea: '🤢', - nerd: '🤓', - neutral: '😐', - open: '😃', - party: '🥳', - peek: '🫣', - plead: '🥺', - relief: '😌', - rofl: '🤣', - sad: '😔', - salute: '🫡', - shock: '😱', - shush: '🤫', - skeptic: '🤨', - sleep: '😴', - sleepy: '😪', - smile: '😄', - smile.slight: '🙂', - smile.sweat: '😅', - smile.tear: '🥲', - smirk: '😏', - sneeze: '🤧', - speak.not: '🫢', - squint: '😆', - stars: '🤩', - straight: '😑', - suffer: '😖', - surprise: '😯', - symbols: '🤬', - tear: '😢', - tear.relief: '😥', - tear.withheld: '🥹', - teeth: '😬', - think: '🤔', - tired: '🫩', - tongue: '😛', - tongue.squint: '😝', - tongue.wink: '😜', - triumph: '😤', - unhappy: '😕', - vomit: '🤮', - weary: '😩', - wink: '😉', - woozy: '🥴', - worry: '😟', - wow: '😮', - yawn: '🥱', - zip: '🤐', - ], - factory: '🏭', - fairy: '🧚', - faith: [ - christ: '✝', - dharma: '☸', - islam: '☪', - judaism: '✡', - menorah: '🕎', - om: '🕉', - orthodox: '☦', - peace: '☮', - star.dot: '🔯', - worship: '🛐', - yinyang: '☯', - ], - falafel: '🧆', - family: '👪', - fax: '📠', - feather: '🪶', - feeding: [breast: '🤱'], - fencing: '🤺', - ferriswheel: '🎡', - filebox: '🗃', - filedividers: '🗂', - film: '🎞', - finger: [ - r: '👉', - l: '👈', - t: '👆', - t.alt: '☝', - b: '👇', - front: '🫵', - m: '🖕', - ], - fingerprint: '🫆', - fingers: [cross: '🤞', pinch: '🤌', snap: '🫰'], - fire: '🔥', - firecracker: '🧨', - fireengine: '🚒', - fireworks: '🎆', - fish: ['🐟', tropical: '🐠'], - fishing: '🎣', - fist: [ - front: '👊', - r: '🤜', - l: '🤛', - raised: '✊', - ], - flag: [ - black: '🏴', - white: '🏳', - goal: '🏁', - golf: '⛳', - red: '🚩', - ], - flags: [jp.crossed: '🎌'], - flamingo: '🦩', - flashlight: '🔦', - flatbread: '🫓', - fleur: '⚜', - floppy: '💾', - flower: [ - hibiscus: '🌺', - lotus: '🪷', - pink: '🌸', - rose: '🌹', - sun: '🌻', - tulip: '🌷', - white: '💮', - wilted: '🥀', - yellow: '🌼', - ], - fly: '🪰', - fog: '🌫', - folder: ['📁', open: '📂'], - fondue: '🫕', - foot: '🦶', - football: ['⚽', am: '🏈'], - forex: '💱', - fountain: '⛲', - fox: '🦊', - free: '🆓', - fries: '🍟', - frisbee: '🥏', - frog: [face: '🐸'], - fuelpump: '⛽', - garlic: '🧄', - gear: '⚙', - gem: '💎', - genie: '🧞', - ghost: '👻', - giraffe: '🦒', - girl: '👧', - glass: [ - clink: '🥂', - milk: '🥛', - pour: '🫗', - tumbler: '🥃', - ], - glasses: ['👓', sun: '🕶'], - globe: [ - am: '🌎', - as.au: '🌏', - eu.af: '🌍', - meridian: '🌐', - ], - gloves: '🧤', - goal: '🥅', - goat: '🐐', - goggles: '🥽', - golfing: '🏌', - gorilla: '🦍', - grapes: '🍇', - guard: [man: '💂'], - guitar: '🎸', - gymnastics: '🤸', - haircut: '💇', - hammer: ['🔨', pick: '⚒', wrench: '🛠'], - hamsa: '🪬', - hamster: [face: '🐹'], - hand: [ - raised: '✋', - raised.alt: '🤚', - r: '🫱', - l: '🫲', - t: '🫴', - b: '🫳', - ok: '👌', - call: '🤙', - love: '🤟', - part: '🖖', - peace: '✌', - pinch: '🤏', - rock: '🤘', - splay: '🖐', - wave: '👋', - write: '✍', - ], - handbag: '👜', - handball: '🤾', - handholding: [man.man: '👬', woman.man: '👫', woman.woman: '👭'], - hands: [ - folded: '🙏', - palms: '🤲', - clap: '👏', - heart: '🫶', - open: '👐', - raised: '🙌', - shake: '🤝', - ], - harp: '🪉', - hash: '#', - hat: [ribbon: '👒', top: '🎩'], - headphone: '🎧', - heart: [ - '❤', - arrow: '💘', - beat: '💓', - black: '🖤', - blue: '💙', - box: '💟', - broken: '💔', - brown: '🤎', - double: '💕', - excl: '❣', - green: '💚', - grow: '💗', - orange: '🧡', - purple: '💜', - real: '🫀', - revolve: '💞', - ribbon: '💝', - spark: '💖', - white: '🤍', - yellow: '💛', - ], - hedgehog: '🦔', - helicopter: '🚁', - helix: '🧬', - helmet: [cross: '⛑', military: '🪖'], - hippo: '🦛', - hockey: '🏑', - hole: '🕳', - honey: '🍯', - hongbao: '🧧', - hook: '🪝', - horn: [postal: '📯'], - horse: [ - '🐎', - carousel: '🎠', - face: '🐴', - race: '🏇', - ], - hospital: '🏥', - hotdog: '🌭', - hotel: ['🏨', love: '🏩'], - hotspring: '♨', - hourglass: ['⌛', flow: '⏳'], - house: [ - '🏠', - derelict: '🏚', - garden: '🏡', - multiple: '🏘', - ], - hundred: '💯', - hut: '🛖', - ice: '🧊', - icecream: ['🍨', shaved: '🍧', soft: '🍦'], - icehockey: '🏒', - id: '🆔', - info: 'ℹ', - izakaya: '🏮', - jar: '🫙', - jeans: '👖', - jigsaw: '🧩', - joystick: '🕹', - juggling: '🤹', - juice: '🧃', - kaaba: '🕋', - kadomatsu: '🎍', - kangaroo: '🦘', - gachi: '🈷', - go: '🈴', - hi: '㊙', - ka: '🉑', - kachi: '🈹', - kara: '🈳', - kon: '🈲', - man: '🈵', - muryo: '🈚', - shin: '🈸', - shuku: '㊗', - toku: '🉐', - yo: '🈺', - yubi: '🈯', - yuryo: '🈶', - koko: '🈁', - sa: '🈂', - kebab: '🥙', - key: ['🔑', old: '🗝'], - keyboard: '⌨', - kiss: '💏', - kissmark: '💋', - kite: '🪁', - kiwi: '🥝', - knife: ['🔪', dagger: '🗡'], - knot: '🪢', - koala: '🐨', - koinobori: '🎏', - label: '🏷', - lacrosse: '🥍', - ladder: '🪜', - lamp: [diya: '🪔'], - laptop: '💻', - a: '🅰', - ab: '🆎', - b: '🅱', - cl: '🆑', - o: '🅾', - leaf: [ - clover.three: '☘', - clover.four: '🍀', - fall: '🍂', - herb: '🌿', - maple: '🍁', - wind: '🍃', - ], - leftluggage: '🛅', - leg: ['🦵', mech: '🦿'], - lemon: '🍋', - leopard: '🐆', - letter: [love: '💌'], - liberty: '🗽', - lightbulb: '💡', - lightning: '⚡', - lion: '🦁', - lipstick: '💄', - litter: ['🚮', not: '🚯'], - lizard: '🦎', - llama: '🦙', - lobster: '🦞', - lock: [ - '🔒', - key: '🔐', - open: '🔓', - pen: '🔏', - ], - lollipop: '🍭', - lotion: '🧴', - luggage: '🧳', - lungs: '🫁', - mage: '🧙', - magnet: '🧲', - magnify: [r: '🔎', l: '🔍'], - mahjong: [dragon.red: '🀄'], - mail: ['✉', arrow: '📩'], - mailbox: [ - closed.empty: '📪', - closed.full: '📫', - open.empty: '📭', - open.full: '📬', - ], - mammoth: '🦣', - man: [ - '👨', - box: '🚹', - crown: '🤴', - guapimao: '👲', - levitate: '🕴', - old: '👴', - pregnant: '🫃', - turban: '👳', - tuxedo: '🤵', - ], - mango: '🥭', - map: [world: '🗺', jp: '🗾'], - martialarts: '🥋', - masks: '🎭', - mate: '🧉', - matryoshka: '🪆', - meat: ['🥩', bone: '🍖'], - medal: [ - first: '🥇', - second: '🥈', - third: '🥉', - sports: '🏅', - military: '🎖', - ], - megaphone: ['📢', simple: '📣'], - melon: '🍈', - merperson: '🧜', - metro: 'Ⓜ', - microbe: '🦠', - microphone: ['🎤', studio: '🎙'], - microscope: '🔬', - milkyway: '🌌', - mirror: '🪞', - mixer: '🎛', - money: [ - bag: '💰', - dollar: '💵', - euro: '💶', - pound: '💷', - yen: '💴', - wings: '💸', - ], - monkey: [ - '🐒', - face: '🐵', - hear.not: '🙉', - see.not: '🙈', - speak.not: '🙊', - ], - moon: [ - crescent: '🌙', - full: '🌕', - full.face: '🌝', - new: '🌑', - new.face: '🌚', - wane.one: '🌖', - wane.two: '🌗', - wane.three.face: '🌜', - wane.three: '🌘', - wax.one: '🌒', - wax.two: '🌓', - wax.two.face: '🌛', - wax.three: '🌔', - ], - mortarboard: '🎓', - mosque: '🕌', - mosquito: '🦟', - motorcycle: '🏍', - motorway: '🛣', - mountain: [ - '⛰', - fuji: '🗻', - snow: '🏔', - sunrise: '🌄', - ], - mouse: ['🐁', face: '🐭'], - mousetrap: '🪤', - mouth: ['👄', bite: '🫦'], - moyai: '🗿', - museum: '🏛', - mushroom: '🍄', - musicalscore: '🎼', - nails: [polish: '💅'], - namebadge: '📛', - nazar: '🧿', - necktie: '👔', - needle: '🪡', - nest: [empty: '🪹', eggs: '🪺'], - new: '🆕', - newspaper: ['📰', rolled: '🗞'], - ng: '🆖', - ningyo: '🎎', - ninja: '🥷', - noentry: '⛔', - nose: '👃', - notebook: ['📓', deco: '📔'], - notepad: '🗒', - notes: ['🎵', triple: '🎶'], - numbers: '🔢', - octopus: '🐙', - office: '🏢', - oil: '🛢', - ok: '🆗', - olive: '🫒', - oni: '👹', - onion: '🧅', - orangutan: '🦧', - otter: '🦦', - owl: '🦉', - ox: '🐂', - oyster: '🦪', - package: '📦', - paella: '🥘', - page: ['📄', curl: '📃', pencil: '📝'], - pager: '📟', - pages: [tabs: '📑'], - painting: '🖼', - palette: '🎨', - pancakes: '🥞', - panda: '🐼', - parachute: '🪂', - park: '🏞', - parking: '🅿', - parrot: '🦜', - partalteration: '〽', - party: '🎉', - peach: '🍑', - peacock: '🦚', - peanuts: '🥜', - pear: '🍐', - pedestrian: ['🚶', not: '🚷'], - pen: [ball: '🖊', fountain: '🖋'], - pencil: '✏', - penguin: '🐧', - pepper: ['🫑', hot: '🌶'], - person: [ - '🧑', - angry: '🙎', - beard: '🧔', - blonde: '👱', - bow: '🙇', - crown: '🫅', - deaf: '🧏', - facepalm: '🤦', - frown: '🙍', - hijab: '🧕', - kneel: '🧎', - lotus: '🧘', - massage: '💆', - no: '🙅', - ok: '🙆', - old: '🧓', - pregnant: '🫄', - raise: '🙋', - sassy: '💁', - shrug: '🤷', - stand: '🧍', - steam: '🧖', - ], - petri: '🧫', - phone: [ - '📱', - arrow: '📲', - classic: '☎', - not: '📵', - off: '📴', - receiver: '📞', - signal: '📶', - vibrate: '📳', - ], - piano: '🎹', - pick: '⛏', - pie: '🥧', - pig: ['🐖', face: '🐷', nose: '🐽'], - pill: '💊', - pin: ['📌', round: '📍'], - pinata: '🪅', - pineapple: '🍍', - pingpong: '🏓', - pistol: '🔫', - pizza: '🍕', - placard: '🪧', - planet: '🪐', - plant: '🪴', - plaster: '🩹', - plate: [cutlery: '🍽'], - playback: [ - down: '⏬', - eject: '⏏', - forward: '⏩', - pause: '⏸', - record: '⏺', - repeat: '🔁', - repeat.once: '🔂', - repeat.v: '🔃', - restart: '⏮', - rewind: '⏪', - shuffle: '🔀', - skip: '⏭', - stop: '⏹', - toggle: '⏯', - up: '⏫', - ], - playingcard: [flower: '🎴', joker: '🃏'], - plunger: '🪠', - policeofficer: '👮', - poo: '💩', - popcorn: '🍿', - post: [eu: '🏤', jp: '🏣'], - postbox: '📮', - potato: ['🥔', sweet: '🍠'], - pouch: '👝', - powerplug: '🔌', - present: '🎁', - pretzel: '🥨', - printer: '🖨', - prints: [foot: '👣', paw: '🐾'], - prohibited: '🚫', - projector: '📽', - pumpkin: [lantern: '🎃'], - purse: '👛', - quest: ['❓', white: '❔'], - rabbit: ['🐇', face: '🐰'], - raccoon: '🦝', - radio: '📻', - radioactive: '☢', - railway: '🛤', - rainbow: '🌈', - ram: '🐏', - rat: '🐀', - razor: '🪒', - receipt: '🧾', - recycling: '♻', - reg: '®', - restroom: '🚻', - rhino: '🦏', - ribbon: ['🎀', remind: '🎗'], - rice: [ - '🍚', - cracker: '🍘', - ear: '🌾', - onigiri: '🍙', - ], - ring: '💍', - ringbuoy: '🛟', - robot: '🤖', - rock: '🪨', - rocket: '🚀', - rollercoaster: '🎢', - rosette: '🏵', - rugby: '🏉', - ruler: ['📏', triangle: '📐'], - running: '🏃', - safetypin: '🧷', - safetyvest: '🦺', - sake: '🍶', - salad: '🥗', - salt: '🧂', - sandwich: '🥪', - santa: [man: '🎅', woman: '🤶'], - satdish: '📡', - satellite: '🛰', - saw: '🪚', - saxophone: '🎷', - scales: '⚖', - scarf: '🧣', - school: '🏫', - scissors: '✂', - scooter: ['🛴', motor: '🛵'], - scorpion: '🦂', - screwdriver: '🪛', - scroll: '📜', - seal: '🦭', - seat: '💺', - seedling: '🌱', - shark: '🦈', - sheep: '🐑', - shell: [spiral: '🐚'], - shield: '🛡', - ship: ['🚢', cruise: '🛳', ferry: '⛴'], - shirt: [sports: '🎽', t: '👕'], - shoe: [ - '👞', - ballet: '🩰', - flat: '🥿', - heel: '👠', - hike: '🥾', - ice: '⛸', - roller: '🛼', - sandal.heel: '👡', - ski: '🎿', - sneaker: '👟', - tall: '👢', - thong: '🩴', - ], - shopping: '🛍', - shorts: '🩳', - shoshinsha: '🔰', - shovel: '🪏', - shower: '🚿', - shrimp: ['🦐', fried: '🍤'], - shrine: '⛩', - sign: [crossing: '🚸', stop: '🛑'], - silhouette: [ - '👤', - double: '👥', - hug: '🫂', - speak: '🗣', - ], - siren: '🚨', - skateboard: '🛹', - skewer: [dango: '🍡', oden: '🍢'], - skiing: '⛷', - skull: ['💀', bones: '☠'], - skunk: '🦨', - sled: '🛷', - slide: '🛝', - slider: '🎚', - sloth: '🦥', - slots: '🎰', - snail: '🐌', - snake: '🐍', - snowboarding: '🏂', - snowflake: '❄', - snowman: ['⛄', snow: '☃'], - soap: '🧼', - socks: '🧦', - softball: '🥎', - sos: '🆘', - soup: '🍲', - spaghetti: '🍝', - sparkle: [box: '❇'], - sparkler: '🎇', - sparkles: '✨', - speaker: [ - '🔈', - not: '🔇', - wave: '🔉', - waves: '🔊', - ], - spider: '🕷', - spiderweb: '🕸', - spinach: '🥬', - splatter: '🫟', - sponge: '🧽', - spoon: '🥄', - square: [ - black: '⬛', - black.tiny: '▪', - black.small: '◾', - black.medium: '◼', - white: '⬜', - white.tiny: '▫', - white.small: '◽', - white.medium: '◻', - blue: '🟦', - brown: '🟫', - green: '🟩', - orange: '🟧', - purple: '🟪', - red: '🟥', - yellow: '🟨', - ], - squid: '🦑', - stadium: '🏟', - star: [ - '⭐', - arc: '💫', - box: '✴', - glow: '🌟', - shoot: '🌠', - ], - stethoscope: '🩺', - store: [big: '🏬', small: '🏪'], - strawberry: '🍓', - suit: [ - club: '♣', - diamond: '♦', - heart: '♥', - spade: '♠', - ], - sun: ['☀', cloud: '🌤', face: '🌞'], - sunrise: '🌅', - superhero: '🦸', - supervillain: '🦹', - surfing: '🏄', - sushi: '🍣', - swan: '🦢', - swimming: '🏊', - swimsuit: '🩱', - swords: '⚔', - symbols: '🔣', - synagogue: '🕍', - syringe: '💉', - taco: '🌮', - takeout: '🥡', - tamale: '🫔', - tanabata: '🎋', - tangerine: '🍊', - tap: ['🚰', not: '🚱'], - taxi: ['🚕', front: '🚖'], - teacup: '🍵', - teapot: '🫖', - teddy: '🧸', - telescope: '🔭', - temple: '🛕', - ten: '🔟', - tengu: '👺', - tennis: '🎾', - tent: '⛺', - testtube: '🧪', - thermometer: '🌡', - thread: '🧵', - thumb: [up: '👍', down: '👎'], - ticket: [event: '🎟', travel: '🎫'], - tiger: ['🐅', face: '🐯'], - tm: '™', - toilet: '🚽', - toiletpaper: '🧻', - tomato: '🍅', - tombstone: '🪦', - tongue: '👅', - toolbox: '🧰', - tooth: '🦷', - toothbrush: '🪥', - tornado: '🌪', - tower: [tokyo: '🗼'], - trackball: '🖲', - tractor: '🚜', - trafficlight: [v: '🚦', h: '🚥'], - train: [ - '🚆', - car: '🚃', - light: '🚈', - metro: '🚇', - mono: '🚝', - mountain: '🚞', - speed: '🚄', - speed.bullet: '🚅', - steam: '🚂', - stop: '🚉', - suspend: '🚟', - tram: '🚊', - tram.car: '🚋', - ], - transgender: '⚧', - tray: [inbox: '📥', mail: '📨', outbox: '📤'], - tree: [ - deciduous: '🌳', - evergreen: '🌲', - leafless: '🪾', - palm: '🌴', - xmas: '🎄', - ], - triangle: [ - r: '▶', - l: '◀', - t: '🔼', - b: '🔽', - t.red: '🔺', - b.red: '🔻', - ], - trident: '🔱', - troll: '🧌', - trophy: '🏆', - truck: ['🚚', trailer: '🚛'], - trumpet: '🎺', - tsukimi: '🎑', - turkey: '🦃', - turtle: '🐢', - tv: '📺', - ufo: '🛸', - umbrella: [ - open: '☂', - closed: '🌂', - rain: '☔', - sun: '⛱', - ], - unicorn: '🦄', - unknown: '🦳', - up: '🆙', - urn: '⚱', - vampire: '🧛', - violin: '🎻', - volcano: '🌋', - volleyball: '🏐', - vs: '🆚', - waffle: '🧇', - wand: '🪄', - warning: '⚠', - watch: ['⌚', stop: '⏱'], - watermelon: '🍉', - waterpolo: '🤽', - wave: '🌊', - wc: '🚾', - weightlifting: '🏋', - whale: ['🐋', spout: '🐳'], - wheel: '🛞', - wheelchair: ['🦽', box: '♿', motor: '🦼'], - wind: '🌬', - windchime: '🎐', - window: '🪟', - wine: '🍷', - wolf: '🐺', - woman: [ - '👩', - box: '🚺', - crown: '👸', - old: '👵', - pregnant: '🤰', - ], - wood: '🪵', - worm: '🪱', - wrench: '🔧', - wrestling: '🤼', - xray: '🩻', - yarn: '🧶', - yoyo: '🪀', - zebra: '🦓', - zodiac: [ - aquarius: '♒', - aries: '♈', - cancer: '♋', - capri: '♑', - gemini: '♊', - leo: '♌', - libra: '♎', - ophi: '⛎', - pisces: '♓', - sagit: '♐', - scorpio: '♏', - taurus: '♉', - virgo: '♍', - ], - zombie: '🧟', - zzz: '💤', -}; diff --git a/crates/typst-library/src/symbols/mod.rs b/crates/typst-library/src/symbols/mod.rs deleted file mode 100644 index 7e0fb55bd..000000000 --- a/crates/typst-library/src/symbols/mod.rs +++ /dev/null @@ -1,24 +0,0 @@ -//! Modifiable symbols. - -mod emoji; -mod sym; - -pub use self::emoji::*; -pub use self::sym::*; - -use crate::foundations::{category, Category, Scope}; - -/// 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. -pub(super) fn define(global: &mut Scope) { - global.category(SYMBOLS); - global.define_module(sym()); - global.define_module(emoji()); -} diff --git a/crates/typst-library/src/symbols/sym.rs b/crates/typst-library/src/symbols/sym.rs deleted file mode 100644 index bdda4bde3..000000000 --- a/crates/typst-library/src/symbols/sym.rs +++ /dev/null @@ -1,1000 +0,0 @@ -use crate::foundations::{Module, Scope, Symbol}; - -/// A module with all general symbols. -pub fn sym() -> Module { - let mut scope = Scope::new(); - for (name, symbol) in SYM { - scope.define(*name, symbol.clone()); - } - Module::new("sym", scope) -} - -/// The list of general symbols. -pub(crate) const SYM: &[(&str, Symbol)] = typst_macros::symbols! { - // Control. - wj: '\u{2060}', - zwj: '\u{200D}', - zwnj: '\u{200C}', - zws: '\u{200B}', - lrm: '\u{200E}', - rlm: '\u{200F}', - - // Spaces. - space: [ - ' ', - nobreak: '\u{A0}', - nobreak.narrow: '\u{202F}', - en: '\u{2002}', - quad: '\u{2003}', - third: '\u{2004}', - quarter: '\u{2005}', - sixth: '\u{2006}', - med: '\u{205F}', - fig: '\u{2007}', - punct: '\u{2008}', - thin: '\u{2009}', - hair: '\u{200A}', - ], - - // Delimiters. - paren: [l: '(', l.double: '⦅', r: ')', r.double: '⦆', t: '⏜', b: '⏝'], - brace: [l: '{', l.double: '⦃', r: '}', r.double: '⦄', t: '⏞', b: '⏟'], - bracket: [l: '[', l.double: '⟦', r: ']', r.double: '⟧', t: '⎴', b: '⎵'], - shell: [l: '❲', l.double: '⟬', r: '❳', r.double: '⟭', t: '⏠', b: '⏡'], - bar: [v: '|', v.double: '‖', v.triple: '⦀', v.broken: '¦', v.circle: '⦶', h: '―'], - fence: [l: '⧘', l.double: '⧚', r: '⧙', r.double: '⧛', dotted: '⦙'], - angle: [ - '∠', - l: '⟨', - l.curly: '⧼', - l.dot: '⦑', - l.double: '《', - r: '⟩', - r.curly: '⧽', - r.dot: '⦒', - r.double: '》', - acute: '⦟', - arc: '∡', - arc.rev: '⦛', - oblique: '⦦', - rev: '⦣', - right: '∟', - right.rev: '⯾', - right.arc: '⊾', - right.dot: '⦝', - right.sq: '⦜', - s: '⦞', - spatial: '⟀', - spheric: '∢', - spheric.rev: '⦠', - spheric.top: '⦡', - ], - ceil: [ - #[call(crate::math::ceil)] l: '⌈', - r: '⌉', - ], - floor: [ - #[call(crate::math::floor)] l: '⌊', - r: '⌋', - ], - - // Punctuation. - amp: ['&', inv: '⅋'], - ast: [ - op: '∗', - basic: '*', - low: '⁎', - double: '⁑', - triple: '⁂', - small: '﹡', - circle: '⊛', - square: '⧆', - ], - at: '@', - backslash: ['\\', circle: '⦸', not: '⧷'], - co: '℅', - colon: [':', double: '∷', eq: '≔', double.eq: '⩴'], - comma: ',', - dagger: ['†', double: '‡'], - dash: [ - #[call(crate::math::accent::dash)] en: '–', - em: '—', - em.two: '⸺', - em.three: '⸻', - fig: '‒', - wave: '〜', - colon: '∹', - circle: '⊝', - wave.double: '〰', - ], - dot: [ - #[call(crate::math::accent::dot)] op: '⋅', - basic: '.', - c: '·', - circle: '⊙', - circle.big: '⨀', - square: '⊡', - #[call(crate::math::accent::dot_double)] double: '¨', - #[call(crate::math::accent::dot_triple)] triple: '\u{20db}', - #[call(crate::math::accent::dot_quad)] quad: '\u{20dc}', - ], - excl: ['!', double: '‼', inv: '¡', quest: '⁉'], - quest: ['?', double: '⁇', excl: '⁈', inv: '¿'], - interrobang: '‽', - hash: '#', - hyph: ['‐', minus: '\u{2D}', nobreak: '\u{2011}', point: '‧', soft: '\u{ad}'], - numero: '№', - percent: '%', - permille: '‰', - pilcrow: ['¶', rev: '⁋'], - section: '§', - semi: [';', rev: '⁏'], - slash: ['/', double: '⫽', triple: '⫻', big: '⧸'], - dots: [h.c: '⋯', h: '…', v: '⋮', down: '⋱', up: '⋰'], - tilde: [ - #[call(crate::math::accent::tilde)] op: '∼', - basic: '~', - dot: '⩪', - eq: '≃', - eq.not: '≄', - eq.rev: '⋍', - equiv: '≅', - equiv.not: '≇', - nequiv: '≆', - not: '≁', - rev: '∽', - rev.equiv: '≌', - triple: '≋', - ], - - // Accents, quotes, and primes. - acute: [ - #[call(crate::math::accent::acute)] '´', - #[call(crate::math::accent::acute_double)] double: '˝', - ], - breve: #[call(crate::math::accent::breve)] '˘', - caret: '‸', - caron: #[call(crate::math::accent::caron)] 'ˇ', - hat: #[call(crate::math::accent::hat)] '^', - diaer: #[call(crate::math::accent::dot_double)] '¨', - grave: #[call(crate::math::accent::grave)] '`', - macron: #[call(crate::math::accent::macron)] '¯', - quote: [ - double: '"', - single: '\'', - l.double: '“', - l.single: '‘', - r.double: '”', - r.single: '’', - angle.l.double: '«', - angle.l.single: '‹', - angle.r.double: '»', - angle.r.single: '›', - high.double: '‟', - high.single: '‛', - low.double: '„', - low.single: '‚', - ], - prime: [ - '′', - rev: '‵', - double: '″', - double.rev: '‶', - triple: '‴', - triple.rev: '‷', - quad: '⁗', - ], - - // https://en.wikipedia.org/wiki/List_of_mathematical_symbols_by_subject - // Arithmetic. - plus: [ - '+', - circle: '⊕', - circle.arrow: '⟴', - circle.big: '⨁', - dot: '∔', - double: '⧺', - minus: '±', - small: '﹢', - square: '⊞', - triangle: '⨹', - triple: '⧻', - ], - minus: [ - '−', - circle: '⊖', - dot: '∸', - plus: '∓', - square: '⊟', - tilde: '≂', - triangle: '⨺', - ], - div: ['÷', circle: '⨸'], - times: [ - '×', - big: '⨉', - circle: '⊗', - circle.big: '⨂', - div: '⋇', - three.l: '⋋', - three.r: '⋌', - l: '⋉', - r: '⋊', - square: '⊠', - triangle: '⨻', - ], - ratio: '∶', - - // Relations. - eq: [ - '=', - star: '≛', - circle: '⊜', - colon: '≕', - def: '≝', - delta: '≜', - equi: '≚', - est: '≙', - gt: '⋝', - lt: '⋜', - m: '≞', - not: '≠', - prec: '⋞', - quest: '≟', - small: '﹦', - succ: '⋟', - triple: '≡', - triple.not: '≢', - quad: '≣', - ], - gt: [ - '>', - circle: '⧁', - dot: '⋗', - approx: '⪆', - double: '≫', - eq: '≥', - eq.slant: '⩾', - eq.lt: '⋛', - eq.not: '≱', - equiv: '≧', - lt: '≷', - lt.not: '≹', - neq: '⪈', - napprox: '⪊', - nequiv: '≩', - not: '≯', - ntilde: '⋧', - small: '﹥', - tilde: '≳', - tilde.not: '≵', - tri: '⊳', - tri.eq: '⊵', - tri.eq.not: '⋭', - tri.not: '⋫', - triple: '⋙', - triple.nested: '⫸', - ], - lt: [ - '<', - circle: '⧀', - dot: '⋖', - approx: '⪅', - double: '≪', - eq: '≤', - eq.slant: '⩽' , - eq.gt: '⋚', - eq.not: '≰', - equiv: '≦', - gt: '≶', - gt.not: '≸', - neq: '⪇', - napprox: '⪉', - nequiv: '≨', - not: '≮', - ntilde: '⋦', - small: '﹤', - tilde: '≲', - tilde.not: '≴', - tri: '⊲', - tri.eq: '⊴', - tri.eq.not: '⋬', - tri.not: '⋪', - triple: '⋘', - triple.nested: '⫷', - ], - approx: ['≈', eq: '≊', not: '≉'], - prec: [ - '≺', - approx: '⪷', - curly.eq: '≼', - curly.eq.not: '⋠', - double: '⪻', - eq: '⪯', - equiv: '⪳', - napprox: '⪹', - neq: '⪱', - nequiv: '⪵', - not: '⊀', - ntilde: '⋨', - tilde: '≾', - ], - succ: [ - '≻', - approx: '⪸', - curly.eq: '≽', - curly.eq.not: '⋡', - double: '⪼', - eq: '⪰', - equiv: '⪴', - napprox: '⪺', - neq: '⪲', - nequiv: '⪶', - not: '⊁', - ntilde: '⋩', - tilde: '≿', - ], - equiv: ['≡', not: '≢'], - prop: '∝', - original: '⊶', - image: '⊷', - asymp: [ - '≍', - not: '≭', - ], - - // Set theory. - emptyset: [ - '∅', - arrow.r: '⦳', - arrow.l: '⦴', - bar: '⦱', - circle: '⦲', - rev: '⦰', - ], - nothing: [ - '∅', - arrow.r: '⦳', - arrow.l: '⦴', - bar: '⦱', - circle: '⦲', - rev: '⦰', - ], - without: '∖', - complement: '∁', - in: [ - '∈', - not: '∉', - rev: '∋', - rev.not: '∌', - rev.small: '∍', - small: '∊', - ], - subset: [ - '⊂', - dot: '⪽', - double: '⋐', - eq: '⊆', - eq.not: '⊈', - eq.sq: '⊑', - eq.sq.not: '⋢', - neq: '⊊', - not: '⊄', - sq: '⊏', - sq.neq: '⋤', - ], - supset: [ - '⊃', - dot: '⪾', - double: '⋑', - eq: '⊇', - eq.not: '⊉', - eq.sq: '⊒', - eq.sq.not: '⋣', - neq: '⊋', - not: '⊅', - sq: '⊐', - sq.neq: '⋥', - ], - union: [ - '∪', - arrow: '⊌', - big: '⋃', - dot: '⊍', - dot.big: '⨃', - double: '⋓', - minus: '⩁', - or: '⩅', - plus: '⊎', - plus.big: '⨄', - sq: '⊔', - sq.big: '⨆', - sq.double: '⩏', - ], - sect: [ - '∩', - and: '⩄', - big: '⋂', - dot: '⩀', - double: '⋒', - sq: '⊓', - sq.big: '⨅', - sq.double: '⩎', - ], - - // Calculus. - infinity: [ - '∞', - bar: '⧞', - incomplete: '⧜', - tie: '⧝', - ], - oo: '∞', - partial: '∂', - gradient: '∇', - nabla: '∇', - sum: ['∑', integral: '⨋'], - product: ['∏', co: '∐'], - integral: [ - '∫', - arrow.hook: '⨗', - ccw: '⨑', - cont: '∮', - cont.ccw: '∳', - cont.cw: '∲', - cw: '∱', - dash: '⨍', - dash.double: '⨎', - double: '∬', - quad: '⨌', - sect: '⨙', - slash: '⨏', - square: '⨖', - surf: '∯', - times: '⨘', - triple: '∭', - union: '⨚', - vol: '∰', - ], - laplace: '∆', - - // Logic. - forall: '∀', - exists: ['∃', not: '∄'], - top: '⊤', - bot: '⊥', - not: '¬', - and: ['∧', big: '⋀', curly: '⋏', dot: '⟑', double: '⩓'], - or: ['∨', big: '⋁', curly: '⋎', dot: '⟇', double: '⩔'], - xor: ['⊕', big: '⨁'], - models: '⊧', - forces: ['⊩', not: '⊮'], - therefore: '∴', - because: '∵', - qed: '∎', - - // Function and category theory. - compose: '∘', - convolve: '∗', - multimap: ['⊸', double: '⧟'], - - // Game theory. - tiny: '⧾', - miny: '⧿', - - // Number theory. - divides: ['∣', not: '∤'], - - // Algebra. - wreath: '≀', - - // Geometry. - parallel: [ - '∥', - struck: '⫲', - circle: '⦷', - eq: '⋕', - equiv: '⩨', - not: '∦', - slanted.eq: '⧣', - slanted.eq.tilde: '⧤', - slanted.equiv: '⧥', - tilde: '⫳', - ], - perp: ['⟂', circle: '⦹'], - - // Miscellaneous Technical. - diameter: '⌀', - join: ['⨝', r: '⟖', l: '⟕', l.r: '⟗'], - degree: ['°', c: '℃', f: '℉'], - smash: '⨳', - - // Currency. - bitcoin: '₿', - dollar: '$', - euro: '€', - franc: '₣', - lira: '₺', - peso: '₱', - pound: '£', - ruble: '₽', - rupee: '₹', - won: '₩', - yen: '¥', - - // Miscellaneous. - ballot: ['☐', cross: '☒', check: '☑', check.heavy: '🗹'], - checkmark: ['✓', light: '🗸', heavy: '✔'], - crossmark: ['✗', heavy: '✘'], - floral: ['❦', l: '☙', r: '❧'], - refmark: '※', - copyright: ['©', sound: '℗'], - copyleft: '🄯', - trademark: ['™', registered: '®', service: '℠'], - maltese: '✠', - suit: [ - club.filled: '♣', - club.stroked: '♧', - diamond.filled: '♦', - diamond.stroked: '♢', - heart.filled: '♥', - heart.stroked: '♡', - spade.filled: '♠', - spade.stroked: '♤', - ], - - // Music. - note: [ - up: '🎜', - down: '🎝', - whole: '𝅝', - half: '𝅗𝅥', - quarter: '𝅘𝅥', - quarter.alt: '♩', - eighth: '𝅘𝅥𝅮', - eighth.alt: '♪', - eighth.beamed: '♫', - sixteenth: '𝅘𝅥𝅯', - sixteenth.beamed: '♬', - grace: '𝆕', - grace.slash: '𝆔', - ], - rest: [ - whole: '𝄻', - multiple: '𝄺', - multiple.measure: '𝄩', - half: '𝄼', - quarter: '𝄽', - eighth: '𝄾', - sixteenth: '𝄿', - ], - natural: [ - '♮', - t: '𝄮', - b: '𝄯', - ], - flat: [ - '♭', - t: '𝄬', - b: '𝄭', - double: '𝄫', - quarter: '𝄳', - ], - sharp: [ - '♯', - t: '𝄰', - b: '𝄱', - double: '𝄪', - quarter: '𝄲', - ], - - // Shapes. - bullet: '•', - circle: [ - #[call(crate::math::accent::circle)] stroked: '○', - stroked.tiny: '∘', - stroked.small: '⚬', - stroked.big: '◯', - filled: '●', - filled.tiny: '⦁', - filled.small: '∙', - filled.big: '⬤', - dotted: '◌', - nested: '⊚', - ], - ellipse: [ - stroked.h: '⬭', - stroked.v: '⬯', - filled.h: '⬬', - filled.v: '⬮', - ], - triangle: [ - stroked.t: '△', - stroked.b: '▽', - stroked.r: '▷', - stroked.l: '◁', - stroked.bl: '◺', - stroked.br: '◿', - stroked.tl: '◸', - stroked.tr: '◹', - stroked.small.t: '▵', - stroked.small.b: '▿', - stroked.small.r: '▹', - stroked.small.l: '◃', - stroked.rounded: '🛆', - stroked.nested: '⟁', - stroked.dot: '◬', - filled.t: '▲', - filled.b: '▼', - filled.r: '▶', - filled.l: '◀', - filled.bl: '◣', - filled.br: '◢', - filled.tl: '◤', - filled.tr: '◥', - filled.small.t: '▴', - filled.small.b: '▾', - filled.small.r: '▸', - filled.small.l: '◂', - ], - square: [ - stroked: '□', - stroked.tiny: '▫', - stroked.small: '◽', - stroked.medium: '◻', - stroked.big: '⬜', - stroked.dotted: '⬚', - stroked.rounded: '▢', - filled: '■', - filled.tiny: '▪', - filled.small: '◾', - filled.medium: '◼', - filled.big: '⬛', - ], - rect: [ - stroked.h: '▭', - stroked.v: '▯', - filled.h: '▬', - filled.v: '▮', - ], - penta: [stroked: '⬠', filled: '⬟'], - hexa: [stroked: '⬡', filled: '⬢'], - diamond: [ - stroked: '◇', - stroked.small: '⋄', - stroked.medium: '⬦', - stroked.dot: '⟐', - filled: '◆', - filled.medium: '⬥', - filled.small: '⬩', - ], - lozenge: [ - stroked: '◊', - stroked.small: '⬫', - stroked.medium: '⬨', - filled: '⧫', - filled.small: '⬪', - filled.medium: '⬧', - ], - parallelogram: [ - stroked: '▱', - filled: '▰', - ], - star: [op: '⋆', stroked: '☆', filled: '★'], - - // Arrows, harpoons, and tacks. - arrow: [ - #[call(crate::math::accent::arrow)] r: '→', - r.long.bar: '⟼', - r.bar: '↦', - r.curve: '⤷', - r.turn: '⮎', - r.dashed: '⇢', - r.dotted: '⤑', - r.double: '⇒', - r.double.bar: '⤇', - r.double.long: '⟹', - r.double.long.bar: '⟾', - r.double.not: '⇏', - r.filled: '➡', - r.hook: '↪', - r.long: '⟶', - r.long.squiggly: '⟿', - r.loop: '↬', - r.not: '↛', - r.quad: '⭆', - r.squiggly: '⇝', - r.stop: '⇥', - r.stroked: '⇨', - r.tail: '↣', - r.tilde: '⥲', - r.triple: '⇛', - r.twohead.bar: '⤅', - r.twohead: '↠', - r.wave: '↝', - #[call(crate::math::accent::arrow_l)] l: '←', - l.bar: '↤', - l.curve: '⤶', - l.turn: '⮌', - l.dashed: '⇠', - l.dotted: '⬸', - l.double: '⇐', - l.double.bar: '⤆', - l.double.long: '⟸', - l.double.long.bar: '⟽', - l.double.not: '⇍', - l.filled: '⬅', - l.hook: '↩', - l.long: '⟵', - l.long.bar: '⟻', - l.long.squiggly: '⬳', - l.loop: '↫', - l.not: '↚', - l.quad: '⭅', - l.squiggly: '⇜', - l.stop: '⇤', - l.stroked: '⇦', - l.tail: '↢', - l.tilde: '⭉', - l.triple: '⇚', - l.twohead.bar: '⬶', - l.twohead: '↞', - l.wave: '↜', - t: '↑', - t.bar: '↥', - t.curve: '⤴', - t.turn: '⮍', - t.dashed: '⇡', - t.double: '⇑', - t.filled: '⬆', - t.quad: '⟰', - t.stop: '⤒', - t.stroked: '⇧', - t.triple: '⤊', - t.twohead: '↟', - b: '↓', - b.bar: '↧', - b.curve: '⤵', - b.turn: '⮏', - b.dashed: '⇣', - b.double: '⇓', - b.filled: '⬇', - b.quad: '⟱', - b.stop: '⤓', - b.stroked: '⇩', - b.triple: '⤋', - b.twohead: '↡', - #[call(crate::math::accent::arrow_l_r)] l.r: '↔', - l.r.double: '⇔', - l.r.double.long: '⟺', - l.r.double.not: '⇎', - l.r.filled: '⬌', - l.r.long: '⟷', - l.r.not: '↮', - l.r.stroked: '⬄', - l.r.wave: '↭', - t.b: '↕', - t.b.double: '⇕', - t.b.filled: '⬍', - t.b.stroked: '⇳', - tr: '↗', - tr.double: '⇗', - tr.filled: '⬈', - tr.hook: '⤤', - tr.stroked: '⬀', - br: '↘', - br.double: '⇘', - br.filled: '⬊', - br.hook: '⤥', - br.stroked: '⬂', - tl: '↖', - tl.double: '⇖', - tl.filled: '⬉', - tl.hook: '⤣', - tl.stroked: '⬁', - bl: '↙', - bl.double: '⇙', - bl.filled: '⬋', - bl.hook: '⤦', - bl.stroked: '⬃', - tl.br: '⤡', - tr.bl: '⤢', - ccw: '↺', - ccw.half: '↶', - cw: '↻', - cw.half: '↷', - zigzag: '↯', - ], - arrows: [ - rr: '⇉', - ll: '⇇', - tt: '⇈', - bb: '⇊', - lr: '⇆', - lr.stop: '↹', - rl: '⇄', - tb: '⇅', - bt: '⇵', - rrr: '⇶', - lll: '⬱', - ], - arrowhead: [ - t: '⌃', - b: '⌄', - ], - harpoon: [ - #[call(crate::math::accent::harpoon)] rt: '⇀', - rt.bar: '⥛', - rt.stop: '⥓', - rb: '⇁', - rb.bar: '⥟', - rb.stop: '⥗', - #[call(crate::math::accent::harpoon_lt)] lt: '↼', - lt.bar: '⥚', - lt.stop: '⥒', - lb: '↽', - lb.bar: '⥞', - lb.stop: '⥖', - tl: '↿', - tl.bar: '⥠', - tl.stop: '⥘', - tr: '↾', - tr.bar: '⥜', - tr.stop: '⥔', - bl: '⇃', - bl.bar: '⥡', - bl.stop: '⥙', - br: '⇂', - br.bar: '⥝', - br.stop: '⥕', - lt.rt: '⥎', - lb.rb: '⥐', - lb.rt: '⥋', - lt.rb: '⥊', - tl.bl: '⥑', - tr.br: '⥏', - tl.br: '⥍', - tr.bl: '⥌', - ], - harpoons: [ - rtrb: '⥤', - blbr: '⥥', - bltr: '⥯', - lbrb: '⥧', - ltlb: '⥢', - ltrb: '⇋', - ltrt: '⥦', - rblb: '⥩', - rtlb: '⇌', - rtlt: '⥨', - tlbr: '⥮', - tltr: '⥣', - ], - tack: [ - r: '⊢', - r.not: '⊬', - r.long: '⟝', - r.short: '⊦', - r.double: '⊨', - r.double.not: '⊭', - l: '⊣', - l.long: '⟞', - l.short: '⫞', - l.double: '⫤', - t: '⊥', - t.big: '⟘', - t.double: '⫫', - t.short: '⫠', - b: '⊤', - b.big: '⟙', - b.double: '⫪', - b.short: '⫟', - l.r: '⟛', - ], - - // Lowercase Greek. - alpha: 'α', - beta: ['β', alt: 'ϐ'], - chi: 'χ', - delta: 'δ', - epsilon: ['ε', alt: 'ϵ'], - eta: 'η', - gamma: 'γ', - iota: 'ι', - kai: 'ϗ', - kappa: ['κ', alt: 'ϰ'], - lambda: 'λ', - mu: 'μ', - nu: 'ν', - ohm: ['Ω', inv: '℧'], - omega: 'ω', - omicron: 'ο', - phi: ['φ', alt: 'ϕ'], - pi: ['π', alt: 'ϖ'], - psi: 'ψ', - rho: ['ρ', alt: 'ϱ'], - sigma: ['σ', alt: 'ς'], - tau: 'τ', - theta: ['θ', alt: 'ϑ'], - upsilon: 'υ', - xi: 'ξ', - zeta: 'ζ', - - // Uppercase Greek. - Alpha: 'Α', - Beta: 'Β', - Chi: 'Χ', - Delta: 'Δ', - Epsilon: 'Ε', - Eta: 'Η', - Gamma: 'Γ', - Iota: 'Ι', - Kai: 'Ϗ', - Kappa: 'Κ', - Lambda: 'Λ', - Mu: 'Μ', - Nu: 'Ν', - Omega: 'Ω', - Omicron: 'Ο', - Phi: 'Φ', - Pi: 'Π', - Psi: 'Ψ', - Rho: 'Ρ', - Sigma: 'Σ', - Tau: 'Τ', - Theta: 'Θ', - Upsilon: 'Υ', - Xi: 'Ξ', - Zeta: 'Ζ', - - // Hebrew. - // In math, the following symbols are replaced with corresponding characters - // from Letterlike Symbols. - // See https://github.com/typst/typst/pull/3375. - aleph: 'א', - alef: 'א', - beth: 'ב', - bet: 'ב', - gimmel: 'ג', - gimel: 'ג', - daleth: 'ד', - dalet: 'ד', - shin: 'ש', - - // Double-struck. - AA: '𝔸', - BB: '𝔹', - CC: 'ℂ', - DD: '𝔻', - EE: '𝔼', - FF: '𝔽', - GG: '𝔾', - HH: 'ℍ', - II: '𝕀', - JJ: '𝕁', - KK: '𝕂', - LL: '𝕃', - MM: '𝕄', - NN: 'ℕ', - OO: '𝕆', - PP: 'ℙ', - QQ: 'ℚ', - RR: 'ℝ', - SS: '𝕊', - TT: '𝕋', - UU: '𝕌', - VV: '𝕍', - WW: '𝕎', - XX: '𝕏', - YY: '𝕐', - ZZ: 'ℤ', - - // Miscellaneous letter-likes. - ell: 'ℓ', - planck: ['ℎ', reduce: 'ℏ'], - angstrom: 'Å', - kelvin: 'K', - Re: 'ℜ', - Im: 'ℑ', - dotless: [i: 'ı', j: 'ȷ'], -}; diff --git a/crates/typst-macros/src/lib.rs b/crates/typst-macros/src/lib.rs index acc5e6034..e1c3c13ab 100644 --- a/crates/typst-macros/src/lib.rs +++ b/crates/typst-macros/src/lib.rs @@ -9,7 +9,6 @@ mod category; mod elem; mod func; mod scope; -mod symbols; mod time; mod ty; @@ -338,52 +337,6 @@ pub fn derive_cast(item: BoundaryStream) -> BoundaryStream { .into() } -/// Defines a list of `Symbol`s. -/// -/// The `#[call(path)]` attribute can be used to specify a function to call when -/// the symbol is invoked. The function must be `NativeFunc`. -/// -/// ```ignore -/// const EMOJI: &[(&str, Symbol)] = symbols! { -/// // A plain symbol without modifiers. -/// abacus: '🧮', -/// -/// // A symbol with a modifierless default and one modifier. -/// alien: ['👽', monster: '👾'], -/// -/// // A symbol where each variant has a modifier. The first one will be -/// // the default. -/// clock: [one: '🕐', two: '🕑', ...], -/// -/// // A callable symbol without modifiers. -/// breve: #[call(crate::math::breve)] '˘', -/// -/// // A callable symbol with a modifierless default and one modifier. -/// acute: [ -/// #[call(crate::math::acute)] '´', -/// double: '˝', -/// ], -/// -/// // A callable symbol where each variant has a modifier. -/// arrow: [ -/// #[call(crate::math::arrow)] r: '→', -/// r.long.bar: '⟼', -/// #[call(crate::math::arrow_l)] l: '←', -/// l.long.bar: '⟻', -/// ], -/// } -/// ``` -/// -/// _Note:_ While this could use `macro_rules!` instead of a proc-macro, it was -/// horribly slow in rust-analyzer. The underlying cause might be -/// [this issue](https://github.com/rust-lang/rust-analyzer/issues/11108). -#[proc_macro] -pub fn symbols(stream: BoundaryStream) -> BoundaryStream { - symbols::symbols(stream.into()) - .unwrap_or_else(|err| err.to_compile_error()) - .into() -} - /// Times function invocations. /// /// When tracing is enabled in the typst-cli, this macro will record the diff --git a/crates/typst-macros/src/symbols.rs b/crates/typst-macros/src/symbols.rs deleted file mode 100644 index 9917f4369..000000000 --- a/crates/typst-macros/src/symbols.rs +++ /dev/null @@ -1,129 +0,0 @@ -use proc_macro2::TokenStream; -use quote::quote; -use syn::ext::IdentExt; -use syn::parse::{Parse, ParseStream, Parser}; -use syn::punctuated::Punctuated; -use syn::{Ident, LitChar, Path, Result, Token}; - -use crate::util::foundations; - -/// Expand the `symbols!` macro. -pub fn symbols(stream: TokenStream) -> Result { - let list: Punctuated = - Punctuated::parse_terminated.parse2(stream)?; - let pairs = list.iter().map(|symbol| { - let name = symbol.name.to_string(); - let kind = match &symbol.kind { - Kind::Single(c, h) => { - let symbol = construct_sym_char(c, h); - quote! { #foundations::Symbol::single(#symbol), } - } - Kind::Multiple(variants) => { - let variants = variants.iter().map(|variant| { - let name = &variant.name; - let c = &variant.c; - let symbol = construct_sym_char(c, &variant.handler); - quote! { (#name, #symbol) } - }); - quote! { - #foundations::Symbol::list(&[#(#variants),*]) - } - } - }; - quote! { (#name, #kind) } - }); - Ok(quote! { &[#(#pairs),*] }) -} - -fn construct_sym_char(ch: &LitChar, handler: &Handler) -> TokenStream { - match &handler.0 { - None => quote! { #foundations::SymChar::pure(#ch), }, - Some(path) => quote! { - #foundations::SymChar::with_func( - #ch, - <#path as ::typst_library::foundations::NativeFunc>::func, - ), - }, - } -} - -struct Symbol { - name: syn::Ident, - kind: Kind, -} - -enum Kind { - Single(syn::LitChar, Handler), - Multiple(Punctuated), -} - -struct Variant { - name: String, - c: syn::LitChar, - handler: Handler, -} - -struct Handler(Option); - -impl Parse for Symbol { - fn parse(input: ParseStream) -> Result { - let name = input.call(Ident::parse_any)?; - input.parse::()?; - let kind = input.parse()?; - Ok(Self { name, kind }) - } -} - -impl Parse for Kind { - fn parse(input: ParseStream) -> Result { - let handler = input.parse::()?; - if input.peek(syn::LitChar) { - Ok(Self::Single(input.parse()?, handler)) - } else { - if handler.0.is_some() { - return Err(input.error("unexpected handler")); - } - let content; - syn::bracketed!(content in input); - Ok(Self::Multiple(Punctuated::parse_terminated(&content)?)) - } - } -} - -impl Parse for Variant { - fn parse(input: ParseStream) -> Result { - let mut name = String::new(); - let handler = input.parse::()?; - if input.peek(syn::Ident::peek_any) { - name.push_str(&input.call(Ident::parse_any)?.to_string()); - while input.peek(Token![.]) { - input.parse::()?; - name.push('.'); - name.push_str(&input.call(Ident::parse_any)?.to_string()); - } - input.parse::()?; - } - let c = input.parse()?; - Ok(Self { name, c, handler }) - } -} - -impl Parse for Handler { - fn parse(input: ParseStream) -> Result { - let Ok(attrs) = input.call(syn::Attribute::parse_outer) else { - return Ok(Self(None)); - }; - let handler = attrs - .iter() - .find_map(|attr| { - if attr.path().is_ident("call") { - if let Ok(path) = attr.parse_args::() { - return Some(Self(Some(path))); - } - } - None - }) - .unwrap_or(Self(None)); - Ok(handler) - } -} diff --git a/docs/src/lib.rs b/docs/src/lib.rs index bc9b53c9a..9228a9906 100644 --- a/docs/src/lib.rs +++ b/docs/src/lib.rs @@ -671,15 +671,15 @@ fn symbols_model(resolver: &dyn Resolver, group: &GroupData) -> SymbolsModel { for (variant, c) in symbol.variants() { let shorthand = |list: &[(&'static str, char)]| { - list.iter().copied().find(|&(_, x)| x == c.char()).map(|(s, _)| s) + list.iter().copied().find(|&(_, x)| x == c).map(|(s, _)| s) }; list.push(SymbolModel { name: complete(variant), markup_shorthand: shorthand(typst::syntax::ast::Shorthand::LIST), math_shorthand: shorthand(typst::syntax::ast::MathShorthand::LIST), - codepoint: c.char() as _, - accent: typst::math::Accent::combine(c.char()).is_some(), + codepoint: c as _, + accent: typst::math::Accent::combine(c).is_some(), alternates: symbol .variants() .filter(|(other, _)| other != &variant) diff --git a/tests/suite/symbols/symbol.typ b/tests/suite/symbols/symbol.typ index 8f9a49ca2..30d87e44f 100644 --- a/tests/suite/symbols/symbol.typ +++ b/tests/suite/symbols/symbol.typ @@ -33,6 +33,19 @@ // Error: 2-10 expected at least one variant #symbol() +--- symbol-constructor-invalid-modifier --- +// Error: 2:3-2:24 invalid symbol modifier: " id!" +#symbol( + ("invalid. id!", "x") +) + +--- symbol-constructor-duplicate-variant --- +// Error: 3:3-3:29 duplicate variant +#symbol( + ("duplicate.variant", "x"), + ("duplicate.variant", "y"), +) + --- symbol-unknown-modifier --- // Error: 13-20 unknown symbol modifier #emoji.face.garbage