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