feat: support entity

This commit is contained in:
PoiScript 2023-11-19 16:41:03 +08:00
parent 917fe2f5d2
commit 310664b05b
No known key found for this signature in database
GPG key ID: 22C2B1249D99985E
14 changed files with 805 additions and 11 deletions

View file

@ -50,7 +50,7 @@ impl Traverser for MyHtmlHandler {
special_block quote_block center_block verse_block comment_block example_block export_block
source_block babel_call clock cookie radio_target drawer dyn_block fn_def fn_ref macros
snippet timestamp target fixed_width org_table org_table_row org_table_cell latex_fragment
latex_environment
latex_environment entity
}
}

148
src/ast/entity.rs Normal file
View file

@ -0,0 +1,148 @@
use crate::{entities::ENTITIES, SyntaxKind};
use super::{filter_token, Entity};
impl Entity {
fn entity(&self) -> Option<&(&str, &str, bool, &str, &str, &str, &str)> {
let token = self
.syntax
.children_with_tokens()
.find_map(filter_token(SyntaxKind::TEXT))?;
let token = token.text();
ENTITIES.iter().find(|i| i.0 == token)
}
/// Entity name
///
/// ```rust
/// use orgize::{ast::Entity, Org};
///
/// let e = Org::parse("\\alpha{}").first_node::<Entity>().unwrap();
/// assert_eq!(e.name(), "alpha");
/// let e = Org::parse("\\_ ").first_node::<Entity>().unwrap();
/// assert_eq!(e.name(), " ");
/// ```
pub fn name(&self) -> &str {
self.entity().map(|e| e.0).unwrap_or_else(|| {
debug_assert!(false);
""
})
}
/// Entity LaTeX representation
///
/// ```rust
/// use orgize::{ast::Entity, Org};
///
/// let e = Org::parse("\\middot").first_node::<Entity>().unwrap();
/// assert_eq!(e.latex(), "\\textperiodcentered{}");
/// ```
pub fn latex(&self) -> &str {
self.entity().map(|e| e.1).unwrap_or_else(|| {
debug_assert!(false);
""
})
}
/// Whether entity needs to be in math mode
///
/// ```rust
/// use orgize::{ast::Entity, Org};
///
/// let e = Org::parse("\\middot").first_node::<Entity>().unwrap();
/// assert!(!e.is_latex_math());
/// let e = Org::parse("\\alefsym").first_node::<Entity>().unwrap();
/// assert!(e.is_latex_math());
/// ```
pub fn is_latex_math(&self) -> bool {
self.entity().map(|e| e.2).unwrap_or_else(|| {
debug_assert!(false);
false
})
}
/// Entity HTML representation
///
/// ```rust
/// use orgize::{ast::Entity, Org};
///
/// let e = Org::parse("\\S").first_node::<Entity>().unwrap();
/// assert_eq!(e.html(), "&sect;");
/// ```
pub fn html(&self) -> &str {
self.entity().map(|e| e.3).unwrap_or_else(|| {
debug_assert!(false);
""
})
}
/// Entity ASCII representation
///
/// ```rust
/// use orgize::{ast::Entity, Org};
///
/// let e = Org::parse("\\S").first_node::<Entity>().unwrap();
/// assert_eq!(e.ascii(), "section");
/// ```
pub fn ascii(&self) -> &str {
self.entity().map(|e| e.4).unwrap_or_else(|| {
debug_assert!(false);
""
})
}
/// Entity Latin1 encoding representation
///
/// ```rust
/// use orgize::{ast::Entity, Org};
///
/// let e = Org::parse("\\S").first_node::<Entity>().unwrap();
/// assert_eq!(e.latin1(), "§");
/// let e = Org::parse("\\rsaquo").first_node::<Entity>().unwrap();
/// assert_eq!(e.latin1(), ">");
/// ```
pub fn latin1(&self) -> &str {
self.entity().map(|e| e.5).unwrap_or_else(|| {
debug_assert!(false);
""
})
}
/// Entity UTF-8 encoding representation
///
/// ```rust
/// use orgize::{ast::Entity, Org};
///
/// let e = Org::parse("\\S").first_node::<Entity>().unwrap();
/// assert_eq!(e.utf8(), "§");
/// let e = Org::parse("\\rsaquo").first_node::<Entity>().unwrap();
/// assert_eq!(e.utf8(), "");
/// ```
pub fn utf8(&self) -> &str {
self.entity().map(|e| e.6).unwrap_or_else(|| {
debug_assert!(false);
""
})
}
/// Entity contains optional brackets
///
/// ```rust
/// use orgize::{ast::Entity, Org};
///
/// let e = Org::parse("\\beta").first_node::<Entity>().unwrap();
/// assert!(!e.is_use_brackets());
/// let e = Org::parse("\\S{}").first_node::<Entity>().unwrap();
/// assert!(e.is_use_brackets());
/// let e = Org::parse("\\_ ").first_node::<Entity>().unwrap();
/// assert!(!e.is_use_brackets());
/// ```
pub fn is_use_brackets(&self) -> bool {
self.syntax
.children_with_tokens()
.filter(|n| n.kind() == SyntaxKind::TEXT)
.nth(1)
.is_some()
}
}

View file

