From c706dce677dbcde40561c3cae373d80581c45890 Mon Sep 17 00:00:00 2001 From: blank X Date: Fri, 26 Mar 2021 01:23:21 +0700 Subject: [PATCH] Use a different html unescaper for descriptions --- Cargo.lock | 53 +- Cargo.toml | 7 +- src/main.rs | 1 + src/structs.rs | 9 +- src/unescape.rs | 1513 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 1571 insertions(+), 12 deletions(-) create mode 100644 src/unescape.rs diff --git a/Cargo.lock b/Cargo.lock index 8d08528..3119a2d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,14 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "aho-corasick" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" +dependencies = [ + "memchr", +] + [[package]] name = "async-stream" version = "0.3.0" @@ -202,10 +211,11 @@ dependencies = [ [[package]] name = "hanimers" -version = "0.1.7" +version = "0.1.8" dependencies = [ "clap", "quick-xml", + "regex", "reqwest", "serde", "serde_json", @@ -419,6 +429,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "once_cell" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" + [[package]] name = "openssl" version = "0.10.32" @@ -533,9 +549,9 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.20.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26aab6b48e2590e4a64d1ed808749ba06257882b461d01ca71baeb747074a6dd" +checksum = "8533f14c8382aaad0d592c812ac3b826162128b65662331e1127b45c3d18536b" dependencies = [ "memchr", ] @@ -598,6 +614,24 @@ dependencies = [ "bitflags", ] +[[package]] +name = "regex" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", + "thread_local", +] + +[[package]] +name = "regex-syntax" +version = "0.6.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581" + [[package]] name = "remove_dir_all" version = "0.5.3" @@ -774,6 +808,15 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "thread_local" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd" +dependencies = [ + "once_cell", +] + [[package]] name = "tinyvec" version = "1.1.1" @@ -791,9 +834,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.2.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8190d04c665ea9e6b6a0dc45523ade572c088d2e6566244c1122671dbf4ae3a" +checksum = "134af885d758d645f0f0505c9a8b3f9bf8a348fd822e112ab5248138348f1722" dependencies = [ "autocfg", "bytes", diff --git a/Cargo.toml b/Cargo.toml index 4806fb4..c785030 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hanimers" -version = "0.1.7" +version = "0.1.8" authors = ["blank X "] edition = "2018" @@ -10,9 +10,10 @@ edition = "2018" lto = true [dependencies] -tokio = { version = "1.2", features = ["rt"] } +tokio = { version = "1.4", features = ["rt"] } reqwest = "0.11" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -quick-xml = "0.20" +quick-xml = "0.22" clap = { version = "2.33", default-features = false } +regex = "1.4" diff --git a/src/main.rs b/src/main.rs index 52ee0ed..62ae4b4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ mod commands; +mod unescape; mod structs; mod utils; use clap::{App, AppSettings, Arg, SubCommand}; diff --git a/src/structs.rs b/src/structs.rs index 99add07..10dd2e1 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -5,6 +5,7 @@ use serde::de::{self, Visitor}; use serde::{Deserialize, Deserializer}; use quick_xml::Reader; use quick_xml::events::Event; +use crate::unescape::unescape; extern crate reqwest; extern crate quick_xml; extern crate serde_json; @@ -193,20 +194,20 @@ where E: de::Error { // https://brokenco.de/2020/08/03/serde-deserialize-with-string.html - let mut to_return = String::new(); - let mut reader = Reader::from_str(&value); + let mut text = String::with_capacity(value.len()); + let mut reader = Reader::from_str(value); reader.check_end_names(false); let mut buf = Vec::new(); loop { match reader.read_event(&mut buf) { - Ok(Event::Text(e)) => to_return.push_str(&e.unescape_and_decode(&reader).map_err(de::Error::custom)?), + Ok(Event::Text(e)) => text.push_str(&unescape(reader.decode(e.escaped()).map_err(serde::de::Error::custom)?)), Ok(Event::Eof) => break, Err(err) => panic!("Error at position {}: {:?}", reader.buffer_position(), err), _ => () }; buf.clear(); } - Ok(to_return) + Ok(text) } } diff --git a/src/unescape.rs b/src/unescape.rs new file mode 100644 index 0000000..24ee15c --- /dev/null +++ b/src/unescape.rs @@ -0,0 +1,1513 @@ +use std::borrow::Cow; +use regex::{RegexBuilder, Captures}; + +fn hex_char_decode(c: u8) -> u8 { + match c { + b'a'..=b'f' => c - b'a' + 10, + b'A'..=b'F' => c - b'A' + 10, + b'0'..=b'9' => c - b'0', + _ => panic!("Invalid hex character passed: {}", c) + } +} + +fn hex_to_bytes(hex: &[u8]) -> Vec { + let mut capacity = hex.len() / 2; + if capacity % 2 != 0 { + capacity += 1; + } + let mut result = Vec::with_capacity(capacity); + for chars in hex.chunks(2) { + let (left, right) = if chars.len() == 1 { + (b'0', chars[0]) + } else { + (chars[0], chars[1]) + }; + result.push(hex_char_decode(left) << 4 | hex_char_decode(right)); + } + result +} + +pub fn unescape<'t>(text: &'t str) -> Cow<'t, str> { + let regex = RegexBuilder::new("&([a-z0-9_\\-]+|#(?:x[0-9a-f]+|[0-9]+));?") + .case_insensitive(true) + .build() + .unwrap(); + regex.replace_all(text, |caps: &Captures| { + let data = caps[1].to_ascii_lowercase(); + if data.starts_with("#x") { + if let Ok(result) = String::from_utf8(hex_to_bytes(data[2..].as_bytes())) { + result + } else { + caps[0].to_string() + } + } else if data.starts_with("#") { + if let Ok(result) = String::from_utf8(vec![data[1..].parse().unwrap()]) { + result + } else { + caps[0].to_string() + } + } else { + // stolen from https://dev.w3.org/html5/html-author/charref + match data.as_str() { + "Tab" => "\t", + "NewLine" => "\n", + "excl" => "!", + "quot" | "QUOT" => "\"", + "num" => "#", + "dollar" => "$", + "percnt" => "%", + "amp" | "AMP" => "&", + "apos" => "'", + "lpar" => "(", + "rpar" => ")", + "ast" | "midast" => "*", + "plus" => "+", + "comma" => ",", + "period" => ".", + "sol" => "/", + "colon" => ":", + "semi" => ";", + "lt" | "LT" => "<", + "equals" => "=", + "gt" | "GT" => ">", + "quest" => "?", + "commat" => "@", + "lsqb" | "lbrack" => "[", + "bsol" => "\\", + "rsqb" | "rbrack" => "]", + "Hat" => "^", + "lowbar" => "_", + "grave" | "DiacriticalGrave" => "`", + "lcub" | "lbrace" => "{", + "verbar" | "vert" | "VerticalLine" => "|", + "rcub" | "rbrace" => "}", + "nbsp" | "NonBreakingSpace" => " ", + "iexcl" => "¡", + "cent" => "¢", + "pound" => "£", + "curren" => "¤", + "yen" => "¥", + "brvbar" => "¦", + "sect" => "§", + "Dot" | "die" | "DoubleDot" | "uml" => "¨", + "copy" | "COPY" => "©", + "ordf" => "ª", + "laquo" => "«", + "not" => "¬", + "shy" => "­", + "reg" | "circledR" | "REG" => "®", + "macr" | "OverBar" | "strns" => "¯", + "deg" => "°", + "plusmn" | "pm" | "PlusMinus" => "±", + "sup2" => "²", + "sup3" => "³", + "acute" | "DiacriticalAcute" => "´", + "micro" => "µ", + "para" => "¶", + "middot" | "centerdot" | "CenterDot" => "·", + "cedil" | "Cedilla" => "¸", + "sup1" => "¹", + "ordm" => "º", + "raquo" => "»", + "frac14" => "¼", + "frac12" | "half" => "½", + "frac34" => "¾", + "iquest" => "¿", + "Agrave" => "À", + "Aacute" => "Á", + "Acirc" => "Â", + "Atilde" => "Ã", + "Auml" => "Ä", + "Aring" => "Å", + "AElig" => "Æ", + "Ccedil" => "Ç", + "Egrave" => "È", + "Eacute" => "É", + "Ecirc" => "Ê", + "Euml" => "Ë", + "Igrave" => "Ì", + "Iacute" => "Í", + "Icirc" => "Î", + "Iuml" => "Ï", + "ETH" => "Ð", + "Ntilde" => "Ñ", + "Ograve" => "Ò", + "Oacute" => "Ó", + "Ocirc" => "Ô", + "Otilde" => "Õ", + "Ouml" => "Ö", + "times" => "×", + "Oslash" => "Ø", + "Ugrave" => "Ù", + "Uacute" => "Ú", + "Ucirc" => "Û", + "Uuml" => "Ü", + "Yacute" => "Ý", + "THORN" => "Þ", + "szlig" => "ß", + "agrave" => "à", + "aacute" => "á", + "acirc" => "â", + "atilde" => "ã", + "auml" => "ä", + "aring" => "å", + "aelig" => "æ", + "ccedil" => "ç", + "egrave" => "è", + "eacute" => "é", + "ecirc" => "ê", + "euml" => "ë", + "igrave" => "ì", + "iacute" => "í", + "icirc" => "î", + "iuml" => "ï", + "eth" => "ð", + "ntilde" => "ñ", + "ograve" => "ò", + "oacute" => "ó", + "ocirc" => "ô", + "otilde" => "õ", + "ouml" => "ö", + "divide" | "div" => "÷", + "oslash" => "ø", + "ugrave" => "ù", + "uacute" => "ú", + "ucirc" => "û", + "uuml" => "ü", + "yacute" => "ý", + "thorn" => "þ", + "yuml" => "ÿ", + "Amacr" => "Ā", + "amacr" => "ā", + "Abreve" => "Ă", + "abreve" => "ă", + "Aogon" => "Ą", + "aogon" => "ą", + "Cacute" => "Ć", + "cacute" => "ć", + "Ccirc" => "Ĉ", + "ccirc" => "ĉ", + "Cdot" => "Ċ", + "cdot" => "ċ", + "Ccaron" => "Č", + "ccaron" => "č", + "Dcaron" => "Ď", + "dcaron" => "ď", + "Dstrok" => "Đ", + "dstrok" => "đ", + "Emacr" => "Ē", + "emacr" => "ē", + "Edot" => "Ė", + "edot" => "ė", + "Eogon" => "Ę", + "eogon" => "ę", + "Ecaron" => "Ě", + "ecaron" => "ě", + "Gcirc" => "Ĝ", + "gcirc" => "ĝ", + "Gbreve" => "Ğ", + "gbreve" => "ğ", + "Gdot" => "Ġ", + "gdot" => "ġ", + "Gcedil" => "Ģ", + "Hcirc" => "Ĥ", + "hcirc" => "ĥ", + "Hstrok" => "Ħ", + "hstrok" => "ħ", + "Itilde" => "Ĩ", + "itilde" => "ĩ", + "Imacr" => "Ī", + "imacr" => "ī", + "Iogon" => "Į", + "iogon" => "į", + "Idot" => "İ", + "imath" | "inodot" => "ı", + "IJlig" => "IJ", + "ijlig" => "ij", + "Jcirc" => "Ĵ", + "jcirc" => "ĵ", + "Kcedil" => "Ķ", + "kcedil" => "ķ", + "kgreen" => "ĸ", + "Lacute" => "Ĺ", + "lacute" => "ĺ", + "Lcedil" => "Ļ", + "lcedil" => "ļ", + "Lcaron" => "Ľ", + "lcaron" => "ľ", + "Lmidot" => "Ŀ", + "lmidot" => "ŀ", + "Lstrok" => "Ł", + "lstrok" => "ł", + "Nacute" => "Ń", + "nacute" => "ń", + "Ncedil" => "Ņ", + "ncedil" => "ņ", + "Ncaron" => "Ň", + "ncaron" => "ň", + "napos" => "ʼn", + "ENG" => "Ŋ", + "eng" => "ŋ", + "Omacr" => "Ō", + "omacr" => "ō", + "Odblac" => "Ő", + "odblac" => "ő", + "OElig" => "Œ", + "oelig" => "œ", + "Racute" => "Ŕ", + "racute" => "ŕ", + "Rcedil" => "Ŗ", + "rcedil" => "ŗ", + "Rcaron" => "Ř", + "rcaron" => "ř", + "Sacute" => "Ś", + "sacute" => "ś", + "Scirc" => "Ŝ", + "scirc" => "ŝ", + "Scedil" => "Ş", + "scedil" => "ş", + "Scaron" => "Š", + "scaron" => "š", + "Tcedil" => "Ţ", + "tcedil" => "ţ", + "Tcaron" => "Ť", + "tcaron" => "ť", + "Tstrok" => "Ŧ", + "tstrok" => "ŧ", + "Utilde" => "Ũ", + "utilde" => "ũ", + "Umacr" => "Ū", + "umacr" => "ū", + "Ubreve" => "Ŭ", + "ubreve" => "ŭ", + "Uring" => "Ů", + "uring" => "ů", + "Udblac" => "Ű", + "udblac" => "ű", + "Uogon" => "Ų", + "uogon" => "ų", + "Wcirc" => "Ŵ", + "wcirc" => "ŵ", + "Ycirc" => "Ŷ", + "ycirc" => "ŷ", + "Yuml" => "Ÿ", + "Zacute" => "Ź", + "zacute" => "ź", + "Zdot" => "Ż", + "zdot" => "ż", + "Zcaron" => "Ž", + "zcaron" => "ž", + "fnof" => "ƒ", + "imped" => "Ƶ", + "gacute" => "ǵ", + "jmath" => "ȷ", + "circ" => "ˆ", + "caron" | "Hacek" => "ˇ", + "breve" | "Breve" => "˘", + "dot" | "DiacriticalDot" => "˙", + "ring" => "˚", + "ogon" => "˛", + "tilde" | "DiacriticalTilde" => "˜", + "dblac" | "DiacriticalDoubleAcute" => "˝", + "DownBreve" => "̑", + "UnderBar" => "̲", + "Alpha" => "Α", + "Beta" => "Β", + "Gamma" => "Γ", + "Delta" => "Δ", + "Epsilon" => "Ε", + "Zeta" => "Ζ", + "Eta" => "Η", + "Theta" => "Θ", + "Iota" => "Ι", + "Kappa" => "Κ", + "Lambda" => "Λ", + "Mu" => "Μ", + "Nu" => "Ν", + "Xi" => "Ξ", + "Omicron" => "Ο", + "Pi" => "Π", + "Rho" => "Ρ", + "Sigma" => "Σ", + "Tau" => "Τ", + "Upsilon" => "Υ", + "Phi" => "Φ", + "Chi" => "Χ", + "Psi" => "Ψ", + "Omega" => "Ω", + "alpha" => "α", + "beta" => "β", + "gamma" => "γ", + "delta" => "δ", + "epsiv" | "varepsilon" | "epsilon" => "ε", + "zeta" => "ζ", + "eta" => "η", + "theta" => "θ", + "iota" => "ι", + "kappa" => "κ", + "lambda" => "λ", + "mu" => "μ", + "nu" => "ν", + "xi" => "ξ", + "omicron" => "ο", + "pi" => "π", + "rho" => "ρ", + "sigmav" | "varsigma" | "sigmaf" => "ς", + "sigma" => "σ", + "tau" => "τ", + "upsi" | "upsilon" => "υ", + "phi" | "phiv" | "varphi" => "φ", + "chi" => "χ", + "psi" => "ψ", + "omega" => "ω", + "thetav" | "vartheta" | "thetasym" => "ϑ", + "Upsi" | "upsih" => "ϒ", + "straightphi" => "ϕ", + "piv" | "varpi" => "ϖ", + "Gammad" => "Ϝ", + "gammad" | "digamma" => "ϝ", + "kappav" | "varkappa" => "ϰ", + "rhov" | "varrho" => "ϱ", + "epsi" | "straightepsilon" => "ϵ", + "bepsi" | "backepsilon" => "϶", + "IOcy" => "Ё", + "DJcy" => "Ђ", + "GJcy" => "Ѓ", + "Jukcy" => "Є", + "DScy" => "Ѕ", + "Iukcy" => "І", + "YIcy" => "Ї", + "Jsercy" => "Ј", + "LJcy" => "Љ", + "NJcy" => "Њ", + "TSHcy" => "Ћ", + "KJcy" => "Ќ", + "Ubrcy" => "Ў", + "DZcy" => "Џ", + "Acy" => "А", + "Bcy" => "Б", + "Vcy" => "В", + "Gcy" => "Г", + "Dcy" => "Д", + "IEcy" => "Е", + "ZHcy" => "Ж", + "Zcy" => "З", + "Icy" => "И", + "Jcy" => "Й", + "Kcy" => "К", + "Lcy" => "Л", + "Mcy" => "М", + "Ncy" => "Н", + "Ocy" => "О", + "Pcy" => "П", + "Rcy" => "Р", + "Scy" => "С", + "Tcy" => "Т", + "Ucy" => "У", + "Fcy" => "Ф", + "KHcy" => "Х", + "TScy" => "Ц", + "CHcy" => "Ч", + "SHcy" => "Ш", + "SHCHcy" => "Щ", + "HARDcy" => "Ъ", + "Ycy" => "Ы", + "SOFTcy" => "Ь", + "Ecy" => "Э", + "YUcy" => "Ю", + "YAcy" => "Я", + "acy" => "а", + "bcy" => "б", + "vcy" => "в", + "gcy" => "г", + "dcy" => "д", + "iecy" => "е", + "zhcy" => "ж", + "zcy" => "з", + "icy" => "и", + "jcy" => "й", + "kcy" => "к", + "lcy" => "л", + "mcy" => "м", + "ncy" => "н", + "ocy" => "о", + "pcy" => "п", + "rcy" => "р", + "scy" => "с", + "tcy" => "т", + "ucy" => "у", + "fcy" => "ф", + "khcy" => "х", + "tscy" => "ц", + "chcy" => "ч", + "shcy" => "ш", + "shchcy" => "щ", + "hardcy" => "ъ", + "ycy" => "ы", + "softcy" => "ь", + "ecy" => "э", + "yucy" => "ю", + "yacy" => "я", + "iocy" => "ё", + "djcy" => "ђ", + "gjcy" => "ѓ", + "jukcy" => "є", + "dscy" => "ѕ", + "iukcy" => "і", + "yicy" => "ї", + "jsercy" => "ј", + "ljcy" => "љ", + "njcy" => "њ", + "tshcy" => "ћ", + "kjcy" => "ќ", + "ubrcy" => "ў", + "dzcy" => "џ", + "ensp" => " ", + "emsp" => " ", + "emsp13" => " ", + "emsp14" => " ", + "numsp" => " ", + "puncsp" => " ", + "thinsp" | "ThinSpace" => " ", + "hairsp" | "VeryThinSpace" => " ", + "ZeroWidthSpace" | "NegativeVeryThinSpace" | "NegativeThinSpace" | "NegativeMediumSpace" | "NegativeThickSpace" => "​", + "zwnj" => "‌", + "zwj" => "‍", + "lrm" => "‎", + "rlm" => "‏", + "hyphen" | "dash" => "‐", + "ndash" => "–", + "mdash" => "—", + "horbar" => "―", + "Verbar" | "Vert" => "‖", + "lsquo" | "OpenCurlyQuote" => "‘", + "rsquo" | "rsquor" | "CloseCurlyQuote" => "’", + "lsquor" | "sbquo" => "‚", + "ldquo" | "OpenCurlyDoubleQuote" => "“", + "rdquo" | "rdquor" | "CloseCurlyDoubleQuote" => "”", + "ldquor" | "bdquo" => "„", + "dagger" => "†", + "Dagger" | "ddagger" => "‡", + "bull" | "bullet" => "•", + "nldr" => "‥", + "hellip" | "mldr" => "…", + "permil" => "‰", + "pertenk" => "‱", + "prime" => "′", + "Prime" => "″", + "tprime" => "‴", + "bprime" | "backprime" => "‵", + "lsaquo" => "‹", + "rsaquo" => "›", + "oline" => "‾", + "caret" => "⁁", + "hybull" => "⁃", + "frasl" => "⁄", + "bsemi" => "⁏", + "qprime" => "⁗", + "MediumSpace" => " ", + "NoBreak" => "⁠", + "ApplyFunction" | "af" => "⁡", + "InvisibleTimes" | "it" => "⁢", + "InvisibleComma" | "ic" => "⁣", + "euro" => "€", + "tdot" | "TripleDot" => "⃛", + "DotDot" => "⃜", + "Copf" | "complexes" => "ℂ", + "incare" => "℅", + "gscr" => "ℊ", + "hamilt" | "HilbertSpace" | "Hscr" => "ℋ", + "Hfr" | "Poincareplane" => "ℌ", + "quaternions" | "Hopf" => "ℍ", + "planckh" => "ℎ", + "planck" | "hbar" | "plankv" | "hslash" => "ℏ", + "Iscr" | "imagline" => "ℐ", + "image" | "Im" | "imagpart" | "Ifr" => "ℑ", + "Lscr" | "lagran" | "Laplacetrf" => "ℒ", + "ell" => "ℓ", + "Nopf" | "naturals" => "ℕ", + "numero" => "№", + "copysr" => "℗", + "weierp" | "wp" => "℘", + "Popf" | "primes" => "ℙ", + "rationals" | "Qopf" => "ℚ", + "Rscr" | "realine" => "ℛ", + "real" | "Re" | "realpart" | "Rfr" => "ℜ", + "reals" | "Ropf" => "ℝ", + "rx" => "℞", + "trade" | "TRADE" => "™", + "integers" | "Zopf" => "ℤ", + "ohm" => "Ω", + "mho" => "℧", + "Zfr" | "zeetrf" => "ℨ", + "iiota" => "℩", + "angst" => "Å", + "bernou" | "Bernoullis" | "Bscr" => "ℬ", + "Cfr" | "Cayleys" => "ℭ", + "escr" => "ℯ", + "Escr" | "expectation" => "ℰ", + "Fscr" | "Fouriertrf" => "ℱ", + "phmmat" | "Mellintrf" | "Mscr" => "ℳ", + "order" | "orderof" | "oscr" => "ℴ", + "alefsym" | "aleph" => "ℵ", + "beth" => "ℶ", + "gimel" => "ℷ", + "daleth" => "ℸ", + "CapitalDifferentialD" | "DD" => "ⅅ", + "DifferentialD" | "dd" => "ⅆ", + "ExponentialE" | "exponentiale" | "ee" => "ⅇ", + "ImaginaryI" | "ii" => "ⅈ", + "frac13" => "⅓", + "frac23" => "⅔", + "frac15" => "⅕", + "frac25" => "⅖", + "frac35" => "⅗", + "frac45" => "⅘", + "frac16" => "⅙", + "frac56" => "⅚", + "frac18" => "⅛", + "frac38" => "⅜", + "frac58" => "⅝", + "frac78" => "⅞", + "larr" | "leftarrow" | "LeftArrow" | "slarr" | "ShortLeftArrow" => "←", + "uarr" | "uparrow" | "UpArrow" | "ShortUpArrow" => "↑", + "rarr" | "rightarrow" | "RightArrow" | "srarr" | "ShortRightArrow" => "→", + "darr" | "downarrow" | "DownArrow" | "ShortDownArrow" => "↓", + "harr" | "leftrightarrow" | "LeftRightArrow" => "↔", + "varr" | "updownarrow" | "UpDownArrow" => "↕", + "nwarr" | "UpperLeftArrow" | "nwarrow" => "↖", + "nearr" | "UpperRightArrow" | "nearrow" => "↗", + "searr" | "searrow" | "LowerRightArrow" => "↘", + "swarr" | "swarrow" | "LowerLeftArrow" => "↙", + "nlarr" | "nleftarrow" => "↚", + "nrarr" | "nrightarrow" => "↛", + "rarrw" | "rightsquigarrow" => "↝", + "Larr" | "twoheadleftarrow" => "↞", + "Uarr" => "↟", + "Rarr" | "twoheadrightarrow" => "↠", + "Darr" => "↡", + "larrtl" | "leftarrowtail" => "↢", + "rarrtl" | "rightarrowtail" => "↣", + "LeftTeeArrow" | "mapstoleft" => "↤", + "UpTeeArrow" | "mapstoup" => "↥", + "map" | "RightTeeArrow" | "mapsto" => "↦", + "DownTeeArrow" | "mapstodown" => "↧", + "larrhk" | "hookleftarrow" => "↩", + "rarrhk" | "hookrightarrow" => "↪", + "larrlp" | "looparrowleft" => "↫", + "rarrlp" | "looparrowright" => "↬", + "harrw" | "leftrightsquigarrow" => "↭", + "nharr" | "nleftrightarrow" => "↮", + "lsh" | "Lsh" => "↰", + "rsh" | "Rsh" => "↱", + "ldsh" => "↲", + "rdsh" => "↳", + "crarr" => "↵", + "cularr" | "curvearrowleft" => "↶", + "curarr" | "curvearrowright" => "↷", + "olarr" | "circlearrowleft" => "↺", + "orarr" | "circlearrowright" => "↻", + "lharu" | "LeftVector" | "leftharpoonup" => "↼", + "lhard" | "leftharpoondown" | "DownLeftVector" => "↽", + "uharr" | "upharpoonright" | "RightUpVector" => "↾", + "uharl" | "upharpoonleft" | "LeftUpVector" => "↿", + "rharu" | "RightVector" | "rightharpoonup" => "⇀", + "rhard" | "rightharpoondown" | "DownRightVector" => "⇁", + "dharr" | "RightDownVector" | "downharpoonright" => "⇂", + "dharl" | "LeftDownVector" | "downharpoonleft" => "⇃", + "rlarr" | "rightleftarrows" | "RightArrowLeftArrow" => "⇄", + "udarr" | "UpArrowDownArrow" => "⇅", + "lrarr" | "leftrightarrows" | "LeftArrowRightArrow" => "⇆", + "llarr" | "leftleftarrows" => "⇇", + "uuarr" | "upuparrows" => "⇈", + "rrarr" | "rightrightarrows" => "⇉", + "ddarr" | "downdownarrows" => "⇊", + "lrhar" | "ReverseEquilibrium" | "leftrightharpoons" => "⇋", + "rlhar" | "rightleftharpoons" | "Equilibrium" => "⇌", + "nlArr" | "nLeftarrow" => "⇍", + "nhArr" | "nLeftrightarrow" => "⇎", + "nrArr" | "nRightarrow" => "⇏", + "lArr" | "Leftarrow" | "DoubleLeftArrow" => "⇐", + "uArr" | "Uparrow" | "DoubleUpArrow" => "⇑", + "rArr" | "Rightarrow" | "Implies" | "DoubleRightArrow" => "⇒", + "dArr" | "Downarrow" | "DoubleDownArrow" => "⇓", + "hArr" | "Leftrightarrow" | "DoubleLeftRightArrow" | "iff" => "⇔", + "vArr" | "Updownarrow" | "DoubleUpDownArrow" => "⇕", + "nwArr" => "⇖", + "neArr" => "⇗", + "seArr" => "⇘", + "swArr" => "⇙", + "lAarr" | "Lleftarrow" => "⇚", + "rAarr" | "Rrightarrow" => "⇛", + "zigrarr" => "⇝", + "larrb" | "LeftArrowBar" => "⇤", + "rarrb" | "RightArrowBar" => "⇥", + "duarr" | "DownArrowUpArrow" => "⇵", + "loarr" => "⇽", + "roarr" => "⇾", + "hoarr" => "⇿", + "forall" | "ForAll" => "∀", + "comp" | "complement" => "∁", + "part" | "PartialD" => "∂", + "exist" | "Exists" => "∃", + "nexist" | "NotExists" | "nexists" => "∄", + "empty" | "emptyset" | "emptyv" | "varnothing" => "∅", + "nabla" | "Del" => "∇", + "isin" | "isinv" | "Element" | "in" => "∈", + "notin" | "NotElement" | "notinva" => "∉", + "niv" | "ReverseElement" | "ni" | "SuchThat" => "∋", + "notni" | "notniva" | "NotReverseElement" => "∌", + "prod" | "Product" => "∏", + "coprod" | "Coproduct" => "∐", + "sum" | "Sum" => "∑", + "minus" => "−", + "mnplus" | "mp" | "MinusPlus" => "∓", + "plusdo" | "dotplus" => "∔", + "setmn" | "setminus" | "Backslash" | "ssetmn" | "smallsetminus" => "∖", + "lowast" => "∗", + "compfn" | "SmallCircle" => "∘", + "radic" | "Sqrt" => "√", + "prop" | "propto" | "Proportional" | "vprop" | "varpropto" => "∝", + "infin" => "∞", + "angrt" => "∟", + "ang" | "angle" => "∠", + "angmsd" | "measuredangle" => "∡", + "angsph" => "∢", + "mid" | "VerticalBar" | "smid" | "shortmid" => "∣", + "nmid" | "NotVerticalBar" | "nsmid" | "nshortmid" => "∤", + "par" | "parallel" | "DoubleVerticalBar" | "spar" | "shortparallel" => "∥", + "npar" | "nparallel" | "NotDoubleVerticalBar" | "nspar" | "nshortparallel" => "∦", + "and" | "wedge" => "∧", + "or" | "vee" => "∨", + "cap" => "∩", + "cup" => "∪", + "int" | "Integral" => "∫", + "Int" => "∬", + "tint" | "iiint" => "∭", + "conint" | "oint" | "ContourIntegral" => "∮", + "Conint" | "DoubleContourIntegral" => "∯", + "Cconint" => "∰", + "cwint" => "∱", + "cwconint" | "ClockwiseContourIntegral" => "∲", + "awconint" | "CounterClockwiseContourIntegral" => "∳", + "there4" | "therefore" | "Therefore" => "∴", + "becaus" | "because" | "Because" => "∵", + "ratio" => "∶", + "Colon" | "Proportion" => "∷", + "minusd" | "dotminus" => "∸", + "mDDot" => "∺", + "homtht" => "∻", + "sim" | "Tilde" | "thksim" | "thicksim" => "∼", + "bsim" | "backsim" => "∽", + "ac" | "mstpos" => "∾", + "acd" => "∿", + "wreath" | "VerticalTilde" | "wr" => "≀", + "nsim" | "NotTilde" => "≁", + "esim" | "EqualTilde" | "eqsim" => "≂", + "sime" | "TildeEqual" | "simeq" => "≃", + "nsime" | "nsimeq" | "NotTildeEqual" => "≄", + "cong" | "TildeFullEqual" => "≅", + "simne" => "≆", + "ncong" | "NotTildeFullEqual" => "≇", + "asymp" | "ap" | "TildeTilde" | "approx" | "thkap" | "thickapprox" => "≈", + "nap" | "NotTildeTilde" | "napprox" => "≉", + "ape" | "approxeq" => "≊", + "apid" => "≋", + "bcong" | "backcong" => "≌", + "asympeq" | "CupCap" => "≍", + "bump" | "HumpDownHump" | "Bumpeq" => "≎", + "bumpe" | "HumpEqual" | "bumpeq" => "≏", + "esdot" | "DotEqual" | "doteq" => "≐", + "eDot" | "doteqdot" => "≑", + "efDot" | "fallingdotseq" => "≒", + "erDot" | "risingdotseq" => "≓", + "colone" | "coloneq" | "Assign" => "≔", + "ecolon" | "eqcolon" => "≕", + "ecir" | "eqcirc" => "≖", + "cire" | "circeq" => "≗", + "wedgeq" => "≙", + "veeeq" => "≚", + "trie" | "triangleq" => "≜", + "equest" | "questeq" => "≟", + "ne" | "NotEqual" => "≠", + "equiv" | "Congruent" => "≡", + "nequiv" | "NotCongruent" => "≢", + "le" | "leq" => "≤", + "ge" | "GreaterEqual" | "geq" => "≥", + "lE" | "LessFullEqual" | "leqq" => "≦", + "gE" | "GreaterFullEqual" | "geqq" => "≧", + "lnE" | "lneqq" => "≨", + "gnE" | "gneqq" => "≩", + "Lt" | "NestedLessLess" | "ll" => "≪", + "Gt" | "NestedGreaterGreater" | "gg" => "≫", + "twixt" | "between" => "≬", + "NotCupCap" => "≭", + "nlt" | "NotLess" | "nless" => "≮", + "ngt" | "NotGreater" | "ngtr" => "≯", + "nle" | "NotLessEqual" | "nleq" => "≰", + "nge" | "NotGreaterEqual" | "ngeq" => "≱", + "lsim" | "LessTilde" | "lesssim" => "≲", + "gsim" | "gtrsim" | "GreaterTilde" => "≳", + "nlsim" | "NotLessTilde" => "≴", + "ngsim" | "NotGreaterTilde" => "≵", + "lg" | "lessgtr" | "LessGreater" => "≶", + "gl" | "gtrless" | "GreaterLess" => "≷", + "ntlg" | "NotLessGreater" => "≸", + "ntgl" | "NotGreaterLess" => "≹", + "pr" | "Precedes" | "prec" => "≺", + "sc" | "Succeeds" | "succ" => "≻", + "prcue" | "PrecedesSlantEqual" | "preccurlyeq" => "≼", + "sccue" | "SucceedsSlantEqual" | "succcurlyeq" => "≽", + "prsim" | "precsim" | "PrecedesTilde" => "≾", + "scsim" | "succsim" | "SucceedsTilde" => "≿", + "npr" | "nprec" | "NotPrecedes" => "⊀", + "nsc" | "nsucc" | "NotSucceeds" => "⊁", + "sub" | "subset" => "⊂", + "sup" | "supset" | "Superset" => "⊃", + "nsub" => "⊄", + "nsup" => "⊅", + "sube" | "SubsetEqual" | "subseteq" => "⊆", + "supe" | "supseteq" | "SupersetEqual" => "⊇", + "nsube" | "nsubseteq" | "NotSubsetEqual" => "⊈", + "nsupe" | "nsupseteq" | "NotSupersetEqual" => "⊉", + "subne" | "subsetneq" => "⊊", + "supne" | "supsetneq" => "⊋", + "cupdot" => "⊍", + "uplus" | "UnionPlus" => "⊎", + "sqsub" | "SquareSubset" | "sqsubset" => "⊏", + "sqsup" | "SquareSuperset" | "sqsupset" => "⊐", + "sqsube" | "SquareSubsetEqual" | "sqsubseteq" => "⊑", + "sqsupe" | "SquareSupersetEqual" | "sqsupseteq" => "⊒", + "sqcap" | "SquareIntersection" => "⊓", + "sqcup" | "SquareUnion" => "⊔", + "oplus" | "CirclePlus" => "⊕", + "ominus" | "CircleMinus" => "⊖", + "otimes" | "CircleTimes" => "⊗", + "osol" => "⊘", + "odot" | "CircleDot" => "⊙", + "ocir" | "circledcirc" => "⊚", + "oast" | "circledast" => "⊛", + "odash" | "circleddash" => "⊝", + "plusb" | "boxplus" => "⊞", + "minusb" | "boxminus" => "⊟", + "timesb" | "boxtimes" => "⊠", + "sdotb" | "dotsquare" => "⊡", + "vdash" | "RightTee" => "⊢", + "dashv" | "LeftTee" => "⊣", + "top" | "DownTee" => "⊤", + "bottom" | "bot" | "perp" | "UpTee" => "⊥", + "models" => "⊧", + "vDash" | "DoubleRightTee" => "⊨", + "Vdash" => "⊩", + "Vvdash" => "⊪", + "VDash" => "⊫", + "nvdash" => "⊬", + "nvDash" => "⊭", + "nVdash" => "⊮", + "nVDash" => "⊯", + "prurel" => "⊰", + "vltri" | "vartriangleleft" | "LeftTriangle" => "⊲", + "vrtri" | "vartriangleright" | "RightTriangle" => "⊳", + "ltrie" | "trianglelefteq" | "LeftTriangleEqual" => "⊴", + "rtrie" | "trianglerighteq" | "RightTriangleEqual" => "⊵", + "origof" => "⊶", + "imof" => "⊷", + "mumap" | "multimap" => "⊸", + "hercon" => "⊹", + "intcal" | "intercal" => "⊺", + "veebar" => "⊻", + "barvee" => "⊽", + "angrtvb" => "⊾", + "lrtri" => "⊿", + "xwedge" | "Wedge" | "bigwedge" => "⋀", + "xvee" | "Vee" | "bigvee" => "⋁", + "xcap" | "Intersection" | "bigcap" => "⋂", + "xcup" | "Union" | "bigcup" => "⋃", + "diam" | "diamond" | "Diamond" => "⋄", + "sdot" => "⋅", + "sstarf" | "Star" => "⋆", + "divonx" | "divideontimes" => "⋇", + "bowtie" => "⋈", + "ltimes" => "⋉", + "rtimes" => "⋊", + "lthree" | "leftthreetimes" => "⋋", + "rthree" | "rightthreetimes" => "⋌", + "bsime" | "backsimeq" => "⋍", + "cuvee" | "curlyvee" => "⋎", + "cuwed" | "curlywedge" => "⋏", + "Sub" | "Subset" => "⋐", + "Sup" | "Supset" => "⋑", + "Cap" => "⋒", + "Cup" => "⋓", + "fork" | "pitchfork" => "⋔", + "epar" => "⋕", + "ltdot" | "lessdot" => "⋖", + "gtdot" | "gtrdot" => "⋗", + "Ll" => "⋘", + "Gg" | "ggg" => "⋙", + "leg" | "LessEqualGreater" | "lesseqgtr" => "⋚", + "gel" | "gtreqless" | "GreaterEqualLess" => "⋛", + "cuepr" | "curlyeqprec" => "⋞", + "cuesc" | "curlyeqsucc" => "⋟", + "nprcue" | "NotPrecedesSlantEqual" => "⋠", + "nsccue" | "NotSucceedsSlantEqual" => "⋡", + "nsqsube" | "NotSquareSubsetEqual" => "⋢", + "nsqsupe" | "NotSquareSupersetEqual" => "⋣", + "lnsim" => "⋦", + "gnsim" => "⋧", + "prnsim" | "precnsim" => "⋨", + "scnsim" | "succnsim" => "⋩", + "nltri" | "ntriangleleft" | "NotLeftTriangle" => "⋪", + "nrtri" | "ntriangleright" | "NotRightTriangle" => "⋫", + "nltrie" | "ntrianglelefteq" | "NotLeftTriangleEqual" => "⋬", + "nrtrie" | "ntrianglerighteq" | "NotRightTriangleEqual" => "⋭", + "vellip" => "⋮", + "ctdot" => "⋯", + "utdot" => "⋰", + "dtdot" => "⋱", + "disin" => "⋲", + "isinsv" => "⋳", + "isins" => "⋴", + "isindot" => "⋵", + "notinvc" => "⋶", + "notinvb" => "⋷", + "isinE" => "⋹", + "nisd" => "⋺", + "xnis" => "⋻", + "nis" => "⋼", + "notnivc" => "⋽", + "notnivb" => "⋾", + "barwed" | "barwedge" => "⌅", + "Barwed" | "doublebarwedge" => "⌆", + "lceil" | "LeftCeiling" => "⌈", + "rceil" | "RightCeiling" => "⌉", + "lfloor" | "LeftFloor" => "⌊", + "rfloor" | "RightFloor" => "⌋", + "drcrop" => "⌌", + "dlcrop" => "⌍", + "urcrop" => "⌎", + "ulcrop" => "⌏", + "bnot" => "⌐", + "profline" => "⌒", + "profsurf" => "⌓", + "telrec" => "⌕", + "target" => "⌖", + "ulcorn" | "ulcorner" => "⌜", + "urcorn" | "urcorner" => "⌝", + "dlcorn" | "llcorner" => "⌞", + "drcorn" | "lrcorner" => "⌟", + "frown" | "sfrown" => "⌢", + "smile" | "ssmile" => "⌣", + "cylcty" => "⌭", + "profalar" => "⌮", + "topbot" => "⌶", + "ovbar" => "⌽", + "solbar" => "⌿", + "angzarr" => "⍼", + "lmoust" | "lmoustache" => "⎰", + "rmoust" | "rmoustache" => "⎱", + "tbrk" | "OverBracket" => "⎴", + "bbrk" | "UnderBracket" => "⎵", + "bbrktbrk" => "⎶", + "OverParenthesis" => "⏜", + "UnderParenthesis" => "⏝", + "OverBrace" => "⏞", + "UnderBrace" => "⏟", + "trpezium" => "⏢", + "elinters" => "⏧", + "blank" => "␣", + "oS" | "circledS" => "Ⓢ", + "boxh" | "HorizontalLine" => "─", + "boxv" => "│", + "boxdr" => "┌", + "boxdl" => "┐", + "boxur" => "└", + "boxul" => "┘", + "boxvr" => "├", + "boxvl" => "┤", + "boxhd" => "┬", + "boxhu" => "┴", + "boxvh" => "┼", + "boxH" => "═", + "boxV" => "║", + "boxdR" => "╒", + "boxDr" => "╓", + "boxDR" => "╔", + "boxdL" => "╕", + "boxDl" => "╖", + "boxDL" => "╗", + "boxuR" => "╘", + "boxUr" => "╙", + "boxUR" => "╚", + "boxuL" => "╛", + "boxUl" => "╜", + "boxUL" => "╝", + "boxvR" => "╞", + "boxVr" => "╟", + "boxVR" => "╠", + "boxvL" => "╡", + "boxVl" => "╢", + "boxVL" => "╣", + "boxHd" => "╤", + "boxhD" => "╥", + "boxHD" => "╦", + "boxHu" => "╧", + "boxhU" => "╨", + "boxHU" => "╩", + "boxvH" => "╪", + "boxVh" => "╫", + "boxVH" => "╬", + "uhblk" => "▀", + "lhblk" => "▄", + "block" => "█", + "blk14" => "░", + "blk12" => "▒", + "blk34" => "▓", + "squ" | "square" | "Square" => "□", + "squf" | "squarf" | "blacksquare" | "FilledVerySmallSquare" => "▪", + "EmptyVerySmallSquare" => "▫", + "rect" => "▭", + "marker" => "▮", + "fltns" => "▱", + "xutri" | "bigtriangleup" => "△", + "utrif" | "blacktriangle" => "▴", + "utri" | "triangle" => "▵", + "rtrif" | "blacktriangleright" => "▸", + "rtri" | "triangleright" => "▹", + "xdtri" | "bigtriangledown" => "▽", + "dtrif" | "blacktriangledown" => "▾", + "dtri" | "triangledown" => "▿", + "ltrif" | "blacktriangleleft" => "◂", + "ltri" | "triangleleft" => "◃", + "loz" | "lozenge" => "◊", + "cir" => "○", + "tridot" => "◬", + "xcirc" | "bigcirc" => "◯", + "ultri" => "◸", + "urtri" => "◹", + "lltri" => "◺", + "EmptySmallSquare" => "◻", + "FilledSmallSquare" => "◼", + "starf" | "bigstar" => "★", + "star" => "☆", + "phone" => "☎", + "female" => "♀", + "male" => "♂", + "spades" | "spadesuit" => "♠", + "clubs" | "clubsuit" => "♣", + "hearts" | "heartsuit" => "♥", + "diams" | "diamondsuit" => "♦", + "sung" => "♪", + "flat" => "♭", + "natur" | "natural" => "♮", + "sharp" => "♯", + "check" | "checkmark" => "✓", + "cross" => "✗", + "malt" | "maltese" => "✠", + "sext" => "✶", + "VerticalSeparator" => "❘", + "lbbrk" => "❲", + "rbbrk" => "❳", + "lobrk" | "LeftDoubleBracket" => "⟦", + "robrk" | "RightDoubleBracket" => "⟧", + "lang" | "LeftAngleBracket" | "langle" => "⟨", + "rang" | "RightAngleBracket" | "rangle" => "⟩", + "Lang" => "⟪", + "Rang" => "⟫", + "loang" => "⟬", + "roang" => "⟭", + "xlarr" | "longleftarrow" | "LongLeftArrow" => "⟵", + "xrarr" | "longrightarrow" | "LongRightArrow" => "⟶", + "xharr" | "longleftrightarrow" | "LongLeftRightArrow" => "⟷", + "xlArr" | "Longleftarrow" | "DoubleLongLeftArrow" => "⟸", + "xrArr" | "Longrightarrow" | "DoubleLongRightArrow" => "⟹", + "xhArr" | "Longleftrightarrow" | "DoubleLongLeftRightArrow" => "⟺", + "xmap" | "longmapsto" => "⟼", + "dzigrarr" => "⟿", + "nvlArr" => "⤂", + "nvrArr" => "⤃", + "nvHarr" => "⤄", + "Map" => "⤅", + "lbarr" => "⤌", + "rbarr" | "bkarow" => "⤍", + "lBarr" => "⤎", + "rBarr" | "dbkarow" => "⤏", + "RBarr" | "drbkarow" => "⤐", + "DDotrahd" => "⤑", + "UpArrowBar" => "⤒", + "DownArrowBar" => "⤓", + "Rarrtl" => "⤖", + "latail" => "⤙", + "ratail" => "⤚", + "lAtail" => "⤛", + "rAtail" => "⤜", + "larrfs" => "⤝", + "rarrfs" => "⤞", + "larrbfs" => "⤟", + "rarrbfs" => "⤠", + "nwarhk" => "⤣", + "nearhk" => "⤤", + "searhk" | "hksearow" => "⤥", + "swarhk" | "hkswarow" => "⤦", + "nwnear" => "⤧", + "nesear" | "toea" => "⤨", + "seswar" | "tosa" => "⤩", + "swnwar" => "⤪", + "rarrc" => "⤳", + "cudarrr" => "⤵", + "ldca" => "⤶", + "rdca" => "⤷", + "cudarrl" => "⤸", + "larrpl" => "⤹", + "curarrm" => "⤼", + "cularrp" => "⤽", + "rarrpl" => "⥅", + "harrcir" => "⥈", + "Uarrocir" => "⥉", + "lurdshar" => "⥊", + "ldrushar" => "⥋", + "LeftRightVector" => "⥎", + "RightUpDownVector" => "⥏", + "DownLeftRightVector" => "⥐", + "LeftUpDownVector" => "⥑", + "LeftVectorBar" => "⥒", + "RightVectorBar" => "⥓", + "RightUpVectorBar" => "⥔", + "RightDownVectorBar" => "⥕", + "DownLeftVectorBar" => "⥖", + "DownRightVectorBar" => "⥗", + "LeftUpVectorBar" => "⥘", + "LeftDownVectorBar" => "⥙", + "LeftTeeVector" => "⥚", + "RightTeeVector" => "⥛", + "RightUpTeeVector" => "⥜", + "RightDownTeeVector" => "⥝", + "DownLeftTeeVector" => "⥞", + "DownRightTeeVector" => "⥟", + "LeftUpTeeVector" => "⥠", + "LeftDownTeeVector" => "⥡", + "lHar" => "⥢", + "uHar" => "⥣", + "rHar" => "⥤", + "dHar" => "⥥", + "luruhar" => "⥦", + "ldrdhar" => "⥧", + "ruluhar" => "⥨", + "rdldhar" => "⥩", + "lharul" => "⥪", + "llhard" => "⥫", + "rharul" => "⥬", + "lrhard" => "⥭", + "udhar" | "UpEquilibrium" => "⥮", + "duhar" | "ReverseUpEquilibrium" => "⥯", + "RoundImplies" => "⥰", + "erarr" => "⥱", + "simrarr" => "⥲", + "larrsim" => "⥳", + "rarrsim" => "⥴", + "rarrap" => "⥵", + "ltlarr" => "⥶", + "gtrarr" => "⥸", + "subrarr" => "⥹", + "suplarr" => "⥻", + "lfisht" => "⥼", + "rfisht" => "⥽", + "ufisht" => "⥾", + "dfisht" => "⥿", + "lopar" => "⦅", + "ropar" => "⦆", + "lbrke" => "⦋", + "rbrke" => "⦌", + "lbrkslu" => "⦍", + "rbrksld" => "⦎", + "lbrksld" => "⦏", + "rbrkslu" => "⦐", + "langd" => "⦑", + "rangd" => "⦒", + "lparlt" => "⦓", + "rpargt" => "⦔", + "gtlPar" => "⦕", + "ltrPar" => "⦖", + "vzigzag" => "⦚", + "vangrt" => "⦜", + "angrtvbd" => "⦝", + "ange" => "⦤", + "range" => "⦥", + "dwangle" => "⦦", + "uwangle" => "⦧", + "angmsdaa" => "⦨", + "angmsdab" => "⦩", + "angmsdac" => "⦪", + "angmsdad" => "⦫", + "angmsdae" => "⦬", + "angmsdaf" => "⦭", + "angmsdag" => "⦮", + "angmsdah" => "⦯", + "bemptyv" => "⦰", + "demptyv" => "⦱", + "cemptyv" => "⦲", + "raemptyv" => "⦳", + "laemptyv" => "⦴", + "ohbar" => "⦵", + "omid" => "⦶", + "opar" => "⦷", + "operp" => "⦹", + "olcross" => "⦻", + "odsold" => "⦼", + "olcir" => "⦾", + "ofcir" => "⦿", + "olt" => "⧀", + "ogt" => "⧁", + "cirscir" => "⧂", + "cirE" => "⧃", + "solb" => "⧄", + "bsolb" => "⧅", + "boxbox" => "⧉", + "trisb" => "⧍", + "rtriltri" => "⧎", + "LeftTriangleBar" => "⧏", + "RightTriangleBar" => "⧐", + "race" => "⧚", + "iinfin" => "⧜", + "infintie" => "⧝", + "nvinfin" => "⧞", + "eparsl" => "⧣", + "smeparsl" => "⧤", + "eqvparsl" => "⧥", + "lozf" | "blacklozenge" => "⧫", + "RuleDelayed" => "⧴", + "dsol" => "⧶", + "xodot" | "bigodot" => "⨀", + "xoplus" | "bigoplus" => "⨁", + "xotime" | "bigotimes" => "⨂", + "xuplus" | "biguplus" => "⨄", + "xsqcup" | "bigsqcup" => "⨆", + "qint" | "iiiint" => "⨌", + "fpartint" => "⨍", + "cirfnint" => "⨐", + "awint" => "⨑", + "rppolint" => "⨒", + "scpolint" => "⨓", + "npolint" => "⨔", + "pointint" => "⨕", + "quatint" => "⨖", + "intlarhk" => "⨗", + "pluscir" => "⨢", + "plusacir" => "⨣", + "simplus" => "⨤", + "plusdu" => "⨥", + "plussim" => "⨦", + "plustwo" => "⨧", + "mcomma" => "⨩", + "minusdu" => "⨪", + "loplus" => "⨭", + "roplus" => "⨮", + "Cross" => "⨯", + "timesd" => "⨰", + "timesbar" => "⨱", + "smashp" => "⨳", + "lotimes" => "⨴", + "rotimes" => "⨵", + "otimesas" => "⨶", + "Otimes" => "⨷", + "odiv" => "⨸", + "triplus" => "⨹", + "triminus" => "⨺", + "tritime" => "⨻", + "iprod" | "intprod" => "⨼", + "amalg" => "⨿", + "capdot" => "⩀", + "ncup" => "⩂", + "ncap" => "⩃", + "capand" => "⩄", + "cupor" => "⩅", + "cupcap" => "⩆", + "capcup" => "⩇", + "cupbrcap" => "⩈", + "capbrcup" => "⩉", + "cupcup" => "⩊", + "capcap" => "⩋", + "ccups" => "⩌", + "ccaps" => "⩍", + "ccupssm" => "⩐", + "And" => "⩓", + "Or" => "⩔", + "andand" => "⩕", + "oror" => "⩖", + "orslope" => "⩗", + "andslope" => "⩘", + "andv" => "⩚", + "orv" => "⩛", + "andd" => "⩜", + "ord" => "⩝", + "wedbar" => "⩟", + "sdote" => "⩦", + "simdot" => "⩪", + "congdot" => "⩭", + "easter" => "⩮", + "apacir" => "⩯", + "apE" => "⩰", + "eplus" => "⩱", + "pluse" => "⩲", + "Esim" => "⩳", + "Colone" => "⩴", + "Equal" => "⩵", + "eDDot" | "ddotseq" => "⩷", + "equivDD" => "⩸", + "ltcir" => "⩹", + "gtcir" => "⩺", + "ltquest" => "⩻", + "gtquest" => "⩼", + "les" | "LessSlantEqual" | "leqslant" => "⩽", + "ges" | "GreaterSlantEqual" | "geqslant" => "⩾", + "lesdot" => "⩿", + "gesdot" => "⪀", + "lesdoto" => "⪁", + "gesdoto" => "⪂", + "lesdotor" => "⪃", + "gesdotol" => "⪄", + "lap" | "lessapprox" => "⪅", + "gap" | "gtrapprox" => "⪆", + "lne" | "lneq" => "⪇", + "gne" | "gneq" => "⪈", + "lnap" | "lnapprox" => "⪉", + "gnap" | "gnapprox" => "⪊", + "lEg" | "lesseqqgtr" => "⪋", + "gEl" | "gtreqqless" => "⪌", + "lsime" => "⪍", + "gsime" => "⪎", + "lsimg" => "⪏", + "gsiml" => "⪐", + "lgE" => "⪑", + "glE" => "⪒", + "lesges" => "⪓", + "gesles" => "⪔", + "els" | "eqslantless" => "⪕", + "egs" | "eqslantgtr" => "⪖", + "elsdot" => "⪗", + "egsdot" => "⪘", + "el" => "⪙", + "eg" => "⪚", + "siml" => "⪝", + "simg" => "⪞", + "simlE" => "⪟", + "simgE" => "⪠", + "LessLess" => "⪡", + "GreaterGreater" => "⪢", + "glj" => "⪤", + "gla" => "⪥", + "ltcc" => "⪦", + "gtcc" => "⪧", + "lescc" => "⪨", + "gescc" => "⪩", + "smt" => "⪪", + "lat" => "⪫", + "smte" => "⪬", + "late" => "⪭", + "bumpE" => "⪮", + "pre" | "preceq" | "PrecedesEqual" => "⪯", + "sce" | "succeq" | "SucceedsEqual" => "⪰", + "prE" => "⪳", + "scE" => "⪴", + "prnE" | "precneqq" => "⪵", + "scnE" | "succneqq" => "⪶", + "prap" | "precapprox" => "⪷", + "scap" | "succapprox" => "⪸", + "prnap" | "precnapprox" => "⪹", + "scnap" | "succnapprox" => "⪺", + "Pr" => "⪻", + "Sc" => "⪼", + "subdot" => "⪽", + "supdot" => "⪾", + "subplus" => "⪿", + "supplus" => "⫀", + "submult" => "⫁", + "supmult" => "⫂", + "subedot" => "⫃", + "supedot" => "⫄", + "subE" | "subseteqq" => "⫅", + "supE" | "supseteqq" => "⫆", + "subsim" => "⫇", + "supsim" => "⫈", + "subnE" | "subsetneqq" => "⫋", + "supnE" | "supsetneqq" => "⫌", + "csub" => "⫏", + "csup" => "⫐", + "csube" => "⫑", + "csupe" => "⫒", + "subsup" => "⫓", + "supsub" => "⫔", + "subsub" => "⫕", + "supsup" => "⫖", + "suphsub" => "⫗", + "supdsub" => "⫘", + "forkv" => "⫙", + "topfork" => "⫚", + "mlcp" => "⫛", + "Dashv" | "DoubleLeftTee" => "⫤", + "Vdashl" => "⫦", + "Barv" => "⫧", + "vBar" => "⫨", + "vBarv" => "⫩", + "Vbar" => "⫫", + "Not" => "⫬", + "bNot" => "⫭", + "rnmid" => "⫮", + "cirmid" => "⫯", + "midcir" => "⫰", + "topcir" => "⫱", + "nhpar" => "⫲", + "parsim" => "⫳", + "parsl" => "⫽", + "fflig" => "ff", + "filig" => "fi", + "fllig" => "fl", + "ffilig" => "ffi", + "ffllig" => "ffl", + "Ascr" => "𝒜", + "Cscr" => "𝒞", + "Dscr" => "𝒟", + "Gscr" => "𝒢", + "Jscr" => "𝒥", + "Kscr" => "𝒦", + "Nscr" => "𝒩", + "Oscr" => "𝒪", + "Pscr" => "𝒫", + "Qscr" => "𝒬", + "Sscr" => "𝒮", + "Tscr" => "𝒯", + "Uscr" => "𝒰", + "Vscr" => "𝒱", + "Wscr" => "𝒲", + "Xscr" => "𝒳", + "Yscr" => "𝒴", + "Zscr" => "𝒵", + "ascr" => "𝒶", + "bscr" => "𝒷", + "cscr" => "𝒸", + "dscr" => "𝒹", + "fscr" => "𝒻", + "hscr" => "𝒽", + "iscr" => "𝒾", + "jscr" => "𝒿", + "kscr" => "𝓀", + "lscr" => "𝓁", + "mscr" => "𝓂", + "nscr" => "𝓃", + "pscr" => "𝓅", + "qscr" => "𝓆", + "rscr" => "𝓇", + "sscr" => "𝓈", + "tscr" => "𝓉", + "uscr" => "𝓊", + "vscr" => "𝓋", + "wscr" => "𝓌", + "xscr" => "𝓍", + "yscr" => "𝓎", + "zscr" => "𝓏", + "Afr" => "𝔄", + "Bfr" => "𝔅", + "Dfr" => "𝔇", + "Efr" => "𝔈", + "Ffr" => "𝔉", + "Gfr" => "𝔊", + "Jfr" => "𝔍", + "Kfr" => "𝔎", + "Lfr" => "𝔏", + "Mfr" => "𝔐", + "Nfr" => "𝔑", + "Ofr" => "𝔒", + "Pfr" => "𝔓", + "Qfr" => "𝔔", + "Sfr" => "𝔖", + "Tfr" => "𝔗", + "Ufr" => "𝔘", + "Vfr" => "𝔙", + "Wfr" => "𝔚", + "Xfr" => "𝔛", + "Yfr" => "𝔜", + "afr" => "𝔞", + "bfr" => "𝔟", + "cfr" => "𝔠", + "dfr" => "𝔡", + "efr" => "𝔢", + "ffr" => "𝔣", + "gfr" => "𝔤", + "hfr" => "𝔥", + "ifr" => "𝔦", + "jfr" => "𝔧", + "kfr" => "𝔨", + "lfr" => "𝔩", + "mfr" => "𝔪", + "nfr" => "𝔫", + "ofr" => "𝔬", + "pfr" => "𝔭", + "qfr" => "𝔮", + "rfr" => "𝔯", + "sfr" => "𝔰", + "tfr" => "𝔱", + "ufr" => "𝔲", + "vfr" => "𝔳", + "wfr" => "𝔴", + "xfr" => "𝔵", + "yfr" => "𝔶", + "zfr" => "𝔷", + "Aopf" => "𝔸", + "Bopf" => "𝔹", + "Dopf" => "𝔻", + "Eopf" => "𝔼", + "Fopf" => "𝔽", + "Gopf" => "𝔾", + "Iopf" => "𝕀", + "Jopf" => "𝕁", + "Kopf" => "𝕂", + "Lopf" => "𝕃", + "Mopf" => "𝕄", + "Oopf" => "𝕆", + "Sopf" => "𝕊", + "Topf" => "𝕋", + "Uopf" => "𝕌", + "Vopf" => "𝕍", + "Wopf" => "𝕎", + "Xopf" => "𝕏", + "Yopf" => "𝕐", + "aopf" => "𝕒", + "bopf" => "𝕓", + "copf" => "𝕔", + "dopf" => "𝕕", + "eopf" => "𝕖", + "fopf" => "𝕗", + "gopf" => "𝕘", + "hopf" => "𝕙", + "iopf" => "𝕚", + "jopf" => "𝕛", + "kopf" => "𝕜", + "lopf" => "𝕝", + "mopf" => "𝕞", + "nopf" => "𝕟", + "oopf" => "𝕠", + "popf" => "𝕡", + "qopf" => "𝕢", + "ropf" => "𝕣", + "sopf" => "𝕤", + "topf" => "𝕥", + "uopf" => "𝕦", + "vopf" => "𝕧", + "wopf" => "𝕨", + "xopf" => "𝕩", + "yopf" => "𝕪", + "zopf" => "𝕫", + _ => &caps[0] + }.to_string() + } + }) +} + +#[test] +fn test_unescape() { + assert_eq!(&*unescape("test"), "test"); + assert_eq!(&*unescape("<test>"), ""); + assert_eq!(&*unescape("0"), "0"); + assert_eq!(&*unescape("0"), "0"); + assert_eq!(&*unescape("&foo;"), "&foo;"); +}