typst/library/src/text/symbol.rs
2022-12-22 01:33:09 +01:00

112 lines
3.4 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use crate::prelude::*;
use crate::text::TextNode;
/// # Symbol
/// A symbol identified by symmie notation.
///
/// Symmie is Typst's notation for Unicode symbols. It is based on the idea of
/// _modifiers._ Many symbols in Unicode are very similar. In symmie, such
/// groups of symbols share a common name. To distinguish between the symbols
/// within a group, we use one or multiple modifiers that are separated from the
/// name by colons.
///
/// There is currently no easily viewable list of all names, but in the
/// meantime you can rely on the autocompletion in Typst's web editor.
///
/// ## Syntax
/// This function also has dedicated syntax: In markup, you can enclose symmie
/// notation within colons to produce a symbol. And in math, you can just write
/// the notation directly. There, all letter sequence of length at least two are
/// automatically parsed as symbols (unless a variable of that name is defined).
///
/// Additionally, some very common but hard to type symbols can be expressed with
/// dedicated shortcuts. These are:
///
/// | Symmie | Shorthand | Result |
/// | ----------- | --------- | ------ |
/// | `dots:b` | `...` | … |
/// | `dash:en` | `---` | |
/// | `dash:em` | `--` | — |
/// | none yet | `-?` | A soft hyphen |
/// | none yet | `~` | A non breaking space |
///
/// Within math mode, additional shorthands are available:
///
/// | Symmie | Shorthand | Result |
/// | ------------------ | --------- | ------ |
/// | `arrow:r` | `->` | `→` |
/// | `arrow:r:double` | `=>` | `⇒` |
/// | `arrow:l` | `<-` | `←` |
/// | `arrow:r:bar` | <code>&VerticalLine;-></code> | `↦` |
/// | `arrow:l:r` | `<->` | `↔` |
/// | `arrow:l:r:double` | `<=>` | `⇔` |
/// | `eq:not` | `!=` | `≠` |
/// | `eq:gt` | `>=` | `≥` |
/// | `eq:lt` | `<=` | `≤` |
/// | `colon:eq` | `:=` | `≔` |
///
/// ## Example
/// ```
/// // In text, with colons.
/// :arrow:l: \
/// :arrow:r: \
/// :arrow:t: \
/// :turtle: \
/// :face:halo: \
/// :woman:old:
///
/// // In math, directly.
/// $f : NN -> RR$ \
/// $A sub:eq B without C$ \
/// $a times:div b eq:not c$
/// ```
///
/// ## Parameters
/// - notation: EcoString (positional, required)
/// The symbol's symmie notation.
///
/// Consists of a name, followed by a number colon-separated modifiers
/// in no particular order.
///
/// ### Example
/// ```
/// #symbol("NN") \
/// #symbol("face:grin")
/// ```
///
/// ## Category
/// text
#[func]
#[capable(Show)]
#[derive(Debug, Hash)]
pub struct SymbolNode(pub EcoString);
#[node]
impl SymbolNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
Ok(Self(args.expect("notation")?).pack())
}
fn field(&self, name: &str) -> Option<Value> {
match name {
"notation" => Some(Value::Str(self.0.clone().into())),
_ => None,
}
}
}
impl Show for SymbolNode {
fn show(&self, _: &mut Vt, this: &Content, _: StyleChain) -> SourceResult<Content> {
match symmie::get(&self.0) {
Some(c) => Ok(TextNode::packed(c)),
None => {
if let Some(span) = this.span() {
bail!(span, "unknown symbol");
}
Ok(Content::empty())
}
}
}
}