From bd0ae11d01e024bc7a311b576c93031fee95f53f Mon Sep 17 00:00:00 2001 From: funkpower Date: Sat, 19 Sep 2026 11:36:31 -0400 Subject: [PATCH] mdscrub: decode character references, keep block boundaries, narrow the fence --- crates/mdscrub/src/entities.rs | 2296 +++++++++++++++++++++++++ crates/mdscrub/src/html.rs | 184 +- crates/mdscrub/src/lib.rs | 2 + crates/mdscrub/src/pages.rs | 2 +- crates/mdscrub/src/unescape.rs | 150 ++ parity/KNOWN.md | 19 - parity/README.md | 11 +- parity/SOURCE.md | 19 + parity/cases/unescape/entities.txt | 2272 ++++++++++++++++++++++++ parity/golden/mdscrub/breaks.md | 6 +- parity/golden/mdscrub/breaks.rust.md | 9 - parity/golden/unescape/entities.jsonl | 2272 ++++++++++++++++++++++++ parity/oracle/unescape.py | 23 + parity/src/bin/regen.rs | 24 +- parity/src/lib.rs | 4 - parity/tests/mdscrub.rs | 23 +- parity/tests/unescape.rs | 57 + 17 files changed, 7274 insertions(+), 99 deletions(-) create mode 100644 crates/mdscrub/src/entities.rs create mode 100644 crates/mdscrub/src/unescape.rs create mode 100644 parity/SOURCE.md create mode 100644 parity/cases/unescape/entities.txt delete mode 100644 parity/golden/mdscrub/breaks.rust.md create mode 100644 parity/golden/unescape/entities.jsonl create mode 100644 parity/oracle/unescape.py create mode 100644 parity/tests/unescape.rs diff --git a/crates/mdscrub/src/entities.rs b/crates/mdscrub/src/entities.rs new file mode 100644 index 0000000..4514bfb --- /dev/null +++ b/crates/mdscrub/src/entities.rs @@ -0,0 +1,2296 @@ +//! The HTML5 named character references, and the two correction +//! tables that go with them. +//! +//! Generated from the table in the HTML5 specification. Sorted by name +//! so it can be searched rather than scanned; the names keep their +//! trailing semicolon where the specification gives them one, because +//! the ones without it are exactly the legacy forms that a decoder has +//! to accept in running text. + +/// Named references, sorted by name. +pub static NAMED: &[(&str, &str)] = &[ + ("AElig", "\u{c6}"), + ("AElig;", "\u{c6}"), + ("AMP", "&"), + ("AMP;", "&"), + ("Aacute", "\u{c1}"), + ("Aacute;", "\u{c1}"), + ("Abreve;", "\u{102}"), + ("Acirc", "\u{c2}"), + ("Acirc;", "\u{c2}"), + ("Acy;", "\u{410}"), + ("Afr;", "\u{1d504}"), + ("Agrave", "\u{c0}"), + ("Agrave;", "\u{c0}"), + ("Alpha;", "\u{391}"), + ("Amacr;", "\u{100}"), + ("And;", "\u{2a53}"), + ("Aogon;", "\u{104}"), + ("Aopf;", "\u{1d538}"), + ("ApplyFunction;", "\u{2061}"), + ("Aring", "\u{c5}"), + ("Aring;", "\u{c5}"), + ("Ascr;", "\u{1d49c}"), + ("Assign;", "\u{2254}"), + ("Atilde", "\u{c3}"), + ("Atilde;", "\u{c3}"), + ("Auml", "\u{c4}"), + ("Auml;", "\u{c4}"), + ("Backslash;", "\u{2216}"), + ("Barv;", "\u{2ae7}"), + ("Barwed;", "\u{2306}"), + ("Bcy;", "\u{411}"), + ("Because;", "\u{2235}"), + ("Bernoullis;", "\u{212c}"), + ("Beta;", "\u{392}"), + ("Bfr;", "\u{1d505}"), + ("Bopf;", "\u{1d539}"), + ("Breve;", "\u{2d8}"), + ("Bscr;", "\u{212c}"), + ("Bumpeq;", "\u{224e}"), + ("CHcy;", "\u{427}"), + ("COPY", "\u{a9}"), + ("COPY;", "\u{a9}"), + ("Cacute;", "\u{106}"), + ("Cap;", "\u{22d2}"), + ("CapitalDifferentialD;", "\u{2145}"), + ("Cayleys;", "\u{212d}"), + ("Ccaron;", "\u{10c}"), + ("Ccedil", "\u{c7}"), + ("Ccedil;", "\u{c7}"), + ("Ccirc;", "\u{108}"), + ("Cconint;", "\u{2230}"), + ("Cdot;", "\u{10a}"), + ("Cedilla;", "\u{b8}"), + ("CenterDot;", "\u{b7}"), + ("Cfr;", "\u{212d}"), + ("Chi;", "\u{3a7}"), + ("CircleDot;", "\u{2299}"), + ("CircleMinus;", "\u{2296}"), + ("CirclePlus;", "\u{2295}"), + ("CircleTimes;", "\u{2297}"), + ("ClockwiseContourIntegral;", "\u{2232}"), + ("CloseCurlyDoubleQuote;", "\u{201d}"), + ("CloseCurlyQuote;", "\u{2019}"), + ("Colon;", "\u{2237}"), + ("Colone;", "\u{2a74}"), + ("Congruent;", "\u{2261}"), + ("Conint;", "\u{222f}"), + ("ContourIntegral;", "\u{222e}"), + ("Copf;", "\u{2102}"), + ("Coproduct;", "\u{2210}"), + ("CounterClockwiseContourIntegral;", "\u{2233}"), + ("Cross;", "\u{2a2f}"), + ("Cscr;", "\u{1d49e}"), + ("Cup;", "\u{22d3}"), + ("CupCap;", "\u{224d}"), + ("DD;", "\u{2145}"), + ("DDotrahd;", "\u{2911}"), + ("DJcy;", "\u{402}"), + ("DScy;", "\u{405}"), + ("DZcy;", "\u{40f}"), + ("Dagger;", "\u{2021}"), + ("Darr;", "\u{21a1}"), + ("Dashv;", "\u{2ae4}"), + ("Dcaron;", "\u{10e}"), + ("Dcy;", "\u{414}"), + ("Del;", "\u{2207}"), + ("Delta;", "\u{394}"), + ("Dfr;", "\u{1d507}"), + ("DiacriticalAcute;", "\u{b4}"), + ("DiacriticalDot;", "\u{2d9}"), + ("DiacriticalDoubleAcute;", "\u{2dd}"), + ("DiacriticalGrave;", "`"), + ("DiacriticalTilde;", "\u{2dc}"), + ("Diamond;", "\u{22c4}"), + ("DifferentialD;", "\u{2146}"), + ("Dopf;", "\u{1d53b}"), + ("Dot;", "\u{a8}"), + ("DotDot;", "\u{20dc}"), + ("DotEqual;", "\u{2250}"), + ("DoubleContourIntegral;", "\u{222f}"), + ("DoubleDot;", "\u{a8}"), + ("DoubleDownArrow;", "\u{21d3}"), + ("DoubleLeftArrow;", "\u{21d0}"), + ("DoubleLeftRightArrow;", "\u{21d4}"), + ("DoubleLeftTee;", "\u{2ae4}"), + ("DoubleLongLeftArrow;", "\u{27f8}"), + ("DoubleLongLeftRightArrow;", "\u{27fa}"), + ("DoubleLongRightArrow;", "\u{27f9}"), + ("DoubleRightArrow;", "\u{21d2}"), + ("DoubleRightTee;", "\u{22a8}"), + ("DoubleUpArrow;", "\u{21d1}"), + ("DoubleUpDownArrow;", "\u{21d5}"), + ("DoubleVerticalBar;", "\u{2225}"), + ("DownArrow;", "\u{2193}"), + ("DownArrowBar;", "\u{2913}"), + ("DownArrowUpArrow;", "\u{21f5}"), + ("DownBreve;", "\u{311}"), + ("DownLeftRightVector;", "\u{2950}"), + ("DownLeftTeeVector;", "\u{295e}"), + ("DownLeftVector;", "\u{21bd}"), + ("DownLeftVectorBar;", "\u{2956}"), + ("DownRightTeeVector;", "\u{295f}"), + ("DownRightVector;", "\u{21c1}"), + ("DownRightVectorBar;", "\u{2957}"), + ("DownTee;", "\u{22a4}"), + ("DownTeeArrow;", "\u{21a7}"), + ("Downarrow;", "\u{21d3}"), + ("Dscr;", "\u{1d49f}"), + ("Dstrok;", "\u{110}"), + ("ENG;", "\u{14a}"), + ("ETH", "\u{d0}"), + ("ETH;", "\u{d0}"), + ("Eacute", "\u{c9}"), + ("Eacute;", "\u{c9}"), + ("Ecaron;", "\u{11a}"), + ("Ecirc", "\u{ca}"), + ("Ecirc;", "\u{ca}"), + ("Ecy;", "\u{42d}"), + ("Edot;", "\u{116}"), + ("Efr;", "\u{1d508}"), + ("Egrave", "\u{c8}"), + ("Egrave;", "\u{c8}"), + ("Element;", "\u{2208}"), + ("Emacr;", "\u{112}"), + ("EmptySmallSquare;", "\u{25fb}"), + ("EmptyVerySmallSquare;", "\u{25ab}"), + ("Eogon;", "\u{118}"), + ("Eopf;", "\u{1d53c}"), + ("Epsilon;", "\u{395}"), + ("Equal;", "\u{2a75}"), + ("EqualTilde;", "\u{2242}"), + ("Equilibrium;", "\u{21cc}"), + ("Escr;", "\u{2130}"), + ("Esim;", "\u{2a73}"), + ("Eta;", "\u{397}"), + ("Euml", "\u{cb}"), + ("Euml;", "\u{cb}"), + ("Exists;", "\u{2203}"), + ("ExponentialE;", "\u{2147}"), + ("Fcy;", "\u{424}"), + ("Ffr;", "\u{1d509}"), + ("FilledSmallSquare;", "\u{25fc}"), + ("FilledVerySmallSquare;", "\u{25aa}"), + ("Fopf;", "\u{1d53d}"), + ("ForAll;", "\u{2200}"), + ("Fouriertrf;", "\u{2131}"), + ("Fscr;", "\u{2131}"), + ("GJcy;", "\u{403}"), + ("GT", ">"), + ("GT;", ">"), + ("Gamma;", "\u{393}"), + ("Gammad;", "\u{3dc}"), + ("Gbreve;", "\u{11e}"), + ("Gcedil;", "\u{122}"), + ("Gcirc;", "\u{11c}"), + ("Gcy;", "\u{413}"), + ("Gdot;", "\u{120}"), + ("Gfr;", "\u{1d50a}"), + ("Gg;", "\u{22d9}"), + ("Gopf;", "\u{1d53e}"), + ("GreaterEqual;", "\u{2265}"), + ("GreaterEqualLess;", "\u{22db}"), + ("GreaterFullEqual;", "\u{2267}"), + ("GreaterGreater;", "\u{2aa2}"), + ("GreaterLess;", "\u{2277}"), + ("GreaterSlantEqual;", "\u{2a7e}"), + ("GreaterTilde;", "\u{2273}"), + ("Gscr;", "\u{1d4a2}"), + ("Gt;", "\u{226b}"), + ("HARDcy;", "\u{42a}"), + ("Hacek;", "\u{2c7}"), + ("Hat;", "^"), + ("Hcirc;", "\u{124}"), + ("Hfr;", "\u{210c}"), + ("HilbertSpace;", "\u{210b}"), + ("Hopf;", "\u{210d}"), + ("HorizontalLine;", "\u{2500}"), + ("Hscr;", "\u{210b}"), + ("Hstrok;", "\u{126}"), + ("HumpDownHump;", "\u{224e}"), + ("HumpEqual;", "\u{224f}"), + ("IEcy;", "\u{415}"), + ("IJlig;", "\u{132}"), + ("IOcy;", "\u{401}"), + ("Iacute", "\u{cd}"), + ("Iacute;", "\u{cd}"), + ("Icirc", "\u{ce}"), + ("Icirc;", "\u{ce}"), + ("Icy;", "\u{418}"), + ("Idot;", "\u{130}"), + ("Ifr;", "\u{2111}"), + ("Igrave", "\u{cc}"), + ("Igrave;", "\u{cc}"), + ("Im;", "\u{2111}"), + ("Imacr;", "\u{12a}"), + ("ImaginaryI;", "\u{2148}"), + ("Implies;", "\u{21d2}"), + ("Int;", "\u{222c}"), + ("Integral;", "\u{222b}"), + ("Intersection;", "\u{22c2}"), + ("InvisibleComma;", "\u{2063}"), + ("InvisibleTimes;", "\u{2062}"), + ("Iogon;", "\u{12e}"), + ("Iopf;", "\u{1d540}"), + ("Iota;", "\u{399}"), + ("Iscr;", "\u{2110}"), + ("Itilde;", "\u{128}"), + ("Iukcy;", "\u{406}"), + ("Iuml", "\u{cf}"), + ("Iuml;", "\u{cf}"), + ("Jcirc;", "\u{134}"), + ("Jcy;", "\u{419}"), + ("Jfr;", "\u{1d50d}"), + ("Jopf;", "\u{1d541}"), + ("Jscr;", "\u{1d4a5}"), + ("Jsercy;", "\u{408}"), + ("Jukcy;", "\u{404}"), + ("KHcy;", "\u{425}"), + ("KJcy;", "\u{40c}"), + ("Kappa;", "\u{39a}"), + ("Kcedil;", "\u{136}"), + ("Kcy;", "\u{41a}"), + ("Kfr;", "\u{1d50e}"), + ("Kopf;", "\u{1d542}"), + ("Kscr;", "\u{1d4a6}"), + ("LJcy;", "\u{409}"), + ("LT", "<"), + ("LT;", "<"), + ("Lacute;", "\u{139}"), + ("Lambda;", "\u{39b}"), + ("Lang;", "\u{27ea}"), + ("Laplacetrf;", "\u{2112}"), + ("Larr;", "\u{219e}"), + ("Lcaron;", "\u{13d}"), + ("Lcedil;", "\u{13b}"), + ("Lcy;", "\u{41b}"), + ("LeftAngleBracket;", "\u{27e8}"), + ("LeftArrow;", "\u{2190}"), + ("LeftArrowBar;", "\u{21e4}"), + ("LeftArrowRightArrow;", "\u{21c6}"), + ("LeftCeiling;", "\u{2308}"), + ("LeftDoubleBracket;", "\u{27e6}"), + ("LeftDownTeeVector;", "\u{2961}"), + ("LeftDownVector;", "\u{21c3}"), + ("LeftDownVectorBar;", "\u{2959}"), + ("LeftFloor;", "\u{230a}"), + ("LeftRightArrow;", "\u{2194}"), + ("LeftRightVector;", "\u{294e}"), + ("LeftTee;", "\u{22a3}"), + ("LeftTeeArrow;", "\u{21a4}"), + ("LeftTeeVector;", "\u{295a}"), + ("LeftTriangle;", "\u{22b2}"), + ("LeftTriangleBar;", "\u{29cf}"), + ("LeftTriangleEqual;", "\u{22b4}"), + ("LeftUpDownVector;", "\u{2951}"), + ("LeftUpTeeVector;", "\u{2960}"), + ("LeftUpVector;", "\u{21bf}"), + ("LeftUpVectorBar;", "\u{2958}"), + ("LeftVector;", "\u{21bc}"), + ("LeftVectorBar;", "\u{2952}"), + ("Leftarrow;", "\u{21d0}"), + ("Leftrightarrow;", "\u{21d4}"), + ("LessEqualGreater;", "\u{22da}"), + ("LessFullEqual;", "\u{2266}"), + ("LessGreater;", "\u{2276}"), + ("LessLess;", "\u{2aa1}"), + ("LessSlantEqual;", "\u{2a7d}"), + ("LessTilde;", "\u{2272}"), + ("Lfr;", "\u{1d50f}"), + ("Ll;", "\u{22d8}"), + ("Lleftarrow;", "\u{21da}"), + ("Lmidot;", "\u{13f}"), + ("LongLeftArrow;", "\u{27f5}"), + ("LongLeftRightArrow;", "\u{27f7}"), + ("LongRightArrow;", "\u{27f6}"), + ("Longleftarrow;", "\u{27f8}"), + ("Longleftrightarrow;", "\u{27fa}"), + ("Longrightarrow;", "\u{27f9}"), + ("Lopf;", "\u{1d543}"), + ("LowerLeftArrow;", "\u{2199}"), + ("LowerRightArrow;", "\u{2198}"), + ("Lscr;", "\u{2112}"), + ("Lsh;", "\u{21b0}"), + ("Lstrok;", "\u{141}"), + ("Lt;", "\u{226a}"), + ("Map;", "\u{2905}"), + ("Mcy;", "\u{41c}"), + ("MediumSpace;", "\u{205f}"), + ("Mellintrf;", "\u{2133}"), + ("Mfr;", "\u{1d510}"), + ("MinusPlus;", "\u{2213}"), + ("Mopf;", "\u{1d544}"), + ("Mscr;", "\u{2133}"), + ("Mu;", "\u{39c}"), + ("NJcy;", "\u{40a}"), + ("Nacute;", "\u{143}"), + ("Ncaron;", "\u{147}"), + ("Ncedil;", "\u{145}"), + ("Ncy;", "\u{41d}"), + ("NegativeMediumSpace;", "\u{200b}"), + ("NegativeThickSpace;", "\u{200b}"), + ("NegativeThinSpace;", "\u{200b}"), + ("NegativeVeryThinSpace;", "\u{200b}"), + ("NestedGreaterGreater;", "\u{226b}"), + ("NestedLessLess;", "\u{226a}"), + ("NewLine;", "\u{a}"), + ("Nfr;", "\u{1d511}"), + ("NoBreak;", "\u{2060}"), + ("NonBreakingSpace;", "\u{a0}"), + ("Nopf;", "\u{2115}"), + ("Not;", "\u{2aec}"), + ("NotCongruent;", "\u{2262}"), + ("NotCupCap;", "\u{226d}"), + ("NotDoubleVerticalBar;", "\u{2226}"), + ("NotElement;", "\u{2209}"), + ("NotEqual;", "\u{2260}"), + ("NotEqualTilde;", "\u{2242}\u{338}"), + ("NotExists;", "\u{2204}"), + ("NotGreater;", "\u{226f}"), + ("NotGreaterEqual;", "\u{2271}"), + ("NotGreaterFullEqual;", "\u{2267}\u{338}"), + ("NotGreaterGreater;", "\u{226b}\u{338}"), + ("NotGreaterLess;", "\u{2279}"), + ("NotGreaterSlantEqual;", "\u{2a7e}\u{338}"), + ("NotGreaterTilde;", "\u{2275}"), + ("NotHumpDownHump;", "\u{224e}\u{338}"), + ("NotHumpEqual;", "\u{224f}\u{338}"), + ("NotLeftTriangle;", "\u{22ea}"), + ("NotLeftTriangleBar;", "\u{29cf}\u{338}"), + ("NotLeftTriangleEqual;", "\u{22ec}"), + ("NotLess;", "\u{226e}"), + ("NotLessEqual;", "\u{2270}"), + ("NotLessGreater;", "\u{2278}"), + ("NotLessLess;", "\u{226a}\u{338}"), + ("NotLessSlantEqual;", "\u{2a7d}\u{338}"), + ("NotLessTilde;", "\u{2274}"), + ("NotNestedGreaterGreater;", "\u{2aa2}\u{338}"), + ("NotNestedLessLess;", "\u{2aa1}\u{338}"), + ("NotPrecedes;", "\u{2280}"), + ("NotPrecedesEqual;", "\u{2aaf}\u{338}"), + ("NotPrecedesSlantEqual;", "\u{22e0}"), + ("NotReverseElement;", "\u{220c}"), + ("NotRightTriangle;", "\u{22eb}"), + ("NotRightTriangleBar;", "\u{29d0}\u{338}"), + ("NotRightTriangleEqual;", "\u{22ed}"), + ("NotSquareSubset;", "\u{228f}\u{338}"), + ("NotSquareSubsetEqual;", "\u{22e2}"), + ("NotSquareSuperset;", "\u{2290}\u{338}"), + ("NotSquareSupersetEqual;", "\u{22e3}"), + ("NotSubset;", "\u{2282}\u{20d2}"), + ("NotSubsetEqual;", "\u{2288}"), + ("NotSucceeds;", "\u{2281}"), + ("NotSucceedsEqual;", "\u{2ab0}\u{338}"), + ("NotSucceedsSlantEqual;", "\u{22e1}"), + ("NotSucceedsTilde;", "\u{227f}\u{338}"), + ("NotSuperset;", "\u{2283}\u{20d2}"), + ("NotSupersetEqual;", "\u{2289}"), + ("NotTilde;", "\u{2241}"), + ("NotTildeEqual;", "\u{2244}"), + ("NotTildeFullEqual;", "\u{2247}"), + ("NotTildeTilde;", "\u{2249}"), + ("NotVerticalBar;", "\u{2224}"), + ("Nscr;", "\u{1d4a9}"), + ("Ntilde", "\u{d1}"), + ("Ntilde;", "\u{d1}"), + ("Nu;", "\u{39d}"), + ("OElig;", "\u{152}"), + ("Oacute", "\u{d3}"), + ("Oacute;", "\u{d3}"), + ("Ocirc", "\u{d4}"), + ("Ocirc;", "\u{d4}"), + ("Ocy;", "\u{41e}"), + ("Odblac;", "\u{150}"), + ("Ofr;", "\u{1d512}"), + ("Ograve", "\u{d2}"), + ("Ograve;", "\u{d2}"), + ("Omacr;", "\u{14c}"), + ("Omega;", "\u{3a9}"), + ("Omicron;", "\u{39f}"), + ("Oopf;", "\u{1d546}"), + ("OpenCurlyDoubleQuote;", "\u{201c}"), + ("OpenCurlyQuote;", "\u{2018}"), + ("Or;", "\u{2a54}"), + ("Oscr;", "\u{1d4aa}"), + ("Oslash", "\u{d8}"), + ("Oslash;", "\u{d8}"), + ("Otilde", "\u{d5}"), + ("Otilde;", "\u{d5}"), + ("Otimes;", "\u{2a37}"), + ("Ouml", "\u{d6}"), + ("Ouml;", "\u{d6}"), + ("OverBar;", "\u{203e}"), + ("OverBrace;", "\u{23de}"), + ("OverBracket;", "\u{23b4}"), + ("OverParenthesis;", "\u{23dc}"), + ("PartialD;", "\u{2202}"), + ("Pcy;", "\u{41f}"), + ("Pfr;", "\u{1d513}"), + ("Phi;", "\u{3a6}"), + ("Pi;", "\u{3a0}"), + ("PlusMinus;", "\u{b1}"), + ("Poincareplane;", "\u{210c}"), + ("Popf;", "\u{2119}"), + ("Pr;", "\u{2abb}"), + ("Precedes;", "\u{227a}"), + ("PrecedesEqual;", "\u{2aaf}"), + ("PrecedesSlantEqual;", "\u{227c}"), + ("PrecedesTilde;", "\u{227e}"), + ("Prime;", "\u{2033}"), + ("Product;", "\u{220f}"), + ("Proportion;", "\u{2237}"), + ("Proportional;", "\u{221d}"), + ("Pscr;", "\u{1d4ab}"), + ("Psi;", "\u{3a8}"), + ("QUOT", "\""), + ("QUOT;", "\""), + ("Qfr;", "\u{1d514}"), + ("Qopf;", "\u{211a}"), + ("Qscr;", "\u{1d4ac}"), + ("RBarr;", "\u{2910}"), + ("REG", "\u{ae}"), + ("REG;", "\u{ae}"), + ("Racute;", "\u{154}"), + ("Rang;", "\u{27eb}"), + ("Rarr;", "\u{21a0}"), + ("Rarrtl;", "\u{2916}"), + ("Rcaron;", "\u{158}"), + ("Rcedil;", "\u{156}"), + ("Rcy;", "\u{420}"), + ("Re;", "\u{211c}"), + ("ReverseElement;", "\u{220b}"), + ("ReverseEquilibrium;", "\u{21cb}"), + ("ReverseUpEquilibrium;", "\u{296f}"), + ("Rfr;", "\u{211c}"), + ("Rho;", "\u{3a1}"), + ("RightAngleBracket;", "\u{27e9}"), + ("RightArrow;", "\u{2192}"), + ("RightArrowBar;", "\u{21e5}"), + ("RightArrowLeftArrow;", "\u{21c4}"), + ("RightCeiling;", "\u{2309}"), + ("RightDoubleBracket;", "\u{27e7}"), + ("RightDownTeeVector;", "\u{295d}"), + ("RightDownVector;", "\u{21c2}"), + ("RightDownVectorBar;", "\u{2955}"), + ("RightFloor;", "\u{230b}"), + ("RightTee;", "\u{22a2}"), + ("RightTeeArrow;", "\u{21a6}"), + ("RightTeeVector;", "\u{295b}"), + ("RightTriangle;", "\u{22b3}"), + ("RightTriangleBar;", "\u{29d0}"), + ("RightTriangleEqual;", "\u{22b5}"), + ("RightUpDownVector;", "\u{294f}"), + ("RightUpTeeVector;", "\u{295c}"), + ("RightUpVector;", "\u{21be}"), + ("RightUpVectorBar;", "\u{2954}"), + ("RightVector;", "\u{21c0}"), + ("RightVectorBar;", "\u{2953}"), + ("Rightarrow;", "\u{21d2}"), + ("Ropf;", "\u{211d}"), + ("RoundImplies;", "\u{2970}"), + ("Rrightarrow;", "\u{21db}"), + ("Rscr;", "\u{211b}"), + ("Rsh;", "\u{21b1}"), + ("RuleDelayed;", "\u{29f4}"), + ("SHCHcy;", "\u{429}"), + ("SHcy;", "\u{428}"), + ("SOFTcy;", "\u{42c}"), + ("Sacute;", "\u{15a}"), + ("Sc;", "\u{2abc}"), + ("Scaron;", "\u{160}"), + ("Scedil;", "\u{15e}"), + ("Scirc;", "\u{15c}"), + ("Scy;", "\u{421}"), + ("Sfr;", "\u{1d516}"), + ("ShortDownArrow;", "\u{2193}"), + ("ShortLeftArrow;", "\u{2190}"), + ("ShortRightArrow;", "\u{2192}"), + ("ShortUpArrow;", "\u{2191}"), + ("Sigma;", "\u{3a3}"), + ("SmallCircle;", "\u{2218}"), + ("Sopf;", "\u{1d54a}"), + ("Sqrt;", "\u{221a}"), + ("Square;", "\u{25a1}"), + ("SquareIntersection;", "\u{2293}"), + ("SquareSubset;", "\u{228f}"), + ("SquareSubsetEqual;", "\u{2291}"), + ("SquareSuperset;", "\u{2290}"), + ("SquareSupersetEqual;", "\u{2292}"), + ("SquareUnion;", "\u{2294}"), + ("Sscr;", "\u{1d4ae}"), + ("Star;", "\u{22c6}"), + ("Sub;", "\u{22d0}"), + ("Subset;", "\u{22d0}"), + ("SubsetEqual;", "\u{2286}"), + ("Succeeds;", "\u{227b}"), + ("SucceedsEqual;", "\u{2ab0}"), + ("SucceedsSlantEqual;", "\u{227d}"), + ("SucceedsTilde;", "\u{227f}"), + ("SuchThat;", "\u{220b}"), + ("Sum;", "\u{2211}"), + ("Sup;", "\u{22d1}"), + ("Superset;", "\u{2283}"), + ("SupersetEqual;", "\u{2287}"), + ("Supset;", "\u{22d1}"), + ("THORN", "\u{de}"), + ("THORN;", "\u{de}"), + ("TRADE;", "\u{2122}"), + ("TSHcy;", "\u{40b}"), + ("TScy;", "\u{426}"), + ("Tab;", "\u{9}"), + ("Tau;", "\u{3a4}"), + ("Tcaron;", "\u{164}"), + ("Tcedil;", "\u{162}"), + ("Tcy;", "\u{422}"), + ("Tfr;", "\u{1d517}"), + ("Therefore;", "\u{2234}"), + ("Theta;", "\u{398}"), + ("ThickSpace;", "\u{205f}\u{200a}"), + ("ThinSpace;", "\u{2009}"), + ("Tilde;", "\u{223c}"), + ("TildeEqual;", "\u{2243}"), + ("TildeFullEqual;", "\u{2245}"), + ("TildeTilde;", "\u{2248}"), + ("Topf;", "\u{1d54b}"), + ("TripleDot;", "\u{20db}"), + ("Tscr;", "\u{1d4af}"), + ("Tstrok;", "\u{166}"), + ("Uacute", "\u{da}"), + ("Uacute;", "\u{da}"), + ("Uarr;", "\u{219f}"), + ("Uarrocir;", "\u{2949}"), + ("Ubrcy;", "\u{40e}"), + ("Ubreve;", "\u{16c}"), + ("Ucirc", "\u{db}"), + ("Ucirc;", "\u{db}"), + ("Ucy;", "\u{423}"), + ("Udblac;", "\u{170}"), + ("Ufr;", "\u{1d518}"), + ("Ugrave", "\u{d9}"), + ("Ugrave;", "\u{d9}"), + ("Umacr;", "\u{16a}"), + ("UnderBar;", "_"), + ("UnderBrace;", "\u{23df}"), + ("UnderBracket;", "\u{23b5}"), + ("UnderParenthesis;", "\u{23dd}"), + ("Union;", "\u{22c3}"), + ("UnionPlus;", "\u{228e}"), + ("Uogon;", "\u{172}"), + ("Uopf;", "\u{1d54c}"), + ("UpArrow;", "\u{2191}"), + ("UpArrowBar;", "\u{2912}"), + ("UpArrowDownArrow;", "\u{21c5}"), + ("UpDownArrow;", "\u{2195}"), + ("UpEquilibrium;", "\u{296e}"), + ("UpTee;", "\u{22a5}"), + ("UpTeeArrow;", "\u{21a5}"), + ("Uparrow;", "\u{21d1}"), + ("Updownarrow;", "\u{21d5}"), + ("UpperLeftArrow;", "\u{2196}"), + ("UpperRightArrow;", "\u{2197}"), + ("Upsi;", "\u{3d2}"), + ("Upsilon;", "\u{3a5}"), + ("Uring;", "\u{16e}"), + ("Uscr;", "\u{1d4b0}"), + ("Utilde;", "\u{168}"), + ("Uuml", "\u{dc}"), + ("Uuml;", "\u{dc}"), + ("VDash;", "\u{22ab}"), + ("Vbar;", "\u{2aeb}"), + ("Vcy;", "\u{412}"), + ("Vdash;", "\u{22a9}"), + ("Vdashl;", "\u{2ae6}"), + ("Vee;", "\u{22c1}"), + ("Verbar;", "\u{2016}"), + ("Vert;", "\u{2016}"), + ("VerticalBar;", "\u{2223}"), + ("VerticalLine;", "|"), + ("VerticalSeparator;", "\u{2758}"), + ("VerticalTilde;", "\u{2240}"), + ("VeryThinSpace;", "\u{200a}"), + ("Vfr;", "\u{1d519}"), + ("Vopf;", "\u{1d54d}"), + ("Vscr;", "\u{1d4b1}"), + ("Vvdash;", "\u{22aa}"), + ("Wcirc;", "\u{174}"), + ("Wedge;", "\u{22c0}"), + ("Wfr;", "\u{1d51a}"), + ("Wopf;", "\u{1d54e}"), + ("Wscr;", "\u{1d4b2}"), + ("Xfr;", "\u{1d51b}"), + ("Xi;", "\u{39e}"), + ("Xopf;", "\u{1d54f}"), + ("Xscr;", "\u{1d4b3}"), + ("YAcy;", "\u{42f}"), + ("YIcy;", "\u{407}"), + ("YUcy;", "\u{42e}"), + ("Yacute", "\u{dd}"), + ("Yacute;", "\u{dd}"), + ("Ycirc;", "\u{176}"), + ("Ycy;", "\u{42b}"), + ("Yfr;", "\u{1d51c}"), + ("Yopf;", "\u{1d550}"), + ("Yscr;", "\u{1d4b4}"), + ("Yuml;", "\u{178}"), + ("ZHcy;", "\u{416}"), + ("Zacute;", "\u{179}"), + ("Zcaron;", "\u{17d}"), + ("Zcy;", "\u{417}"), + ("Zdot;", "\u{17b}"), + ("ZeroWidthSpace;", "\u{200b}"), + ("Zeta;", "\u{396}"), + ("Zfr;", "\u{2128}"), + ("Zopf;", "\u{2124}"), + ("Zscr;", "\u{1d4b5}"), + ("aacute", "\u{e1}"), + ("aacute;", "\u{e1}"), + ("abreve;", "\u{103}"), + ("ac;", "\u{223e}"), + ("acE;", "\u{223e}\u{333}"), + ("acd;", "\u{223f}"), + ("acirc", "\u{e2}"), + ("acirc;", "\u{e2}"), + ("acute", "\u{b4}"), + ("acute;", "\u{b4}"), + ("acy;", "\u{430}"), + ("aelig", "\u{e6}"), + ("aelig;", "\u{e6}"), + ("af;", "\u{2061}"), + ("afr;", "\u{1d51e}"), + ("agrave", "\u{e0}"), + ("agrave;", "\u{e0}"), + ("alefsym;", "\u{2135}"), + ("aleph;", "\u{2135}"), + ("alpha;", "\u{3b1}"), + ("amacr;", "\u{101}"), + ("amalg;", "\u{2a3f}"), + ("amp", "&"), + ("amp;", "&"), + ("and;", "\u{2227}"), + ("andand;", "\u{2a55}"), + ("andd;", "\u{2a5c}"), + ("andslope;", "\u{2a58}"), + ("andv;", "\u{2a5a}"), + ("ang;", "\u{2220}"), + ("ange;", "\u{29a4}"), + ("angle;", "\u{2220}"), + ("angmsd;", "\u{2221}"), + ("angmsdaa;", "\u{29a8}"), + ("angmsdab;", "\u{29a9}"), + ("angmsdac;", "\u{29aa}"), + ("angmsdad;", "\u{29ab}"), + ("angmsdae;", "\u{29ac}"), + ("angmsdaf;", "\u{29ad}"), + ("angmsdag;", "\u{29ae}"), + ("angmsdah;", "\u{29af}"), + ("angrt;", "\u{221f}"), + ("angrtvb;", "\u{22be}"), + ("angrtvbd;", "\u{299d}"), + ("angsph;", "\u{2222}"), + ("angst;", "\u{c5}"), + ("angzarr;", "\u{237c}"), + ("aogon;", "\u{105}"), + ("aopf;", "\u{1d552}"), + ("ap;", "\u{2248}"), + ("apE;", "\u{2a70}"), + ("apacir;", "\u{2a6f}"), + ("ape;", "\u{224a}"), + ("apid;", "\u{224b}"), + ("apos;", "'"), + ("approx;", "\u{2248}"), + ("approxeq;", "\u{224a}"), + ("aring", "\u{e5}"), + ("aring;", "\u{e5}"), + ("ascr;", "\u{1d4b6}"), + ("ast;", "*"), + ("asymp;", "\u{2248}"), + ("asympeq;", "\u{224d}"), + ("atilde", "\u{e3}"), + ("atilde;", "\u{e3}"), + ("auml", "\u{e4}"), + ("auml;", "\u{e4}"), + ("awconint;", "\u{2233}"), + ("awint;", "\u{2a11}"), + ("bNot;", "\u{2aed}"), + ("backcong;", "\u{224c}"), + ("backepsilon;", "\u{3f6}"), + ("backprime;", "\u{2035}"), + ("backsim;", "\u{223d}"), + ("backsimeq;", "\u{22cd}"), + ("barvee;", "\u{22bd}"), + ("barwed;", "\u{2305}"), + ("barwedge;", "\u{2305}"), + ("bbrk;", "\u{23b5}"), + ("bbrktbrk;", "\u{23b6}"), + ("bcong;", "\u{224c}"), + ("bcy;", "\u{431}"), + ("bdquo;", "\u{201e}"), + ("becaus;", "\u{2235}"), + ("because;", "\u{2235}"), + ("bemptyv;", "\u{29b0}"), + ("bepsi;", "\u{3f6}"), + ("bernou;", "\u{212c}"), + ("beta;", "\u{3b2}"), + ("beth;", "\u{2136}"), + ("between;", "\u{226c}"), + ("bfr;", "\u{1d51f}"), + ("bigcap;", "\u{22c2}"), + ("bigcirc;", "\u{25ef}"), + ("bigcup;", "\u{22c3}"), + ("bigodot;", "\u{2a00}"), + ("bigoplus;", "\u{2a01}"), + ("bigotimes;", "\u{2a02}"), + ("bigsqcup;", "\u{2a06}"), + ("bigstar;", "\u{2605}"), + ("bigtriangledown;", "\u{25bd}"), + ("bigtriangleup;", "\u{25b3}"), + ("biguplus;", "\u{2a04}"), + ("bigvee;", "\u{22c1}"), + ("bigwedge;", "\u{22c0}"), + ("bkarow;", "\u{290d}"), + ("blacklozenge;", "\u{29eb}"), + ("blacksquare;", "\u{25aa}"), + ("blacktriangle;", "\u{25b4}"), + ("blacktriangledown;", "\u{25be}"), + ("blacktriangleleft;", "\u{25c2}"), + ("blacktriangleright;", "\u{25b8}"), + ("blank;", "\u{2423}"), + ("blk12;", "\u{2592}"), + ("blk14;", "\u{2591}"), + ("blk34;", "\u{2593}"), + ("block;", "\u{2588}"), + ("bne;", "=\u{20e5}"), + ("bnequiv;", "\u{2261}\u{20e5}"), + ("bnot;", "\u{2310}"), + ("bopf;", "\u{1d553}"), + ("bot;", "\u{22a5}"), + ("bottom;", "\u{22a5}"), + ("bowtie;", "\u{22c8}"), + ("boxDL;", "\u{2557}"), + ("boxDR;", "\u{2554}"), + ("boxDl;", "\u{2556}"), + ("boxDr;", "\u{2553}"), + ("boxH;", "\u{2550}"), + ("boxHD;", "\u{2566}"), + ("boxHU;", "\u{2569}"), + ("boxHd;", "\u{2564}"), + ("boxHu;", "\u{2567}"), + ("boxUL;", "\u{255d}"), + ("boxUR;", "\u{255a}"), + ("boxUl;", "\u{255c}"), + ("boxUr;", "\u{2559}"), + ("boxV;", "\u{2551}"), + ("boxVH;", "\u{256c}"), + ("boxVL;", "\u{2563}"), + ("boxVR;", "\u{2560}"), + ("boxVh;", "\u{256b}"), + ("boxVl;", "\u{2562}"), + ("boxVr;", "\u{255f}"), + ("boxbox;", "\u{29c9}"), + ("boxdL;", "\u{2555}"), + ("boxdR;", "\u{2552}"), + ("boxdl;", "\u{2510}"), + ("boxdr;", "\u{250c}"), + ("boxh;", "\u{2500}"), + ("boxhD;", "\u{2565}"), + ("boxhU;", "\u{2568}"), + ("boxhd;", "\u{252c}"), + ("boxhu;", "\u{2534}"), + ("boxminus;", "\u{229f}"), + ("boxplus;", "\u{229e}"), + ("boxtimes;", "\u{22a0}"), + ("boxuL;", "\u{255b}"), + ("boxuR;", "\u{2558}"), + ("boxul;", "\u{2518}"), + ("boxur;", "\u{2514}"), + ("boxv;", "\u{2502}"), + ("boxvH;", "\u{256a}"), + ("boxvL;", "\u{2561}"), + ("boxvR;", "\u{255e}"), + ("boxvh;", "\u{253c}"), + ("boxvl;", "\u{2524}"), + ("boxvr;", "\u{251c}"), + ("bprime;", "\u{2035}"), + ("breve;", "\u{2d8}"), + ("brvbar", "\u{a6}"), + ("brvbar;", "\u{a6}"), + ("bscr;", "\u{1d4b7}"), + ("bsemi;", "\u{204f}"), + ("bsim;", "\u{223d}"), + ("bsime;", "\u{22cd}"), + ("bsol;", "\\"), + ("bsolb;", "\u{29c5}"), + ("bsolhsub;", "\u{27c8}"), + ("bull;", "\u{2022}"), + ("bullet;", "\u{2022}"), + ("bump;", "\u{224e}"), + ("bumpE;", "\u{2aae}"), + ("bumpe;", "\u{224f}"), + ("bumpeq;", "\u{224f}"), + ("cacute;", "\u{107}"), + ("cap;", "\u{2229}"), + ("capand;", "\u{2a44}"), + ("capbrcup;", "\u{2a49}"), + ("capcap;", "\u{2a4b}"), + ("capcup;", "\u{2a47}"), + ("capdot;", "\u{2a40}"), + ("caps;", "\u{2229}\u{fe00}"), + ("caret;", "\u{2041}"), + ("caron;", "\u{2c7}"), + ("ccaps;", "\u{2a4d}"), + ("ccaron;", "\u{10d}"), + ("ccedil", "\u{e7}"), + ("ccedil;", "\u{e7}"), + ("ccirc;", "\u{109}"), + ("ccups;", "\u{2a4c}"), + ("ccupssm;", "\u{2a50}"), + ("cdot;", "\u{10b}"), + ("cedil", "\u{b8}"), + ("cedil;", "\u{b8}"), + ("cemptyv;", "\u{29b2}"), + ("cent", "\u{a2}"), + ("cent;", "\u{a2}"), + ("centerdot;", "\u{b7}"), + ("cfr;", "\u{1d520}"), + ("chcy;", "\u{447}"), + ("check;", "\u{2713}"), + ("checkmark;", "\u{2713}"), + ("chi;", "\u{3c7}"), + ("cir;", "\u{25cb}"), + ("cirE;", "\u{29c3}"), + ("circ;", "\u{2c6}"), + ("circeq;", "\u{2257}"), + ("circlearrowleft;", "\u{21ba}"), + ("circlearrowright;", "\u{21bb}"), + ("circledR;", "\u{ae}"), + ("circledS;", "\u{24c8}"), + ("circledast;", "\u{229b}"), + ("circledcirc;", "\u{229a}"), + ("circleddash;", "\u{229d}"), + ("cire;", "\u{2257}"), + ("cirfnint;", "\u{2a10}"), + ("cirmid;", "\u{2aef}"), + ("cirscir;", "\u{29c2}"), + ("clubs;", "\u{2663}"), + ("clubsuit;", "\u{2663}"), + ("colon;", ":"), + ("colone;", "\u{2254}"), + ("coloneq;", "\u{2254}"), + ("comma;", ","), + ("commat;", "@"), + ("comp;", "\u{2201}"), + ("compfn;", "\u{2218}"), + ("complement;", "\u{2201}"), + ("complexes;", "\u{2102}"), + ("cong;", "\u{2245}"), + ("congdot;", "\u{2a6d}"), + ("conint;", "\u{222e}"), + ("copf;", "\u{1d554}"), + ("coprod;", "\u{2210}"), + ("copy", "\u{a9}"), + ("copy;", "\u{a9}"), + ("copysr;", "\u{2117}"), + ("crarr;", "\u{21b5}"), + ("cross;", "\u{2717}"), + ("cscr;", "\u{1d4b8}"), + ("csub;", "\u{2acf}"), + ("csube;", "\u{2ad1}"), + ("csup;", "\u{2ad0}"), + ("csupe;", "\u{2ad2}"), + ("ctdot;", "\u{22ef}"), + ("cudarrl;", "\u{2938}"), + ("cudarrr;", "\u{2935}"), + ("cuepr;", "\u{22de}"), + ("cuesc;", "\u{22df}"), + ("cularr;", "\u{21b6}"), + ("cularrp;", "\u{293d}"), + ("cup;", "\u{222a}"), + ("cupbrcap;", "\u{2a48}"), + ("cupcap;", "\u{2a46}"), + ("cupcup;", "\u{2a4a}"), + ("cupdot;", "\u{228d}"), + ("cupor;", "\u{2a45}"), + ("cups;", "\u{222a}\u{fe00}"), + ("curarr;", "\u{21b7}"), + ("curarrm;", "\u{293c}"), + ("curlyeqprec;", "\u{22de}"), + ("curlyeqsucc;", "\u{22df}"), + ("curlyvee;", "\u{22ce}"), + ("curlywedge;", "\u{22cf}"), + ("curren", "\u{a4}"), + ("curren;", "\u{a4}"), + ("curvearrowleft;", "\u{21b6}"), + ("curvearrowright;", "\u{21b7}"), + ("cuvee;", "\u{22ce}"), + ("cuwed;", "\u{22cf}"), + ("cwconint;", "\u{2232}"), + ("cwint;", "\u{2231}"), + ("cylcty;", "\u{232d}"), + ("dArr;", "\u{21d3}"), + ("dHar;", "\u{2965}"), + ("dagger;", "\u{2020}"), + ("daleth;", "\u{2138}"), + ("darr;", "\u{2193}"), + ("dash;", "\u{2010}"), + ("dashv;", "\u{22a3}"), + ("dbkarow;", "\u{290f}"), + ("dblac;", "\u{2dd}"), + ("dcaron;", "\u{10f}"), + ("dcy;", "\u{434}"), + ("dd;", "\u{2146}"), + ("ddagger;", "\u{2021}"), + ("ddarr;", "\u{21ca}"), + ("ddotseq;", "\u{2a77}"), + ("deg", "\u{b0}"), + ("deg;", "\u{b0}"), + ("delta;", "\u{3b4}"), + ("demptyv;", "\u{29b1}"), + ("dfisht;", "\u{297f}"), + ("dfr;", "\u{1d521}"), + ("dharl;", "\u{21c3}"), + ("dharr;", "\u{21c2}"), + ("diam;", "\u{22c4}"), + ("diamond;", "\u{22c4}"), + ("diamondsuit;", "\u{2666}"), + ("diams;", "\u{2666}"), + ("die;", "\u{a8}"), + ("digamma;", "\u{3dd}"), + ("disin;", "\u{22f2}"), + ("div;", "\u{f7}"), + ("divide", "\u{f7}"), + ("divide;", "\u{f7}"), + ("divideontimes;", "\u{22c7}"), + ("divonx;", "\u{22c7}"), + ("djcy;", "\u{452}"), + ("dlcorn;", "\u{231e}"), + ("dlcrop;", "\u{230d}"), + ("dollar;", "$"), + ("dopf;", "\u{1d555}"), + ("dot;", "\u{2d9}"), + ("doteq;", "\u{2250}"), + ("doteqdot;", "\u{2251}"), + ("dotminus;", "\u{2238}"), + ("dotplus;", "\u{2214}"), + ("dotsquare;", "\u{22a1}"), + ("doublebarwedge;", "\u{2306}"), + ("downarrow;", "\u{2193}"), + ("downdownarrows;", "\u{21ca}"), + ("downharpoonleft;", "\u{21c3}"), + ("downharpoonright;", "\u{21c2}"), + ("drbkarow;", "\u{2910}"), + ("drcorn;", "\u{231f}"), + ("drcrop;", "\u{230c}"), + ("dscr;", "\u{1d4b9}"), + ("dscy;", "\u{455}"), + ("dsol;", "\u{29f6}"), + ("dstrok;", "\u{111}"), + ("dtdot;", "\u{22f1}"), + ("dtri;", "\u{25bf}"), + ("dtrif;", "\u{25be}"), + ("duarr;", "\u{21f5}"), + ("duhar;", "\u{296f}"), + ("dwangle;", "\u{29a6}"), + ("dzcy;", "\u{45f}"), + ("dzigrarr;", "\u{27ff}"), + ("eDDot;", "\u{2a77}"), + ("eDot;", "\u{2251}"), + ("eacute", "\u{e9}"), + ("eacute;", "\u{e9}"), + ("easter;", "\u{2a6e}"), + ("ecaron;", "\u{11b}"), + ("ecir;", "\u{2256}"), + ("ecirc", "\u{ea}"), + ("ecirc;", "\u{ea}"), + ("ecolon;", "\u{2255}"), + ("ecy;", "\u{44d}"), + ("edot;", "\u{117}"), + ("ee;", "\u{2147}"), + ("efDot;", "\u{2252}"), + ("efr;", "\u{1d522}"), + ("eg;", "\u{2a9a}"), + ("egrave", "\u{e8}"), + ("egrave;", "\u{e8}"), + ("egs;", "\u{2a96}"), + ("egsdot;", "\u{2a98}"), + ("el;", "\u{2a99}"), + ("elinters;", "\u{23e7}"), + ("ell;", "\u{2113}"), + ("els;", "\u{2a95}"), + ("elsdot;", "\u{2a97}"), + ("emacr;", "\u{113}"), + ("empty;", "\u{2205}"), + ("emptyset;", "\u{2205}"), + ("emptyv;", "\u{2205}"), + ("emsp13;", "\u{2004}"), + ("emsp14;", "\u{2005}"), + ("emsp;", "\u{2003}"), + ("eng;", "\u{14b}"), + ("ensp;", "\u{2002}"), + ("eogon;", "\u{119}"), + ("eopf;", "\u{1d556}"), + ("epar;", "\u{22d5}"), + ("eparsl;", "\u{29e3}"), + ("eplus;", "\u{2a71}"), + ("epsi;", "\u{3b5}"), + ("epsilon;", "\u{3b5}"), + ("epsiv;", "\u{3f5}"), + ("eqcirc;", "\u{2256}"), + ("eqcolon;", "\u{2255}"), + ("eqsim;", "\u{2242}"), + ("eqslantgtr;", "\u{2a96}"), + ("eqslantless;", "\u{2a95}"), + ("equals;", "="), + ("equest;", "\u{225f}"), + ("equiv;", "\u{2261}"), + ("equivDD;", "\u{2a78}"), + ("eqvparsl;", "\u{29e5}"), + ("erDot;", "\u{2253}"), + ("erarr;", "\u{2971}"), + ("escr;", "\u{212f}"), + ("esdot;", "\u{2250}"), + ("esim;", "\u{2242}"), + ("eta;", "\u{3b7}"), + ("eth", "\u{f0}"), + ("eth;", "\u{f0}"), + ("euml", "\u{eb}"), + ("euml;", "\u{eb}"), + ("euro;", "\u{20ac}"), + ("excl;", "!"), + ("exist;", "\u{2203}"), + ("expectation;", "\u{2130}"), + ("exponentiale;", "\u{2147}"), + ("fallingdotseq;", "\u{2252}"), + ("fcy;", "\u{444}"), + ("female;", "\u{2640}"), + ("ffilig;", "\u{fb03}"), + ("fflig;", "\u{fb00}"), + ("ffllig;", "\u{fb04}"), + ("ffr;", "\u{1d523}"), + ("filig;", "\u{fb01}"), + ("fjlig;", "fj"), + ("flat;", "\u{266d}"), + ("fllig;", "\u{fb02}"), + ("fltns;", "\u{25b1}"), + ("fnof;", "\u{192}"), + ("fopf;", "\u{1d557}"), + ("forall;", "\u{2200}"), + ("fork;", "\u{22d4}"), + ("forkv;", "\u{2ad9}"), + ("fpartint;", "\u{2a0d}"), + ("frac12", "\u{bd}"), + ("frac12;", "\u{bd}"), + ("frac13;", "\u{2153}"), + ("frac14", "\u{bc}"), + ("frac14;", "\u{bc}"), + ("frac15;", "\u{2155}"), + ("frac16;", "\u{2159}"), + ("frac18;", "\u{215b}"), + ("frac23;", "\u{2154}"), + ("frac25;", "\u{2156}"), + ("frac34", "\u{be}"), + ("frac34;", "\u{be}"), + ("frac35;", "\u{2157}"), + ("frac38;", "\u{215c}"), + ("frac45;", "\u{2158}"), + ("frac56;", "\u{215a}"), + ("frac58;", "\u{215d}"), + ("frac78;", "\u{215e}"), + ("frasl;", "\u{2044}"), + ("frown;", "\u{2322}"), + ("fscr;", "\u{1d4bb}"), + ("gE;", "\u{2267}"), + ("gEl;", "\u{2a8c}"), + ("gacute;", "\u{1f5}"), + ("gamma;", "\u{3b3}"), + ("gammad;", "\u{3dd}"), + ("gap;", "\u{2a86}"), + ("gbreve;", "\u{11f}"), + ("gcirc;", "\u{11d}"), + ("gcy;", "\u{433}"), + ("gdot;", "\u{121}"), + ("ge;", "\u{2265}"), + ("gel;", "\u{22db}"), + ("geq;", "\u{2265}"), + ("geqq;", "\u{2267}"), + ("geqslant;", "\u{2a7e}"), + ("ges;", "\u{2a7e}"), + ("gescc;", "\u{2aa9}"), + ("gesdot;", "\u{2a80}"), + ("gesdoto;", "\u{2a82}"), + ("gesdotol;", "\u{2a84}"), + ("gesl;", "\u{22db}\u{fe00}"), + ("gesles;", "\u{2a94}"), + ("gfr;", "\u{1d524}"), + ("gg;", "\u{226b}"), + ("ggg;", "\u{22d9}"), + ("gimel;", "\u{2137}"), + ("gjcy;", "\u{453}"), + ("gl;", "\u{2277}"), + ("glE;", "\u{2a92}"), + ("gla;", "\u{2aa5}"), + ("glj;", "\u{2aa4}"), + ("gnE;", "\u{2269}"), + ("gnap;", "\u{2a8a}"), + ("gnapprox;", "\u{2a8a}"), + ("gne;", "\u{2a88}"), + ("gneq;", "\u{2a88}"), + ("gneqq;", "\u{2269}"), + ("gnsim;", "\u{22e7}"), + ("gopf;", "\u{1d558}"), + ("grave;", "`"), + ("gscr;", "\u{210a}"), + ("gsim;", "\u{2273}"), + ("gsime;", "\u{2a8e}"), + ("gsiml;", "\u{2a90}"), + ("gt", ">"), + ("gt;", ">"), + ("gtcc;", "\u{2aa7}"), + ("gtcir;", "\u{2a7a}"), + ("gtdot;", "\u{22d7}"), + ("gtlPar;", "\u{2995}"), + ("gtquest;", "\u{2a7c}"), + ("gtrapprox;", "\u{2a86}"), + ("gtrarr;", "\u{2978}"), + ("gtrdot;", "\u{22d7}"), + ("gtreqless;", "\u{22db}"), + ("gtreqqless;", "\u{2a8c}"), + ("gtrless;", "\u{2277}"), + ("gtrsim;", "\u{2273}"), + ("gvertneqq;", "\u{2269}\u{fe00}"), + ("gvnE;", "\u{2269}\u{fe00}"), + ("hArr;", "\u{21d4}"), + ("hairsp;", "\u{200a}"), + ("half;", "\u{bd}"), + ("hamilt;", "\u{210b}"), + ("hardcy;", "\u{44a}"), + ("harr;", "\u{2194}"), + ("harrcir;", "\u{2948}"), + ("harrw;", "\u{21ad}"), + ("hbar;", "\u{210f}"), + ("hcirc;", "\u{125}"), + ("hearts;", "\u{2665}"), + ("heartsuit;", "\u{2665}"), + ("hellip;", "\u{2026}"), + ("hercon;", "\u{22b9}"), + ("hfr;", "\u{1d525}"), + ("hksearow;", "\u{2925}"), + ("hkswarow;", "\u{2926}"), + ("hoarr;", "\u{21ff}"), + ("homtht;", "\u{223b}"), + ("hookleftarrow;", "\u{21a9}"), + ("hookrightarrow;", "\u{21aa}"), + ("hopf;", "\u{1d559}"), + ("horbar;", "\u{2015}"), + ("hscr;", "\u{1d4bd}"), + ("hslash;", "\u{210f}"), + ("hstrok;", "\u{127}"), + ("hybull;", "\u{2043}"), + ("hyphen;", "\u{2010}"), + ("iacute", "\u{ed}"), + ("iacute;", "\u{ed}"), + ("ic;", "\u{2063}"), + ("icirc", "\u{ee}"), + ("icirc;", "\u{ee}"), + ("icy;", "\u{438}"), + ("iecy;", "\u{435}"), + ("iexcl", "\u{a1}"), + ("iexcl;", "\u{a1}"), + ("iff;", "\u{21d4}"), + ("ifr;", "\u{1d526}"), + ("igrave", "\u{ec}"), + ("igrave;", "\u{ec}"), + ("ii;", "\u{2148}"), + ("iiiint;", "\u{2a0c}"), + ("iiint;", "\u{222d}"), + ("iinfin;", "\u{29dc}"), + ("iiota;", "\u{2129}"), + ("ijlig;", "\u{133}"), + ("imacr;", "\u{12b}"), + ("image;", "\u{2111}"), + ("imagline;", "\u{2110}"), + ("imagpart;", "\u{2111}"), + ("imath;", "\u{131}"), + ("imof;", "\u{22b7}"), + ("imped;", "\u{1b5}"), + ("in;", "\u{2208}"), + ("incare;", "\u{2105}"), + ("infin;", "\u{221e}"), + ("infintie;", "\u{29dd}"), + ("inodot;", "\u{131}"), + ("int;", "\u{222b}"), + ("intcal;", "\u{22ba}"), + ("integers;", "\u{2124}"), + ("intercal;", "\u{22ba}"), + ("intlarhk;", "\u{2a17}"), + ("intprod;", "\u{2a3c}"), + ("iocy;", "\u{451}"), + ("iogon;", "\u{12f}"), + ("iopf;", "\u{1d55a}"), + ("iota;", "\u{3b9}"), + ("iprod;", "\u{2a3c}"), + ("iquest", "\u{bf}"), + ("iquest;", "\u{bf}"), + ("iscr;", "\u{1d4be}"), + ("isin;", "\u{2208}"), + ("isinE;", "\u{22f9}"), + ("isindot;", "\u{22f5}"), + ("isins;", "\u{22f4}"), + ("isinsv;", "\u{22f3}"), + ("isinv;", "\u{2208}"), + ("it;", "\u{2062}"), + ("itilde;", "\u{129}"), + ("iukcy;", "\u{456}"), + ("iuml", "\u{ef}"), + ("iuml;", "\u{ef}"), + ("jcirc;", "\u{135}"), + ("jcy;", "\u{439}"), + ("jfr;", "\u{1d527}"), + ("jmath;", "\u{237}"), + ("jopf;", "\u{1d55b}"), + ("jscr;", "\u{1d4bf}"), + ("jsercy;", "\u{458}"), + ("jukcy;", "\u{454}"), + ("kappa;", "\u{3ba}"), + ("kappav;", "\u{3f0}"), + ("kcedil;", "\u{137}"), + ("kcy;", "\u{43a}"), + ("kfr;", "\u{1d528}"), + ("kgreen;", "\u{138}"), + ("khcy;", "\u{445}"), + ("kjcy;", "\u{45c}"), + ("kopf;", "\u{1d55c}"), + ("kscr;", "\u{1d4c0}"), + ("lAarr;", "\u{21da}"), + ("lArr;", "\u{21d0}"), + ("lAtail;", "\u{291b}"), + ("lBarr;", "\u{290e}"), + ("lE;", "\u{2266}"), + ("lEg;", "\u{2a8b}"), + ("lHar;", "\u{2962}"), + ("lacute;", "\u{13a}"), + ("laemptyv;", "\u{29b4}"), + ("lagran;", "\u{2112}"), + ("lambda;", "\u{3bb}"), + ("lang;", "\u{27e8}"), + ("langd;", "\u{2991}"), + ("langle;", "\u{27e8}"), + ("lap;", "\u{2a85}"), + ("laquo", "\u{ab}"), + ("laquo;", "\u{ab}"), + ("larr;", "\u{2190}"), + ("larrb;", "\u{21e4}"), + ("larrbfs;", "\u{291f}"), + ("larrfs;", "\u{291d}"), + ("larrhk;", "\u{21a9}"), + ("larrlp;", "\u{21ab}"), + ("larrpl;", "\u{2939}"), + ("larrsim;", "\u{2973}"), + ("larrtl;", "\u{21a2}"), + ("lat;", "\u{2aab}"), + ("latail;", "\u{2919}"), + ("late;", "\u{2aad}"), + ("lates;", "\u{2aad}\u{fe00}"), + ("lbarr;", "\u{290c}"), + ("lbbrk;", "\u{2772}"), + ("lbrace;", "{"), + ("lbrack;", "["), + ("lbrke;", "\u{298b}"), + ("lbrksld;", "\u{298f}"), + ("lbrkslu;", "\u{298d}"), + ("lcaron;", "\u{13e}"), + ("lcedil;", "\u{13c}"), + ("lceil;", "\u{2308}"), + ("lcub;", "{"), + ("lcy;", "\u{43b}"), + ("ldca;", "\u{2936}"), + ("ldquo;", "\u{201c}"), + ("ldquor;", "\u{201e}"), + ("ldrdhar;", "\u{2967}"), + ("ldrushar;", "\u{294b}"), + ("ldsh;", "\u{21b2}"), + ("le;", "\u{2264}"), + ("leftarrow;", "\u{2190}"), + ("leftarrowtail;", "\u{21a2}"), + ("leftharpoondown;", "\u{21bd}"), + ("leftharpoonup;", "\u{21bc}"), + ("leftleftarrows;", "\u{21c7}"), + ("leftrightarrow;", "\u{2194}"), + ("leftrightarrows;", "\u{21c6}"), + ("leftrightharpoons;", "\u{21cb}"), + ("leftrightsquigarrow;", "\u{21ad}"), + ("leftthreetimes;", "\u{22cb}"), + ("leg;", "\u{22da}"), + ("leq;", "\u{2264}"), + ("leqq;", "\u{2266}"), + ("leqslant;", "\u{2a7d}"), + ("les;", "\u{2a7d}"), + ("lescc;", "\u{2aa8}"), + ("lesdot;", "\u{2a7f}"), + ("lesdoto;", "\u{2a81}"), + ("lesdotor;", "\u{2a83}"), + ("lesg;", "\u{22da}\u{fe00}"), + ("lesges;", "\u{2a93}"), + ("lessapprox;", "\u{2a85}"), + ("lessdot;", "\u{22d6}"), + ("lesseqgtr;", "\u{22da}"), + ("lesseqqgtr;", "\u{2a8b}"), + ("lessgtr;", "\u{2276}"), + ("lesssim;", "\u{2272}"), + ("lfisht;", "\u{297c}"), + ("lfloor;", "\u{230a}"), + ("lfr;", "\u{1d529}"), + ("lg;", "\u{2276}"), + ("lgE;", "\u{2a91}"), + ("lhard;", "\u{21bd}"), + ("lharu;", "\u{21bc}"), + ("lharul;", "\u{296a}"), + ("lhblk;", "\u{2584}"), + ("ljcy;", "\u{459}"), + ("ll;", "\u{226a}"), + ("llarr;", "\u{21c7}"), + ("llcorner;", "\u{231e}"), + ("llhard;", "\u{296b}"), + ("lltri;", "\u{25fa}"), + ("lmidot;", "\u{140}"), + ("lmoust;", "\u{23b0}"), + ("lmoustache;", "\u{23b0}"), + ("lnE;", "\u{2268}"), + ("lnap;", "\u{2a89}"), + ("lnapprox;", "\u{2a89}"), + ("lne;", "\u{2a87}"), + ("lneq;", "\u{2a87}"), + ("lneqq;", "\u{2268}"), + ("lnsim;", "\u{22e6}"), + ("loang;", "\u{27ec}"), + ("loarr;", "\u{21fd}"), + ("lobrk;", "\u{27e6}"), + ("longleftarrow;", "\u{27f5}"), + ("longleftrightarrow;", "\u{27f7}"), + ("longmapsto;", "\u{27fc}"), + ("longrightarrow;", "\u{27f6}"), + ("looparrowleft;", "\u{21ab}"), + ("looparrowright;", "\u{21ac}"), + ("lopar;", "\u{2985}"), + ("lopf;", "\u{1d55d}"), + ("loplus;", "\u{2a2d}"), + ("lotimes;", "\u{2a34}"), + ("lowast;", "\u{2217}"), + ("lowbar;", "_"), + ("loz;", "\u{25ca}"), + ("lozenge;", "\u{25ca}"), + ("lozf;", "\u{29eb}"), + ("lpar;", "("), + ("lparlt;", "\u{2993}"), + ("lrarr;", "\u{21c6}"), + ("lrcorner;", "\u{231f}"), + ("lrhar;", "\u{21cb}"), + ("lrhard;", "\u{296d}"), + ("lrm;", "\u{200e}"), + ("lrtri;", "\u{22bf}"), + ("lsaquo;", "\u{2039}"), + ("lscr;", "\u{1d4c1}"), + ("lsh;", "\u{21b0}"), + ("lsim;", "\u{2272}"), + ("lsime;", "\u{2a8d}"), + ("lsimg;", "\u{2a8f}"), + ("lsqb;", "["), + ("lsquo;", "\u{2018}"), + ("lsquor;", "\u{201a}"), + ("lstrok;", "\u{142}"), + ("lt", "<"), + ("lt;", "<"), + ("ltcc;", "\u{2aa6}"), + ("ltcir;", "\u{2a79}"), + ("ltdot;", "\u{22d6}"), + ("lthree;", "\u{22cb}"), + ("ltimes;", "\u{22c9}"), + ("ltlarr;", "\u{2976}"), + ("ltquest;", "\u{2a7b}"), + ("ltrPar;", "\u{2996}"), + ("ltri;", "\u{25c3}"), + ("ltrie;", "\u{22b4}"), + ("ltrif;", "\u{25c2}"), + ("lurdshar;", "\u{294a}"), + ("luruhar;", "\u{2966}"), + ("lvertneqq;", "\u{2268}\u{fe00}"), + ("lvnE;", "\u{2268}\u{fe00}"), + ("mDDot;", "\u{223a}"), + ("macr", "\u{af}"), + ("macr;", "\u{af}"), + ("male;", "\u{2642}"), + ("malt;", "\u{2720}"), + ("maltese;", "\u{2720}"), + ("map;", "\u{21a6}"), + ("mapsto;", "\u{21a6}"), + ("mapstodown;", "\u{21a7}"), + ("mapstoleft;", "\u{21a4}"), + ("mapstoup;", "\u{21a5}"), + ("marker;", "\u{25ae}"), + ("mcomma;", "\u{2a29}"), + ("mcy;", "\u{43c}"), + ("mdash;", "\u{2014}"), + ("measuredangle;", "\u{2221}"), + ("mfr;", "\u{1d52a}"), + ("mho;", "\u{2127}"), + ("micro", "\u{b5}"), + ("micro;", "\u{b5}"), + ("mid;", "\u{2223}"), + ("midast;", "*"), + ("midcir;", "\u{2af0}"), + ("middot", "\u{b7}"), + ("middot;", "\u{b7}"), + ("minus;", "\u{2212}"), + ("minusb;", "\u{229f}"), + ("minusd;", "\u{2238}"), + ("minusdu;", "\u{2a2a}"), + ("mlcp;", "\u{2adb}"), + ("mldr;", "\u{2026}"), + ("mnplus;", "\u{2213}"), + ("models;", "\u{22a7}"), + ("mopf;", "\u{1d55e}"), + ("mp;", "\u{2213}"), + ("mscr;", "\u{1d4c2}"), + ("mstpos;", "\u{223e}"), + ("mu;", "\u{3bc}"), + ("multimap;", "\u{22b8}"), + ("mumap;", "\u{22b8}"), + ("nGg;", "\u{22d9}\u{338}"), + ("nGt;", "\u{226b}\u{20d2}"), + ("nGtv;", "\u{226b}\u{338}"), + ("nLeftarrow;", "\u{21cd}"), + ("nLeftrightarrow;", "\u{21ce}"), + ("nLl;", "\u{22d8}\u{338}"), + ("nLt;", "\u{226a}\u{20d2}"), + ("nLtv;", "\u{226a}\u{338}"), + ("nRightarrow;", "\u{21cf}"), + ("nVDash;", "\u{22af}"), + ("nVdash;", "\u{22ae}"), + ("nabla;", "\u{2207}"), + ("nacute;", "\u{144}"), + ("nang;", "\u{2220}\u{20d2}"), + ("nap;", "\u{2249}"), + ("napE;", "\u{2a70}\u{338}"), + ("napid;", "\u{224b}\u{338}"), + ("napos;", "\u{149}"), + ("napprox;", "\u{2249}"), + ("natur;", "\u{266e}"), + ("natural;", "\u{266e}"), + ("naturals;", "\u{2115}"), + ("nbsp", "\u{a0}"), + ("nbsp;", "\u{a0}"), + ("nbump;", "\u{224e}\u{338}"), + ("nbumpe;", "\u{224f}\u{338}"), + ("ncap;", "\u{2a43}"), + ("ncaron;", "\u{148}"), + ("ncedil;", "\u{146}"), + ("ncong;", "\u{2247}"), + ("ncongdot;", "\u{2a6d}\u{338}"), + ("ncup;", "\u{2a42}"), + ("ncy;", "\u{43d}"), + ("ndash;", "\u{2013}"), + ("ne;", "\u{2260}"), + ("neArr;", "\u{21d7}"), + ("nearhk;", "\u{2924}"), + ("nearr;", "\u{2197}"), + ("nearrow;", "\u{2197}"), + ("nedot;", "\u{2250}\u{338}"), + ("nequiv;", "\u{2262}"), + ("nesear;", "\u{2928}"), + ("nesim;", "\u{2242}\u{338}"), + ("nexist;", "\u{2204}"), + ("nexists;", "\u{2204}"), + ("nfr;", "\u{1d52b}"), + ("ngE;", "\u{2267}\u{338}"), + ("nge;", "\u{2271}"), + ("ngeq;", "\u{2271}"), + ("ngeqq;", "\u{2267}\u{338}"), + ("ngeqslant;", "\u{2a7e}\u{338}"), + ("nges;", "\u{2a7e}\u{338}"), + ("ngsim;", "\u{2275}"), + ("ngt;", "\u{226f}"), + ("ngtr;", "\u{226f}"), + ("nhArr;", "\u{21ce}"), + ("nharr;", "\u{21ae}"), + ("nhpar;", "\u{2af2}"), + ("ni;", "\u{220b}"), + ("nis;", "\u{22fc}"), + ("nisd;", "\u{22fa}"), + ("niv;", "\u{220b}"), + ("njcy;", "\u{45a}"), + ("nlArr;", "\u{21cd}"), + ("nlE;", "\u{2266}\u{338}"), + ("nlarr;", "\u{219a}"), + ("nldr;", "\u{2025}"), + ("nle;", "\u{2270}"), + ("nleftarrow;", "\u{219a}"), + ("nleftrightarrow;", "\u{21ae}"), + ("nleq;", "\u{2270}"), + ("nleqq;", "\u{2266}\u{338}"), + ("nleqslant;", "\u{2a7d}\u{338}"), + ("nles;", "\u{2a7d}\u{338}"), + ("nless;", "\u{226e}"), + ("nlsim;", "\u{2274}"), + ("nlt;", "\u{226e}"), + ("nltri;", "\u{22ea}"), + ("nltrie;", "\u{22ec}"), + ("nmid;", "\u{2224}"), + ("nopf;", "\u{1d55f}"), + ("not", "\u{ac}"), + ("not;", "\u{ac}"), + ("notin;", "\u{2209}"), + ("notinE;", "\u{22f9}\u{338}"), + ("notindot;", "\u{22f5}\u{338}"), + ("notinva;", "\u{2209}"), + ("notinvb;", "\u{22f7}"), + ("notinvc;", "\u{22f6}"), + ("notni;", "\u{220c}"), + ("notniva;", "\u{220c}"), + ("notnivb;", "\u{22fe}"), + ("notnivc;", "\u{22fd}"), + ("npar;", "\u{2226}"), + ("nparallel;", "\u{2226}"), + ("nparsl;", "\u{2afd}\u{20e5}"), + ("npart;", "\u{2202}\u{338}"), + ("npolint;", "\u{2a14}"), + ("npr;", "\u{2280}"), + ("nprcue;", "\u{22e0}"), + ("npre;", "\u{2aaf}\u{338}"), + ("nprec;", "\u{2280}"), + ("npreceq;", "\u{2aaf}\u{338}"), + ("nrArr;", "\u{21cf}"), + ("nrarr;", "\u{219b}"), + ("nrarrc;", "\u{2933}\u{338}"), + ("nrarrw;", "\u{219d}\u{338}"), + ("nrightarrow;", "\u{219b}"), + ("nrtri;", "\u{22eb}"), + ("nrtrie;", "\u{22ed}"), + ("nsc;", "\u{2281}"), + ("nsccue;", "\u{22e1}"), + ("nsce;", "\u{2ab0}\u{338}"), + ("nscr;", "\u{1d4c3}"), + ("nshortmid;", "\u{2224}"), + ("nshortparallel;", "\u{2226}"), + ("nsim;", "\u{2241}"), + ("nsime;", "\u{2244}"), + ("nsimeq;", "\u{2244}"), + ("nsmid;", "\u{2224}"), + ("nspar;", "\u{2226}"), + ("nsqsube;", "\u{22e2}"), + ("nsqsupe;", "\u{22e3}"), + ("nsub;", "\u{2284}"), + ("nsubE;", "\u{2ac5}\u{338}"), + ("nsube;", "\u{2288}"), + ("nsubset;", "\u{2282}\u{20d2}"), + ("nsubseteq;", "\u{2288}"), + ("nsubseteqq;", "\u{2ac5}\u{338}"), + ("nsucc;", "\u{2281}"), + ("nsucceq;", "\u{2ab0}\u{338}"), + ("nsup;", "\u{2285}"), + ("nsupE;", "\u{2ac6}\u{338}"), + ("nsupe;", "\u{2289}"), + ("nsupset;", "\u{2283}\u{20d2}"), + ("nsupseteq;", "\u{2289}"), + ("nsupseteqq;", "\u{2ac6}\u{338}"), + ("ntgl;", "\u{2279}"), + ("ntilde", "\u{f1}"), + ("ntilde;", "\u{f1}"), + ("ntlg;", "\u{2278}"), + ("ntriangleleft;", "\u{22ea}"), + ("ntrianglelefteq;", "\u{22ec}"), + ("ntriangleright;", "\u{22eb}"), + ("ntrianglerighteq;", "\u{22ed}"), + ("nu;", "\u{3bd}"), + ("num;", "#"), + ("numero;", "\u{2116}"), + ("numsp;", "\u{2007}"), + ("nvDash;", "\u{22ad}"), + ("nvHarr;", "\u{2904}"), + ("nvap;", "\u{224d}\u{20d2}"), + ("nvdash;", "\u{22ac}"), + ("nvge;", "\u{2265}\u{20d2}"), + ("nvgt;", ">\u{20d2}"), + ("nvinfin;", "\u{29de}"), + ("nvlArr;", "\u{2902}"), + ("nvle;", "\u{2264}\u{20d2}"), + ("nvlt;", "<\u{20d2}"), + ("nvltrie;", "\u{22b4}\u{20d2}"), + ("nvrArr;", "\u{2903}"), + ("nvrtrie;", "\u{22b5}\u{20d2}"), + ("nvsim;", "\u{223c}\u{20d2}"), + ("nwArr;", "\u{21d6}"), + ("nwarhk;", "\u{2923}"), + ("nwarr;", "\u{2196}"), + ("nwarrow;", "\u{2196}"), + ("nwnear;", "\u{2927}"), + ("oS;", "\u{24c8}"), + ("oacute", "\u{f3}"), + ("oacute;", "\u{f3}"), + ("oast;", "\u{229b}"), + ("ocir;", "\u{229a}"), + ("ocirc", "\u{f4}"), + ("ocirc;", "\u{f4}"), + ("ocy;", "\u{43e}"), + ("odash;", "\u{229d}"), + ("odblac;", "\u{151}"), + ("odiv;", "\u{2a38}"), + ("odot;", "\u{2299}"), + ("odsold;", "\u{29bc}"), + ("oelig;", "\u{153}"), + ("ofcir;", "\u{29bf}"), + ("ofr;", "\u{1d52c}"), + ("ogon;", "\u{2db}"), + ("ograve", "\u{f2}"), + ("ograve;", "\u{f2}"), + ("ogt;", "\u{29c1}"), + ("ohbar;", "\u{29b5}"), + ("ohm;", "\u{3a9}"), + ("oint;", "\u{222e}"), + ("olarr;", "\u{21ba}"), + ("olcir;", "\u{29be}"), + ("olcross;", "\u{29bb}"), + ("oline;", "\u{203e}"), + ("olt;", "\u{29c0}"), + ("omacr;", "\u{14d}"), + ("omega;", "\u{3c9}"), + ("omicron;", "\u{3bf}"), + ("omid;", "\u{29b6}"), + ("ominus;", "\u{2296}"), + ("oopf;", "\u{1d560}"), + ("opar;", "\u{29b7}"), + ("operp;", "\u{29b9}"), + ("oplus;", "\u{2295}"), + ("or;", "\u{2228}"), + ("orarr;", "\u{21bb}"), + ("ord;", "\u{2a5d}"), + ("order;", "\u{2134}"), + ("orderof;", "\u{2134}"), + ("ordf", "\u{aa}"), + ("ordf;", "\u{aa}"), + ("ordm", "\u{ba}"), + ("ordm;", "\u{ba}"), + ("origof;", "\u{22b6}"), + ("oror;", "\u{2a56}"), + ("orslope;", "\u{2a57}"), + ("orv;", "\u{2a5b}"), + ("oscr;", "\u{2134}"), + ("oslash", "\u{f8}"), + ("oslash;", "\u{f8}"), + ("osol;", "\u{2298}"), + ("otilde", "\u{f5}"), + ("otilde;", "\u{f5}"), + ("otimes;", "\u{2297}"), + ("otimesas;", "\u{2a36}"), + ("ouml", "\u{f6}"), + ("ouml;", "\u{f6}"), + ("ovbar;", "\u{233d}"), + ("par;", "\u{2225}"), + ("para", "\u{b6}"), + ("para;", "\u{b6}"), + ("parallel;", "\u{2225}"), + ("parsim;", "\u{2af3}"), + ("parsl;", "\u{2afd}"), + ("part;", "\u{2202}"), + ("pcy;", "\u{43f}"), + ("percnt;", "%"), + ("period;", "."), + ("permil;", "\u{2030}"), + ("perp;", "\u{22a5}"), + ("pertenk;", "\u{2031}"), + ("pfr;", "\u{1d52d}"), + ("phi;", "\u{3c6}"), + ("phiv;", "\u{3d5}"), + ("phmmat;", "\u{2133}"), + ("phone;", "\u{260e}"), + ("pi;", "\u{3c0}"), + ("pitchfork;", "\u{22d4}"), + ("piv;", "\u{3d6}"), + ("planck;", "\u{210f}"), + ("planckh;", "\u{210e}"), + ("plankv;", "\u{210f}"), + ("plus;", "+"), + ("plusacir;", "\u{2a23}"), + ("plusb;", "\u{229e}"), + ("pluscir;", "\u{2a22}"), + ("plusdo;", "\u{2214}"), + ("plusdu;", "\u{2a25}"), + ("pluse;", "\u{2a72}"), + ("plusmn", "\u{b1}"), + ("plusmn;", "\u{b1}"), + ("plussim;", "\u{2a26}"), + ("plustwo;", "\u{2a27}"), + ("pm;", "\u{b1}"), + ("pointint;", "\u{2a15}"), + ("popf;", "\u{1d561}"), + ("pound", "\u{a3}"), + ("pound;", "\u{a3}"), + ("pr;", "\u{227a}"), + ("prE;", "\u{2ab3}"), + ("prap;", "\u{2ab7}"), + ("prcue;", "\u{227c}"), + ("pre;", "\u{2aaf}"), + ("prec;", "\u{227a}"), + ("precapprox;", "\u{2ab7}"), + ("preccurlyeq;", "\u{227c}"), + ("preceq;", "\u{2aaf}"), + ("precnapprox;", "\u{2ab9}"), + ("precneqq;", "\u{2ab5}"), + ("precnsim;", "\u{22e8}"), + ("precsim;", "\u{227e}"), + ("prime;", "\u{2032}"), + ("primes;", "\u{2119}"), + ("prnE;", "\u{2ab5}"), + ("prnap;", "\u{2ab9}"), + ("prnsim;", "\u{22e8}"), + ("prod;", "\u{220f}"), + ("profalar;", "\u{232e}"), + ("profline;", "\u{2312}"), + ("profsurf;", "\u{2313}"), + ("prop;", "\u{221d}"), + ("propto;", "\u{221d}"), + ("prsim;", "\u{227e}"), + ("prurel;", "\u{22b0}"), + ("pscr;", "\u{1d4c5}"), + ("psi;", "\u{3c8}"), + ("puncsp;", "\u{2008}"), + ("qfr;", "\u{1d52e}"), + ("qint;", "\u{2a0c}"), + ("qopf;", "\u{1d562}"), + ("qprime;", "\u{2057}"), + ("qscr;", "\u{1d4c6}"), + ("quaternions;", "\u{210d}"), + ("quatint;", "\u{2a16}"), + ("quest;", "?"), + ("questeq;", "\u{225f}"), + ("quot", "\""), + ("quot;", "\""), + ("rAarr;", "\u{21db}"), + ("rArr;", "\u{21d2}"), + ("rAtail;", "\u{291c}"), + ("rBarr;", "\u{290f}"), + ("rHar;", "\u{2964}"), + ("race;", "\u{223d}\u{331}"), + ("racute;", "\u{155}"), + ("radic;", "\u{221a}"), + ("raemptyv;", "\u{29b3}"), + ("rang;", "\u{27e9}"), + ("rangd;", "\u{2992}"), + ("range;", "\u{29a5}"), + ("rangle;", "\u{27e9}"), + ("raquo", "\u{bb}"), + ("raquo;", "\u{bb}"), + ("rarr;", "\u{2192}"), + ("rarrap;", "\u{2975}"), + ("rarrb;", "\u{21e5}"), + ("rarrbfs;", "\u{2920}"), + ("rarrc;", "\u{2933}"), + ("rarrfs;", "\u{291e}"), + ("rarrhk;", "\u{21aa}"), + ("rarrlp;", "\u{21ac}"), + ("rarrpl;", "\u{2945}"), + ("rarrsim;", "\u{2974}"), + ("rarrtl;", "\u{21a3}"), + ("rarrw;", "\u{219d}"), + ("ratail;", "\u{291a}"), + ("ratio;", "\u{2236}"), + ("rationals;", "\u{211a}"), + ("rbarr;", "\u{290d}"), + ("rbbrk;", "\u{2773}"), + ("rbrace;", "}"), + ("rbrack;", "]"), + ("rbrke;", "\u{298c}"), + ("rbrksld;", "\u{298e}"), + ("rbrkslu;", "\u{2990}"), + ("rcaron;", "\u{159}"), + ("rcedil;", "\u{157}"), + ("rceil;", "\u{2309}"), + ("rcub;", "}"), + ("rcy;", "\u{440}"), + ("rdca;", "\u{2937}"), + ("rdldhar;", "\u{2969}"), + ("rdquo;", "\u{201d}"), + ("rdquor;", "\u{201d}"), + ("rdsh;", "\u{21b3}"), + ("real;", "\u{211c}"), + ("realine;", "\u{211b}"), + ("realpart;", "\u{211c}"), + ("reals;", "\u{211d}"), + ("rect;", "\u{25ad}"), + ("reg", "\u{ae}"), + ("reg;", "\u{ae}"), + ("rfisht;", "\u{297d}"), + ("rfloor;", "\u{230b}"), + ("rfr;", "\u{1d52f}"), + ("rhard;", "\u{21c1}"), + ("rharu;", "\u{21c0}"), + ("rharul;", "\u{296c}"), + ("rho;", "\u{3c1}"), + ("rhov;", "\u{3f1}"), + ("rightarrow;", "\u{2192}"), + ("rightarrowtail;", "\u{21a3}"), + ("rightharpoondown;", "\u{21c1}"), + ("rightharpoonup;", "\u{21c0}"), + ("rightleftarrows;", "\u{21c4}"), + ("rightleftharpoons;", "\u{21cc}"), + ("rightrightarrows;", "\u{21c9}"), + ("rightsquigarrow;", "\u{219d}"), + ("rightthreetimes;", "\u{22cc}"), + ("ring;", "\u{2da}"), + ("risingdotseq;", "\u{2253}"), + ("rlarr;", "\u{21c4}"), + ("rlhar;", "\u{21cc}"), + ("rlm;", "\u{200f}"), + ("rmoust;", "\u{23b1}"), + ("rmoustache;", "\u{23b1}"), + ("rnmid;", "\u{2aee}"), + ("roang;", "\u{27ed}"), + ("roarr;", "\u{21fe}"), + ("robrk;", "\u{27e7}"), + ("ropar;", "\u{2986}"), + ("ropf;", "\u{1d563}"), + ("roplus;", "\u{2a2e}"), + ("rotimes;", "\u{2a35}"), + ("rpar;", ")"), + ("rpargt;", "\u{2994}"), + ("rppolint;", "\u{2a12}"), + ("rrarr;", "\u{21c9}"), + ("rsaquo;", "\u{203a}"), + ("rscr;", "\u{1d4c7}"), + ("rsh;", "\u{21b1}"), + ("rsqb;", "]"), + ("rsquo;", "\u{2019}"), + ("rsquor;", "\u{2019}"), + ("rthree;", "\u{22cc}"), + ("rtimes;", "\u{22ca}"), + ("rtri;", "\u{25b9}"), + ("rtrie;", "\u{22b5}"), + ("rtrif;", "\u{25b8}"), + ("rtriltri;", "\u{29ce}"), + ("ruluhar;", "\u{2968}"), + ("rx;", "\u{211e}"), + ("sacute;", "\u{15b}"), + ("sbquo;", "\u{201a}"), + ("sc;", "\u{227b}"), + ("scE;", "\u{2ab4}"), + ("scap;", "\u{2ab8}"), + ("scaron;", "\u{161}"), + ("sccue;", "\u{227d}"), + ("sce;", "\u{2ab0}"), + ("scedil;", "\u{15f}"), + ("scirc;", "\u{15d}"), + ("scnE;", "\u{2ab6}"), + ("scnap;", "\u{2aba}"), + ("scnsim;", "\u{22e9}"), + ("scpolint;", "\u{2a13}"), + ("scsim;", "\u{227f}"), + ("scy;", "\u{441}"), + ("sdot;", "\u{22c5}"), + ("sdotb;", "\u{22a1}"), + ("sdote;", "\u{2a66}"), + ("seArr;", "\u{21d8}"), + ("searhk;", "\u{2925}"), + ("searr;", "\u{2198}"), + ("searrow;", "\u{2198}"), + ("sect", "\u{a7}"), + ("sect;", "\u{a7}"), + ("semi;", ";"), + ("seswar;", "\u{2929}"), + ("setminus;", "\u{2216}"), + ("setmn;", "\u{2216}"), + ("sext;", "\u{2736}"), + ("sfr;", "\u{1d530}"), + ("sfrown;", "\u{2322}"), + ("sharp;", "\u{266f}"), + ("shchcy;", "\u{449}"), + ("shcy;", "\u{448}"), + ("shortmid;", "\u{2223}"), + ("shortparallel;", "\u{2225}"), + ("shy", "\u{ad}"), + ("shy;", "\u{ad}"), + ("sigma;", "\u{3c3}"), + ("sigmaf;", "\u{3c2}"), + ("sigmav;", "\u{3c2}"), + ("sim;", "\u{223c}"), + ("simdot;", "\u{2a6a}"), + ("sime;", "\u{2243}"), + ("simeq;", "\u{2243}"), + ("simg;", "\u{2a9e}"), + ("simgE;", "\u{2aa0}"), + ("siml;", "\u{2a9d}"), + ("simlE;", "\u{2a9f}"), + ("simne;", "\u{2246}"), + ("simplus;", "\u{2a24}"), + ("simrarr;", "\u{2972}"), + ("slarr;", "\u{2190}"), + ("smallsetminus;", "\u{2216}"), + ("smashp;", "\u{2a33}"), + ("smeparsl;", "\u{29e4}"), + ("smid;", "\u{2223}"), + ("smile;", "\u{2323}"), + ("smt;", "\u{2aaa}"), + ("smte;", "\u{2aac}"), + ("smtes;", "\u{2aac}\u{fe00}"), + ("softcy;", "\u{44c}"), + ("sol;", "/"), + ("solb;", "\u{29c4}"), + ("solbar;", "\u{233f}"), + ("sopf;", "\u{1d564}"), + ("spades;", "\u{2660}"), + ("spadesuit;", "\u{2660}"), + ("spar;", "\u{2225}"), + ("sqcap;", "\u{2293}"), + ("sqcaps;", "\u{2293}\u{fe00}"), + ("sqcup;", "\u{2294}"), + ("sqcups;", "\u{2294}\u{fe00}"), + ("sqsub;", "\u{228f}"), + ("sqsube;", "\u{2291}"), + ("sqsubset;", "\u{228f}"), + ("sqsubseteq;", "\u{2291}"), + ("sqsup;", "\u{2290}"), + ("sqsupe;", "\u{2292}"), + ("sqsupset;", "\u{2290}"), + ("sqsupseteq;", "\u{2292}"), + ("squ;", "\u{25a1}"), + ("square;", "\u{25a1}"), + ("squarf;", "\u{25aa}"), + ("squf;", "\u{25aa}"), + ("srarr;", "\u{2192}"), + ("sscr;", "\u{1d4c8}"), + ("ssetmn;", "\u{2216}"), + ("ssmile;", "\u{2323}"), + ("sstarf;", "\u{22c6}"), + ("star;", "\u{2606}"), + ("starf;", "\u{2605}"), + ("straightepsilon;", "\u{3f5}"), + ("straightphi;", "\u{3d5}"), + ("strns;", "\u{af}"), + ("sub;", "\u{2282}"), + ("subE;", "\u{2ac5}"), + ("subdot;", "\u{2abd}"), + ("sube;", "\u{2286}"), + ("subedot;", "\u{2ac3}"), + ("submult;", "\u{2ac1}"), + ("subnE;", "\u{2acb}"), + ("subne;", "\u{228a}"), + ("subplus;", "\u{2abf}"), + ("subrarr;", "\u{2979}"), + ("subset;", "\u{2282}"), + ("subseteq;", "\u{2286}"), + ("subseteqq;", "\u{2ac5}"), + ("subsetneq;", "\u{228a}"), + ("subsetneqq;", "\u{2acb}"), + ("subsim;", "\u{2ac7}"), + ("subsub;", "\u{2ad5}"), + ("subsup;", "\u{2ad3}"), + ("succ;", "\u{227b}"), + ("succapprox;", "\u{2ab8}"), + ("succcurlyeq;", "\u{227d}"), + ("succeq;", "\u{2ab0}"), + ("succnapprox;", "\u{2aba}"), + ("succneqq;", "\u{2ab6}"), + ("succnsim;", "\u{22e9}"), + ("succsim;", "\u{227f}"), + ("sum;", "\u{2211}"), + ("sung;", "\u{266a}"), + ("sup1", "\u{b9}"), + ("sup1;", "\u{b9}"), + ("sup2", "\u{b2}"), + ("sup2;", "\u{b2}"), + ("sup3", "\u{b3}"), + ("sup3;", "\u{b3}"), + ("sup;", "\u{2283}"), + ("supE;", "\u{2ac6}"), + ("supdot;", "\u{2abe}"), + ("supdsub;", "\u{2ad8}"), + ("supe;", "\u{2287}"), + ("supedot;", "\u{2ac4}"), + ("suphsol;", "\u{27c9}"), + ("suphsub;", "\u{2ad7}"), + ("suplarr;", "\u{297b}"), + ("supmult;", "\u{2ac2}"), + ("supnE;", "\u{2acc}"), + ("supne;", "\u{228b}"), + ("supplus;", "\u{2ac0}"), + ("supset;", "\u{2283}"), + ("supseteq;", "\u{2287}"), + ("supseteqq;", "\u{2ac6}"), + ("supsetneq;", "\u{228b}"), + ("supsetneqq;", "\u{2acc}"), + ("supsim;", "\u{2ac8}"), + ("supsub;", "\u{2ad4}"), + ("supsup;", "\u{2ad6}"), + ("swArr;", "\u{21d9}"), + ("swarhk;", "\u{2926}"), + ("swarr;", "\u{2199}"), + ("swarrow;", "\u{2199}"), + ("swnwar;", "\u{292a}"), + ("szlig", "\u{df}"), + ("szlig;", "\u{df}"), + ("target;", "\u{2316}"), + ("tau;", "\u{3c4}"), + ("tbrk;", "\u{23b4}"), + ("tcaron;", "\u{165}"), + ("tcedil;", "\u{163}"), + ("tcy;", "\u{442}"), + ("tdot;", "\u{20db}"), + ("telrec;", "\u{2315}"), + ("tfr;", "\u{1d531}"), + ("there4;", "\u{2234}"), + ("therefore;", "\u{2234}"), + ("theta;", "\u{3b8}"), + ("thetasym;", "\u{3d1}"), + ("thetav;", "\u{3d1}"), + ("thickapprox;", "\u{2248}"), + ("thicksim;", "\u{223c}"), + ("thinsp;", "\u{2009}"), + ("thkap;", "\u{2248}"), + ("thksim;", "\u{223c}"), + ("thorn", "\u{fe}"), + ("thorn;", "\u{fe}"), + ("tilde;", "\u{2dc}"), + ("times", "\u{d7}"), + ("times;", "\u{d7}"), + ("timesb;", "\u{22a0}"), + ("timesbar;", "\u{2a31}"), + ("timesd;", "\u{2a30}"), + ("tint;", "\u{222d}"), + ("toea;", "\u{2928}"), + ("top;", "\u{22a4}"), + ("topbot;", "\u{2336}"), + ("topcir;", "\u{2af1}"), + ("topf;", "\u{1d565}"), + ("topfork;", "\u{2ada}"), + ("tosa;", "\u{2929}"), + ("tprime;", "\u{2034}"), + ("trade;", "\u{2122}"), + ("triangle;", "\u{25b5}"), + ("triangledown;", "\u{25bf}"), + ("triangleleft;", "\u{25c3}"), + ("trianglelefteq;", "\u{22b4}"), + ("triangleq;", "\u{225c}"), + ("triangleright;", "\u{25b9}"), + ("trianglerighteq;", "\u{22b5}"), + ("tridot;", "\u{25ec}"), + ("trie;", "\u{225c}"), + ("triminus;", "\u{2a3a}"), + ("triplus;", "\u{2a39}"), + ("trisb;", "\u{29cd}"), + ("tritime;", "\u{2a3b}"), + ("trpezium;", "\u{23e2}"), + ("tscr;", "\u{1d4c9}"), + ("tscy;", "\u{446}"), + ("tshcy;", "\u{45b}"), + ("tstrok;", "\u{167}"), + ("twixt;", "\u{226c}"), + ("twoheadleftarrow;", "\u{219e}"), + ("twoheadrightarrow;", "\u{21a0}"), + ("uArr;", "\u{21d1}"), + ("uHar;", "\u{2963}"), + ("uacute", "\u{fa}"), + ("uacute;", "\u{fa}"), + ("uarr;", "\u{2191}"), + ("ubrcy;", "\u{45e}"), + ("ubreve;", "\u{16d}"), + ("ucirc", "\u{fb}"), + ("ucirc;", "\u{fb}"), + ("ucy;", "\u{443}"), + ("udarr;", "\u{21c5}"), + ("udblac;", "\u{171}"), + ("udhar;", "\u{296e}"), + ("ufisht;", "\u{297e}"), + ("ufr;", "\u{1d532}"), + ("ugrave", "\u{f9}"), + ("ugrave;", "\u{f9}"), + ("uharl;", "\u{21bf}"), + ("uharr;", "\u{21be}"), + ("uhblk;", "\u{2580}"), + ("ulcorn;", "\u{231c}"), + ("ulcorner;", "\u{231c}"), + ("ulcrop;", "\u{230f}"), + ("ultri;", "\u{25f8}"), + ("umacr;", "\u{16b}"), + ("uml", "\u{a8}"), + ("uml;", "\u{a8}"), + ("uogon;", "\u{173}"), + ("uopf;", "\u{1d566}"), + ("uparrow;", "\u{2191}"), + ("updownarrow;", "\u{2195}"), + ("upharpoonleft;", "\u{21bf}"), + ("upharpoonright;", "\u{21be}"), + ("uplus;", "\u{228e}"), + ("upsi;", "\u{3c5}"), + ("upsih;", "\u{3d2}"), + ("upsilon;", "\u{3c5}"), + ("upuparrows;", "\u{21c8}"), + ("urcorn;", "\u{231d}"), + ("urcorner;", "\u{231d}"), + ("urcrop;", "\u{230e}"), + ("uring;", "\u{16f}"), + ("urtri;", "\u{25f9}"), + ("uscr;", "\u{1d4ca}"), + ("utdot;", "\u{22f0}"), + ("utilde;", "\u{169}"), + ("utri;", "\u{25b5}"), + ("utrif;", "\u{25b4}"), + ("uuarr;", "\u{21c8}"), + ("uuml", "\u{fc}"), + ("uuml;", "\u{fc}"), + ("uwangle;", "\u{29a7}"), + ("vArr;", "\u{21d5}"), + ("vBar;", "\u{2ae8}"), + ("vBarv;", "\u{2ae9}"), + ("vDash;", "\u{22a8}"), + ("vangrt;", "\u{299c}"), + ("varepsilon;", "\u{3f5}"), + ("varkappa;", "\u{3f0}"), + ("varnothing;", "\u{2205}"), + ("varphi;", "\u{3d5}"), + ("varpi;", "\u{3d6}"), + ("varpropto;", "\u{221d}"), + ("varr;", "\u{2195}"), + ("varrho;", "\u{3f1}"), + ("varsigma;", "\u{3c2}"), + ("varsubsetneq;", "\u{228a}\u{fe00}"), + ("varsubsetneqq;", "\u{2acb}\u{fe00}"), + ("varsupsetneq;", "\u{228b}\u{fe00}"), + ("varsupsetneqq;", "\u{2acc}\u{fe00}"), + ("vartheta;", "\u{3d1}"), + ("vartriangleleft;", "\u{22b2}"), + ("vartriangleright;", "\u{22b3}"), + ("vcy;", "\u{432}"), + ("vdash;", "\u{22a2}"), + ("vee;", "\u{2228}"), + ("veebar;", "\u{22bb}"), + ("veeeq;", "\u{225a}"), + ("vellip;", "\u{22ee}"), + ("verbar;", "|"), + ("vert;", "|"), + ("vfr;", "\u{1d533}"), + ("vltri;", "\u{22b2}"), + ("vnsub;", "\u{2282}\u{20d2}"), + ("vnsup;", "\u{2283}\u{20d2}"), + ("vopf;", "\u{1d567}"), + ("vprop;", "\u{221d}"), + ("vrtri;", "\u{22b3}"), + ("vscr;", "\u{1d4cb}"), + ("vsubnE;", "\u{2acb}\u{fe00}"), + ("vsubne;", "\u{228a}\u{fe00}"), + ("vsupnE;", "\u{2acc}\u{fe00}"), + ("vsupne;", "\u{228b}\u{fe00}"), + ("vzigzag;", "\u{299a}"), + ("wcirc;", "\u{175}"), + ("wedbar;", "\u{2a5f}"), + ("wedge;", "\u{2227}"), + ("wedgeq;", "\u{2259}"), + ("weierp;", "\u{2118}"), + ("wfr;", "\u{1d534}"), + ("wopf;", "\u{1d568}"), + ("wp;", "\u{2118}"), + ("wr;", "\u{2240}"), + ("wreath;", "\u{2240}"), + ("wscr;", "\u{1d4cc}"), + ("xcap;", "\u{22c2}"), + ("xcirc;", "\u{25ef}"), + ("xcup;", "\u{22c3}"), + ("xdtri;", "\u{25bd}"), + ("xfr;", "\u{1d535}"), + ("xhArr;", "\u{27fa}"), + ("xharr;", "\u{27f7}"), + ("xi;", "\u{3be}"), + ("xlArr;", "\u{27f8}"), + ("xlarr;", "\u{27f5}"), + ("xmap;", "\u{27fc}"), + ("xnis;", "\u{22fb}"), + ("xodot;", "\u{2a00}"), + ("xopf;", "\u{1d569}"), + ("xoplus;", "\u{2a01}"), + ("xotime;", "\u{2a02}"), + ("xrArr;", "\u{27f9}"), + ("xrarr;", "\u{27f6}"), + ("xscr;", "\u{1d4cd}"), + ("xsqcup;", "\u{2a06}"), + ("xuplus;", "\u{2a04}"), + ("xutri;", "\u{25b3}"), + ("xvee;", "\u{22c1}"), + ("xwedge;", "\u{22c0}"), + ("yacute", "\u{fd}"), + ("yacute;", "\u{fd}"), + ("yacy;", "\u{44f}"), + ("ycirc;", "\u{177}"), + ("ycy;", "\u{44b}"), + ("yen", "\u{a5}"), + ("yen;", "\u{a5}"), + ("yfr;", "\u{1d536}"), + ("yicy;", "\u{457}"), + ("yopf;", "\u{1d56a}"), + ("yscr;", "\u{1d4ce}"), + ("yucy;", "\u{44e}"), + ("yuml", "\u{ff}"), + ("yuml;", "\u{ff}"), + ("zacute;", "\u{17a}"), + ("zcaron;", "\u{17e}"), + ("zcy;", "\u{437}"), + ("zdot;", "\u{17c}"), + ("zeetrf;", "\u{2128}"), + ("zeta;", "\u{3b6}"), + ("zfr;", "\u{1d537}"), + ("zhcy;", "\u{436}"), + ("zigrarr;", "\u{21dd}"), + ("zopf;", "\u{1d56b}"), + ("zscr;", "\u{1d4cf}"), + ("zwj;", "\u{200d}"), + ("zwnj;", "\u{200c}"), +]; + +/// Numeric references the specification says to read as something else, +/// because the numbers name Windows-1252 positions rather than code +/// points. +pub static INVALID_CHARREFS: &[(u32, &str)] = &[ + (0, "\u{fffd}"), + (13, "\u{d}"), + (128, "\u{20ac}"), + (129, "\u{81}"), + (130, "\u{201a}"), + (131, "\u{192}"), + (132, "\u{201e}"), + (133, "\u{2026}"), + (134, "\u{2020}"), + (135, "\u{2021}"), + (136, "\u{2c6}"), + (137, "\u{2030}"), + (138, "\u{160}"), + (139, "\u{2039}"), + (140, "\u{152}"), + (141, "\u{8d}"), + (142, "\u{17d}"), + (143, "\u{8f}"), + (144, "\u{90}"), + (145, "\u{2018}"), + (146, "\u{2019}"), + (147, "\u{201c}"), + (148, "\u{201d}"), + (149, "\u{2022}"), + (150, "\u{2013}"), + (151, "\u{2014}"), + (152, "\u{2dc}"), + (153, "\u{2122}"), + (154, "\u{161}"), + (155, "\u{203a}"), + (156, "\u{153}"), + (157, "\u{9d}"), + (158, "\u{17e}"), + (159, "\u{178}"), +]; + +/// Code points the specification says to drop entirely. +pub static INVALID_CODEPOINTS: &[u32] = &[ + 1, 2, 3, 4, 5, 6, 7, 8, 11, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 64976, 64977, 64978, + 64979, 64980, 64981, 64982, 64983, 64984, 64985, 64986, 64987, 64988, 64989, 64990, 64991, + 64992, 64993, 64994, 64995, 64996, 64997, 64998, 64999, 65000, 65001, 65002, 65003, 65004, + 65005, 65006, 65007, 65534, 65535, 131070, 131071, 196606, 196607, 262142, 262143, 327678, + 327679, 393214, 393215, 458750, 458751, 524286, 524287, 589822, 589823, 655358, 655359, 720894, + 720895, 786430, 786431, 851966, 851967, 917502, 917503, 983038, 983039, 1048574, 1048575, + 1114110, 1114111, +]; diff --git a/crates/mdscrub/src/html.rs b/crates/mdscrub/src/html.rs index 37524f6..dc071d8 100644 --- a/crates/mdscrub/src/html.rs +++ b/crates/mdscrub/src/html.rs @@ -4,7 +4,16 @@ use std::sync::LazyLock; use regex::Regex; -/// An opening or closing inline tag. +/// Python's `\s`, which is the Unicode whitespace property plus the four +/// ASCII information separators. Spelled out wherever a ported pattern uses +/// `\s`, because the difference decides where a page boundary is. +const SPACE: &str = r"[\s\x{1c}-\x{1f}]"; + +fn pattern(source: &str) -> Regex { + Regex::new(source).expect("a valid pattern") +} + +/// An opening or closing inline tag, and its name. /// /// Converted markdown is full of them: pandoc's commonmark output keeps an /// EPUB's styling spans and anchors, and a PDF converter emits anchor spans @@ -13,50 +22,133 @@ use regex::Regex; /// full-text index, and every result a reader sees. /// /// Comments are deliberately not matched: `` has to survive. -static TAG: LazyLock = LazyLock::new(|| Regex::new(r"]*>").expect("valid")); +static TAG: LazyLock = LazyLock::new(|| pattern(r"]*>")); -/// A tag that stands for a line break rather than for styling. -static BREAK: LazyLock = LazyLock::new(|| Regex::new(r"(?i)").expect("valid")); - -/// The start of a fenced code block. -static FENCE: LazyLock = LazyLock::new(|| Regex::new(r"^\s*(```|~~~)").expect("valid")); +/// A markdown image carrying its payload inline. +/// +/// A generated EPUB cover arrives this way — a few hundred characters of +/// base64 in a wrapper — and because the cover is the spine's first document +/// it lands in the first chunk of the book, which is the chunk a "what is +/// this book about" query matches. It holds no text, so it can only dilute +/// the chunk it sits in. +static DATA_URI_IMAGE: LazyLock = + LazyLock::new(|| pattern(&format!(r"!\[[^\]]*\]\({SPACE}*data:[^)]*\)"))); /// Control characters that must never reach a text column. /// /// A database will reject `0x00` outright. The other C0 controls — tab, /// newline and carriage return excepted — are storable and are extraction /// garbage: bad scans and malformed PDFs emit them routinely. -static CONTROL: LazyLock = - LazyLock::new(|| Regex::new(r"[\x00-\x08\x0b\x0c\x0e-\x1f]").expect("valid")); +static CONTROL: LazyLock = LazyLock::new(|| pattern(r"[\x00-\x08\x0b\x0c\x0e-\x1f]")); /// Three or more newlines, left behind wherever a tag-only line was removed. -static BLANK_RUN: LazyLock = LazyLock::new(|| Regex::new(r"\n{3,}").expect("valid")); +static BLANK_RUN: LazyLock = LazyLock::new(|| pattern(r"\n{3,}")); + +/// Tags that stand for a line or block boundary rather than a span of +/// styling. +/// +/// Deleting one outright welds the words either side of it together: a table +/// of contents reading `APPENDICES
OF
LIST
xii` comes out as +/// `APPENDICESOFLISTxii`, which is a word no reader can search for and no +/// tokeniser can split. These become a space instead. Genuinely inline tags +/// still go to nothing, because `claim16` has to stay `claim16`. +const BREAK_TAGS: &[&str] = &[ + "address", + "article", + "aside", + "blockquote", + "br", + "caption", + "dd", + "div", + "dl", + "dt", + "figcaption", + "figure", + "footer", + "h1", + "h2", + "h3", + "h4", + "h5", + "h6", + "header", + "hr", + "li", + "main", + "nav", + "ol", + "p", + "pre", + "section", + "table", + "tbody", + "td", + "tfoot", + "th", + "thead", + "tr", + "ul", +]; /// Strip inline HTML, keeping the text inside it and the HTML comments. /// -/// Fenced code blocks are left alone, so a book that quotes HTML keeps its -/// examples. `
` becomes a line break rather than nothing, because -/// deleting it welds the words on either side into one — which is a spelling -/// mistake in the index that no reader can search for. +/// Character references are decoded first: a tag that was escaped twice +/// arrives as `<sup>107` and no tag pattern can see it, so the markup +/// would otherwise survive into the text. Fenced code blocks are left alone, +/// so a book that quotes HTML keeps its examples. pub fn strip_tags(markdown: &str) -> String { - let mut out = Vec::new(); + let mut out: Vec = Vec::new(); let mut in_fence = false; for line in markdown.split('\n') { - if FENCE.is_match(line) { + if opens_a_fence(line) { in_fence = !in_fence; out.push(line.to_string()); continue; } if in_fence { out.push(line.to_string()); + continue; + } + let text = crate::unescape::unescape(line); + let text = DATA_URI_IMAGE.replace_all(&text, ""); + let text = TAG.replace_all( + &text, + |found: ®ex::Captures| { + if is_break_tag(&found[1]) { " " } else { "" } + }, + ); + // A line that held nothing but tags becomes empty rather than a lone + // space, so the blank-line collapse below still sees it as blank. + if text.trim_matches(textkit::is_space).is_empty() { + out.push(String::new()); } else { - let line = BREAK.replace_all(line, "\n"); - out.push(TAG.replace_all(&line, "").into_owned()); + out.push(text.into_owned()); } } out.join("\n") } +/// Whether a line opens or closes a fenced code block. +/// +/// A run of at least three backticks or tildes whose info string does not +/// itself contain the fence character. The looser reading — any three of +/// them — treats a decorative rule as a fence: `~~~~~~~~~END~~~~~~~~~` in a +/// scanned book switched cleaning off for the rest of the document and left +/// the markup behind. +fn opens_a_fence(line: &str) -> bool { + let line = line.trim_start_matches(textkit::is_space); + ['`', '~'].into_iter().any(|fence| { + let rest = line.trim_start_matches(fence); + line.len() - rest.len() >= 3 && !rest.contains(fence) + }) +} + +fn is_break_tag(name: &str) -> bool { + let name = name.to_lowercase(); + BREAK_TAGS.binary_search(&name.as_str()).is_ok() +} + /// Remove the control characters a text column cannot hold. pub fn scrub_control(text: &str) -> String { CONTROL.replace_all(text, "").into_owned() @@ -71,6 +163,11 @@ pub fn collapse_blank_runs(text: &str) -> String { mod tests { use super::*; + #[test] + fn the_break_tag_list_is_sorted_so_it_can_be_searched() { + assert!(BREAK_TAGS.windows(2).all(|pair| pair[0] < pair[1])); + } + #[test] fn styling_tags_go_and_their_text_stays() { assert_eq!( @@ -79,33 +176,60 @@ mod tests { ); } + #[test] + fn an_inline_tag_leaves_nothing_behind() { + assert_eq!(strip_tags("claim16"), "claim16"); + } + + #[test] + fn a_block_tag_leaves_a_space_so_words_do_not_weld() { + assert_eq!(strip_tags("APPENDICES
OF
LIST"), "APPENDICES OF LIST"); + assert_eq!(strip_tags("