@ -263,6 +263,10 @@ const nodes = [
struct: "LatexFragment",
kind: ["LATEX_FRAGMENT"],
},
{
struct: "Entity",
kind: ["ENTITY"],
},
];
let content = `//! generated file, do not modify it directly

View file

@ -1700,3 +1700,28 @@ impl LatexFragment {
self.syntax.text_range().end().into()
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Entity {
pub(crate) syntax: SyntaxNode,
}
impl AstNode for Entity {
type Language = OrgLanguage;
fn can_cast(kind: SyntaxKind) -> bool {
kind == ENTITY
}
fn cast(node: SyntaxNode) -> Option<Entity> {
Self::can_cast(node.kind()).then(|| Entity { syntax: node })
}
fn syntax(&self) -> &SyntaxNode {
&self.syntax
}
}
impl Entity {
pub fn begin(&self) -> u32 {
self.syntax.text_range().start().into()
}
pub fn end(&self) -> u32 {
self.syntax.text_range().end().into()
}
}

View file

@ -4,6 +4,7 @@ mod generated;
mod affiliated_keyword;
mod drawer;
mod entity;
mod headline;
mod inline_call;
mod link;

468
src/entities.rs Normal file
View file

@ -0,0 +1,468 @@
// https://git.sr.ht/~bzg/org-mode/tree/bfa4f9d5aa3e5c94974cae7a459cb5e5b4b15f52/item/lisp/org-entities.el#L85
// nil -> false
// t -> true
// \x00A0 -> \\x00A0
#[rustfmt::skip]
pub const ENTITIES: &[(&str, &str, bool, &str, &str, &str, &str)] = &[
// ("* Letters"
// Latin
("Agrave", "\\`{A}", false, "&Agrave;", "A", "À", "À"),
("agrave", "\\`{a}", false, "&agrave;", "a", "à", "à"),
("Aacute", "\\'{A}", false, "&Aacute;", "A", "Á", "Á"),
("aacute", "\\'{a}", false, "&aacute;", "a", "á", "á"),
("Acirc", "\\^{A}", false, "&Acirc;", "A", "Â", "Â"),
("acirc", "\\^{a}", false, "&acirc;", "a", "â", "â"),
("Amacr", "\\={A}", false, "&Amacr;", "A", "Ã", "Ã"),
("amacr", "\\={a}", false, "&amacr;", "a", "ã", "ã"),
("Atilde", "\\~{A}", false, "&Atilde;", "A", "Ã", "Ã"),
("atilde", "\\~{a}", false, "&atilde;", "a", "ã", "ã"),
("Auml", "\\\"{A}", false, "&Auml;", "Ae", "Ä", "Ä"),
("auml", "\\\"{a}", false, "&auml;", "ae", "ä", "ä"),
("Aring", "\\AA{}", false, "&Aring;", "A", "Å", "Å"),
("AA", "\\AA{}", false, "&Aring;", "A", "Å", "Å"),
("aring", "\\aa{}", false, "&aring;", "a", "å", "å"),
("AElig", "\\AE{}", false, "&AElig;", "AE", "Æ", "Æ"),
("aelig", "\\ae{}", false, "&aelig;", "ae", "æ", "æ"),
("Ccedil", "\\c{C}", false, "&Ccedil;", "C", "Ç", "Ç"),
("ccedil", "\\c{c}", false, "&ccedil;", "c", "ç", "ç"),
("Egrave", "\\`{E}", false, "&Egrave;", "E", "È", "È"),
("egrave", "\\`{e}", false, "&egrave;", "e", "è", "è"),
("Eacute", "\\'{E}", false, "&Eacute;", "E", "É", "É"),
("eacute", "\\'{e}", false, "&eacute;", "e", "é", "é"),
("Ecirc", "\\^{E}", false, "&Ecirc;", "E", "Ê", "Ê"),
("ecirc", "\\^{e}", false, "&ecirc;", "e", "ê", "ê"),
("Euml", "\\\"{E}", false, "&Euml;", "E", "Ë", "Ë"),
("euml", "\\\"{e}", false, "&euml;", "e", "ë", "ë"),
("Igrave", "\\`{I}", false, "&Igrave;", "I", "Ì", "Ì"),
("igrave", "\\`{i}", false, "&igrave;", "i", "ì", "ì"),
("Iacute", "\\'{I}", false, "&Iacute;", "I", "Í", "Í"),
("iacute", "\\'{i}", false, "&iacute;", "i", "í", "í"),
("Idot", "\\.{I}", false, "&idot;", "I", "İ", "İ"),
("inodot", "\\i", false, "&inodot;", "i", "ı", "ı"),
("Icirc", "\\^{I}", false, "&Icirc;", "I", "Î", "Î"),
("icirc", "\\^{i}", false, "&icirc;", "i", "î", "î"),
("Iuml", "\\\"{I}", false, "&Iuml;", "I", "Ï", "Ï"),
("iuml", "\\\"{i}", false, "&iuml;", "i", "ï", "ï"),
("Ntilde", "\\~{N}", false, "&Ntilde;", "N", "Ñ", "Ñ"),
("ntilde", "\\~{n}", false, "&ntilde;", "n", "ñ", "ñ"),
("Ograve", "\\`{O}", false, "&Ograve;", "O", "Ò", "Ò"),
("ograve", "\\`{o}", false, "&ograve;", "o", "ò", "ò"),
("Oacute", "\\'{O}", false, "&Oacute;", "O", "Ó", "Ó"),
("oacute", "\\'{o}", false, "&oacute;", "o", "ó", "ó"),
("Ocirc", "\\^{O}", false, "&Ocirc;", "O", "Ô", "Ô"),
("ocirc", "\\^{o}", false, "&ocirc;", "o", "ô", "ô"),
("Otilde", "\\~{O}", false, "&Otilde;", "O", "Õ", "Õ"),
("otilde", "\\~{o}", false, "&otilde;", "o", "õ", "õ"),
("Ouml", "\\\"{O}", false, "&Ouml;", "Oe", "Ö", "Ö"),
("ouml", "\\\"{o}", false, "&ouml;", "oe", "ö", "ö"),
("Oslash", "\\O", false, "&Oslash;", "O", "Ø", "Ø"),
("oslash", "\\o{}", false, "&oslash;", "o", "ø", "ø"),
("OElig", "\\OE{}", false, "&OElig;", "OE", "OE", "Œ"),
("oelig", "\\oe{}", false, "&oelig;", "oe", "oe", "œ"),
("Scaron", "\\v{S}", false, "&Scaron;", "S", "S", "Š"),
("scaron", "\\v{s}", false, "&scaron;", "s", "s", "š"),
("szlig", "\\ss{}", false, "&szlig;", "ss", "ß", "ß"),
("Ugrave", "\\`{U}", false, "&Ugrave;", "U", "Ù", "Ù"),
("ugrave", "\\`{u}", false, "&ugrave;", "u", "ù", "ù"),
("Uacute", "\\'{U}", false, "&Uacute;", "U", "Ú", "Ú"),
("uacute", "\\'{u}", false, "&uacute;", "u", "ú", "ú"),
("Ucirc", "\\^{U}", false, "&Ucirc;", "U", "Û", "Û"),
("ucirc", "\\^{u}", false, "&ucirc;", "u", "û", "û"),
("Uuml", "\\\"{U}", false, "&Uuml;", "Ue", "Ü", "Ü"),
("uuml", "\\\"{u}", false, "&uuml;", "ue", "ü", "ü"),
("Yacute", "\\'{Y}", false, "&Yacute;", "Y", "Ý", "Ý"),
("yacute", "\\'{y}", false, "&yacute;", "y", "ý", "ý"),
("Yuml", "\\\"{Y}", false, "&Yuml;", "Y", "Y", "Ÿ"),
("yuml", "\\\"{y}", false, "&yuml;", "y", "ÿ", "ÿ"),
// Latin (special face)
("fnof", "\\textit{f}", false, "&fnof;", "f", "f", "ƒ"),
("real", "\\Re", true, "&real;", "R", "R", ""),
("image", "\\Im", true, "&image;", "I", "I", ""),
("weierp", "\\wp", true, "&weierp;", "P", "P", ""),
("ell", "\\ell", true, "&ell;", "ell", "ell", ""),
("imath", "\\imath", true, "&imath;", "[dotless i]", "dotless i", "ı"),
("jmath", "\\jmath", true, "&jmath;", "[dotless j]", "dotless j", "ȷ"),
// Greek
("Alpha", "A", false, "&Alpha;", "Alpha", "Alpha", "Α"),
("alpha", "\\alpha", true, "&alpha;", "alpha", "alpha", "α"),
("Beta", "B", false, "&Beta;", "Beta", "Beta", "Β"),
("beta", "\\beta", true, "&beta;", "beta", "beta", "β"),
("Gamma", "\\Gamma", true, "&Gamma;", "Gamma", "Gamma", "Γ"),
("gamma", "\\gamma", true, "&gamma;", "gamma", "gamma", "γ"),
("Delta", "\\Delta", true, "&Delta;", "Delta", "Delta", "Δ"),
("delta", "\\delta", true, "&delta;", "delta", "delta", "δ"),
("Epsilon", "E", false, "&Epsilon;", "Epsilon", "Epsilon", "Ε"),
("epsilon", "\\epsilon", true, "&epsilon;", "epsilon", "epsilon", "ε"),
("varepsilon", "\\varepsilon", true, "&epsilon;", "varepsilon", "varepsilon", "ε"),
("Zeta", "Z", false, "&Zeta;", "Zeta", "Zeta", "Ζ"),
("zeta", "\\zeta", true, "&zeta;", "zeta", "zeta", "ζ"),
("Eta", "H", false, "&Eta;", "Eta", "Eta", "Η"),
("eta", "\\eta", true, "&eta;", "eta", "eta", "η"),
("Theta", "\\Theta", true, "&Theta;", "Theta", "Theta", "Θ"),
("theta", "\\theta", true, "&theta;", "theta", "theta", "θ"),
("thetasym", "\\vartheta", true, "&thetasym;", "theta", "theta", "ϑ"),
("vartheta", "\\vartheta", true, "&thetasym;", "theta", "theta", "ϑ"),
("Iota", "I", false, "&Iota;", "Iota", "Iota", "Ι"),
("iota", "\\iota", true, "&iota;", "iota", "iota", "ι"),
("Kappa", "K", false, "&Kappa;", "Kappa", "Kappa", "Κ"),
("kappa", "\\kappa", true, "&kappa;", "kappa", "kappa", "κ"),
("Lambda", "\\Lambda", true, "&Lambda;", "Lambda", "Lambda", "Λ"),
("lambda", "\\lambda", true, "&lambda;", "lambda", "lambda", "λ"),
("Mu", "M", false, "&Mu;", "Mu", "Mu", "Μ"),
("mu", "\\mu", true, "&mu;", "mu", "mu", "μ"),
("nu", "\\nu", true, "&nu;", "nu", "nu", "ν"),
("Nu", "N", false, "&Nu;", "Nu", "Nu", "Ν"),
("Xi", "\\Xi", true, "&Xi;", "Xi", "Xi", "Ξ"),
("xi", "\\xi", true, "&xi;", "xi", "xi", "ξ"),
("Omicron", "O", false, "&Omicron;", "Omicron", "Omicron", "Ο"),
("omicron", "\\textit{o}", false, "&omicron;", "omicron", "omicron", "ο"),
("Pi", "\\Pi", true, "&Pi;", "Pi", "Pi", "Π"),
("pi", "\\pi", true, "&pi;", "pi", "pi", "π"),
("Rho", "P", false, "&Rho;", "Rho", "Rho", "Ρ"),
("rho", "\\rho", true, "&rho;", "rho", "rho", "ρ"),
("Sigma", "\\Sigma", true, "&Sigma;", "Sigma", "Sigma", "Σ"),
("sigma", "\\sigma", true, "&sigma;", "sigma", "sigma", "σ"),
("sigmaf", "\\varsigma", true, "&sigmaf;", "sigmaf", "sigmaf", "ς"),
("varsigma", "\\varsigma", true, "&sigmaf;", "varsigma", "varsigma", "ς"),
("Tau", "T", false, "&Tau;", "Tau", "Tau", "Τ"),
("Upsilon", "\\Upsilon", true, "&Upsilon;", "Upsilon", "Upsilon", "Υ"),
("upsih", "\\Upsilon", true, "&upsih;", "upsilon", "upsilon", "ϒ"),
("upsilon", "\\upsilon", true, "&upsilon;", "upsilon", "upsilon", "υ"),
("Phi", "\\Phi", true, "&Phi;", "Phi", "Phi", "Φ"),
("phi", "\\phi", true, "&phi;", "phi", "phi", "ɸ"),
("varphi", "\\varphi", true, "&varphi;", "varphi", "varphi", "φ"),
("Chi", "X", false, "&Chi;", "Chi", "Chi", "Χ"),
("chi", "\\chi", true, "&chi;", "chi", "chi", "χ"),
("acutex", "\\acute x", true, "&acute;x", "'x", "'x", "𝑥́"),
("Psi", "\\Psi", true, "&Psi;", "Psi", "Psi", "Ψ"),
("psi", "\\psi", true, "&psi;", "psi", "psi", "ψ"),
("tau", "\\tau", true, "&tau;", "tau", "tau", "τ"),
("Omega", "\\Omega", true, "&Omega;", "Omega", "Omega", "Ω"),
("omega", "\\omega", true, "&omega;", "omega", "omega", "ω"),
("piv", "\\varpi", true, "&piv;", "omega-pi", "omega-pi", "ϖ"),
("varpi", "\\varpi", true, "&piv;", "omega-pi", "omega-pi", "ϖ"),
("partial", "\\partial", true, "&part;", "[partial differential]", "[partial differential]", ""),
// Hebrew
("alefsym", "\\aleph", true, "&alefsym;", "aleph", "aleph", ""),
("aleph", "\\aleph", true, "&aleph;", "aleph", "aleph", ""),
("gimel", "\\gimel", true, "&gimel;", "gimel", "gimel", ""),
("beth", "\\beth", true, "&beth;", "beth", "beth", "ב"),
("dalet", "\\daleth", true, "&daleth;", "dalet", "dalet", "ד"),
// Icelandic
("ETH", "\\DH{}", false, "&ETH;", "D", "Ð", "Ð"),
("eth", "\\dh{}", false, "&eth;", "dh", "ð", "ð"),
("THORN", "\\TH{}", false, "&THORN;", "TH", "Þ", "Þ"),
("thorn", "\\th{}", false, "&thorn;", "th", "þ", "þ"),
//, "* Punctuation",
// Dots and Marks
("dots", "\\dots{}", false, "&hellip;", "...", "...", ""),
("cdots", "\\cdots{}", true, "&ctdot;", "...", "...", ""),
("hellip", "\\dots{}", false, "&hellip;", "...", "...", ""),
("middot", "\\textperiodcentered{}", false, "&middot;", ".", "·", "·"),
("iexcl", "!`", false, "&iexcl;", "!", "¡", "¡"),
("iquest", "?`", false, "&iquest;", "?", "¿", "¿"),
// Dash-like
("shy", "\\-", false, "&shy;", "", "", ""),
("ndash", "--", false, "&ndash;", "-", "-", ""),
("mdash", "---", false, "&mdash;", "--", "--", ""),
// Quotations
("quot", "\\textquotedbl{}", false, "&quot;", "\"", "\"", "\""),
("acute", "\\textasciiacute{}", false, "&acute;", "'", "´", "´"),
("ldquo", "\\textquotedblleft{}", false, "&ldquo;", "\"", "\"", ""),
("rdquo", "\\textquotedblright{}", false, "&rdquo;", "\"", "\"", ""),
("bdquo", "\\quotedblbase{}", false, "&bdquo;", "\"", "\"", ""),
("lsquo", "\\textquoteleft{}", false, "&lsquo;", "`", "`", ""),
("rsquo", "\\textquoteright{}", false, "&rsquo;", "'", "'", ""),
("sbquo", "\\quotesinglbase{}", false, "&sbquo;", ", ", ", ", ""),
("laquo", "\\guillemotleft{}", false, "&laquo;", "<<", "«", "«"),
("raquo", "\\guillemotright{}", false, "&raquo;", ">>", "»", "»"),
("lsaquo", "\\guilsinglleft{}", false, "&lsaquo;", "<", "<", ""),
("rsaquo", "\\guilsinglright{}", false, "&rsaquo;", ">", ">", ""),
//, "* Other",
// Misc. (often used)
("circ", "\\^{}", false, "&circ;", "^", "^", ""),
("vert", "\\vert{}", true, "&vert;", "|", "|", "|"),
("vbar", "|", false, "|", "|", "|", "|"),
("brvbar", "\\textbrokenbar{}", false, "&brvbar;", "|", "¦", "¦"),
("S", "\\S", false, "&sect;", "section", "§", "§"),
("sect", "\\S", false, "&sect;", "section", "§", "§"),
("P", "\\P{}", false, "&para;", "paragraph", "", ""),
("para", "\\P{}", false, "&para;", "paragraph", "", ""),
("amp", "\\&", false, "&amp;", "&", "&", "&"),
("lt", "\\textless{}", false, "&lt;", "<", "<", "<"),
("gt", "\\textgreater{}", false, "&gt;", ">", ">", ">"),
("tilde", "\\textasciitilde{}", false, "~", "~", "~", "~"),
("slash", "/", false, "/", "/", "/", "/"),
("plus", "+", false, "+", "+", "+", "+"),
("under", "\\_", false, "_", "_", "_", "_"),
("equal", "=", false, "=", "=", "=", "="),
("asciicirc", "\\textasciicircum{}", false, "^", "^", "^", "^"),
("dagger", "\\textdagger{}", false, "&dagger;", "[dagger]", "[dagger]", ""),
("dag", "\\dag{}", false, "&dagger;", "[dagger]", "[dagger]", ""),
("Dagger", "\\textdaggerdbl{}", false, "&Dagger;", "[doubledagger]", "[doubledagger]", ""),
("ddag", "\\ddag{}", false, "&Dagger;", "[doubledagger]", "[doubledagger]", ""),
// Whitespace
("nbsp", "~", false, "&nbsp;", ", ", "\\x00A0", "\\x00A0"),
("ensp", "\\hspace*{.5em}", false, "&ensp;", ", ", ", ", ""),
("emsp", "\\hspace*{1em}", false, "&emsp;", ", ", ", ", ""),
("thinsp", "\\hspace*{.2em}", false, "&thinsp;", ", ", ", ", ""),
// Currency
("curren", "\\textcurrency{}", false, "&curren;", "curr.", "¤", "¤"),
("cent", "\\textcent{}", false, "&cent;", "cent", "¢", "¢"),
("pound", "\\pounds{}", false, "&pound;", "pound", "£", "£"),
("yen", "\\textyen{}", false, "&yen;", "yen", "¥", "¥"),
("euro", "\\texteuro{}", false, "&euro;", "EUR", "EUR", ""),
("EUR", "\\texteuro{}", false, "&euro;", "EUR", "EUR", ""),
("dollar", "\\$", false, "$", "$", "$", "$"),
("USD", "\\$", false, "$", "$", "$", "$"),
// Property Marks
("copy", "\\textcopyright{}", false, "&copy;", "(c)", "©", "©"),
("reg", "\\textregistered{}", false, "&reg;", "(r)", "®", "®"),
("trade", "\\texttrademark{}", false, "&trade;", "TM", "TM", ""),
// Science, etrueal.
("minus", "-", true, "&minus;", "-", "-", ""),
("pm", "\\textpm{}", false, "&plusmn;", "+-", "±", "±"),
("plusmn", "\\textpm{}", false, "&plusmn;", "+-", "±", "±"),
("times", "\\texttimes{}", false, "&times;", "*", "×", "×"),
("frasl", "/", false, "&frasl;", "/", "/", ""),
("colon", "\\colon", true, ":", ":", ":", ":"),
("div", "\\textdiv{}", false, "&divide;", "/", "÷", "÷"),
("frac12", "\\textonehalf{}", false, "&frac12;", "1/2", "½", "½"),
("frac14", "\\textonequarter{}", false, "&frac14;", "1/4", "¼", "¼"),
("frac34", "\\textthreequarters{}", false, "&frac34;", "3/4", "¾", "¾"),
("permil", "\\textperthousand{}", false, "&permil;", "per thousand", "per thousand", ""),
("sup1", "\\textonesuperior{}", false, "&sup1;", "^1", "¹", "¹"),
("sup2", "\\texttwosuperior{}", false, "&sup2;", "^2", "²", "²"),
("sup3", "\\textthreesuperior{}", false, "&sup3;", "^3", "³", "³"),
("radic", "\\sqrt{\\,}", true, "&radic;", "[square root]", "[square root]", ""),
("sum", "\\sum", true, "&sum;", "[sum]", "[sum]", ""),
("prod", "\\prod", true, "&prod;", "[product]", "[n-ary product]", ""),
("micro", "\\textmu{}", false, "&micro;", "micro", "µ", "µ"),
("macr", "\\textasciimacron{}", false, "&macr;", "[macron]", "¯", "¯"),
("deg", "\\textdegree{}", false, "&deg;", "degree", "°", "°"),
("prime", "\\prime", true, "&prime;", "'", "'", ""),
("Prime", "\\prime{}\\prime", true, "&Prime;", "''", "''", ""),
("infin", "\\infty", true, "&infin;", "[infinity]", "[infinity]", ""),
("infty", "\\infty", true, "&infin;", "[infinity]", "[infinity]", ""),
("prop", "\\propto", true, "&prop;", "[proportional to]", "[proportional to]", ""),
("propto", "\\propto", true, "&prop;", "[proportional to]", "[proportional to]", ""),
("not", "\\textlnot{}", false, "&not;", "[angled dash]", "¬", "¬"),
("neg", "\\neg{}", true, "&not;", "[angled dash]", "¬", "¬"),
("land", "\\land", true, "&and;", "[logical and]", "[logical and]", ""),
("wedge", "\\wedge", true, "&and;", "[logical and]", "[logical and]", ""),
("lor", "\\lor", true, "&or;", "[logical or]", "[logical or]", ""),
("vee", "\\vee", true, "&or;", "[logical or]", "[logical or]", ""),
("cap", "\\cap", true, "&cap;", "[intersection]", "[intersection]", ""),
("cup", "\\cup", true, "&cup;", "[union]", "[union]", ""),
("smile", "\\smile", true, "&smile;", "[cup product]", "[cup product]", ""),
("frown", "\\frown", true, "&frown;", "[Cap product]", "[cap product]", ""),
("int", "\\int", true, "&int;", "[integral]", "[integral]", ""),
("therefore", "\\therefore", true, "&there4;", "[therefore]", "[therefore]", ""),
("there4", "\\therefore", true, "&there4;", "[therefore]", "[therefore]", ""),
("because", "\\because", true, "&because;", "[because]", "[because]", ""),
("sim", "\\sim", true, "&sim;", "~", "~", ""),
("cong", "\\cong", true, "&cong;", "[approx. equal to]", "[approx. equal to]", ""),
("simeq", "\\simeq", true, "&cong;", "[approx. equal to]", "[approx. equal to]", ""),
("asymp", "\\asymp", true, "&asymp;", "[, almostrueequal to]", "[, almostrueequal to]", ""),
("approx", "\\approx", true, "&asymp;", "[, almostrueequal to]", "[, almostrueequal to]", ""),
("ne", "\\ne", true, "&ne;", "[, notrueequal to]", "[, notrueequal to]", ""),
("neq", "\\neq", true, "&ne;", "[, notrueequal to]", "[, notrueequal to]", ""),
("equiv", "\\equiv", true, "&equiv;", "[identical to]", "[identical to]", ""),
("triangleq", "\\triangleq", true, "&triangleq;", "[defined to]", "[defined to]", ""),
("le", "\\le", true, "&le;", "<=", "<=", ""),
("leq", "\\le", true, "&le;", "<=", "<=", ""),
("ge", "\\ge", true, "&ge;", ">=", ">=", ""),
("geq", "\\ge", true, "&ge;", ">=", ">=", ""),
("lessgtr", "\\lessgtr", true, "&lessgtr;", "[less than or greater than]", "[less than or greater than]", ""),
("lesseqgtr", "\\lesseqgtr", true, "&lesseqgtr;", "[less than or equal or greater than or equal]", "[less than or equal or greater than or equal]", ""),
("ll", "\\ll", true, "&Lt;", "<<", "<<", ""),
("Ll", "\\lll", true, "&Ll;", "<<<", "<<<", ""),
("lll", "\\lll", true, "&Ll;", "<<<", "<<<", ""),
("gg", "\\gg", true, "&Gt;", ">>", ">>", ""),
("Gg", "\\ggg", true, "&Gg;", ">>>", ">>>", ""),
("ggg", "\\ggg", true, "&Gg;", ">>>", ">>>", ""),
("prec", "\\prec", true, "&pr;", "[precedes]", "[precedes]", ""),
("preceq", "\\preceq", true, "&prcue;", "[precedes or equal]", "[precedes or equal]", ""),
("preccurlyeq", "\\preccurlyeq", true, "&prcue;", "[precedes or equal]", "[precedes or equal]", ""),
("succ", "\\succ", true, "&sc;", "[succeeds]", "[succeeds]", ""),
("succeq", "\\succeq", true, "&sccue;", "[succeeds or equal]", "[succeeds or equal]", ""),
("succcurlyeq", "\\succcurlyeq", true, "&sccue;", "[succeeds or equal]", "[succeeds or equal]", ""),
("sub", "\\subset", true, "&sub;", "[, subsetrueof]", "[, subsetrueof]", ""),
("subset", "\\subset", true, "&sub;", "[, subsetrueof]", "[, subsetrueof]", ""),
("sup", "\\supset", true, "&sup;", "[, supersetrueof]", "[, supersetrueof]", ""),
("supset", "\\supset", true, "&sup;", "[, supersetrueof]", "[, supersetrueof]", ""),
("nsub", "\\not\\subset", true, "&nsub;", "[, notruea, subsetrueof]", "[, notruea, subsetrueof", ""),
("sube", "\\subseteq", true, "&sube;", "[, subsetrueof or equal to]", "[, subsetrueof or equal to]", ""),
("nsup", "\\not\\supset", true, "&nsup;", "[, notruea, supersetrueof]", "[, notruea, supersetrueof]", ""),
("supe", "\\supseteq", true, "&supe;", "[, supersetrueof or equal to]", "[, supersetrueof or equal to]", ""),
("setminus", "\\setminus", true, "&setminus;", "\\", "\\", ""),
("forall", "\\forall", true, "&forall;", "[for all]", "[for all]", ""),
("exist", "\\exists", true, "&exist;", "[there exists]", "[there exists]", ""),
("exists", "\\exists", true, "&exist;", "[there exists]", "[there exists]", ""),
("nexist", "\\nexists", true, "&exist;", "[there does, notrueexists]", "[there does, notrue exists]", ""),
("nexists", "\\nexists", true, "&exist;", "[there does, notrueexists]", "[there does, notrue exists]", ""),
("empty", "\\emptyset", true, "&empty;", "[empty set]", "[empty set]", ""),
("emptyset", "\\emptyset", true, "&empty;", "[empty set]", "[empty set]", ""),
("isin", "\\in", true, "&isin;", "[, elementrueof]", "[, elementrueof]", ""),
("in", "\\in", true, "&isin;", "[, elementrueof]", "[, elementrueof]", ""),
("notin", "\\notin", true, "&notin;", "[, notruean, elementrueof]", "[, notruean, elementrueof]", ""),
("ni", "\\ni", true, "&ni;", "[contains as member]", "[contains as member]", ""),
("nabla", "\\nabla", true, "&nabla;", "[nabla]", "[nabla]", ""),
("ang", "\\angle", true, "&ang;", "[angle]", "[angle]", ""),
("angle", "\\angle", true, "&ang;", "[angle]", "[angle]", ""),
("perp", "\\perp", true, "&perp;", "[up tack]", "[up tack]", ""),
("parallel", "\\parallel", true, "&parallel;", "||", "||", ""),
("sdot", "\\cdot", true, "&sdot;", "[dot]", "[dot]", ""),
("cdot", "\\cdot", true, "&sdot;", "[dot]", "[dot]", ""),
("lceil", "\\lceil", true, "&lceil;", "[, leftrueceiling]", "[, leftrueceiling]", ""),
("rceil", "\\rceil", true, "&rceil;", "[, rightrueceiling]", "[, rightrueceiling]", ""),
("lfloor", "\\lfloor", true, "&lfloor;", "[, leftruefloor]", "[, leftruefloor]", ""),
("rfloor", "\\rfloor", true, "&rfloor;", "[, rightruefloor]", "[, rightruefloor]", ""),
("lang", "\\langle", true, "&lang;", "<", "<", ""),
("rang", "\\rangle", true, "&rang;", ">", ">", ""),
("langle", "\\langle", true, "&lang;", "<", "<", ""),
("rangle", "\\rangle", true, "&rang;", ">", ">", ""),
("hbar", "\\hbar", true, "&hbar;", "hbar", "hbar", ""),
("mho", "\\mho", true, "&mho;", "mho", "mho", ""),
// Arrows
("larr", "\\leftarrow", true, "&larr;", "<-", "<-", ""),
("leftarrow", "\\leftarrow", true, "&larr;", "<-", "<-", ""),
("gets", "\\gets", true, "&larr;", "<-", "<-", ""),
("lArr", "\\Leftarrow", true, "&lArr;", "<=", "<=", ""),
("Leftarrow", "\\Leftarrow", true, "&lArr;", "<=", "<=", ""),
("uarr", "\\uparrow", true, "&uarr;", "[uparrow]", "[uparrow]", ""),
("uparrow", "\\uparrow", true, "&uarr;", "[uparrow]", "[uparrow]", ""),
("uArr", "\\Uparrow", true, "&uArr;", "[dbluparrow]", "[dbluparrow]", ""),
("Uparrow", "\\Uparrow", true, "&uArr;", "[dbluparrow]", "[dbluparrow]", ""),
("rarr", "\\rightarrow", true, "&rarr;", "->", "->", ""),
("to", "\\to", true, "&rarr;", "->", "->", ""),
("rightarrow", "\\rightarrow", true, "&rarr;", "->", "->", ""),
("rArr", "\\Rightarrow", true, "&rArr;", "=>", "=>", ""),
("Rightarrow", "\\Rightarrow", true, "&rArr;", "=>", "=>", ""),
("darr", "\\downarrow", true, "&darr;", "[downarrow]", "[downarrow]", ""),
("downarrow", "\\downarrow", true, "&darr;", "[downarrow]", "[downarrow]", ""),
("dArr", "\\Downarrow", true, "&dArr;", "[dbldownarrow]", "[dbldownarrow]", ""),
("Downarrow", "\\Downarrow", true, "&dArr;", "[dbldownarrow]", "[dbldownarrow]", ""),
("harr", "\\leftrightarrow", true, "&harr;", "<->", "<->", ""),
("leftrightarrow", "\\leftrightarrow", true, "&harr;", "<->", "<->", ""),
("hArr", "\\Leftrightarrow", true, "&hArr;", "<=>", "<=>", ""),
("Leftrightarrow", "\\Leftrightarrow", true, "&hArr;", "<=>", "<=>", ""),
("crarr", "\\hookleftarrow", true, "&crarr;", "<-'", "<-'", ""),
("hookleftarrow", "\\hookleftarrow", true, "&crarr;", "<-'", "<-'", ""),
// Function names
("arccos", "\\arccos", true, "arccos", "arccos", "arccos", "arccos"),
("arcsin", "\\arcsin", true, "arcsin", "arcsin", "arcsin", "arcsin"),
("arctan", "\\arctan", true, "arctan", "arctan", "arctan", "arctan"),
("arg", "\\arg", true, "arg", "arg", "arg", "arg"),
("cos", "\\cos", true, "cos", "cos", "cos", "cos"),
("cosh", "\\cosh", true, "cosh", "cosh", "cosh", "cosh"),
("cot", "\\cot", true, "cot", "cot", "cot", "cot"),
("coth", "\\coth", true, "coth", "coth", "coth", "coth"),
("csc", "\\csc", true, "csc", "csc", "csc", "csc"),
("deg", "\\deg", true, "&deg;", "deg", "deg", "deg"),
("det", "\\det", true, "det", "det", "det", "det"),
("dim", "\\dim", true, "dim", "dim", "dim", "dim"),
("exp", "\\exp", true, "exp", "exp", "exp", "exp"),
("gcd", "\\gcd", true, "gcd", "gcd", "gcd", "gcd"),
("hom", "\\hom", true, "hom", "hom", "hom", "hom"),
("inf", "\\inf", true, "inf", "inf", "inf", "inf"),
("ker", "\\ker", true, "ker", "ker", "ker", "ker"),
("lg", "\\lg", true, "lg", "lg", "lg", "lg"),
("lim", "\\lim", true, "lim", "lim", "lim", "lim"),
("liminf", "\\liminf", true, "liminf", "liminf", "liminf", "liminf"),
("limsup", "\\limsup", true, "limsup", "limsup", "limsup", "limsup"),
("ln", "\\ln", true, "ln", "ln", "ln", "ln"),
("log", "\\log", true, "log", "log", "log", "log"),
("max", "\\max", true, "max", "max", "max", "max"),
("min", "\\min", true, "min", "min", "min", "min"),
("Pr", "\\Pr", true, "Pr", "Pr", "Pr", "Pr"),
("sec", "\\sec", true, "sec", "sec", "sec", "sec"),
("sin", "\\sin", true, "sin", "sin", "sin", "sin"),
("sinh", "\\sinh", true, "sinh", "sinh", "sinh", "sinh"),
("sup", "\\sup", true, "&sup;", "sup", "sup", "sup"),
("tan", "\\tan", true, "tan", "tan", "tan", "tan"),
("tanh", "\\tanh", true, "tanh", "tanh", "tanh", "tanh"),
// Signs & Symbols
("bull", "\\textbullet{}", false, "&bull;", "*", "*", ""),
("bullet", "\\textbullet{}", false, "&bull;", "*", "*", ""),
("star", "\\star", true, "*", "*", "*", ""),
("lowast", "\\ast", true, "&lowast;", "*", "*", ""),
("ast", "\\ast", true, "&lowast;", "*", "*", "*"),
("odot", "\\odot", true, "o", "[circled dot]", "[circled dot]", "ʘ"),
("oplus", "\\oplus", true, "&oplus;", "[circled plus]", "[circled plus]", ""),
("otimes", "\\otimes", true, "&otimes;", "[circled times]", "[circled times]", ""),
("check", "\\checkmark", true, "&checkmark;", "[checkmark]", "[checkmark]", ""),
("checkmark", "\\checkmark", true, "&check;", "[checkmark]", "[checkmark]", ""),
// Miscellaneous (seldom used)
("ordf", "\\textordfeminine{}", false, "&ordf;", "_a_", "ª", "ª"),
("ordm", "\\textordmasculine{}", false, "&ordm;", "_o_", "º", "º"),
("cedil", "\\c{}", false, "&cedil;", "[cedilla]", "¸", "¸"),
("oline", "\\overline{~}", true, "&oline;", "[overline]", "¯", ""),
("uml", "\\textasciidieresis{}", false, "&uml;", "[diaeresis]", "¨", "¨"),
("zwnj", "\\/{}", false, "&zwnj;", "", "", ""),
("zwj", "", false, "&zwj;", "", "", ""),
("lrm", "", false, "&lrm;", "", "", "\u{200E}"),
("rlm", "", false, "&rlm;", "", "", "\u{200F}"),
// Smilies
("smiley", "\\ddot\\smile", true, "&#9786;", ":-)", ":-)", ""),
("blacksmile", "\\ddot\\smile", true, "&#9787;", ":-)", ":-)", ""),
("sad", "\\ddot\\frown", true, "&#9785;", ":-(", ":-(", ""),
("frowny", "\\ddot\\frown", true, "&#9785;", ":-(", ":-(", ""),
// Suits
("clubs", "\\clubsuit", true, "&clubs;", "[clubs]", "[clubs]", ""),
("clubsuit", "\\clubsuit", true, "&clubs;", "[clubs]", "[clubs]", ""),
("spades", "\\spadesuit", true, "&spades;", "[spades]", "[spades]", ""),
("spadesuit", "\\spadesuit", true, "&spades;", "[spades]", "[spades]", ""),
("hearts", "\\heartsuit", true, "&hearts;", "[hearts]", "[hearts]", ""),
("heartsuit", "\\heartsuit", true, "&heartsuit;", "[hearts]", "[hearts]", ""),
("diams", "\\diamondsuit", true, "&diams;", "[diamonds]", "[diamonds]", ""),
("diamondsuit", "\\diamondsuit", true, "&diams;", "[diamonds]", "[diamonds]", ""),
("diamond", "\\diamondsuit", true, "&diamond;", "[diamond]", "[diamond]", ""),
("Diamond", "\\diamondsuit", true, "&diamond;", "[diamond]", "[diamond]", ""),
("loz", "\\lozenge", true, "&loz;", "[lozenge]", "[lozenge]", ""),
// spaces
// fish shell:
// for i in (seq 1 20)
// echo '("'(string repeat -n $i ' ')'", "\\\\hspace*{'(math '0.5*'$i)'em}", true, "'(string repeat -n $i '&ensp;')'", "'(string repeat -n $i ' ')'", "'(string repeat -n $i ' ')'", "'(string repeat -n $i '\\\\x2002')'")'
// end
(" ", "\\hspace*{0.5em}", true, "&ensp;", " ", " ", "\\x2002"),
(" ", "\\hspace*{1em}", true, "&ensp;&ensp;", " ", " ", "\\x2002\\x2002"),
(" ", "\\hspace*{1.5em}", true, "&ensp;&ensp;&ensp;", " ", " ", "\\x2002\\x2002\\x2002"),
(" ", "\\hspace*{2em}", true, "&ensp;&ensp;&ensp;&ensp;", " ", " ", "\\x2002\\x2002\\x2002\\x2002"),
(" ", "\\hspace*{2.5em}", true, "&ensp;&ensp;&ensp;&ensp;&ensp;", " ", " ", "\\x2002\\x2002\\x2002\\x2002\\x2002"),
(" ", "\\hspace*{3em}", true, "&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;", " ", " ", "\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002"),
(" ", "\\hspace*{3.5em}", true, "&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;", " ", " ", "\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002"),
(" ", "\\hspace*{4em}", true, "&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;", " ", " ", "\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002"),
(" ", "\\hspace*{4.5em}", true, "&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;", " ", " ", "\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002"),
(" ", "\\hspace*{5em}", true, "&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;", " ", " ", "\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002"),
(" ", "\\hspace*{5.5em}", true, "&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;", " ", " ", "\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002"),
(" ", "\\hspace*{6em}", true, "&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;", " ", " ", "\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002"),
(" ", "\\hspace*{6.5em}", true, "&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;", " ", " ", "\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002"),
(" ", "\\hspace*{7em}", true, "&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;", " ", " ", "\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002"),
(" ", "\\hspace*{7.5em}", true, "&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;", " ", " ", "\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002"),
(" ", "\\hspace*{8em}", true, "&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;", " ", " ", "\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002"),
(" ", "\\hspace*{8.5em}", true, "&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;", " ", " ", "\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002"),
(" ", "\\hspace*{9em}", true, "&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;", " ", " ", "\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002"),
(" ", "\\hspace*{9.5em}", true, "&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;", " ", " ", "\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002"),
(" ", "\\hspace*{10em}", true, "&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;", " ", " ", "\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002\\x2002"),
];

