summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock6
-rw-r--r--Cargo.toml1
-rw-r--r--crates/typst-eval/src/markup.rs4
-rw-r--r--crates/typst-eval/src/math.rs2
-rw-r--r--crates/typst-library/Cargo.toml1
-rw-r--r--crates/typst-library/src/foundations/symbol.rs143
-rw-r--r--crates/typst-library/src/math/mod.rs4
-rw-r--r--crates/typst-library/src/symbols.rs49
-rw-r--r--crates/typst-library/src/symbols/emoji.rs1363
-rw-r--r--crates/typst-library/src/symbols/mod.rs24
-rw-r--r--crates/typst-library/src/symbols/sym.rs1000
-rw-r--r--crates/typst-macros/src/lib.rs47
-rw-r--r--crates/typst-macros/src/symbols.rs129
-rw-r--r--docs/src/lib.rs6
-rw-r--r--tests/suite/symbols/symbol.typ13
15 files changed, 145 insertions, 2647 deletions
diff --git a/Cargo.lock b/Cargo.lock
index bfd1ccda..78ab71c5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -396,6 +396,11 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2849,6 +2854,7 @@ dependencies = [
"bumpalo",
"chinese-number",
"ciborium",
+ "codex",
"comemo",
"csv",
"ecow",
diff --git a/Cargo.toml b/Cargo.toml
index e1f6dccb..cebc2e97 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 e28eb9dd..25ea5751 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<Self::Output> {
- 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<Self::Output> {
- 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 c61a3251..51dc0a3d 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<Self::Output> {
- 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 a1fb1033..d854e4d5 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 86676fa2..fcb3a3ce 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<fn() -> 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<Func> {
- 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<Self> {
- 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<Item = (&str, SymChar)> {
+ pub fn variants(&self) -> impl Iterator<Item = (&str, char)> {
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<Item = &str> + '_ {
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<Func> {
- self.1.map(|f| f())
- }
-}
-
-impl From<char> 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<SymChar>),
- Static(std::slice::Iter<'static, (&'static str, SymChar)>),
- Runtime(std::slice::Iter<'a, (EcoString, SymChar)>),
+ Single(std::option::IntoIter<char>),
+ 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<Self::Item> {
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<Item = (&'a str, SymChar)>,
+ variants: impl Iterator<Item = (&'a str, char)>,
modifiers: &str,
-) -> Option<SymChar> {
+) -> Option<char> {
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 53b1f072..5a83c854 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 00000000..1617d3aa
--- /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<codex::Module> for Scope {
+ fn from(module: codex::Module) -> Scope {
+ let mut scope = Self::new();
+ extend_scope_from_codex_module(&mut scope, module);
+ scope
+ }
+}
+
+impl From<codex::Symbol> 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 1bd57ec0..00000000
--- 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 7e0fb55b..00000000
--- 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 bdda4bde..00000000
--- 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 acc5e603..e1c3c13a 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 9917f436..00000000
--- 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<TokenStream> {
- let list: Punctuated<Symbol, Token![,]> =
- 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<Variant, Token![,]>),
-}
-
-struct Variant {
- name: String,
- c: syn::LitChar,
- handler: Handler,
-}
-
-struct Handler(Option<Path>);
-
-impl Parse for Symbol {
- fn parse(input: ParseStream) -> Result<Self> {
- let name = input.call(Ident::parse_any)?;
- input.parse::<Token![:]>()?;
- let kind = input.parse()?;
- Ok(Self { name, kind })
- }
-}
-
-impl Parse for Kind {
- fn parse(input: ParseStream) -> Result<Self> {
- let handler = input.parse::<Handler>()?;
- 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<Self> {
- let mut name = String::new();
- let handler = input.parse::<Handler>()?;
- if input.peek(syn::Ident::peek_any) {
- name.push_str(&input.call(Ident::parse_any)?.to_string());
- while input.peek(Token![.]) {
- input.parse::<Token![.]>()?;
- name.push('.');
- name.push_str(&input.call(Ident::parse_any)?.to_string());
- }
- input.parse::<Token![:]>()?;
- }
- let c = input.parse()?;
- Ok(Self { name, c, handler })
- }
-}
-
-impl Parse for Handler {
- fn parse(input: ParseStream) -> Result<Self> {
- 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::<Path>() {
- 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 bc9b53c9..9228a990 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 8f9a49ca..30d87e44 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