one

two

"), " one two "); + assert_eq!(strip_tags("a
b"), "a b"); + } + #[test] fn html_comments_survive() { assert_eq!(strip_tags(""), ""); } #[test] - fn a_break_tag_does_not_weld_the_words_either_side_of_it() { - assert_eq!(strip_tags("first
second"), "first\nsecond"); - assert_eq!(strip_tags("first
second"), "first\nsecond"); - assert_eq!(strip_tags("first
second"), "first\nsecond"); + fn a_doubly_escaped_tag_is_decoded_and_then_removed() { + assert_eq!(strip_tags("<sup>107Ibid."), "107Ibid."); } #[test] - fn fenced_code_keeps_its_tags() { - let markdown = "before x\n\n```html\nkept\n```\n\nafter y"; + fn an_inline_image_payload_goes() { + let line = "![cover](data:image/svg+xml;base64,PHN2ZyB4bWxucz0i) and text"; + assert_eq!(strip_tags(line), " and text"); + } + + #[test] + fn fenced_code_keeps_its_tags_and_its_entities() { + let markdown = "before x\n\n```html\nkept\n& kept\n```\n\nafter"; let cleaned = strip_tags(markdown); assert!(cleaned.contains("kept")); + assert!(cleaned.contains("& kept")); assert!(cleaned.contains("before x")); - assert!(cleaned.contains("after y")); } #[test] - fn a_tag_split_across_two_lines_is_left_alone() { - // Matching per line is what keeps a stray `<` in prose from eating - // the rest of the document. - let markdown = "a < b and\nc > d"; - assert_eq!(strip_tags(markdown), markdown); + fn a_decorative_rule_is_not_a_fence() { + let markdown = "~~~~~~~~~END~~~~~~~~~\nafter"; + assert_eq!(strip_tags(markdown), "~~~~~~~~~END~~~~~~~~~\nafter"); + } + + #[test] + fn a_real_fence_with_an_info_string_still_opens() { + assert!(opens_a_fence("```html")); + assert!(opens_a_fence(" ~~~")); + assert!(!opens_a_fence("``")); + assert!(!opens_a_fence("text ```")); + } + + #[test] + fn a_line_of_nothing_but_tags_becomes_blank() { + assert_eq!(strip_tags("a\n\nb"), "a\n\nb"); } #[test] diff --git a/crates/mdscrub/src/lib.rs b/crates/mdscrub/src/lib.rs index 42a5f2e..41122ad 100644 --- a/crates/mdscrub/src/lib.rs +++ b/crates/mdscrub/src/lib.rs @@ -10,9 +10,11 @@ //! because one of the things that marks a page boundary — a form feed — is //! also a control character that the later pass deletes. +mod entities; pub mod heading; pub mod html; pub mod pages; +pub mod unescape; /// Clean a converted markdown document. /// diff --git a/crates/mdscrub/src/pages.rs b/crates/mdscrub/src/pages.rs index 43f9b7e..bdedc26 100644 --- a/crates/mdscrub/src/pages.rs +++ b/crates/mdscrub/src/pages.rs @@ -7,7 +7,7 @@ use regex::Regex; /// The separator a paginating PDF converter writes between pages, like /// `{0}------------------------------`. Its numbering is zero-based. static SEPARATOR: LazyLock = - LazyLock::new(|| Regex::new(r"\{(\d+)\}-{20,}[^\S\n]*\n").expect("a valid pattern")); + LazyLock::new(|| Regex::new(r"\{(\d+)\}-{20,}[\s\x{1c}-\x{1f}]*\n").expect("a valid pattern")); /// A form feed, which is what a plain text extractor leaves between pages. const FORM_FEED: char = '\u{c}'; diff --git a/crates/mdscrub/src/unescape.rs b/crates/mdscrub/src/unescape.rs new file mode 100644 index 0000000..cfa4061 --- /dev/null +++ b/crates/mdscrub/src/unescape.rs @@ -0,0 +1,150 @@ +//! Turning HTML character references back into the characters they name. +//! +//! Converted markdown carries doubly-escaped markup: a tag that was escaped +//! once by the source and once by the converter arrives as `<sup>107`, +//! which no tag pattern can see. Decoding first turns it into a real tag that +//! the stripping pass then removes, and fixes `&` and the numeric forms +//! in ordinary prose on the way past. +//! +//! The rules are the specification's, including the parts that exist only +//! because browsers had to accept what was already on the web: a reference +//! with no closing semicolon, a name that is the prefix of a longer name, and +//! numbers that mean Windows-1252 positions rather than code points. + +use std::sync::LazyLock; + +use regex::Regex; + +use crate::entities::{INVALID_CHARREFS, INVALID_CODEPOINTS, NAMED}; + +/// A character reference: a number, a hexadecimal number, or a name of up to +/// thirty-two characters, each with an optional closing semicolon. +static CHARREF: LazyLock = LazyLock::new(|| { + Regex::new(r"&(#[0-9]+;?|#[xX][0-9a-fA-F]+;?|[^\t\n\x0c <&#;]{1,32};?)").expect("valid") +}); + +/// Decode every character reference in `text`. +pub fn unescape(text: &str) -> String { + if !text.contains('&') { + return text.to_string(); + } + CHARREF + .replace_all(text, |found: ®ex::Captures| replace(&found[1])) + .into_owned() +} + +fn replace(reference: &str) -> String { + match reference.strip_prefix('#') { + Some(number) => numeric(number), + None => named(reference), + } +} + +fn numeric(number: &str) -> String { + let digits = number.trim_end_matches(';'); + let value = match digits.strip_prefix(['x', 'X']) { + Some(hex) => u32::from_str_radix(hex, 16), + None => digits.parse::(), + }; + // A number too long to be a code point at all is out of range, which the + // specification answers the same way as any other out-of-range number. + let Ok(value) = value else { + return '\u{fffd}'.to_string(); + }; + + if let Ok(at) = INVALID_CHARREFS.binary_search_by_key(&value, |(number, _)| *number) { + return INVALID_CHARREFS[at].1.to_string(); + } + if (0xd800..=0xdfff).contains(&value) || value > 0x10ffff { + return '\u{fffd}'.to_string(); + } + if INVALID_CODEPOINTS.binary_search(&value).is_ok() { + return String::new(); + } + char::from_u32(value).map(String::from).unwrap_or_default() +} + +fn named(name: &str) -> String { + if let Some(value) = lookup(name) { + return value.to_string(); + } + // The longest name that is a prefix of what was written wins, and the + // rest is left as text: `¬it;` is `¬it;`, not an unknown reference. + for end in (2..name.len()).rev() { + if !name.is_char_boundary(end) { + continue; + } + if let Some(value) = lookup(&name[..end]) { + return format!("{value}{}", &name[end..]); + } + } + format!("&{name}") +} + +fn lookup(name: &str) -> Option<&'static str> { + NAMED + .binary_search_by_key(&name, |(named, _)| named) + .ok() + .map(|at| NAMED[at].1) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn the_table_is_sorted_so_it_can_be_searched() { + assert!(NAMED.windows(2).all(|pair| pair[0].0 < pair[1].0)); + assert!( + INVALID_CHARREFS + .windows(2) + .all(|pair| pair[0].0 < pair[1].0) + ); + assert!(INVALID_CODEPOINTS.windows(2).all(|pair| pair[0] < pair[1])); + } + + #[test] + fn ordinary_references_decode() { + assert_eq!(unescape("a & b"), "a & b"); + assert_eq!(unescape("<sup>107"), "107"); + assert_eq!(unescape("AB"), "AB"); + } + + #[test] + fn a_missing_semicolon_is_still_a_reference() { + assert_eq!(unescape("&"), "&"); + assert_eq!(unescape("A"), "A"); + assert_eq!(unescape("Æ"), "Æ"); + } + + #[test] + fn the_longest_name_wins_and_the_rest_stays_text() { + assert_eq!(unescape("¬it;"), "¬it;"); + assert_eq!(unescape("∉"), "∉"); + } + + #[test] + fn something_that_is_not_a_reference_is_left_alone() { + assert_eq!(unescape("&unknown;"), "&unknown;"); + assert_eq!(unescape("a & b"), "a & b"); + assert_eq!(unescape("no ampersand here"), "no ampersand here"); + } + + #[test] + fn windows_1252_numbers_decode_as_the_specification_says() { + assert_eq!(unescape("€"), "€"); + assert_eq!(unescape("�"), "\u{fffd}"); + } + + #[test] + fn a_number_that_is_not_a_code_point_is_refused() { + assert_eq!(unescape("�"), "\u{fffd}"); + assert_eq!(unescape("�"), "\u{fffd}"); + assert_eq!(unescape("�"), "\u{fffd}"); + } + + #[test] + fn a_code_point_the_specification_drops_comes_out_as_nothing() { + assert_eq!(unescape("ab"), "ab"); + } +} diff --git a/parity/KNOWN.md b/parity/KNOWN.md index 4f2d642..419c9fc 100644 --- a/parity/KNOWN.md +++ b/parity/KNOWN.md @@ -18,25 +18,6 @@ affected and how often it occurs in practice. --- -## mdscrub — a line-break tag becomes a line break, not nothing - -**Python:** `strip_residual_html` removes every inline tag, `
` included, -so `the
northern end` becomes `thenorthern end`. - -**Rust:** `
`, `
` and `
` become a newline; every other tag is -still removed. - -**Why this is acceptable:** the welded word is not a formatting difference, -it is a word that does not exist. It cannot be searched for, it embeds as a -token sequence no query will produce, and it is invisible in a result because -the surrounding sentence reads normally. The divergence only affects -documents that use `
` at all — mostly verse, addresses and tables of -contents converted out of HTML — and within those, only the joins. - -**Measured:** `parity/cases/mdscrub/breaks.md`; both answers are committed as -`golden/mdscrub/breaks.md` and `golden/mdscrub/breaks.rust.md`. Three welds -in eight lines. - ## mdscrub — un-paginated text is not given a page 1 marker **Python:** `_normalize_marker_pages` ends by wrapping any text it found no diff --git a/parity/README.md b/parity/README.md index ef9ebc2..2d89ca1 100644 --- a/parity/README.md +++ b/parity/README.md @@ -23,9 +23,14 @@ can be re-run live, which catches a golden file drifting away from a Python implementation that has moved on: ```sh -CATENA_PARITY_PYTHON=/path/to/venv/bin/python cargo test -p parity --features python +CATENA_PARITY_PYTHON=/path/to/venv/bin/python \ +CATENA_PARITY_PYTHONPATH=/path/to/book-pipeline/src \ + cargo test -p parity --features python ``` +`SOURCE.md` records which commit of that source the golden files came from. +Pointing the oracles at an older checkout will fail, and should. + ## Regenerating Golden files are never regenerated by a test — a golden file that rewrites @@ -33,7 +38,9 @@ itself when it fails is a test that cannot fail. Regenerate deliberately, read the diff, and commit it with the reason: ```sh -CATENA_PARITY_PYTHON=/path/to/venv/bin/python cargo run -p parity --bin regen +CATENA_PARITY_PYTHON=/path/to/venv/bin/python \ +CATENA_PARITY_PYTHONPATH=/path/to/book-pipeline/src \ + cargo run -p parity --bin regen ``` ## Fixtures diff --git a/parity/SOURCE.md b/parity/SOURCE.md new file mode 100644 index 0000000..d95a22e --- /dev/null +++ b/parity/SOURCE.md @@ -0,0 +1,19 @@ +# What the golden files were generated from + +The oracles import the Python these tools were ported from. The golden files +in this directory are the answers that Python gave, at one commit: + +| Source | Commit | +|---|---| +| `book-pipeline` | `7499e3257572968b437ecfdc79feccc91b96585b` | + +Regenerating against a different commit will move the goldens. That is the +point — the diff is the review. Record the new commit here in the same change. + +The oracles find the source through two environment variables, because where +a checkout lives is a fact about one machine and must not be compiled in: + +```sh +CATENA_PARITY_PYTHON=/path/to/venv/bin/python +CATENA_PARITY_PYTHONPATH=/path/to/book-pipeline/src +``` diff --git a/parity/cases/unescape/entities.txt b/parity/cases/unescape/entities.txt new file mode 100644 index 0000000..3e6fffb --- /dev/null +++ b/parity/cases/unescape/entities.txt @@ -0,0 +1,2272 @@ +Æ +Æ +& +& +Á +Á +Ă + + +А +𝔄 +À +À +Α +Ā +⩓ +Ą +𝔸 +⁡ +Å +Å +𝒜 +≔ +à +à +Ä +Ä +∖ +⫧ +⌆ +Б +∵ +ℬ +Β +𝔅 +𝔹 +˘ +ℬ +≎ +Ч +© +© +Ć +⋒ +ⅅ +ℭ +Č +Ç +Ç +Ĉ +∰ +Ċ +¸ +· +ℭ +Χ +⊙ +⊖ +⊕ +⊗ +∲ +” +’ +∷ +⩴ +≡ +∯ +∮ +ℂ +∐ +∳ +⨯ +𝒞 +⋓ +≍ +ⅅ +⤑ +Ђ +Ѕ +Џ +‡ +↡ +⫤ +Ď +Д +∇ +Δ +𝔇 +´ +˙ +˝ +` +˜ +⋄ +ⅆ +𝔻 +¨ +⃜ +≐ +∯ +¨ +⇓ +⇐ +⇔ +⫤ +⟸ +⟺ +⟹ +⇒ +⊨ +⇑ +⇕ +∥ +↓ +⤓ +⇵ +̑ +⥐ +⥞ +↽ +⥖ +⥟ +⇁ +⥗ +⊤ +↧ +⇓ +𝒟 +Đ +Ŋ +Ð +Ð +É +É +Ě +Ê +Ê +Э +Ė +𝔈 +È +È +∈ +Ē +◻ +▫ +Ę +𝔼 +Ε +⩵ +≂ +⇌ +ℰ +⩳ +Η +Ë +Ë +∃ +ⅇ +Ф +𝔉 +◼ +▪ +𝔽 +∀ +ℱ +ℱ +Ѓ +> +> +Γ +Ϝ +Ğ +Ģ +Ĝ +Г +Ġ +𝔊 +⋙ +𝔾 +≥ +⋛ +≧ +⪢ +≷ +⩾ +≳ +𝒢 +≫ +Ъ +ˇ +^ +Ĥ +ℌ +ℋ +ℍ +─ +ℋ +Ħ +≎ +≏ +Е +IJ +Ё +Í +Í +Î +Î +И +İ +ℑ +Ì +Ì +ℑ +Ī +ⅈ +⇒ +∬ +∫ +⋂ +⁣ +⁢ +Į +𝕀 +Ι +ℐ +Ĩ +І +Ï +Ï +Ĵ +Й +𝔍 +𝕁 +𝒥 +Ј +Є +Х +Ќ +Κ +Ķ +К +𝔎 +𝕂 +𝒦 +Љ +< +< +Ĺ +Λ +⟪ +ℒ +↞ +Ľ +Ļ +Л +⟨ +← +⇤ +⇆ +⌈ +⟦ +⥡ +⇃ +⥙ +⌊ +↔ +⥎ +⊣ +↤ +⥚ +⊲ +⧏ +⊴ +⥑ +⥠ +↿ +⥘ +↼ +⥒ +⇐ +⇔ +⋚ +≦ +≶ +⪡ +⩽ +≲ +𝔏 +⋘ +⇚ +Ŀ +⟵ +⟷ +⟶ +⟸ +⟺ +⟹ +𝕃 +↙ +↘ +ℒ +↰ +Ł +≪ +⤅ +М +  +ℳ +𝔐 +∓ +𝕄 +ℳ +Μ +Њ +Ń +Ň +Ņ +Н +​ +​ +​ +​ +≫ +≪ + +𝔑 +⁠ +  +ℕ +⫬ +≢ +≭ +∦ +∉ +≠ +≂̸ +∄ +≯ +≱ +≧̸ +≫̸ +≹ +⩾̸ +≵ +≎̸ +≏̸ +⋪ +⧏̸ +⋬ +≮ +≰ +≸ +≪̸ +⩽̸ +≴ +⪢̸ +⪡̸ +⊀ +⪯̸ +⋠ +∌ +⋫ +⧐̸ +⋭ +⊏̸ +⋢ +⊐̸ +⋣ +⊂⃒ +⊈ +⊁ +⪰̸ +⋡ +≿̸ +⊃⃒ +⊉ +≁ +≄ +≇ +≉ +∤ +𝒩 +Ñ +Ñ +Ν +Œ +Ó +Ó +Ô +Ô +О +Ő +𝔒 +Ò +Ò +Ō +Ω +Ο +𝕆 +“ +‘ +⩔ +𝒪 +Ø +Ø +Õ +Õ +⨷ +Ö +Ö +‾ +⏞ +⎴ +⏜ +∂ +П +𝔓 +Φ +Π +± +ℌ +ℙ +⪻ +≺ +⪯ +≼ +≾ +″ +∏ +∷ +∝ +𝒫 +Ψ +" +" +𝔔 +ℚ +𝒬 +⤐ +® +® +Ŕ +⟫ +↠ +⤖ +Ř +Ŗ +Р +ℜ +∋ +⇋ +⥯ +ℜ +Ρ +⟩ +→ +⇥ +⇄ +⌉ +⟧ +⥝ +⇂ +⥕ +⌋ +⊢ +↦ +⥛ +⊳ +⧐ +⊵ +⥏ +⥜ +↾ +⥔ +⇀ +⥓ +⇒ +ℝ +⥰ +⇛ +ℛ +↱ +⧴ +Щ +Ш +Ь +Ś +⪼ +Š +Ş +Ŝ +С +𝔖 +↓ +← +→ +↑ +Σ +∘ +𝕊 +√ +□ +⊓ +⊏ +⊑ +⊐ +⊒ +⊔ +𝒮 +⋆ +⋐ +⋐ +⊆ +≻ +⪰ +≽ +≿ +∋ +∑ +⋑ +⊃ +⊇ +⋑ +Þ +Þ +™ +Ћ +Ц + +Τ +Ť +Ţ +Т +𝔗 +∴ +Θ +   +  +∼ +≃ +≅ +≈ +𝕋 +⃛ +𝒯 +Ŧ +Ú +Ú +↟ +⥉ +Ў +Ŭ +Û +Û +У +Ű +𝔘 +Ù +Ù +Ū +_ +⏟ +⎵ +⏝ +⋃ +⊎ +Ų +𝕌 +↑ +⤒ +⇅ +↕ +⥮ +⊥ +↥ +⇑ +⇕ +↖ +↗ +ϒ +Υ +Ů +𝒰 +Ũ +Ü +Ü +⊫ +⫫ +В +⊩ +⫦ +⋁ +‖ +‖ +∣ +| +❘ +≀ +  +𝔙 +𝕍 +𝒱 +⊪ +Ŵ +⋀ +𝔚 +𝕎 +𝒲 +𝔛 +Ξ +𝕏 +𝒳 +Я +Ї +Ю +Ý +Ý +Ŷ +Ы +𝔜 +𝕐 +𝒴 +Ÿ +Ж +Ź +Ž +З +Ż +​ +Ζ +ℨ +ℤ +𝒵 +á +á +ă +∾ +∾̳ +∿ +â +â +´ +´ +а +æ +æ +⁡ +𝔞 +à +à +ℵ +ℵ +α +ā +⨿ +& +& +∧ +⩕ +⩜ +⩘ +⩚ +∠ +⦤ +∠ +∡ +⦨ +⦩ +⦪ +⦫ +⦬ +⦭ +⦮ +⦯ +∟ +⊾ +⦝ +∢ +Å +⍼ +ą +𝕒 +≈ +⩰ +⩯ +≊ +≋ +' +≈ +≊ +å +å +𝒶 +* +≈ +≍ +ã +ã +ä +ä +∳ +⨑ +⫭ +≌ +϶ +‵ +∽ +⋍ +⊽ +⌅ +⌅ +⎵ +⎶ +≌ +б +„ +∵ +∵ +⦰ +϶ +ℬ +β +ℶ +≬ +𝔟 +⋂ +◯ +⋃ +⨀ +⨁ +⨂ +⨆ +★ +▽ +△ +⨄ +⋁ +⋀ +⤍ +⧫ +▪ +▴ +▾ +◂ +▸ +␣ +▒ +░ +▓ +█ +=⃥ +≡⃥ +⌐ +𝕓 +⊥ +⊥ +⋈ +╗ +╔ +╖ +╓ +═ +╦ +╩ +╤ +╧ +╝ +╚ +╜ +╙ +║ +╬ +╣ +╠ +╫ +╢ +╟ +⧉ +╕ +╒ +┐ +┌ +─ +╥ +╨ +┬ +┴ +⊟ +⊞ +⊠ +╛ +╘ +┘ +└ +│ +╪ +╡ +╞ +┼ +┤ +├ +‵ +˘ +¦ +¦ +𝒷 +⁏ +∽ +⋍ +\ +⧅ +⟈ +• +• +≎ +⪮ +≏ +≏ +ć +∩ +⩄ +⩉ +⩋ +⩇ +⩀ +∩︀ +⁁ +ˇ +⩍ +č +ç +ç +ĉ +⩌ +⩐ +ċ +¸ +¸ +⦲ +¢ +¢ +· +𝔠 +ч +✓ +✓ +χ +○ +⧃ +ˆ +≗ +↺ +↻ +® +Ⓢ +⊛ +⊚ +⊝ +≗ +⨐ +⫯ +⧂ +♣ +♣ +: +≔ +≔ +, +@ +∁ +∘ +∁ +ℂ +≅ +⩭ +∮ +𝕔 +∐ +© +© +℗ +↵ +✗ +𝒸 +⫏ +⫑ +⫐ +⫒ +⋯ +⤸ +⤵ +⋞ +⋟ +↶ +⤽ +∪ +⩈ +⩆ +⩊ +⊍ +⩅ +∪︀ +↷ +⤼ +⋞ +⋟ +⋎ +⋏ +¤ +¤ +↶ +↷ +⋎ +⋏ +∲ +∱ +⌭ +⇓ +⥥ +† +ℸ +↓ +‐ +⊣ +⤏ +˝ +ď +д +ⅆ +‡ +⇊ +⩷ +° +° +δ +⦱ +⥿ +𝔡 +⇃ +⇂ +⋄ +⋄ +♦ +♦ +¨ +ϝ +⋲ +÷ +÷ +÷ +⋇ +⋇ +ђ +⌞ +⌍ +$ +𝕕 +˙ +≐ +≑ +∸ +∔ +⊡ +⌆ +↓ +⇊ +⇃ +⇂ +⤐ +⌟ +⌌ +𝒹 +ѕ +⧶ +đ +⋱ +▿ +▾ +⇵ +⥯ +⦦ +џ +⟿ +⩷ +≑ +é +é +⩮ +ě +≖ +ê +ê +≕ +э +ė +ⅇ +≒ +𝔢 +⪚ +è +è +⪖ +⪘ +⪙ +⏧ +ℓ +⪕ +⪗ +ē +∅ +∅ +∅ +  +  +  +ŋ +  +ę +𝕖 +⋕ +⧣ +⩱ +ε +ε +ϵ +≖ +≕ +≂ +⪖ +⪕ += +≟ +≡ +⩸ +⧥ +≓ +⥱ +ℯ +≐ +≂ +η +ð +ð +ë +ë +€ +! +∃ +ℰ +ⅇ +≒ +ф +♀ +ffi +ff +ffl +𝔣 +fi +fj +♭ +fl +▱ +ƒ +𝕗 +∀ +⋔ +⫙ +⨍ +½ +½ +⅓ +¼ +¼ +⅕ +⅙ +⅛ +⅔ +⅖ +¾ +¾ +⅗ +⅜ +⅘ +⅚ +⅝ +⅞ +⁄ +⌢ +𝒻 +≧ +⪌ +ǵ +γ +ϝ +⪆ +ğ +ĝ +г +ġ +≥ +⋛ +≥ +≧ +⩾ +⩾ +⪩ +⪀ +⪂ +⪄ +⋛︀ +⪔ +𝔤 +≫ +⋙ +ℷ +ѓ +≷ +⪒ +⪥ +⪤ +≩ +⪊ +⪊ +⪈ +⪈ +≩ +⋧ +𝕘 +` +ℊ +≳ +⪎ +⪐ +> +> +⪧ +⩺ +⋗ +⦕ +⩼ +⪆ +⥸ +⋗ +⋛ +⪌ +≷ +≳ +≩︀ +≩︀ +⇔ +  +½ +ℋ +ъ +↔ +⥈ +↭ +ℏ +ĥ +♥ +♥ +… +⊹ +𝔥 +⤥ +⤦ +⇿ +∻ +↩ +↪ +𝕙 +― +𝒽 +ℏ +ħ +⁃ +‐ +í +í +⁣ +î +î +и +е +¡ +¡ +⇔ +𝔦 +ì +ì +ⅈ +⨌ +∭ +⧜ +℩ +ij +ī +ℑ +ℐ +ℑ +ı +⊷ +Ƶ +∈ +℅ +∞ +⧝ +ı +∫ +⊺ +ℤ +⊺ +⨗ +⨼ +ё +į +𝕚 +ι +⨼ +¿ +¿ +𝒾 +∈ +⋹ +⋵ +⋴ +⋳ +∈ +⁢ +ĩ +і +ï +ï +ĵ +й +𝔧 +ȷ +𝕛 +𝒿 +ј +є +κ +ϰ +ķ +к +𝔨 +ĸ +х +ќ +𝕜 +𝓀 +⇚ +⇐ +⤛ +⤎ +≦ +⪋ +⥢ +ĺ +⦴ +ℒ +λ +⟨ +⦑ +⟨ +⪅ +« +« +← +⇤ +⤟ +⤝ +↩ +↫ +⤹ +⥳ +↢ +⪫ +⤙ +⪭ +⪭︀ +⤌ +❲ +{ +[ +⦋ +⦏ +⦍ +ľ +ļ +⌈ +{ +л +⤶ +“ +„ +⥧ +⥋ +↲ +≤ +← +↢ +↽ +↼ +⇇ +↔ +⇆ +⇋ +↭ +⋋ +⋚ +≤ +≦ +⩽ +⩽ +⪨ +⩿ +⪁ +⪃ +⋚︀ +⪓ +⪅ +⋖ +⋚ +⪋ +≶ +≲ +⥼ +⌊ +𝔩 +≶ +⪑ +↽ +↼ +⥪ +▄ +љ +≪ +⇇ +⌞ +⥫ +◺ +ŀ +⎰ +⎰ +≨ +⪉ +⪉ +⪇ +⪇ +≨ +⋦ +⟬ +⇽ +⟦ +⟵ +⟷ +⟼ +⟶ +↫ +↬ +⦅ +𝕝 +⨭ +⨴ +∗ +_ +◊ +◊ +⧫ +( +⦓ +⇆ +⌟ +⇋ +⥭ +‎ +⊿ +‹ +𝓁 +↰ +≲ +⪍ +⪏ +[ +‘ +‚ +ł +< +< +⪦ +⩹ +⋖ +⋋ +⋉ +⥶ +⩻ +⦖ +◃ +⊴ +◂ +⥊ +⥦ +≨︀ +≨︀ +∺ +¯ +¯ +♂ +✠ +✠ +↦ +↦ +↧ +↤ +↥ +▮ +⨩ +м +— +∡ +𝔪 +℧ +µ +µ +∣ +* +⫰ +· +· +− +⊟ +∸ +⨪ +⫛ +… +∓ +⊧ +𝕞 +∓ +𝓂 +∾ +μ +⊸ +⊸ +⋙̸ +≫⃒ +≫̸ +⇍ +⇎ +⋘̸ +≪⃒ +≪̸ +⇏ +⊯ +⊮ +∇ +ń +∠⃒ +≉ +⩰̸ +≋̸ +ʼn +≉ +♮ +♮ +ℕ +  +  +≎̸ +≏̸ +⩃ +ň +ņ +≇ +⩭̸ +⩂ +н +– +≠ +⇗ +⤤ +↗ +↗ +≐̸ +≢ +⤨ +≂̸ +∄ +∄ +𝔫 +≧̸ +≱ +≱ +≧̸ +⩾̸ +⩾̸ +≵ +≯ +≯ +⇎ +↮ +⫲ +∋ +⋼ +⋺ +∋ +њ +⇍ +≦̸ +↚ +‥ +≰ +↚ +↮ +≰ +≦̸ +⩽̸ +⩽̸ +≮ +≴ +≮ +⋪ +⋬ +∤ +𝕟 +¬ +¬ +∉ +⋹̸ +⋵̸ +∉ +⋷ +⋶ +∌ +∌ +⋾ +⋽ +∦ +∦ +⫽⃥ +∂̸ +⨔ +⊀ +⋠ +⪯̸ +⊀ +⪯̸ +⇏ +↛ +⤳̸ +↝̸ +↛ +⋫ +⋭ +⊁ +⋡ +⪰̸ +𝓃 +∤ +∦ +≁ +≄ +≄ +∤ +∦ +⋢ +⋣ +⊄ +⫅̸ +⊈ +⊂⃒ +⊈ +⫅̸ +⊁ +⪰̸ +⊅ +⫆̸ +⊉ +⊃⃒ +⊉ +⫆̸ +≹ +ñ +ñ +≸ +⋪ +⋬ +⋫ +⋭ +ν +# +№ +  +⊭ +⤄ +≍⃒ +⊬ +≥⃒ +>⃒ +⧞ +⤂ +≤⃒ +<⃒ +⊴⃒ +⤃ +⊵⃒ +∼⃒ +⇖ +⤣ +↖ +↖ +⤧ +Ⓢ +ó +ó +⊛ +⊚ +ô +ô +о +⊝ +ő +⨸ +⊙ +⦼ +œ +⦿ +𝔬 +˛ +ò +ò +⧁ +⦵ +Ω +∮ +↺ +⦾ +⦻ +‾ +⧀ +ō +ω +ο +⦶ +⊖ +𝕠 +⦷ +⦹ +⊕ +∨ +↻ +⩝ +ℴ +ℴ +ª +ª +º +º +⊶ +⩖ +⩗ +⩛ +ℴ +ø +ø +⊘ +õ +õ +⊗ +⨶ +ö +ö +⌽ +∥ +¶ +¶ +∥ +⫳ +⫽ +∂ +п +% +. +‰ +⊥ +‱ +𝔭 +φ +ϕ +ℳ +☎ +π +⋔ +ϖ +ℏ +ℎ +ℏ ++ +⨣ +⊞ +⨢ +∔ +⨥ +⩲ +± +± +⨦ +⨧ +± +⨕ +𝕡 +£ +£ +≺ +⪳ +⪷ +≼ +⪯ +≺ +⪷ +≼ +⪯ +⪹ +⪵ +⋨ +≾ +′ +ℙ +⪵ +⪹ +⋨ +∏ +⌮ +⌒ +⌓ +∝ +∝ +≾ +⊰ +𝓅 +ψ +  +𝔮 +⨌ +𝕢 +⁗ +𝓆 +ℍ +⨖ +? +≟ +" +" +⇛ +⇒ +⤜ +⤏ +⥤ +∽̱ +ŕ +√ +⦳ +⟩ +⦒ +⦥ +⟩ +» +» +→ +⥵ +⇥ +⤠ +⤳ +⤞ +↪ +↬ +⥅ +⥴ +↣ +↝ +⤚ +∶ +ℚ +⤍ +❳ +} +] +⦌ +⦎ +⦐ +ř +ŗ +⌉ +} +р +⤷ +⥩ +” +” +↳ +ℜ +ℛ +ℜ +ℝ +▭ +® +® +⥽ +⌋ +𝔯 +⇁ +⇀ +⥬ +ρ +ϱ +→ +↣ +⇁ +⇀ +⇄ +⇌ +⇉ +↝ +⋌ +˚ +≓ +⇄ +⇌ +‏ +⎱ +⎱ +⫮ +⟭ +⇾ +⟧ +⦆ +𝕣 +⨮ +⨵ +) +⦔ +⨒ +⇉ +› +𝓇 +↱ +] +’ +’ +⋌ +⋊ +▹ +⊵ +▸ +⧎ +⥨ +℞ +ś +‚ +≻ +⪴ +⪸ +š +≽ +⪰ +ş +ŝ +⪶ +⪺ +⋩ +⨓ +≿ +с +⋅ +⊡ +⩦ +⇘ +⤥ +↘ +↘ +§ +§ +; +⤩ +∖ +∖ +✶ +𝔰 +⌢ +♯ +щ +ш +∣ +∥ +­ +­ +σ +ς +ς +∼ +⩪ +≃ +≃ +⪞ +⪠ +⪝ +⪟ +≆ +⨤ +⥲ +← +∖ +⨳ +⧤ +∣ +⌣ +⪪ +⪬ +⪬︀ +ь +/ +⧄ +⌿ +𝕤 +♠ +♠ +∥ +⊓ +⊓︀ +⊔ +⊔︀ +⊏ +⊑ +⊏ +⊑ +⊐ +⊒ +⊐ +⊒ +□ +□ +▪ +▪ +→ +𝓈 +∖ +⌣ +⋆ +☆ +★ +ϵ +ϕ +¯ +⊂ +⫅ +⪽ +⊆ +⫃ +⫁ +⫋ +⊊ +⪿ +⥹ +⊂ +⊆ +⫅ +⊊ +⫋ +⫇ +⫕ +⫓ +≻ +⪸ +≽ +⪰ +⪺ +⪶ +⋩ +≿ +∑ +♪ +¹ +¹ +² +² +³ +³ +⊃ +⫆ +⪾ +⫘ +⊇ +⫄ +⟉ +⫗ +⥻ +⫂ +⫌ +⊋ +⫀ +⊃ +⊇ +⫆ +⊋ +⫌ +⫈ +⫔ +⫖ +⇙ +⤦ +↙ +↙ +⤪ +ß +ß +⌖ +τ +⎴ +ť +ţ +т +⃛ +⌕ +𝔱 +∴ +∴ +θ +ϑ +ϑ +≈ +∼ +  +≈ +∼ +þ +þ +˜ +× +× +⊠ +⨱ +⨰ +∭ +⤨ +⊤ +⌶ +⫱ +𝕥 +⫚ +⤩ +‴ +™ +▵ +▿ +◃ +⊴ +≜ +▹ +⊵ +◬ +≜ +⨺ +⨹ +⧍ +⨻ +⏢ +𝓉 +ц +ћ +ŧ +≬ +↞ +↠ +⇑ +⥣ +ú +ú +↑ +ў +ŭ +û +û +у +⇅ +ű +⥮ +⥾ +𝔲 +ù +ù +↿ +↾ +▀ +⌜ +⌜ +⌏ +◸ +ū +¨ +¨ +ų +𝕦 +↑ +↕ +↿ +↾ +⊎ +υ +ϒ +υ +⇈ +⌝ +⌝ +⌎ +ů +◹ +𝓊 +⋰ +ũ +▵ +▴ +⇈ +ü +ü +⦧ +⇕ +⫨ +⫩ +⊨ +⦜ +ϵ +ϰ +∅ +ϕ +ϖ +∝ +↕ +ϱ +ς +⊊︀ +⫋︀ +⊋︀ +⫌︀ +ϑ +⊲ +⊳ +в +⊢ +∨ +⊻ +≚ +⋮ +| +| +𝔳 +⊲ +⊂⃒ +⊃⃒ +𝕧 +∝ +⊳ +𝓋 +⫋︀ +⊊︀ +⫌︀ +⊋︀ +⦚ +ŵ +⩟ +∧ +≙ +℘ +𝔴 +𝕨 +℘ +≀ +≀ +𝓌 +⋂ +◯ +⋃ +▽ +𝔵 +⟺ +⟷ +ξ +⟸ +⟵ +⟼ +⋻ +⨀ +𝕩 +⨁ +⨂ +⟹ +⟶ +𝓍 +⨆ +⨄ +△ +⋁ +⋀ +ý +ý +я +ŷ +ы +¥ +¥ +𝔶 +ї +𝕪 +𝓎 +ю +ÿ +ÿ +ź +ž +з +ż +ℨ +ζ +𝔷 +ж +⇝ +𝕫 +𝓏 +‍ +‌ +& +&x +& +A +A +A +A +A +€ +� + +� +� +� +� + + +¬it; +∉ +¬ +&unknown; +& +&&& +a & b +<sup>107Ibid. +plain text +&amp; +&#38; +AT&T and R&D +   +  +∳ + + +; +� +￾ +&a; +&ab; +&abc; +x& \ No newline at end of file diff --git a/parity/golden/mdscrub/breaks.md b/parity/golden/mdscrub/breaks.md index a56d84c..a84c790 100644 --- a/parity/golden/mdscrub/breaks.md +++ b/parity/golden/mdscrub/breaks.md @@ -1,5 +1,5 @@ -The address was set with explicit line breaks:Twelve Mill LaneThe -Valleyand the county beyond. +The address was set with explicit line breaks: Twelve Mill Lane The +Valley and the county beyond. A second paragraph, where the break sits mid sentence — the mill stood at -thenorthern end of the valley, where the fall was steepest. +the northern end of the valley, where the fall was steepest. diff --git a/parity/golden/mdscrub/breaks.rust.md b/parity/golden/mdscrub/breaks.rust.md deleted file mode 100644 index 8aad06f..0000000 --- a/parity/golden/mdscrub/breaks.rust.md +++ /dev/null @@ -1,9 +0,0 @@ -The address was set with explicit line breaks: -Twelve Mill Lane -The -Valley -and the county beyond. - -A second paragraph, where the break sits mid sentence — the mill stood at -the -northern end of the valley, where the fall was steepest. diff --git a/parity/golden/unescape/entities.jsonl b/parity/golden/unescape/entities.jsonl new file mode 100644 index 0000000..1fe56f1 --- /dev/null +++ b/parity/golden/unescape/entities.jsonl @@ -0,0 +1,2272 @@ +"Æ" +"Æ" +"&" +"&" +"Á" +"Á" +"Ă" +"Â" +"Â" +"А" +"𝔄" +"À" +"À" +"Α" +"Ā" +"⩓" +"Ą" +"𝔸" +"⁡" +"Å" +"Å" +"𝒜" +"≔" +"Ã" +"Ã" +"Ä" +"Ä" +"∖" +"⫧" +"⌆" +"Б" +"∵" +"ℬ" +"Β" +"𝔅" +"𝔹" +"˘" +"ℬ" +"≎" +"Ч" +"©" +"©" +"Ć" +"⋒" +"ⅅ" +"ℭ" +"Č" +"Ç" +"Ç" +"Ĉ" +"∰" +"Ċ" +"¸" +"·" +"ℭ" +"Χ" +"⊙" +"⊖" +"⊕" +"⊗" +"∲" +"”" +"’" +"∷" +"⩴" +"≡" +"∯" +"∮" +"ℂ" +"∐" +"∳" +"⨯" +"𝒞" +"⋓" +"≍" +"ⅅ" +"⤑" +"Ђ" +"Ѕ" +"Џ" +"‡" +"↡" +"⫤" +"Ď" +"Д" +"∇" +"Δ" +"𝔇" +"´" +"˙" +"˝" +"`" +"˜" +"⋄" +"ⅆ" +"𝔻" +"¨" +"⃜" +"≐" +"∯" +"¨" +"⇓" +"⇐" +"⇔" +"⫤" +"⟸" +"⟺" +"⟹" +"⇒" +"⊨" +"⇑" +"⇕" +"∥" +"↓" +"⤓" +"⇵" +"̑" +"⥐" +"⥞" +"↽" +"⥖" +"⥟" +"⇁" +"⥗" +"⊤" +"↧" +"⇓" +"𝒟" +"Đ" +"Ŋ" +"Ð" +"Ð" +"É" +"É" +"Ě" +"Ê" +"Ê" +"Э" +"Ė" +"𝔈" +"È" +"È" +"∈" +"Ē" +"◻" +"▫" +"Ę" +"𝔼" +"Ε" +"⩵" +"≂" +"⇌" +"ℰ" +"⩳" +"Η" +"Ë" +"Ë" +"∃" +"ⅇ" +"Ф" +"𝔉" +"◼" +"▪" +"𝔽" +"∀" +"ℱ" +"ℱ" +"Ѓ" +">" +">" +"Γ" +"Ϝ" +"Ğ" +"Ģ" +"Ĝ" +"Г" +"Ġ" +"𝔊" +"⋙" +"𝔾" +"≥" +"⋛" +"≧" +"⪢" +"≷" +"⩾" +"≳" +"𝒢" +"≫" +"Ъ" +"ˇ" +"^" +"Ĥ" +"ℌ" +"ℋ" +"ℍ" +"─" +"ℋ" +"Ħ" +"≎" +"≏" +"Е" +"IJ" +"Ё" +"Í" +"Í" +"Î" +"Î" +"И" +"İ" +"ℑ" +"Ì" +"Ì" +"ℑ" +"Ī" +"ⅈ" +"⇒" +"∬" +"∫" +"⋂" +"⁣" +"⁢" +"Į" +"𝕀" +"Ι" +"ℐ" +"Ĩ" +"І" +"Ï" +"Ï" +"Ĵ" +"Й" +"𝔍" +"𝕁" +"𝒥" +"Ј" +"Є" +"Х" +"Ќ" +"Κ" +"Ķ" +"К" +"𝔎" +"𝕂" +"𝒦" +"Љ" +"<" +"<" +"Ĺ" +"Λ" +"⟪" +"ℒ" +"↞" +"Ľ" +"Ļ" +"Л" +"⟨" +"←" +"⇤" +"⇆" +"⌈" +"⟦" +"⥡" +"⇃" +"⥙" +"⌊" +"↔" +"⥎" +"⊣" +"↤" +"⥚" +"⊲" +"⧏" +"⊴" +"⥑" +"⥠" +"↿" +"⥘" +"↼" +"⥒" +"⇐" +"⇔" +"⋚" +"≦" +"≶" +"⪡" +"⩽" +"≲" +"𝔏" +"⋘" +"⇚" +"Ŀ" +"⟵" +"⟷" +"⟶" +"⟸" +"⟺" +"⟹" +"𝕃" +"↙" +"↘" +"ℒ" +"↰" +"Ł" +"≪" +"⤅" +"М" +" " +"ℳ" +"𝔐" +"∓" +"𝕄" +"ℳ" +"Μ" +"Њ" +"Ń" +"Ň" +"Ņ" +"Н" +"​" +"​" +"​" +"​" +"≫" +"≪" +"\n" +"𝔑" +"⁠" +" " +"ℕ" +"⫬" +"≢" +"≭" +"∦" +"∉" +"≠" +"≂̸" +"∄" +"≯" +"≱" +"≧̸" +"≫̸" +"≹" +"⩾̸" +"≵" +"≎̸" +"≏̸" +"⋪" +"⧏̸" +"⋬" +"≮" +"≰" +"≸" +"≪̸" +"⩽̸" +"≴" +"⪢̸" +"⪡̸" +"⊀" +"⪯̸" +"⋠" +"∌" +"⋫" +"⧐̸" +"⋭" +"⊏̸" +"⋢" +"⊐̸" +"⋣" +"⊂⃒" +"⊈" +"⊁" +"⪰̸" +"⋡" +"≿̸" +"⊃⃒" +"⊉" +"≁" +"≄" +"≇" +"≉" +"∤" +"𝒩" +"Ñ" +"Ñ" +"Ν" +"Œ" +"Ó" +"Ó" +"Ô" +"Ô" +"О" +"Ő" +"𝔒" +"Ò" +"Ò" +"Ō" +"Ω" +"Ο" +"𝕆" +"“" +"‘" +"⩔" +"𝒪" +"Ø" +"Ø" +"Õ" +"Õ" +"⨷" +"Ö" +"Ö" +"‾" +"⏞" +"⎴" +"⏜" +"∂" +"П" +"𝔓" +"Φ" +"Π" +"±" +"ℌ" +"ℙ" +"⪻" +"≺" +"⪯" +"≼" +"≾" +"″" +"∏" +"∷" +"∝" +"𝒫" +"Ψ" +"\"" +"\"" +"𝔔" +"ℚ" +"𝒬" +"⤐" +"®" +"®" +"Ŕ" +"⟫" +"↠" +"⤖" +"Ř" +"Ŗ" +"Р" +"ℜ" +"∋" +"⇋" +"⥯" +"ℜ" +"Ρ" +"⟩" +"→" +"⇥" +"⇄" +"⌉" +"⟧" +"⥝" +"⇂" +"⥕" +"⌋" +"⊢" +"↦" +"⥛" +"⊳" +"⧐" +"⊵" +"⥏" +"⥜" +"↾" +"⥔" +"⇀" +"⥓" +"⇒" +"ℝ" +"⥰" +"⇛" +"ℛ" +"↱" +"⧴" +"Щ" +"Ш" +"Ь" +"Ś" +"⪼" +"Š" +"Ş" +"Ŝ" +"С" +"𝔖" +"↓" +"←" +"→" +"↑" +"Σ" +"∘" +"𝕊" +"√" +"□" +"⊓" +"⊏" +"⊑" +"⊐" +"⊒" +"⊔" +"𝒮" +"⋆" +"⋐" +"⋐" +"⊆" +"≻" +"⪰" +"≽" +"≿" +"∋" +"∑" +"⋑" +"⊃" +"⊇" +"⋑" +"Þ" +"Þ" +"™" +"Ћ" +"Ц" +"\t" +"Τ" +"Ť" +"Ţ" +"Т" +"𝔗" +"∴" +"Θ" +"  " +" " +"∼" +"≃" +"≅" +"≈" +"𝕋" +"⃛" +"𝒯" +"Ŧ" +"Ú" +"Ú" +"↟" +"⥉" +"Ў" +"Ŭ" +"Û" +"Û" +"У" +"Ű" +"𝔘" +"Ù" +"Ù" +"Ū" +"_" +"⏟" +"⎵" +"⏝" +"⋃" +"⊎" +"Ų" +"𝕌" +"↑" +"⤒" +"⇅" +"↕" +"⥮" +"⊥" +"↥" +"⇑" +"⇕" +"↖" +"↗" +"ϒ" +"Υ" +"Ů" +"𝒰" +"Ũ" +"Ü" +"Ü" +"⊫" +"⫫" +"В" +"⊩" +"⫦" +"⋁" +"‖" +"‖" +"∣" +"|" +"❘" +"≀" +" " +"𝔙" +"𝕍" +"𝒱" +"⊪" +"Ŵ" +"⋀" +"𝔚" +"𝕎" +"𝒲" +"𝔛" +"Ξ" +"𝕏" +"𝒳" +"Я" +"Ї" +"Ю" +"Ý" +"Ý" +"Ŷ" +"Ы" +"𝔜" +"𝕐" +"𝒴" +"Ÿ" +"Ж" +"Ź" +"Ž" +"З" +"Ż" +"​" +"Ζ" +"ℨ" +"ℤ" +"𝒵" +"á" +"á" +"ă" +"∾" +"∾̳" +"∿" +"â" +"â" +"´" +"´" +"а" +"æ" +"æ" +"⁡" +"𝔞" +"à" +"à" +"ℵ" +"ℵ" +"α" +"ā" +"⨿" +"&" +"&" +"∧" +"⩕" +"⩜" +"⩘" +"⩚" +"∠" +"⦤" +"∠" +"∡" +"⦨" +"⦩" +"⦪" +"⦫" +"⦬" +"⦭" +"⦮" +"⦯" +"∟" +"⊾" +"⦝" +"∢" +"Å" +"⍼" +"ą" +"𝕒" +"≈" +"⩰" +"⩯" +"≊" +"≋" +"'" +"≈" +"≊" +"å" +"å" +"𝒶" +"*" +"≈" +"≍" +"ã" +"ã" +"ä" +"ä" +"∳" +"⨑" +"⫭" +"≌" +"϶" +"‵" +"∽" +"⋍" +"⊽" +"⌅" +"⌅" +"⎵" +"⎶" +"≌" +"б" +"„" +"∵" +"∵" +"⦰" +"϶" +"ℬ" +"β" +"ℶ" +"≬" +"𝔟" +"⋂" +"◯" +"⋃" +"⨀" +"⨁" +"⨂" +"⨆" +"★" +"▽" +"△" +"⨄" +"⋁" +"⋀" +"⤍" +"⧫" +"▪" +"▴" +"▾" +"◂" +"▸" +"␣" +"▒" +"░" +"▓" +"█" +"=⃥" +"≡⃥" +"⌐" +"𝕓" +"⊥" +"⊥" +"⋈" +"╗" +"╔" +"╖" +"╓" +"═" +"╦" +"╩" +"╤" +"╧" +"╝" +"╚" +"╜" +"╙" +"║" +"╬" +"╣" +"╠" +"╫" +"╢" +"╟" +"⧉" +"╕" +"╒" +"┐" +"┌" +"─" +"╥" +"╨" +"┬" +"┴" +"⊟" +"⊞" +"⊠" +"╛" +"╘" +"┘" +"└" +"│" +"╪" +"╡" +"╞" +"┼" +"┤" +"├" +"‵" +"˘" +"¦" +"¦" +"𝒷" +"⁏" +"∽" +"⋍" +"\\" +"⧅" +"⟈" +"•" +"•" +"≎" +"⪮" +"≏" +"≏" +"ć" +"∩" +"⩄" +"⩉" +"⩋" +"⩇" +"⩀" +"∩︀" +"⁁" +"ˇ" +"⩍" +"č" +"ç" +"ç" +"ĉ" +"⩌" +"⩐" +"ċ" +"¸" +"¸" +"⦲" +"¢" +"¢" +"·" +"𝔠" +"ч" +"✓" +"✓" +"χ" +"○" +"⧃" +"ˆ" +"≗" +"↺" +"↻" +"®" +"Ⓢ" +"⊛" +"⊚" +"⊝" +"≗" +"⨐" +"⫯" +"⧂" +"♣" +"♣" +":" +"≔" +"≔" +"," +"@" +"∁" +"∘" +"∁" +"ℂ" +"≅" +"⩭" +"∮" +"𝕔" +"∐" +"©" +"©" +"℗" +"↵" +"✗" +"𝒸" +"⫏" +"⫑" +"⫐" +"⫒" +"⋯" +"⤸" +"⤵" +"⋞" +"⋟" +"↶" +"⤽" +"∪" +"⩈" +"⩆" +"⩊" +"⊍" +"⩅" +"∪︀" +"↷" +"⤼" +"⋞" +"⋟" +"⋎" +"⋏" +"¤" +"¤" +"↶" +"↷" +"⋎" +"⋏" +"∲" +"∱" +"⌭" +"⇓" +"⥥" +"†" +"ℸ" +"↓" +"‐" +"⊣" +"⤏" +"˝" +"ď" +"д" +"ⅆ" +"‡" +"⇊" +"⩷" +"°" +"°" +"δ" +"⦱" +"⥿" +"𝔡" +"⇃" +"⇂" +"⋄" +"⋄" +"♦" +"♦" +"¨" +"ϝ" +"⋲" +"÷" +"÷" +"÷" +"⋇" +"⋇" +"ђ" +"⌞" +"⌍" +"$" +"𝕕" +"˙" +"≐" +"≑" +"∸" +"∔" +"⊡" +"⌆" +"↓" +"⇊" +"⇃" +"⇂" +"⤐" +"⌟" +"⌌" +"𝒹" +"ѕ" +"⧶" +"đ" +"⋱" +"▿" +"▾" +"⇵" +"⥯" +"⦦" +"џ" +"⟿" +"⩷" +"≑" +"é" +"é" +"⩮" +"ě" +"≖" +"ê" +"ê" +"≕" +"э" +"ė" +"ⅇ" +"≒" +"𝔢" +"⪚" +"è" +"è" +"⪖" +"⪘" +"⪙" +"⏧" +"ℓ" +"⪕" +"⪗" +"ē" +"∅" +"∅" +"∅" +" " +" " +" " +"ŋ" +" " +"ę" +"𝕖" +"⋕" +"⧣" +"⩱" +"ε" +"ε" +"ϵ" +"≖" +"≕" +"≂" +"⪖" +"⪕" +"=" +"≟" +"≡" +"⩸" +"⧥" +"≓" +"⥱" +"ℯ" +"≐" +"≂" +"η" +"ð" +"ð" +"ë" +"ë" +"€" +"!" +"∃" +"ℰ" +"ⅇ" +"≒" +"ф" +"♀" +"ffi" +"ff" +"ffl" +"𝔣" +"fi" +"fj" +"♭" +"fl" +"▱" +"ƒ" +"𝕗" +"∀" +"⋔" +"⫙" +"⨍" +"½" +"½" +"⅓" +"¼" +"¼" +"⅕" +"⅙" +"⅛" +"⅔" +"⅖" +"¾" +"¾" +"⅗" +"⅜" +"⅘" +"⅚" +"⅝" +"⅞" +"⁄" +"⌢" +"𝒻" +"≧" +"⪌" +"ǵ" +"γ" +"ϝ" +"⪆" +"ğ" +"ĝ" +"г" +"ġ" +"≥" +"⋛" +"≥" +"≧" +"⩾" +"⩾" +"⪩" +"⪀" +"⪂" +"⪄" +"⋛︀" +"⪔" +"𝔤" +"≫" +"⋙" +"ℷ" +"ѓ" +"≷" +"⪒" +"⪥" +"⪤" +"≩" +"⪊" +"⪊" +"⪈" +"⪈" +"≩" +"⋧" +"𝕘" +"`" +"ℊ" +"≳" +"⪎" +"⪐" +">" +">" +"⪧" +"⩺" +"⋗" +"⦕" +"⩼" +"⪆" +"⥸" +"⋗" +"⋛" +"⪌" +"≷" +"≳" +"≩︀" +"≩︀" +"⇔" +" " +"½" +"ℋ" +"ъ" +"↔" +"⥈" +"↭" +"ℏ" +"ĥ" +"♥" +"♥" +"…" +"⊹" +"𝔥" +"⤥" +"⤦" +"⇿" +"∻" +"↩" +"↪" +"𝕙" +"―" +"𝒽" +"ℏ" +"ħ" +"⁃" +"‐" +"í" +"í" +"⁣" +"î" +"î" +"и" +"е" +"¡" +"¡" +"⇔" +"𝔦" +"ì" +"ì" +"ⅈ" +"⨌" +"∭" +"⧜" +"℩" +"ij" +"ī" +"ℑ" +"ℐ" +"ℑ" +"ı" +"⊷" +"Ƶ" +"∈" +"℅" +"∞" +"⧝" +"ı" +"∫" +"⊺" +"ℤ" +"⊺" +"⨗" +"⨼" +"ё" +"į" +"𝕚" +"ι" +"⨼" +"¿" +"¿" +"𝒾" +"∈" +"⋹" +"⋵" +"⋴" +"⋳" +"∈" +"⁢" +"ĩ" +"і" +"ï" +"ï" +"ĵ" +"й" +"𝔧" +"ȷ" +"𝕛" +"𝒿" +"ј" +"є" +"κ" +"ϰ" +"ķ" +"к" +"𝔨" +"ĸ" +"х" +"ќ" +"𝕜" +"𝓀" +"⇚" +"⇐" +"⤛" +"⤎" +"≦" +"⪋" +"⥢" +"ĺ" +"⦴" +"ℒ" +"λ" +"⟨" +"⦑" +"⟨" +"⪅" +"«" +"«" +"←" +"⇤" +"⤟" +"⤝" +"↩" +"↫" +"⤹" +"⥳" +"↢" +"⪫" +"⤙" +"⪭" +"⪭︀" +"⤌" +"❲" +"{" +"[" +"⦋" +"⦏" +"⦍" +"ľ" +"ļ" +"⌈" +"{" +"л" +"⤶" +"“" +"„" +"⥧" +"⥋" +"↲" +"≤" +"←" +"↢" +"↽" +"↼" +"⇇" +"↔" +"⇆" +"⇋" +"↭" +"⋋" +"⋚" +"≤" +"≦" +"⩽" +"⩽" +"⪨" +"⩿" +"⪁" +"⪃" +"⋚︀" +"⪓" +"⪅" +"⋖" +"⋚" +"⪋" +"≶" +"≲" +"⥼" +"⌊" +"𝔩" +"≶" +"⪑" +"↽" +"↼" +"⥪" +"▄" +"љ" +"≪" +"⇇" +"⌞" +"⥫" +"◺" +"ŀ" +"⎰" +"⎰" +"≨" +"⪉" +"⪉" +"⪇" +"⪇" +"≨" +"⋦" +"⟬" +"⇽" +"⟦" +"⟵" +"⟷" +"⟼" +"⟶" +"↫" +"↬" +"⦅" +"𝕝" +"⨭" +"⨴" +"∗" +"_" +"◊" +"◊" +"⧫" +"(" +"⦓" +"⇆" +"⌟" +"⇋" +"⥭" +"‎" +"⊿" +"‹" +"𝓁" +"↰" +"≲" +"⪍" +"⪏" +"[" +"‘" +"‚" +"ł" +"<" +"<" +"⪦" +"⩹" +"⋖" +"⋋" +"⋉" +"⥶" +"⩻" +"⦖" +"◃" +"⊴" +"◂" +"⥊" +"⥦" +"≨︀" +"≨︀" +"∺" +"¯" +"¯" +"♂" +"✠" +"✠" +"↦" +"↦" +"↧" +"↤" +"↥" +"▮" +"⨩" +"м" +"—" +"∡" +"𝔪" +"℧" +"µ" +"µ" +"∣" +"*" +"⫰" +"·" +"·" +"−" +"⊟" +"∸" +"⨪" +"⫛" +"…" +"∓" +"⊧" +"𝕞" +"∓" +"𝓂" +"∾" +"μ" +"⊸" +"⊸" +"⋙̸" +"≫⃒" +"≫̸" +"⇍" +"⇎" +"⋘̸" +"≪⃒" +"≪̸" +"⇏" +"⊯" +"⊮" +"∇" +"ń" +"∠⃒" +"≉" +"⩰̸" +"≋̸" +"ʼn" +"≉" +"♮" +"♮" +"ℕ" +" " +" " +"≎̸" +"≏̸" +"⩃" +"ň" +"ņ" +"≇" +"⩭̸" +"⩂" +"н" +"–" +"≠" +"⇗" +"⤤" +"↗" +"↗" +"≐̸" +"≢" +"⤨" +"≂̸" +"∄" +"∄" +"𝔫" +"≧̸" +"≱" +"≱" +"≧̸" +"⩾̸" +"⩾̸" +"≵" +"≯" +"≯" +"⇎" +"↮" +"⫲" +"∋" +"⋼" +"⋺" +"∋" +"њ" +"⇍" +"≦̸" +"↚" +"‥" +"≰" +"↚" +"↮" +"≰" +"≦̸" +"⩽̸" +"⩽̸" +"≮" +"≴" +"≮" +"⋪" +"⋬" +"∤" +"𝕟" +"¬" +"¬" +"∉" +"⋹̸" +"⋵̸" +"∉" +"⋷" +"⋶" +"∌" +"∌" +"⋾" +"⋽" +"∦" +"∦" +"⫽⃥" +"∂̸" +"⨔" +"⊀" +"⋠" +"⪯̸" +"⊀" +"⪯̸" +"⇏" +"↛" +"⤳̸" +"↝̸" +"↛" +"⋫" +"⋭" +"⊁" +"⋡" +"⪰̸" +"𝓃" +"∤" +"∦" +"≁" +"≄" +"≄" +"∤" +"∦" +"⋢" +"⋣" +"⊄" +"⫅̸" +"⊈" +"⊂⃒" +"⊈" +"⫅̸" +"⊁" +"⪰̸" +"⊅" +"⫆̸" +"⊉" +"⊃⃒" +"⊉" +"⫆̸" +"≹" +"ñ" +"ñ" +"≸" +"⋪" +"⋬" +"⋫" +"⋭" +"ν" +"#" +"№" +" " +"⊭" +"⤄" +"≍⃒" +"⊬" +"≥⃒" +">⃒" +"⧞" +"⤂" +"≤⃒" +"<⃒" +"⊴⃒" +"⤃" +"⊵⃒" +"∼⃒" +"⇖" +"⤣" +"↖" +"↖" +"⤧" +"Ⓢ" +"ó" +"ó" +"⊛" +"⊚" +"ô" +"ô" +"о" +"⊝" +"ő" +"⨸" +"⊙" +"⦼" +"œ" +"⦿" +"𝔬" +"˛" +"ò" +"ò" +"⧁" +"⦵" +"Ω" +"∮" +"↺" +"⦾" +"⦻" +"‾" +"⧀" +"ō" +"ω" +"ο" +"⦶" +"⊖" +"𝕠" +"⦷" +"⦹" +"⊕" +"∨" +"↻" +"⩝" +"ℴ" +"ℴ" +"ª" +"ª" +"º" +"º" +"⊶" +"⩖" +"⩗" +"⩛" +"ℴ" +"ø" +"ø" +"⊘" +"õ" +"õ" +"⊗" +"⨶" +"ö" +"ö" +"⌽" +"∥" +"¶" +"¶" +"∥" +"⫳" +"⫽" +"∂" +"п" +"%" +"." +"‰" +"⊥" +"‱" +"𝔭" +"φ" +"ϕ" +"ℳ" +"☎" +"π" +"⋔" +"ϖ" +"ℏ" +"ℎ" +"ℏ" +"+" +"⨣" +"⊞" +"⨢" +"∔" +"⨥" +"⩲" +"±" +"±" +"⨦" +"⨧" +"±" +"⨕" +"𝕡" +"£" +"£" +"≺" +"⪳" +"⪷" +"≼" +"⪯" +"≺" +"⪷" +"≼" +"⪯" +"⪹" +"⪵" +"⋨" +"≾" +"′" +"ℙ" +"⪵" +"⪹" +"⋨" +"∏" +"⌮" +"⌒" +"⌓" +"∝" +"∝" +"≾" +"⊰" +"𝓅" +"ψ" +" " +"𝔮" +"⨌" +"𝕢" +"⁗" +"𝓆" +"ℍ" +"⨖" +"?" +"≟" +"\"" +"\"" +"⇛" +"⇒" +"⤜" +"⤏" +"⥤" +"∽̱" +"ŕ" +"√" +"⦳" +"⟩" +"⦒" +"⦥" +"⟩" +"»" +"»" +"→" +"⥵" +"⇥" +"⤠" +"⤳" +"⤞" +"↪" +"↬" +"⥅" +"⥴" +"↣" +"↝" +"⤚" +"∶" +"ℚ" +"⤍" +"❳" +"}" +"]" +"⦌" +"⦎" +"⦐" +"ř" +"ŗ" +"⌉" +"}" +"р" +"⤷" +"⥩" +"”" +"”" +"↳" +"ℜ" +"ℛ" +"ℜ" +"ℝ" +"▭" +"®" +"®" +"⥽" +"⌋" +"𝔯" +"⇁" +"⇀" +"⥬" +"ρ" +"ϱ" +"→" +"↣" +"⇁" +"⇀" +"⇄" +"⇌" +"⇉" +"↝" +"⋌" +"˚" +"≓" +"⇄" +"⇌" +"‏" +"⎱" +"⎱" +"⫮" +"⟭" +"⇾" +"⟧" +"⦆" +"𝕣" +"⨮" +"⨵" +")" +"⦔" +"⨒" +"⇉" +"›" +"𝓇" +"↱" +"]" +"’" +"’" +"⋌" +"⋊" +"▹" +"⊵" +"▸" +"⧎" +"⥨" +"℞" +"ś" +"‚" +"≻" +"⪴" +"⪸" +"š" +"≽" +"⪰" +"ş" +"ŝ" +"⪶" +"⪺" +"⋩" +"⨓" +"≿" +"с" +"⋅" +"⊡" +"⩦" +"⇘" +"⤥" +"↘" +"↘" +"§" +"§" +";" +"⤩" +"∖" +"∖" +"✶" +"𝔰" +"⌢" +"♯" +"щ" +"ш" +"∣" +"∥" +"­" +"­" +"σ" +"ς" +"ς" +"∼" +"⩪" +"≃" +"≃" +"⪞" +"⪠" +"⪝" +"⪟" +"≆" +"⨤" +"⥲" +"←" +"∖" +"⨳" +"⧤" +"∣" +"⌣" +"⪪" +"⪬" +"⪬︀" +"ь" +"/" +"⧄" +"⌿" +"𝕤" +"♠" +"♠" +"∥" +"⊓" +"⊓︀" +"⊔" +"⊔︀" +"⊏" +"⊑" +"⊏" +"⊑" +"⊐" +"⊒" +"⊐" +"⊒" +"□" +"□" +"▪" +"▪" +"→" +"𝓈" +"∖" +"⌣" +"⋆" +"☆" +"★" +"ϵ" +"ϕ" +"¯" +"⊂" +"⫅" +"⪽" +"⊆" +"⫃" +"⫁" +"⫋" +"⊊" +"⪿" +"⥹" +"⊂" +"⊆" +"⫅" +"⊊" +"⫋" +"⫇" +"⫕" +"⫓" +"≻" +"⪸" +"≽" +"⪰" +"⪺" +"⪶" +"⋩" +"≿" +"∑" +"♪" +"¹" +"¹" +"²" +"²" +"³" +"³" +"⊃" +"⫆" +"⪾" +"⫘" +"⊇" +"⫄" +"⟉" +"⫗" +"⥻" +"⫂" +"⫌" +"⊋" +"⫀" +"⊃" +"⊇" +"⫆" +"⊋" +"⫌" +"⫈" +"⫔" +"⫖" +"⇙" +"⤦" +"↙" +"↙" +"⤪" +"ß" +"ß" +"⌖" +"τ" +"⎴" +"ť" +"ţ" +"т" +"⃛" +"⌕" +"𝔱" +"∴" +"∴" +"θ" +"ϑ" +"ϑ" +"≈" +"∼" +" " +"≈" +"∼" +"þ" +"þ" +"˜" +"×" +"×" +"⊠" +"⨱" +"⨰" +"∭" +"⤨" +"⊤" +"⌶" +"⫱" +"𝕥" +"⫚" +"⤩" +"‴" +"™" +"▵" +"▿" +"◃" +"⊴" +"≜" +"▹" +"⊵" +"◬" +"≜" +"⨺" +"⨹" +"⧍" +"⨻" +"⏢" +"𝓉" +"ц" +"ћ" +"ŧ" +"≬" +"↞" +"↠" +"⇑" +"⥣" +"ú" +"ú" +"↑" +"ў" +"ŭ" +"û" +"û" +"у" +"⇅" +"ű" +"⥮" +"⥾" +"𝔲" +"ù" +"ù" +"↿" +"↾" +"▀" +"⌜" +"⌜" +"⌏" +"◸" +"ū" +"¨" +"¨" +"ų" +"𝕦" +"↑" +"↕" +"↿" +"↾" +"⊎" +"υ" +"ϒ" +"υ" +"⇈" +"⌝" +"⌝" +"⌎" +"ů" +"◹" +"𝓊" +"⋰" +"ũ" +"▵" +"▴" +"⇈" +"ü" +"ü" +"⦧" +"⇕" +"⫨" +"⫩" +"⊨" +"⦜" +"ϵ" +"ϰ" +"∅" +"ϕ" +"ϖ" +"∝" +"↕" +"ϱ" +"ς" +"⊊︀" +"⫋︀" +"⊋︀" +"⫌︀" +"ϑ" +"⊲" +"⊳" +"в" +"⊢" +"∨" +"⊻" +"≚" +"⋮" +"|" +"|" +"𝔳" +"⊲" +"⊂⃒" +"⊃⃒" +"𝕧" +"∝" +"⊳" +"𝓋" +"⫋︀" +"⊊︀" +"⫌︀" +"⊋︀" +"⦚" +"ŵ" +"⩟" +"∧" +"≙" +"℘" +"𝔴" +"𝕨" +"℘" +"≀" +"≀" +"𝓌" +"⋂" +"◯" +"⋃" +"▽" +"𝔵" +"⟺" +"⟷" +"ξ" +"⟸" +"⟵" +"⟼" +"⋻" +"⨀" +"𝕩" +"⨁" +"⨂" +"⟹" +"⟶" +"𝓍" +"⨆" +"⨄" +"△" +"⋁" +"⋀" +"ý" +"ý" +"я" +"ŷ" +"ы" +"¥" +"¥" +"𝔶" +"ї" +"𝕪" +"𝓎" +"ю" +"ÿ" +"ÿ" +"ź" +"ž" +"з" +"ż" +"ℨ" +"ζ" +"𝔷" +"ж" +"⇝" +"𝕫" +"𝓏" +"‍" +"‌" +"&" +"&x" +"&" +"A" +"A" +"A" +"A" +"A" +"€" +"�" +"\r" +"�" +"�" +"�" +"�" +"" +"" +"¬it;" +"∉" +"¬" +"&unknown;" +"&" +"&&&" +"a & b" +"107Ibid." +"plain text" +"&" +"&" +"AT&T and R&D" +"  " +" " +"∳" +"\n" +"\t" +";" +"�" +"" +"&a;" +"&ab;" +"&abc;" +"x&" diff --git a/parity/oracle/unescape.py b/parity/oracle/unescape.py new file mode 100644 index 0000000..3947584 --- /dev/null +++ b/parity/oracle/unescape.py @@ -0,0 +1,23 @@ +"""Decode HTML character references the way Python does, one line at a time. + +Each line of stdin is one case; each line of stdout is that case decoded and +JSON-encoded, because a decoded reference can itself be a newline. + + python3 oracle/unescape.py < cases/unescape/entities.txt +""" + +import html +import json +import sys + + +def main() -> int: + text = sys.stdin.buffer.read().decode("utf-8") + out = sys.stdout + for line in text.split("\n"): + out.write(json.dumps(html.unescape(line), ensure_ascii=False) + "\n") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/parity/src/bin/regen.rs b/parity/src/bin/regen.rs index 014e5bd..a2c5567 100644 --- a/parity/src/bin/regen.rs +++ b/parity/src/bin/regen.rs @@ -19,8 +19,9 @@ type Written = Result, String>; type Job = (&'static str, fn() -> Written); fn main() -> ExitCode { - let jobs: [Job; 3] = [ + let jobs: [Job; 4] = [ ("tokens", tokens), + ("unescape", unescape), ("chunkmd", chunkmd), ("mdscrub", mdscrub), ]; @@ -54,6 +55,18 @@ fn tokens() -> Written { Ok(vec![path.display().to_string()]) } +fn unescape() -> Written { + let dir = parity::golden("unescape"); + std::fs::create_dir_all(&dir).map_err(|e| e.to_string())?; + + let cases = parity::dir().join("cases/unescape/entities.txt"); + let text = std::fs::read_to_string(&cases).map_err(|e| e.to_string())?; + let decoded = parity::run_oracle("unescape.py", &text)?; + let path = dir.join("entities.jsonl"); + std::fs::write(&path, decoded).map_err(|e| e.to_string())?; + Ok(vec![path.display().to_string()]) +} + fn mdscrub() -> Written { let dir = parity::golden("mdscrub"); std::fs::create_dir_all(&dir).map_err(|e| e.to_string())?; @@ -66,15 +79,6 @@ fn mdscrub() -> Written { let path = dir.join(format!("{name}.md")); std::fs::write(&path, cleaned).map_err(|e| e.to_string())?; written.push(path.display().to_string()); - - // Where the Rust deliberately differs, its own answer is committed - // too, so the difference is visible in a review rather than only in - // a test failure. See parity/KNOWN.md. - if parity::DIVERGENT_MDSCRUB.contains(&name.as_str()) { - let path = dir.join(format!("{name}.rust.md")); - std::fs::write(&path, ::mdscrub::scrub(&markdown)).map_err(|e| e.to_string())?; - written.push(path.display().to_string()); - } } Ok(written) } diff --git a/parity/src/lib.rs b/parity/src/lib.rs index 2016033..a7bace8 100644 --- a/parity/src/lib.rs +++ b/parity/src/lib.rs @@ -83,10 +83,6 @@ pub fn run_oracle_with(script: &str, args: &[String], input: &str) -> Result Vec { let dir = dir().join("cases").join(tool); diff --git a/parity/tests/mdscrub.rs b/parity/tests/mdscrub.rs index 39483ed..64afc03 100644 --- a/parity/tests/mdscrub.rs +++ b/parity/tests/mdscrub.rs @@ -13,37 +13,18 @@ fn every_case_cleans_the_same_as_python() { for case in cases { let name = parity::case_name(&case); - if parity::DIVERGENT_MDSCRUB.contains(&name.as_str()) { - continue; - } let ours = mdscrub::scrub(&case_text(&case)); let theirs = parity::read_golden_text(&format!("mdscrub/{name}.md")); assert_eq!(ours, theirs, "{name} differs from the python"); } } -#[test] -fn the_documented_divergences_are_exactly_what_was_argued_for() { - for name in parity::DIVERGENT_MDSCRUB { - let case = parity::dir() - .join("cases/mdscrub") - .join(format!("{name}.md")); - let ours = mdscrub::scrub(&case_text(&case)); - let theirs = parity::read_golden_text(&format!("mdscrub/{name}.md")); - assert_ne!(ours, theirs, "{name} no longer diverges — update KNOWN.md"); - assert_eq!( - ours, - parity::read_golden_text(&format!("mdscrub/{name}.rust.md")), - "{name} diverges differently than recorded" - ); - } -} - -/// The one thing the divergence exists to prevent. +/// The thing the break-tag rule exists to prevent. #[test] fn a_line_break_tag_never_welds_two_words_together() { let cleaned = mdscrub::scrub("the mill stood at the
northern end"); assert!(!cleaned.contains("thenorthern"), "{cleaned:?}"); + assert!(cleaned.contains("the northern"), "{cleaned:?}"); } /// Catches a golden file drifting away from a Python that has moved on. diff --git a/parity/tests/unescape.rs b/parity/tests/unescape.rs new file mode 100644 index 0000000..c203aa6 --- /dev/null +++ b/parity/tests/unescape.rs @@ -0,0 +1,57 @@ +//! Character references must decode exactly as Python decodes them. +//! +//! The table is two thousand entries of specification data and the rules +//! around it exist only because browsers had to accept what was already on +//! the web. Getting one of them wrong leaves markup in the text of a book, +//! which is how `<sup>107` reached thousands of passages before anyone +//! noticed. + +#[test] +fn every_reference_decodes_the_same_as_python() { + let cases = std::fs::read_to_string(parity::dir().join("cases/unescape/entities.txt")) + .expect("a readable case file"); + let cases: Vec<&str> = cases.split('\n').collect(); + let golden = parity::read_golden_text("unescape/entities.jsonl"); + let golden: Vec = golden + .lines() + .map(|line| serde_json::from_str(line).expect("the oracle writes JSON strings")) + .collect(); + + assert_eq!( + cases.len(), + golden.len(), + "{} cases against {} golden answers — regenerate", + cases.len(), + golden.len() + ); + + let mut wrong = Vec::new(); + for (case, expected) in cases.iter().zip(&golden) { + let got = mdscrub::unescape::unescape(case); + if &got != expected { + wrong.push(format!("{case:?}: python {expected:?}, rust {got:?}")); + } + } + assert!( + wrong.is_empty(), + "{} of {} references differ:\n{}", + wrong.len(), + cases.len(), + wrong + .iter() + .take(20) + .cloned() + .collect::>() + .join("\n") + ); +} + +/// Catches a golden file drifting away from a Python that has moved on. +#[test] +#[cfg(feature = "python")] +fn the_golden_file_still_matches_live_python() { + let cases = std::fs::read_to_string(parity::dir().join("cases/unescape/entities.txt")) + .expect("a readable case file"); + let live = parity::run_oracle("unescape.py", &cases).expect("the oracle runs"); + assert_eq!(live, parity::read_golden_text("unescape/entities.jsonl")); +}