View file

@ -49,7 +49,7 @@
/// special_block quote_block center_block verse_block comment_block example_block export_block
/// source_block babel_call clock cookie radio_target drawer dyn_block fn_def fn_ref macros
/// snippet timestamp target fixed_width org_table org_table_row org_table_cell latex_fragment
/// latex_environment
/// latex_environment entity
/// }
/// }
///
@ -197,6 +197,9 @@ macro_rules! forward_handler {
(@method $handler:ty, latex_environment) => {
forward_handler!(@method $handler, latex_environment, WalkEvent<&$crate::ast::LatexEnvironment>);
};
(@method $handler:ty, entity) => {
forward_handler!(@method $handler, entity, WalkEvent<&$crate::ast::Entity>);
};
(@method $handler:ty, $x:ident) => {
std::compile_error!(std::concat!(std::stringify!($x), " is not a method"));
};

View file

@ -461,4 +461,12 @@ impl Traverser for HtmlExport {
ctx.skip();
}
}
#[tracing::instrument(skip(self, ctx))]
fn entity(&mut self, event: WalkEvent<&Entity>, ctx: &mut TraversalContext) {
if let WalkEvent::Enter(e) = event {
self.output += e.html();
ctx.skip();
}
}
}

View file

@ -139,6 +139,7 @@ pub trait Traverser {
LINK => traverse!(Link, link),
LATEX_FRAGMENT => traverse!(LatexFragment, latex_fragment),
LATEX_ENVIRONMENT => traverse!(LatexEnvironment, latex_environment),
ENTITY => traverse!(Entity, entity),
BLOCK_CONTENT | LIST_ITEM_CONTENT => traverse_children!(node),
@ -246,4 +247,6 @@ pub trait Traverser {
_event: WalkEvent<&LatexEnvironment>,
_ctx: &mut TraversalContext,
);
/// Called when entering or leaving `Entity` node
fn entity(&mut self, _event: WalkEvent<&Entity>, _ctx: &mut TraversalContext);
}

View file

@ -2,6 +2,7 @@
pub mod ast;
mod config;
mod entities;
pub mod export;
mod org;
mod syntax;

120
src/syntax/entity.rs Normal file
View file

@ -0,0 +1,120 @@
use nom::{
branch::alt,
bytes::complete::{tag, take_while_m_n},
character::complete::alphanumeric1,
combinator::opt,
IResult,
};
use crate::{
entities::ENTITIES,
syntax::combinator::{backslash_token, node},
SyntaxKind,
};
use super::{combinator::GreenElement, input::Input};
pub fn entity_node(input: Input) -> IResult<Input, GreenElement, ()> {
debug_assert!(input.s.starts_with('\\'));
let mut parser = alt((template1, template2));
crate::lossless_parser!(parser, input)
}
// \NAME POST or // \NAME{}
fn template1(input: Input) -> IResult<Input, GreenElement, ()> {
let (input, backslash) = backslash_token(input)?;
let (input, name) = alphanumeric1(input)?;
if ENTITIES.iter().all(|i| i.0 != name.s) {
return Err(nom::Err::Error(()));
}
let (input, brackets) = opt(tag("{}"))(input)?;
if let Some(brackets) = brackets {
return Ok((
input,
node(
SyntaxKind::ENTITY,
[backslash, name.text_token(), brackets.text_token()],
),
));
}
if let Some(post) = input.bytes().next() {
if post.is_ascii_alphabetic() {
return Err(nom::Err::Error(()));
}
}
Ok((
input,
node(SyntaxKind::ENTITY, [backslash, name.text_token()]),
))
}
// \_SPACES
fn template2(input: Input) -> IResult<Input, GreenElement, ()> {
let (input, backslash) = backslash_token(input)?;
let (input, underscore) = tag("_")(input)?;
let (input, spaces) = take_while_m_n(1, 20, |c| c == ' ')(input)?;
Ok((
input,
node(
SyntaxKind::ENTITY,
[
backslash,
underscore.token(SyntaxKind::UNDERSCORE),
spaces.text_token(),
],
),
))
}
#[test]
fn parse() {
use crate::{ast::Entity, tests::to_ast, ParseConfig};
let to_entity = to_ast::<Entity>(entity_node);
insta::assert_debug_snapshot!(
to_entity("\\cent").syntax,
@r###"
ENTITY@0..5
BACKSLASH@0..1 "\\"
TEXT@1..5 "cent"
"###
);
insta::assert_debug_snapshot!(
to_entity("\\S").syntax,
@r###"
ENTITY@0..2
BACKSLASH@0..1 "\\"
TEXT@1..2 "S"
"###
);
insta::assert_debug_snapshot!(
to_entity("\\frac12{}test").syntax,
@r###"
ENTITY@0..9
BACKSLASH@0..1 "\\"
TEXT@1..7 "frac12"
TEXT@7..9 "{}"
"###
);
insta::assert_debug_snapshot!(
to_entity("\\_ ").syntax,
@r###"
ENTITY@0..21
BACKSLASH@0..1 "\\"
UNDERSCORE@1..2 "_"
TEXT@2..21 " "
"###
);
let c = ParseConfig::default();
assert!(entity_node(("\\poi", &c).into()).is_err());
}

View file

@ -10,6 +10,7 @@ pub mod drawer;
pub mod dyn_block;
pub mod element;
pub mod emphasis;
pub mod entity;
pub mod fixed_width;
pub mod fn_def;
pub mod fn_ref;
@ -196,6 +197,7 @@ pub enum SyntaxKind {
UNDERLINE,
VERBATIM,
CODE,
ENTITY,
/* timestamp */
TIMESTAMP_ACTIVE,

View file

@ -4,6 +4,7 @@ use super::{
combinator::GreenElement,
cookie::cookie_node,
emphasis::{bold_node, code_node, italic_node, strike_node, underline_node, verbatim_node},
entity::entity_node,
fn_ref::fn_ref_node,
inline_call::inline_call_node,
inline_src::inline_src_node,
@ -41,7 +42,7 @@ impl<'a> Iterator for ObjectPositions<'a> {
type Item = (Input<'a>, Input<'a>);
fn next(&mut self) -> Option<Self::Item> {
if self.input.input_len() < 3 || self.pos >= self.input.input_len() {
if self.input.input_len() < 2 || self.pos >= self.input.input_len() {
return None;
}
@ -56,7 +57,7 @@ impl<'a> Iterator for ObjectPositions<'a> {
let p = match bytes[i] {
b'{' => {
if self.input.s.len() - self.pos > 3 {
if self.input.s.len() - self.pos > 2 {
self.next = Some(self.pos);
}
self.pos - 1
@ -73,8 +74,8 @@ impl<'a> Iterator for ObjectPositions<'a> {
self.input.s.len()
);
// a valid object requires at least three characters
if self.input.s.len() - p < 3 {
// a valid object requires at least two characters
if self.input.s.len() - p < 2 {
return None;
}
@ -92,8 +93,8 @@ pub fn object_nodes(input: Input) -> Vec<GreenElement> {
'l: while !i.is_empty() {
for (input, head) in ObjectPositions::new(i) {
debug_assert!(
input.s.len() >= 3,
"object must have at least three characters: {:?}",
input.s.len() >= 2,
"object must have at least two characters: {:?}",
input.s
);
if let Ok((input, node)) = object_node(input) {
@ -146,7 +147,7 @@ fn object_node(i: Input) -> IResult<Input, GreenElement, ()> {
b'c' => inline_call_node(i),
b's' => inline_src_node(i),
b'$' => latex_fragment_node(i),
b'\\' => latex_fragment_node(i),
b'\\' => entity_node(i).or_else(|_| latex_fragment_node(i)),
_ => Err(nom::Err::Error(())),
}
}
@ -155,9 +156,13 @@ fn object_node(i: Input) -> IResult<Input, GreenElement, ()> {
fn positions() {
let config = crate::ParseConfig::default();
let vec = ObjectPositions::new(("*{", &config).into()).collect::<Vec<_>>();
let vec = ObjectPositions::new(("*", &config).into()).collect::<Vec<_>>();
assert!(vec.is_empty());
let vec = ObjectPositions::new(("*{", &config).into()).collect::<Vec<_>>();
assert_eq!(vec.len(), 1);
assert_eq!(vec[0].0.s, "*{");
// https://github.com/PoiScript/orgize/issues/69
let vec = ObjectPositions::new(("{3}", &config).into()).collect::<Vec<_>>();
assert_eq!(vec.len(), 2);
@ -166,12 +171,13 @@ fn positions() {
assert_eq!(vec[1].0.s, "{3}");
let vec = ObjectPositions::new(("*{()}//s\nc<<", &config).into()).collect::<Vec<_>>();
assert_eq!(vec.len(), 5);
assert_eq!(vec.len(), 6);
assert_eq!(vec[0].0.s, "*{()}//s\nc<<");
assert_eq!(vec[1].0.s, "{()}//s\nc<<");
assert_eq!(vec[2].0.s, "()}//s\nc<<");
assert_eq!(vec[3].0.s, ")}//s\nc<<");
assert_eq!(vec[4].0.s, "c<<");
assert_eq!(vec[5].0.s, "<<");
}
#[test]

View file

@ -308,6 +308,11 @@ $$
a&=b+c \\\\
d+e&=f
\\end{align}
-----
Entity
\\alpha\\_ \\rightarrow{}\\_ \\beta
`);
editor.session.on("change", () => render());