instiki/lib/sanitize.rb
Jacques Distler 800880f382 Rough In New Sanitizer
Start work (which may not pan out) on a new sanitizer. Right now, it passes
all but 1 of the HTML5lib Sanitizer's unit tests. But it doesn't do much
of anything to ensure well-formedness. This is not an issue for Maruku-processed
content, but it is a concern for <nowiki> blocks.

(One solution would be to use the HTML5lib parser on <nowiki> blocks.)

In any case, this baby is 3 times as fast as the HTML5lib sanitizer.
2008-05-20 17:02:10 -05:00

2476 lines
66 KiB
Ruby

# == Introduction
#
# This module provides sanitization of XHTML+MathML+SVG
# and of inline style attributes. Its genesis is {described here}[http://golem.ph.utexas.edu/~distler/blog/archives/001181.html].
#
# Uses the {HTML5lib parser}[http://code.google.com/p/html5lib/], so that the parsing behaviour should
# resemble that of browsers.
#
# sanitize_xhtml() is a case-sensitive sanitizer, suitable for XHTML
# sanitize_html() is a case-insensitive sanitizer suitable for HTML
# sanitize_rexml() sanitizes a REXML tree, returning a string
#
# == Files
#
# {sanitize.rb}[http://golem.ph.utexas.edu/~distler/code/instiki/svn/lib/sanitize.rb],
# {HTML5lib}[http://golem.ph.utexas.edu/~distler/code/instiki/svn/vendor/plugins/HTML5lib/]
#
# == Author
#
# {Jacques Distler}[http://golem.ph.utexas.edu/~distler/]
#
# == License
#
# Ruby License
module Sanitize
require 'html5/html5parser'
require 'html5/liberalxmlparser'
require 'html5/treewalkers'
require 'html5/treebuilders'
require 'html5/serializer'
require 'html5/sanitizer'
include HTML5
# Sanitize a string, parsed using XHTML parsing rules.
#
# :call-seq:
# sanitize_xhtml(string) -> string
# sanitize_xhtml(string, {:encoding => 'iso-8859-1', :to_tree => true}) -> REXML::Document
#
# Unless otherwise specified, the string is assumed to be utf-8 encoded.
# By default, the output is a string. But, optionally, you can return a REXML tree.
#
# The string returned is utf-8 encoded. If you want, you can use iconv to convert it to some other encoding.
# (REXML trees are always utf-8 encoded.)
def sanitize_xhtml(html, options = {})
@encoding = 'utf-8'
@treebuilder = TreeBuilders::REXML::TreeBuilder
@to_tree = false
options.each do |name, value|
next unless %w(encoding treebuilder to_tree).include? name.to_s
if name.to_s == 'treebuilder'
@treebuilder = HTML5lib::TreeBuilders.get_tree_builder(value)
else
instance_variable_set("@#{name}", value)
end
end
if @encoding == 'utf-8'
parsed = XHTMLParser.parse_fragment(html.to_utf8, {:tokenizer => HTMLSanitizer,
:lowercase_element_name => false, :lowercase_attr_name => false,
:encoding => @encoding, :tree => @treebuilder })
else
parsed = XHTMLParser.parse_fragment(html.to_ncr, {:tokenizer => HTMLSanitizer,
:lowercase_element_name => false, :lowercase_attr_name => false,
:encoding => @encoding, :tree => @treebuilder })
end
return parsed if @to_tree
return parsed.to_s
end
# Sanitize a string, parsed using HTML parsing rules.
#
# :call-seq:
# sanitize_html( string ) -> string
# sanitize_html( string, {:encoding => 'iso-8859-1', :to_tree => true} ) -> REXML::Document
#
# Unless otherwise specified, the string is assumed to be utf-8 encoded.
# By default, the output is a string. But, optionally, you can return a REXML tree.
#
# The string returned is utf-8 encoded. If you want, you can use iconv to convert it to some other encoding.
# (REXML trees are always utf-8 encoded.)
def sanitize_html(html, options = {})
@encoding = 'utf-8'
@treebuilder = TreeBuilders::REXML::TreeBuilder
@to_tree = false
options.each do |name, value|
next unless %w(encoding treebuilder to_tree).include? name.to_s
if name.to_s == 'treebuilder'
@treebuilder = HTML5lib::TreeBuilders.get_tree_builder(value)
else
instance_variable_set("@#{name}", value)
end
end
if @encoding == 'utf-8'
parsed = HTMLParser.parse_fragment(html.to_utf8, {:tokenizer => HTMLSanitizer,
:encoding => @encoding, :tree => @treebuilder })
else
parsed = HTMLParser.parse_fragment(html.to_ncr, {:tokenizer => HTMLSanitizer,
:encoding => @encoding, :tree => @treebuilder })
end
return parsed if @to_tree
return parsed.to_s
end
# Sanitize a REXML tree. The output is a string.
#
# :call-seq:
# sanitize_rexml(tree) -> string
#
def sanitize_rexml(tree)
tokens = TreeWalkers.get_tree_walker('rexml2').new(tree)
XHTMLSerializer.serialize(tokens, {:encoding=>'utf-8',
:space_before_trailing_solidus => true,
:inject_meta_charset => false,
:sanitize => true})
end
end
# Some useful additions to the String class
class String
# Check whether a string is valid utf-8
#
# :call-seq:
# string.is_utf8? -> boolean
#
# returns true if the sequence of bytes in string is valid utf-8
#--
def is_utf8?
#expand NCRs to utf-8
text = self.gsub(/&#[xX]([a-fA-F0-9]+);/) { |m| [$1.hex].pack('U*') }
text.gsub!(/&#(\d+);/) { |m| [$1.to_i].pack('U*') }
# You might think this is faster, but it isn't
#pieces = self.split(/&#[xX]([a-fA-F0-9]+);/)
#1.step(pieces.length-1, 2) {|i| pieces[i] = [pieces[i].hex].pack('U*')}
#pieces = pieces.join.split(/&#(\d+);/)
#1.step(pieces.length-1, 2) {|i| pieces[i] = [pieces[i].to_i].pack('U*')}
#text = pieces.join
#ensure the resulting string of bytes is valid utf-8
text =~ /\A(
[\x09\x0A\x0D\x20-\x7E] # ASCII
| [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
| \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
| [\xE1-\xEC\xEE][\x80-\xBF]{2} # straight 3-byte
| \xEF[\x80-\xBE]{2} #
| \xEF\xBF[\x80-\xBD] # excluding U+fffe and U+ffff
| \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
| \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
| [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
)*\Z/x;
end
#++
#:stopdoc:
MATHML_ENTITIES = {
'Alpha' => '&#x0391;',
'Beta' => '&#x0392;',
'Epsilon' => '&#x0395;',
'Zeta' => '&#x0396;',
'Eta' => '&#x0397;',
'Iota' => '&#x0399;',
'Kappa' => '&#x039A;',
'Mu' => '&#x039C;',
'Nu' => '&#x039D;',
'Omicron' => '&#x039F;',
'Rho' => '&#x03A1;',
'Tau' => '&#x03A4;',
'Chi' => '&#x03A7;',
'epsilon' => '&#x03B5;',
'zeta' => '&#x03B6;',
'omicron' => '&#x03BF;',
'sigmaf' => '&#x03C2;',
'thetasym' => '&#x03D1;',
'upsih' => '&#x03D2;',
'oline' => '&#x203E;',
'frasl' => '&#x2044;',
'alefsym' => '&#x2135;',
'crarr' => '&#x21B5;',
'empty' => '&#x2205;',
'amp' => '&#x0026;',
'lt' => '&#x003C;',
'zwnj' => '&#x200C;',
'zwj' => '&#x200D;',
'lrm' => '&#x200E;',
'rlm' => '&#x200F;',
'sbquo' => '&#x201A;',
'bdquo' => '&#x201E;',
'lsaquo' => '&#x2039;',
'rsaquo' => '&#x203A;',
'euro' => '&#x20AC;',
'angzarr' => '&#x0237C;',
'cirmid' => '&#x02AEF;',
'cudarrl' => '&#x02938;',
'cudarrr' => '&#x02935;',
'cularr' => '&#x021B6;',
'cularrp' => '&#x0293D;',
'curarr' => '&#x021B7;',
'curarrm' => '&#x0293C;',
'Darr' => '&#x021A1;',
'dArr' => '&#x021D3;',
'ddarr' => '&#x021CA;',
'DDotrahd' => '&#x02911;',
'dfisht' => '&#x0297F;',
'dHar' => '&#x02965;',
'dharl' => '&#x021C3;',
'dharr' => '&#x021C2;',
'duarr' => '&#x021F5;',
'duhar' => '&#x0296F;',
'dzigrarr' => '&#x027FF;',
'erarr' => '&#x02971;',
'hArr' => '&#x021D4;',
'harr' => '&#x02194;',
'harrcir' => '&#x02948;',
'harrw' => '&#x021AD;',
'hoarr' => '&#x021FF;',
'imof' => '&#x022B7;',
'lAarr' => '&#x021DA;',
'Larr' => '&#x0219E;',
'larrbfs' => '&#x0291F;',
'larrfs' => '&#x0291D;',
'larrhk' => '&#x021A9;',
'larrlp' => '&#x021AB;',
'larrpl' => '&#x02939;',
'larrsim' => '&#x02973;',
'larrtl' => '&#x021A2;',
'lAtail' => '&#x0291B;',
'latail' => '&#x02919;',
'lBarr' => '&#x0290E;',
'lbarr' => '&#x0290C;',
'ldca' => '&#x02936;',
'ldrdhar' => '&#x02967;',
'ldrushar' => '&#x0294B;',
'ldsh' => '&#x021B2;',
'lfisht' => '&#x0297C;',
'lHar' => '&#x02962;',
'lhard' => '&#x021BD;',
'lharu' => '&#x021BC;',
'lharul' => '&#x0296A;',
'llarr' => '&#x021C7;',
'llhard' => '&#x0296B;',
'loarr' => '&#x021FD;',
'lrarr' => '&#x021C6;',
'lrhar' => '&#x021CB;',
'lrhard' => '&#x0296D;',
'lsh' => '&#x021B0;',
'lurdshar' => '&#x0294A;',
'luruhar' => '&#x02966;',
'Map' => '&#x02905;',
'map' => '&#x021A6;',
'midcir' => '&#x02AF0;',
'mumap' => '&#x022B8;',
'nearhk' => '&#x02924;',
'neArr' => '&#x021D7;',
'nearr' => '&#x02197;',
'nesear' => '&#x02928;',
'nhArr' => '&#x021CE;',
'nharr' => '&#x021AE;',
'nlArr' => '&#x021CD;',
'nlarr' => '&#x0219A;',
'nrArr' => '&#x021CF;',
'nrarr' => '&#x0219B;',
'nrarrc' => '&#x02933;&#x00338;',
'nrarrw' => '&#x0219D;&#x00338;',
'nvHarr' => '&#x02904;',
'nvlArr' => '&#x02902;',
'nvrArr' => '&#x02903;',
'nwarhk' => '&#x02923;',
'nwArr' => '&#x021D6;',
'nwarr' => '&#x02196;',
'nwnear' => '&#x02927;',
'olarr' => '&#x021BA;',
'orarr' => '&#x021BB;',
'origof' => '&#x022B6;',
'rAarr' => '&#x021DB;',
'Rarr' => '&#x021A0;',
'rarrap' => '&#x02975;',
'rarrbfs' => '&#x02920;',
'rarrc' => '&#x02933;',
'rarrfs' => '&#x0291E;',
'rarrhk' => '&#x021AA;',
'rarrlp' => '&#x021AC;',
'rarrpl' => '&#x02945;',
'rarrsim' => '&#x02974;',
'Rarrtl' => '&#x02916;',
'rarrtl' => '&#x021A3;',
'rarrw' => '&#x0219D;',
'rAtail' => '&#x0291C;',
'ratail' => '&#x0291A;',
'RBarr' => '&#x02910;',
'rBarr' => '&#x0290F;',
'rbarr' => '&#x0290D;',
'rdca' => '&#x02937;',
'rdldhar' => '&#x02969;',
'rdsh' => '&#x021B3;',
'rfisht' => '&#x0297D;',
'rHar' => '&#x02964;',
'rhard' => '&#x021C1;',
'rharu' => '&#x021C0;',
'rharul' => '&#x0296C;',
'rlarr' => '&#x021C4;',
'rlhar' => '&#x021CC;',
'roarr' => '&#x021FE;',
'rrarr' => '&#x021C9;',
'rsh' => '&#x021B1;',
'ruluhar' => '&#x02968;',
'searhk' => '&#x02925;',
'seArr' => '&#x021D8;',
'searr' => '&#x02198;',
'seswar' => '&#x02929;',
'simrarr' => '&#x02972;',
'slarr' => '&#x02190;',
'srarr' => '&#x02192;',
'swarhk' => '&#x02926;',
'swArr' => '&#x021D9;',
'swarr' => '&#x02199;',
'swnwar' => '&#x0292A;',
'Uarr' => '&#x0219F;',
'uArr' => '&#x021D1;',
'Uarrocir' => '&#x02949;',
'udarr' => '&#x021C5;',
'udhar' => '&#x0296E;',
'ufisht' => '&#x0297E;',
'uHar' => '&#x02963;',
'uharl' => '&#x021BF;',
'uharr' => '&#x021BE;',
'uuarr' => '&#x021C8;',
'vArr' => '&#x021D5;',
'varr' => '&#x02195;',
'xhArr' => '&#x027FA;',
'xharr' => '&#x027F7;',
'xlArr' => '&#x027F8;',
'xlarr' => '&#x027F5;',
'xmap' => '&#x027FC;',
'xrArr' => '&#x027F9;',
'xrarr' => '&#x027F6;',
'zigrarr' => '&#x021DD;',
'ac' => '&#x0223E;',
'acE' => '&#x0223E;&#x00333;',
'amalg' => '&#x02A3F;',
'barvee' => '&#x022BD;',
'Barwed' => '&#x02306;',
'barwed' => '&#x02305;',
'bsolb' => '&#x029C5;',
'Cap' => '&#x022D2;',
'capand' => '&#x02A44;',
'capbrcup' => '&#x02A49;',
'capcap' => '&#x02A4B;',
'capcup' => '&#x02A47;',
'capdot' => '&#x02A40;',
'caps' => '&#x02229;&#x0FE00;',
'ccaps' => '&#x02A4D;',
'ccups' => '&#x02A4C;',
'ccupssm' => '&#x02A50;',
'coprod' => '&#x02210;',
'Cup' => '&#x022D3;',
'cupbrcap' => '&#x02A48;',
'cupcap' => '&#x02A46;',
'cupcup' => '&#x02A4A;',
'cupdot' => '&#x0228D;',
'cupor' => '&#x02A45;',
'cups' => '&#x0222A;&#x0FE00;',
'cuvee' => '&#x022CE;',
'cuwed' => '&#x022CF;',
'Dagger' => '&#x02021;',
'dagger' => '&#x02020;',
'diam' => '&#x022C4;',
'divonx' => '&#x022C7;',
'eplus' => '&#x02A71;',
'hercon' => '&#x022B9;',
'intcal' => '&#x022BA;',
'iprod' => '&#x02A3C;',
'loplus' => '&#x02A2D;',
'lotimes' => '&#x02A34;',
'lthree' => '&#x022CB;',
'ltimes' => '&#x022C9;',
'midast' => '&#x0002A;',
'minusb' => '&#x0229F;',
'minusd' => '&#x02238;',
'minusdu' => '&#x02A2A;',
'ncap' => '&#x02A43;',
'ncup' => '&#x02A42;',
'oast' => '&#x0229B;',
'ocir' => '&#x0229A;',
'odash' => '&#x0229D;',
'odiv' => '&#x02A38;',
'odot' => '&#x02299;',
'odsold' => '&#x029BC;',
'ofcir' => '&#x029BF;',
'ogt' => '&#x029C1;',
'ohbar' => '&#x029B5;',
'olcir' => '&#x029BE;',
'olt' => '&#x029C0;',
'omid' => '&#x029B6;',
'ominus' => '&#x02296;',
'opar' => '&#x029B7;',
'operp' => '&#x029B9;',
'oplus' => '&#x02295;',
'osol' => '&#x02298;',
'Otimes' => '&#x02A37;',
'otimes' => '&#x02297;',
'otimesas' => '&#x02A36;',
'ovbar' => '&#x0233D;',
'plusacir' => '&#x02A23;',
'plusb' => '&#x0229E;',
'pluscir' => '&#x02A22;',
'plusdo' => '&#x02214;',
'plusdu' => '&#x02A25;',
'pluse' => '&#x02A72;',
'plussim' => '&#x02A26;',
'plustwo' => '&#x02A27;',
'prod' => '&#x0220F;',
'race' => '&#x029DA;',
'roplus' => '&#x02A2E;',
'rotimes' => '&#x02A35;',
'rthree' => '&#x022CC;',
'rtimes' => '&#x022CA;',
'sdot' => '&#x022C5;',
'sdotb' => '&#x022A1;',
'setmn' => '&#x02216;',
'simplus' => '&#x02A24;',
'smashp' => '&#x02A33;',
'solb' => '&#x029C4;',
'sqcap' => '&#x02293;',
'sqcaps' => '&#x02293;&#x0FE00;',
'sqcup' => '&#x02294;',
'sqcups' => '&#x02294;&#x0FE00;',
'ssetmn' => '&#x02216;',
'sstarf' => '&#x022C6;',
'subdot' => '&#x02ABD;',
'sum' => '&#x02211;',
'supdot' => '&#x02ABE;',
'timesb' => '&#x022A0;',
'timesbar' => '&#x02A31;',
'timesd' => '&#x02A30;',
'tridot' => '&#x025EC;',
'triminus' => '&#x02A3A;',
'triplus' => '&#x02A39;',
'trisb' => '&#x029CD;',
'tritime' => '&#x02A3B;',
'uplus' => '&#x0228E;',
'veebar' => '&#x022BB;',
'wedbar' => '&#x02A5F;',
'wreath' => '&#x02240;',
'xcap' => '&#x022C2;',
'xcirc' => '&#x025EF;',
'xcup' => '&#x022C3;',
'xdtri' => '&#x025BD;',
'xodot' => '&#x02A00;',
'xoplus' => '&#x02A01;',
'xotime' => '&#x02A02;',
'xsqcup' => '&#x02A06;',
'xuplus' => '&#x02A04;',
'xutri' => '&#x025B3;',
'xvee' => '&#x022C1;',
'xwedge' => '&#x022C0;',
'dlcorn' => '&#x0231E;',
'drcorn' => '&#x0231F;',
'gtlPar' => '&#x02995;',
'langd' => '&#x02991;',
'lbrke' => '&#x0298B;',
'lbrksld' => '&#x0298F;',
'lbrkslu' => '&#x0298D;',
'lceil' => '&#x02308;',
'lfloor' => '&#x0230A;',
'lmoust' => '&#x023B0;',
'lparlt' => '&#x02993;',
'ltrPar' => '&#x02996;',
'rangd' => '&#x02992;',
'rbrke' => '&#x0298C;',
'rbrksld' => '&#x0298E;',
'rbrkslu' => '&#x02990;',
'rceil' => '&#x02309;',
'rfloor' => '&#x0230B;',
'rmoust' => '&#x023B1;',
'rpargt' => '&#x02994;',
'ulcorn' => '&#x0231C;',
'urcorn' => '&#x0231D;',
'gnap' => '&#x02A8A;',
'gnE' => '&#x02269;',
'gne' => '&#x02A88;',
'gnsim' => '&#x022E7;',
'gvnE' => '&#x02269;&#x0FE00;',
'lnap' => '&#x02A89;',
'lnE' => '&#x02268;',
'lne' => '&#x02A87;',
'lnsim' => '&#x022E6;',
'lvnE' => '&#x02268;&#x0FE00;',
'nap' => '&#x02249;',
'napE' => '&#x02A70;&#x00338;',
'napid' => '&#x0224B;&#x00338;',
'ncong' => '&#x02247;',
'ncongdot' => '&#x02A6D;&#x00338;',
'nequiv' => '&#x02262;',
'ngE' => '&#x02267;&#x00338;',
'nge' => '&#x02271;',
'nges' => '&#x02A7E;&#x00338;',
'nGg' => '&#x022D9;&#x00338;',
'ngsim' => '&#x02275;',
'nGt' => '&#x0226B;&#x020D2;',
'ngt' => '&#x0226F;',
'nGtv' => '&#x0226B;&#x00338;',
'nlE' => '&#x02266;&#x00338;',
'nle' => '&#x02270;',
'nles' => '&#x02A7D;&#x00338;',
'nLl' => '&#x022D8;&#x00338;',
'nlsim' => '&#x02274;',
'nLt' => '&#x0226A;&#x020D2;',
'nlt' => '&#x0226E;',
'nltri' => '&#x022EA;',
'nltrie' => '&#x022EC;',
'nLtv' => '&#x0226A;&#x00338;',
'nmid' => '&#x02224;',
'npar' => '&#x02226;',
'npr' => '&#x02280;',
'nprcue' => '&#x022E0;',
'npre' => '&#x02AAF;&#x00338;',
'nrtri' => '&#x022EB;',
'nrtrie' => '&#x022ED;',
'nsc' => '&#x02281;',
'nsccue' => '&#x022E1;',
'nsce' => '&#x02AB0;&#x00338;',
'nsim' => '&#x02241;',
'nsime' => '&#x02244;',
'nsmid' => '&#x02224;',
'nspar' => '&#x02226;',
'nsqsube' => '&#x022E2;',
'nsqsupe' => '&#x022E3;',
'nsub' => '&#x02284;',
'nsubE' => '&#x02AC5;&#x00338;',
'nsube' => '&#x02288;',
'nsup' => '&#x02285;',
'nsupE' => '&#x02AC6;&#x00338;',
'nsupe' => '&#x02289;',
'ntgl' => '&#x02279;',
'ntlg' => '&#x02278;',
'nvap' => '&#x0224D;&#x020D2;',
'nVDash' => '&#x022AF;',
'nVdash' => '&#x022AE;',
'nvDash' => '&#x022AD;',
'nvdash' => '&#x022AC;',
'nvge' => '&#x02265;&#x020D2;',
'nvgt' => '&#x0003E;&#x020D2;',
'nvle' => '&#x02264;&#x020D2;',
'nvltrie' => '&#x022B4;&#x020D2;',
'nvrtrie' => '&#x022B5;&#x020D2;',
'nvsim' => '&#x0223C;&#x020D2;',
'parsim' => '&#x02AF3;',
'prnap' => '&#x02AB9;',
'prnE' => '&#x02AB5;',
'prnsim' => '&#x022E8;',
'rnmid' => '&#x02AEE;',
'scnap' => '&#x02ABA;',
'scnE' => '&#x02AB6;',
'scnsim' => '&#x022E9;',
'simne' => '&#x02246;',
'solbar' => '&#x0233F;',
'subnE' => '&#x02ACB;',
'subne' => '&#x0228A;',
'supnE' => '&#x02ACC;',
'supne' => '&#x0228B;',
'vnsub' => '&#x02282;&#x020D2;',
'vnsup' => '&#x02283;&#x020D2;',
'vsubnE' => '&#x02ACB;&#x0FE00;',
'vsubne' => '&#x0228A;&#x0FE00;',
'vsupnE' => '&#x02ACC;&#x0FE00;',
'vsupne' => '&#x0228B;&#x0FE00;',
'ang' => '&#x02220;',
'ange' => '&#x029A4;',
'angmsd' => '&#x02221;',
'angmsdaa' => '&#x029A8;',
'angmsdab' => '&#x029A9;',
'angmsdac' => '&#x029AA;',
'angmsdad' => '&#x029AB;',
'angmsdae' => '&#x029AC;',
'angmsdaf' => '&#x029AD;',
'angmsdag' => '&#x029AE;',
'angmsdah' => '&#x029AF;',
'angrtvb' => '&#x022BE;',
'angrtvbd' => '&#x0299D;',
'bbrk' => '&#x023B5;',
'bbrktbrk' => '&#x023B6;',
'bemptyv' => '&#x029B0;',
'beth' => '&#x02136;',
'boxbox' => '&#x029C9;',
'bprime' => '&#x02035;',
'bsemi' => '&#x0204F;',
'cemptyv' => '&#x029B2;',
'cirE' => '&#x029C3;',
'cirscir' => '&#x029C2;',
'comp' => '&#x02201;',
'daleth' => '&#x02138;',
'demptyv' => '&#x029B1;',
'ell' => '&#x02113;',
'empty' => '&#x02205;',
'emptyv' => '&#x02205;',
'gimel' => '&#x02137;',
'iiota' => '&#x02129;',
'image' => '&#x02111;',
'imath' => '&#x00131;',
'jmath' => '&#x0006A;',
'laemptyv' => '&#x029B4;',
'lltri' => '&#x025FA;',
'lrtri' => '&#x022BF;',
'mho' => '&#x02127;',
'nang' => '&#x02220;&#x020D2;',
'nexist' => '&#x02204;',
'oS' => '&#x024C8;',
'planck' => '&#x0210F;',
'plankv' => '&#x0210F;',
'raemptyv' => '&#x029B3;',
'range' => '&#x029A5;',
'real' => '&#x0211C;',
'tbrk' => '&#x023B4;',
'trpezium' => '&#x0FFFD;',
'ultri' => '&#x025F8;',
'urtri' => '&#x025F9;',
'vzigzag' => '&#x0299A;',
'weierp' => '&#x02118;',
'apE' => '&#x02A70;',
'ape' => '&#x0224A;',
'apid' => '&#x0224B;',
'asymp' => '&#x02248;',
'Barv' => '&#x02AE7;',
'bcong' => '&#x0224C;',
'bepsi' => '&#x003F6;',
'bowtie' => '&#x022C8;',
'bsim' => '&#x0223D;',
'bsime' => '&#x022CD;',
'bsolhsub' => '&#x0005C;&#x02282;',
'bump' => '&#x0224E;',
'bumpE' => '&#x02AAE;',
'bumpe' => '&#x0224F;',
'cire' => '&#x02257;',
'Colon' => '&#x02237;',
'Colone' => '&#x02A74;',
'colone' => '&#x02254;',
'congdot' => '&#x02A6D;',
'csub' => '&#x02ACF;',
'csube' => '&#x02AD1;',
'csup' => '&#x02AD0;',
'csupe' => '&#x02AD2;',
'cuepr' => '&#x022DE;',
'cuesc' => '&#x022DF;',
'Dashv' => '&#x02AE4;',
'dashv' => '&#x022A3;',
'easter' => '&#x02A6E;',
'ecir' => '&#x02256;',
'ecolon' => '&#x02255;',
'eDDot' => '&#x02A77;',
'eDot' => '&#x02251;',
'efDot' => '&#x02252;',
'eg' => '&#x02A9A;',
'egs' => '&#x02A96;',
'egsdot' => '&#x02A98;',
'el' => '&#x02A99;',
'els' => '&#x02A95;',
'elsdot' => '&#x02A97;',
'equest' => '&#x0225F;',
'equivDD' => '&#x02A78;',
'erDot' => '&#x02253;',
'esdot' => '&#x02250;',
'Esim' => '&#x02A73;',
'esim' => '&#x02242;',
'fork' => '&#x022D4;',
'forkv' => '&#x02AD9;',
'frown' => '&#x02322;',
'gap' => '&#x02A86;',
'gE' => '&#x02267;',
'gEl' => '&#x02A8C;',
'gel' => '&#x022DB;',
'ges' => '&#x02A7E;',
'gescc' => '&#x02AA9;',
'gesdot' => '&#x02A80;',
'gesdoto' => '&#x02A82;',
'gesdotol' => '&#x02A84;',
'gesl' => '&#x022DB;&#x0FE00;',
'gesles' => '&#x02A94;',
'Gg' => '&#x022D9;',
'gl' => '&#x02277;',
'gla' => '&#x02AA5;',
'glE' => '&#x02A92;',
'glj' => '&#x02AA4;',
'gsim' => '&#x02273;',
'gsime' => '&#x02A8E;',
'gsiml' => '&#x02A90;',
'Gt' => '&#x0226B;',
'gtcc' => '&#x02AA7;',
'gtcir' => '&#x02A7A;',
'gtdot' => '&#x022D7;',
'gtquest' => '&#x02A7C;',
'gtrarr' => '&#x02978;',
'homtht' => '&#x0223B;',
'lap' => '&#x02A85;',
'lat' => '&#x02AAB;',
'late' => '&#x02AAD;',
'lates' => '&#x02AAD;&#x0FE00;',
'lE' => '&#x02266;',
'lEg' => '&#x02A8B;',
'leg' => '&#x022DA;',
'les' => '&#x02A7D;',
'lescc' => '&#x02AA8;',
'lesdot' => '&#x02A7F;',
'lesdoto' => '&#x02A81;',
'lesdotor' => '&#x02A83;',
'lesg' => '&#x022DA;&#x0FE00;',
'lesges' => '&#x02A93;',
'lg' => '&#x02276;',
'lgE' => '&#x02A91;',
'Ll' => '&#x022D8;',
'lsim' => '&#x02272;',
'lsime' => '&#x02A8D;',
'lsimg' => '&#x02A8F;',
'Lt' => '&#x0226A;',
'ltcc' => '&#x02AA6;',
'ltcir' => '&#x02A79;',
'ltdot' => '&#x022D6;',
'ltlarr' => '&#x02976;',
'ltquest' => '&#x02A7B;',
'ltrie' => '&#x022B4;',
'mcomma' => '&#x02A29;',
'mDDot' => '&#x0223A;',
'mid' => '&#x02223;',
'mlcp' => '&#x02ADB;',
'models' => '&#x022A7;',
'mstpos' => '&#x0223E;',
'Pr' => '&#x02ABB;',
'pr' => '&#x0227A;',
'prap' => '&#x02AB7;',
'prcue' => '&#x0227C;',
'prE' => '&#x02AB3;',
'pre' => '&#x02AAF;',
'prsim' => '&#x0227E;',
'prurel' => '&#x022B0;',
'ratio' => '&#x02236;',
'rtrie' => '&#x022B5;',
'rtriltri' => '&#x029CE;',
'Sc' => '&#x02ABC;',
'sc' => '&#x0227B;',
'scap' => '&#x02AB8;',
'sccue' => '&#x0227D;',
'scE' => '&#x02AB4;',
'sce' => '&#x02AB0;',
'scsim' => '&#x0227F;',
'sdote' => '&#x02A66;',
'sfrown' => '&#x02322;',
'simg' => '&#x02A9E;',
'simgE' => '&#x02AA0;',
'siml' => '&#x02A9D;',
'simlE' => '&#x02A9F;',
'smid' => '&#x02223;',
'smile' => '&#x02323;',
'smt' => '&#x02AAA;',
'smte' => '&#x02AAC;',
'smtes' => '&#x02AAC;&#x0FE00;',
'spar' => '&#x02225;',
'sqsub' => '&#x0228F;',
'sqsube' => '&#x02291;',
'sqsup' => '&#x02290;',
'sqsupe' => '&#x02292;',
'ssmile' => '&#x02323;',
'Sub' => '&#x022D0;',
'subE' => '&#x02AC5;',
'subedot' => '&#x02AC3;',
'submult' => '&#x02AC1;',
'subplus' => '&#x02ABF;',
'subrarr' => '&#x02979;',
'subsim' => '&#x02AC7;',
'subsub' => '&#x02AD5;',
'subsup' => '&#x02AD3;',
'Sup' => '&#x022D1;',
'supdsub' => '&#x02AD8;',
'supE' => '&#x02AC6;',
'supedot' => '&#x02AC4;',
'suphsol' => '&#x02283;&#x0002F;',
'suphsub' => '&#x02AD7;',
'suplarr' => '&#x0297B;',
'supmult' => '&#x02AC2;',
'supplus' => '&#x02AC0;',
'supsim' => '&#x02AC8;',
'supsub' => '&#x02AD4;',
'supsup' => '&#x02AD6;',
'thkap' => '&#x02248;',
'thksim' => '&#x0223C;',
'topfork' => '&#x02ADA;',
'trie' => '&#x0225C;',
'twixt' => '&#x0226C;',
'Vbar' => '&#x02AEB;',
'vBar' => '&#x02AE8;',
'vBarv' => '&#x02AE9;',
'VDash' => '&#x022AB;',
'Vdash' => '&#x022A9;',
'vDash' => '&#x022A8;',
'vdash' => '&#x022A2;',
'Vdashl' => '&#x02AE6;',
'vltri' => '&#x022B2;',
'vprop' => '&#x0221D;',
'vrtri' => '&#x022B3;',
'Vvdash' => '&#x022AA;',
'alpha' => '&#x003B1;',
'beta' => '&#x003B2;',
'chi' => '&#x003C7;',
'Delta' => '&#x00394;',
'delta' => '&#x003B4;',
'epsi' => '&#x003F5;',
'epsiv' => '&#x003B5;',
'eta' => '&#x003B7;',
'Gamma' => '&#x00393;',
'gamma' => '&#x003B3;',
'Gammad' => '&#x003DC;',
'gammad' => '&#x003DD;',
'iota' => '&#x003B9;',
'kappa' => '&#x003BA;',
'kappav' => '&#x003F0;',
'Lambda' => '&#x0039B;',
'lambda' => '&#x003BB;',
'mu' => '&#x003BC;',
'nu' => '&#x003BD;',
'Omega' => '&#x003A9;',
'omega' => '&#x003C9;',
'Phi' => '&#x003A6;',
'phi' => '&#x003D5;',
'phiv' => '&#x003C6;',
'Pi' => '&#x003A0;',
'pi' => '&#x003C0;',
'piv' => '&#x003D6;',
'Psi' => '&#x003A8;',
'psi' => '&#x003C8;',
'rho' => '&#x003C1;',
'rhov' => '&#x003F1;',
'Sigma' => '&#x003A3;',
'sigma' => '&#x003C3;',
'sigmav' => '&#x003C2;',
'tau' => '&#x003C4;',
'Theta' => '&#x00398;',
'theta' => '&#x003B8;',
'thetav' => '&#x003D1;',
'Upsi' => '&#x003D2;',
'upsi' => '&#x003C5;',
'Xi' => '&#x0039E;',
'xi' => '&#x003BE;',
'zeta' => '&#x003B6;',
'Afr' => '&#x1D504;',
'afr' => '&#x1D51E;',
'Bfr' => '&#x1D505;',
'bfr' => '&#x1D51F;',
'Cfr' => '&#x0212D;',
'cfr' => '&#x1D520;',
'Dfr' => '&#x1D507;',
'dfr' => '&#x1D521;',
'Efr' => '&#x1D508;',
'efr' => '&#x1D522;',
'Ffr' => '&#x1D509;',
'ffr' => '&#x1D523;',
'Gfr' => '&#x1D50A;',
'gfr' => '&#x1D524;',
'Hfr' => '&#x0210C;',
'hfr' => '&#x1D525;',
'Ifr' => '&#x02111;',
'ifr' => '&#x1D526;',
'Jfr' => '&#x1D50D;',
'jfr' => '&#x1D527;',
'Kfr' => '&#x1D50E;',
'kfr' => '&#x1D528;',
'Lfr' => '&#x1D50F;',
'lfr' => '&#x1D529;',
'Mfr' => '&#x1D510;',
'mfr' => '&#x1D52A;',
'Nfr' => '&#x1D511;',
'nfr' => '&#x1D52B;',
'Ofr' => '&#x1D512;',
'ofr' => '&#x1D52C;',
'Pfr' => '&#x1D513;',
'pfr' => '&#x1D52D;',
'Qfr' => '&#x1D514;',
'qfr' => '&#x1D52E;',
'Rfr' => '&#x0211C;',
'rfr' => '&#x1D52F;',
'Sfr' => '&#x1D516;',
'sfr' => '&#x1D530;',
'Tfr' => '&#x1D517;',
'tfr' => '&#x1D531;',
'Ufr' => '&#x1D518;',
'ufr' => '&#x1D532;',
'Vfr' => '&#x1D519;',
'vfr' => '&#x1D533;',
'Wfr' => '&#x1D51A;',
'wfr' => '&#x1D534;',
'Xfr' => '&#x1D51B;',
'xfr' => '&#x1D535;',
'Yfr' => '&#x1D51C;',
'yfr' => '&#x1D536;',
'Zfr' => '&#x02128;',
'zfr' => '&#x1D537;',
'Aopf' => '&#x1D538;',
'Bopf' => '&#x1D539;',
'Copf' => '&#x02102;',
'Dopf' => '&#x1D53B;',
'Eopf' => '&#x1D53C;',
'Fopf' => '&#x1D53D;',
'Gopf' => '&#x1D53E;',
'Hopf' => '&#x0210D;',
'Iopf' => '&#x1D540;',
'Jopf' => '&#x1D541;',
'Kopf' => '&#x1D542;',
'Lopf' => '&#x1D543;',
'Mopf' => '&#x1D544;',
'Nopf' => '&#x02115;',
'Oopf' => '&#x1D546;',
'Popf' => '&#x02119;',
'Qopf' => '&#x0211A;',
'Ropf' => '&#x0211D;',
'Sopf' => '&#x1D54A;',
'Topf' => '&#x1D54B;',
'Uopf' => '&#x1D54C;',
'Vopf' => '&#x1D54D;',
'Wopf' => '&#x1D54E;',
'Xopf' => '&#x1D54F;',
'Yopf' => '&#x1D550;',
'Zopf' => '&#x02124;',
'Ascr' => '&#x1D49C;',
'ascr' => '&#x1D4B6;',
'Bscr' => '&#x0212C;',
'bscr' => '&#x1D4B7;',
'Cscr' => '&#x1D49E;',
'cscr' => '&#x1D4B8;',
'Dscr' => '&#x1D49F;',
'dscr' => '&#x1D4B9;',
'Escr' => '&#x02130;',
'escr' => '&#x0212F;',
'Fscr' => '&#x02131;',
'fscr' => '&#x1D4BB;',
'Gscr' => '&#x1D4A2;',
'gscr' => '&#x0210A;',
'Hscr' => '&#x0210B;',
'hscr' => '&#x1D4BD;',
'Iscr' => '&#x02110;',
'iscr' => '&#x1D4BE;',
'Jscr' => '&#x1D4A5;',
'jscr' => '&#x1D4BF;',
'Kscr' => '&#x1D4A6;',
'kscr' => '&#x1D4C0;',
'Lscr' => '&#x02112;',
'lscr' => '&#x1D4C1;',
'Mscr' => '&#x02133;',
'mscr' => '&#x1D4C2;',
'Nscr' => '&#x1D4A9;',
'nscr' => '&#x1D4C3;',
'Oscr' => '&#x1D4AA;',
'oscr' => '&#x02134;',
'Pscr' => '&#x1D4AB;',
'pscr' => '&#x1D4C5;',
'Qscr' => '&#x1D4AC;',
'qscr' => '&#x1D4C6;',
'Rscr' => '&#x0211B;',
'rscr' => '&#x1D4C7;',
'Sscr' => '&#x1D4AE;',
'sscr' => '&#x1D4C8;',
'Tscr' => '&#x1D4AF;',
'tscr' => '&#x1D4C9;',
'Uscr' => '&#x1D4B0;',
'uscr' => '&#x1D4CA;',
'Vscr' => '&#x1D4B1;',
'vscr' => '&#x1D4CB;',
'Wscr' => '&#x1D4B2;',
'wscr' => '&#x1D4CC;',
'Xscr' => '&#x1D4B3;',
'xscr' => '&#x1D4CD;',
'Yscr' => '&#x1D4B4;',
'yscr' => '&#x1D4CE;',
'Zscr' => '&#x1D4B5;',
'zscr' => '&#x1D4CF;',
'acd' => '&#x0223F;',
'aleph' => '&#x02135;',
'And' => '&#x02A53;',
'and' => '&#x02227;',
'andand' => '&#x02A55;',
'andd' => '&#x02A5C;',
'andslope' => '&#x02A58;',
'andv' => '&#x02A5A;',
'angrt' => '&#x0221F;',
'angsph' => '&#x02222;',
'angst' => '&#x0212B;',
'ap' => '&#x02248;',
'apacir' => '&#x02A6F;',
'awconint' => '&#x02233;',
'awint' => '&#x02A11;',
'becaus' => '&#x02235;',
'bernou' => '&#x0212C;',
'bne' => '&#x0003D;&#x020E5;',
'bnequiv' => '&#x02261;&#x020E5;',
'bNot' => '&#x02AED;',
'bnot' => '&#x02310;',
'bottom' => '&#x022A5;',
'cap' => '&#x02229;',
'Cconint' => '&#x02230;',
'cirfnint' => '&#x02A10;',
'compfn' => '&#x02218;',
'cong' => '&#x02245;',
'Conint' => '&#x0222F;',
'conint' => '&#x0222E;',
'ctdot' => '&#x022EF;',
'cup' => '&#x0222A;',
'cwconint' => '&#x02232;',
'cwint' => '&#x02231;',
'cylcty' => '&#x0232D;',
'disin' => '&#x022F2;',
'Dot' => '&#x000A8;',
'DotDot' => '&#x020DC;',
'dsol' => '&#x029F6;',
'dtdot' => '&#x022F1;',
'dwangle' => '&#x029A6;',
'elinters' => '&#x0FFFD;',
'epar' => '&#x022D5;',
'eparsl' => '&#x029E3;',
'equiv' => '&#x02261;',
'eqvparsl' => '&#x029E5;',
'exist' => '&#x02203;',
'fltns' => '&#x025B1;',
'fnof' => '&#x00192;',
'forall' => '&#x02200;',
'fpartint' => '&#x02A0D;',
'ge' => '&#x02265;',
'hamilt' => '&#x0210B;',
'iff' => '&#x021D4;',
'iinfin' => '&#x029DC;',
'imped' => '&#x001B5;',
'infin' => '&#x0221E;',
'infintie' => '&#x029DD;',
'Int' => '&#x0222C;',
'int' => '&#x0222B;',
'intlarhk' => '&#x02A17;',
'isin' => '&#x02208;',
'isindot' => '&#x022F5;',
'isinE' => '&#x022F9;',
'isins' => '&#x022F4;',
'isinsv' => '&#x022F3;',
'isinv' => '&#x02208;',
'lagran' => '&#x02112;',
'Lang' => '&#x0300A;',
'lang' => '&#x02329;',
'lArr' => '&#x021D0;',
'lbbrk' => '&#x03014;',
'le' => '&#x02264;',
'loang' => '&#x03018;',
'lobrk' => '&#x0301A;',
'lopar' => '&#x02985;',
'lowast' => '&#x02217;',
'minus' => '&#x02212;',
'mnplus' => '&#x02213;',
'nabla' => '&#x02207;',
'ne' => '&#x02260;',
'nedot' => '&#x02250;&#x00338;',
'nhpar' => '&#x02AF2;',
'ni' => '&#x0220B;',
'nis' => '&#x022FC;',
'nisd' => '&#x022FA;',
'niv' => '&#x0220B;',
'Not' => '&#x02AEC;',
'notin' => '&#x02209;',
'notindot' => '&#x022F5;&#x00338;',
'notinE' => '&#x022F9;&#x00338;',
'notinva' => '&#x02209;',
'notinvb' => '&#x022F7;',
'notinvc' => '&#x022F6;',
'notni' => '&#x0220C;',
'notniva' => '&#x0220C;',
'notnivb' => '&#x022FE;',
'notnivc' => '&#x022FD;',
'nparsl' => '&#x02AFD;&#x020E5;',
'npart' => '&#x02202;&#x00338;',
'npolint' => '&#x02A14;',
'nvinfin' => '&#x029DE;',
'olcross' => '&#x029BB;',
'Or' => '&#x02A54;',
'or' => '&#x02228;',
'ord' => '&#x02A5D;',
'order' => '&#x02134;',
'oror' => '&#x02A56;',
'orslope' => '&#x02A57;',
'orv' => '&#x02A5B;',
'par' => '&#x02225;',
'parsl' => '&#x02AFD;',
'part' => '&#x02202;',
'permil' => '&#x02030;',
'perp' => '&#x022A5;',
'pertenk' => '&#x02031;',
'phmmat' => '&#x02133;',
'pointint' => '&#x02A15;',
'Prime' => '&#x02033;',
'prime' => '&#x02032;',
'profalar' => '&#x0232E;',
'profline' => '&#x02312;',
'profsurf' => '&#x02313;',
'prop' => '&#x0221D;',
'qint' => '&#x02A0C;',
'qprime' => '&#x02057;',
'quatint' => '&#x02A16;',
'radic' => '&#x0221A;',
'Rang' => '&#x0300B;',
'rang' => '&#x0232A;',
'rArr' => '&#x021D2;',
'rbbrk' => '&#x03015;',
'roang' => '&#x03019;',
'robrk' => '&#x0301B;',
'ropar' => '&#x02986;',
'rppolint' => '&#x02A12;',
'scpolint' => '&#x02A13;',
'sim' => '&#x0223C;',
'simdot' => '&#x02A6A;',
'sime' => '&#x02243;',
'smeparsl' => '&#x029E4;',
'square' => '&#x025A1;',
'squarf' => '&#x025AA;',
'strns' => '&#x000AF;',
'sub' => '&#x02282;',
'sube' => '&#x02286;',
'sup' => '&#x02283;',
'supe' => '&#x02287;',
'tdot' => '&#x020DB;',
'there4' => '&#x02234;',
'tint' => '&#x0222D;',
'top' => '&#x022A4;',
'topbot' => '&#x02336;',
'topcir' => '&#x02AF1;',
'tprime' => '&#x02034;',
'utdot' => '&#x022F0;',
'uwangle' => '&#x029A7;',
'vangrt' => '&#x0299C;',
'veeeq' => '&#x0225A;',
'Verbar' => '&#x02016;',
'wedgeq' => '&#x02259;',
'xnis' => '&#x022FB;',
'boxDL' => '&#x02557;',
'boxDl' => '&#x02556;',
'boxdL' => '&#x02555;',
'boxdl' => '&#x02510;',
'boxDR' => '&#x02554;',
'boxDr' => '&#x02553;',
'boxdR' => '&#x02552;',
'boxdr' => '&#x0250C;',
'boxH' => '&#x02550;',
'boxh' => '&#x02500;',
'boxHD' => '&#x02566;',
'boxHd' => '&#x02564;',
'boxhD' => '&#x02565;',
'boxhd' => '&#x0252C;',
'boxHU' => '&#x02569;',
'boxHu' => '&#x02567;',
'boxhU' => '&#x02568;',
'boxhu' => '&#x02534;',
'boxUL' => '&#x0255D;',
'boxUl' => '&#x0255C;',
'boxuL' => '&#x0255B;',
'boxul' => '&#x02518;',
'boxUR' => '&#x0255A;',
'boxUr' => '&#x02559;',
'boxuR' => '&#x02558;',
'boxur' => '&#x02514;',
'boxV' => '&#x02551;',
'boxv' => '&#x02502;',
'boxVH' => '&#x0256C;',
'boxVh' => '&#x0256B;',
'boxvH' => '&#x0256A;',
'boxvh' => '&#x0253C;',
'boxVL' => '&#x02563;',
'boxVl' => '&#x02562;',
'boxvL' => '&#x02561;',
'boxvl' => '&#x02524;',
'boxVR' => '&#x02560;',
'boxVr' => '&#x0255F;',
'boxvR' => '&#x0255E;',
'boxvr' => '&#x0251C;',
'Acy' => '&#x00410;',
'acy' => '&#x00430;',
'Bcy' => '&#x00411;',
'bcy' => '&#x00431;',
'CHcy' => '&#x00427;',
'chcy' => '&#x00447;',
'Dcy' => '&#x00414;',
'dcy' => '&#x00434;',
'Ecy' => '&#x0042D;',
'ecy' => '&#x0044D;',
'Fcy' => '&#x00424;',
'fcy' => '&#x00444;',
'Gcy' => '&#x00413;',
'gcy' => '&#x00433;',
'HARDcy' => '&#x0042A;',
'hardcy' => '&#x0044A;',
'Icy' => '&#x00418;',
'icy' => '&#x00438;',
'IEcy' => '&#x00415;',
'iecy' => '&#x00435;',
'IOcy' => '&#x00401;',
'iocy' => '&#x00451;',
'Jcy' => '&#x00419;',
'jcy' => '&#x00439;',
'Kcy' => '&#x0041A;',
'kcy' => '&#x0043A;',
'KHcy' => '&#x00425;',
'khcy' => '&#x00445;',
'Lcy' => '&#x0041B;',
'lcy' => '&#x0043B;',
'Mcy' => '&#x0041C;',
'mcy' => '&#x0043C;',
'Ncy' => '&#x0041D;',
'ncy' => '&#x0043D;',
'numero' => '&#x02116;',
'Ocy' => '&#x0041E;',
'ocy' => '&#x0043E;',
'Pcy' => '&#x0041F;',
'pcy' => '&#x0043F;',
'Rcy' => '&#x00420;',
'rcy' => '&#x00440;',
'Scy' => '&#x00421;',
'scy' => '&#x00441;',
'SHCHcy' => '&#x00429;',
'shchcy' => '&#x00449;',
'SHcy' => '&#x00428;',
'shcy' => '&#x00448;',
'SOFTcy' => '&#x0042C;',
'softcy' => '&#x0044C;',
'Tcy' => '&#x00422;',
'tcy' => '&#x00442;',
'TScy' => '&#x00426;',
'tscy' => '&#x00446;',
'Ucy' => '&#x00423;',
'ucy' => '&#x00443;',
'Vcy' => '&#x00412;',
'vcy' => '&#x00432;',
'YAcy' => '&#x0042F;',
'yacy' => '&#x0044F;',
'Ycy' => '&#x0042B;',
'ycy' => '&#x0044B;',
'YUcy' => '&#x0042E;',
'yucy' => '&#x0044E;',
'Zcy' => '&#x00417;',
'zcy' => '&#x00437;',
'ZHcy' => '&#x00416;',
'zhcy' => '&#x00436;',
'DJcy' => '&#x00402;',
'djcy' => '&#x00452;',
'DScy' => '&#x00405;',
'dscy' => '&#x00455;',
'DZcy' => '&#x0040F;',
'dzcy' => '&#x0045F;',
'GJcy' => '&#x00403;',
'gjcy' => '&#x00453;',
'Iukcy' => '&#x00406;',
'iukcy' => '&#x00456;',
'Jsercy' => '&#x00408;',
'jsercy' => '&#x00458;',
'Jukcy' => '&#x00404;',
'jukcy' => '&#x00454;',
'KJcy' => '&#x0040C;',
'kjcy' => '&#x0045C;',
'LJcy' => '&#x00409;',
'ljcy' => '&#x00459;',
'NJcy' => '&#x0040A;',
'njcy' => '&#x0045A;',
'TSHcy' => '&#x0040B;',
'tshcy' => '&#x0045B;',
'Ubrcy' => '&#x0040E;',
'ubrcy' => '&#x0045E;',
'YIcy' => '&#x00407;',
'yicy' => '&#x00457;',
'acute' => '&#x000B4;',
'breve' => '&#x002D8;',
'caron' => '&#x002C7;',
'cedil' => '&#x000B8;',
'circ' => '&#x002C6;',
'dblac' => '&#x002DD;',
'die' => '&#x000A8;',
'dot' => '&#x002D9;',
'grave' => '&#x00060;',
'macr' => '&#x000AF;',
'ogon' => '&#x002DB;',
'ring' => '&#x002DA;',
'tilde' => '&#x002DC;',
'uml' => '&#x000A8;',
'Aacute' => '&#x000C1;',
'aacute' => '&#x000E1;',
'Acirc' => '&#x000C2;',
'acirc' => '&#x000E2;',
'AElig' => '&#x000C6;',
'aelig' => '&#x000E6;',
'Agrave' => '&#x000C0;',
'agrave' => '&#x000E0;',
'Aring' => '&#x000C5;',
'aring' => '&#x000E5;',
'Atilde' => '&#x000C3;',
'atilde' => '&#x000E3;',
'Auml' => '&#x000C4;',
'auml' => '&#x000E4;',
'Ccedil' => '&#x000C7;',
'ccedil' => '&#x000E7;',
'Eacute' => '&#x000C9;',
'eacute' => '&#x000E9;',
'Ecirc' => '&#x000CA;',
'ecirc' => '&#x000EA;',
'Egrave' => '&#x000C8;',
'egrave' => '&#x000E8;',
'ETH' => '&#x000D0;',
'eth' => '&#x000F0;',
'Euml' => '&#x000CB;',
'euml' => '&#x000EB;',
'Iacute' => '&#x000CD;',
'iacute' => '&#x000ED;',
'Icirc' => '&#x000CE;',
'icirc' => '&#x000EE;',
'Igrave' => '&#x000CC;',
'igrave' => '&#x000EC;',
'Iuml' => '&#x000CF;',
'iuml' => '&#x000EF;',
'Ntilde' => '&#x000D1;',
'ntilde' => '&#x000F1;',
'Oacute' => '&#x000D3;',
'oacute' => '&#x000F3;',
'Ocirc' => '&#x000D4;',
'ocirc' => '&#x000F4;',
'Ograve' => '&#x000D2;',
'ograve' => '&#x000F2;',
'Oslash' => '&#x000D8;',
'oslash' => '&#x000F8;',
'Otilde' => '&#x000D5;',
'otilde' => '&#x000F5;',
'Ouml' => '&#x000D6;',
'ouml' => '&#x000F6;',
'szlig' => '&#x000DF;',
'THORN' => '&#x000DE;',
'thorn' => '&#x000FE;',
'Uacute' => '&#x000DA;',
'uacute' => '&#x000FA;',
'Ucirc' => '&#x000DB;',
'ucirc' => '&#x000FB;',
'Ugrave' => '&#x000D9;',
'ugrave' => '&#x000F9;',
'Uuml' => '&#x000DC;',
'uuml' => '&#x000FC;',
'Yacute' => '&#x000DD;',
'yacute' => '&#x000FD;',
'yuml' => '&#x000FF;',
'Abreve' => '&#x00102;',
'abreve' => '&#x00103;',
'Amacr' => '&#x00100;',
'amacr' => '&#x00101;',
'Aogon' => '&#x00104;',
'aogon' => '&#x00105;',
'Cacute' => '&#x00106;',
'cacute' => '&#x00107;',
'Ccaron' => '&#x0010C;',
'ccaron' => '&#x0010D;',
'Ccirc' => '&#x00108;',
'ccirc' => '&#x00109;',
'Cdot' => '&#x0010A;',
'cdot' => '&#x0010B;',
'Dcaron' => '&#x0010E;',
'dcaron' => '&#x0010F;',
'Dstrok' => '&#x00110;',
'dstrok' => '&#x00111;',
'Ecaron' => '&#x0011A;',
'ecaron' => '&#x0011B;',
'Edot' => '&#x00116;',
'edot' => '&#x00117;',
'Emacr' => '&#x00112;',
'emacr' => '&#x00113;',
'ENG' => '&#x0014A;',
'eng' => '&#x0014B;',
'Eogon' => '&#x00118;',
'eogon' => '&#x00119;',
'gacute' => '&#x001F5;',
'Gbreve' => '&#x0011E;',
'gbreve' => '&#x0011F;',
'Gcedil' => '&#x00122;',
'Gcirc' => '&#x0011C;',
'gcirc' => '&#x0011D;',
'Gdot' => '&#x00120;',
'gdot' => '&#x00121;',
'Hcirc' => '&#x00124;',
'hcirc' => '&#x00125;',
'Hstrok' => '&#x00126;',
'hstrok' => '&#x00127;',
'Idot' => '&#x00130;',
'IJlig' => '&#x00132;',
'ijlig' => '&#x00133;',
'Imacr' => '&#x0012A;',
'imacr' => '&#x0012B;',
'inodot' => '&#x00131;',
'Iogon' => '&#x0012E;',
'iogon' => '&#x0012F;',
'Itilde' => '&#x00128;',
'itilde' => '&#x00129;',
'Jcirc' => '&#x00134;',
'jcirc' => '&#x00135;',
'Kcedil' => '&#x00136;',
'kcedil' => '&#x00137;',
'kgreen' => '&#x00138;',
'Lacute' => '&#x00139;',
'lacute' => '&#x0013A;',
'Lcaron' => '&#x0013D;',
'lcaron' => '&#x0013E;',
'Lcedil' => '&#x0013B;',
'lcedil' => '&#x0013C;',
'Lmidot' => '&#x0013F;',
'lmidot' => '&#x00140;',
'Lstrok' => '&#x00141;',
'lstrok' => '&#x00142;',
'Nacute' => '&#x00143;',
'nacute' => '&#x00144;',
'napos' => '&#x00149;',
'Ncaron' => '&#x00147;',
'ncaron' => '&#x00148;',
'Ncedil' => '&#x00145;',
'ncedil' => '&#x00146;',
'Odblac' => '&#x00150;',
'odblac' => '&#x00151;',
'OElig' => '&#x00152;',
'oelig' => '&#x00153;',
'Omacr' => '&#x0014C;',
'omacr' => '&#x0014D;',
'Racute' => '&#x00154;',
'racute' => '&#x00155;',
'Rcaron' => '&#x00158;',
'rcaron' => '&#x00159;',
'Rcedil' => '&#x00156;',
'rcedil' => '&#x00157;',
'Sacute' => '&#x0015A;',
'sacute' => '&#x0015B;',
'Scaron' => '&#x00160;',
'scaron' => '&#x00161;',
'Scedil' => '&#x0015E;',
'scedil' => '&#x0015F;',
'Scirc' => '&#x0015C;',
'scirc' => '&#x0015D;',
'Tcaron' => '&#x00164;',
'tcaron' => '&#x00165;',
'Tcedil' => '&#x00162;',
'tcedil' => '&#x00163;',
'Tstrok' => '&#x00166;',
'tstrok' => '&#x00167;',
'Ubreve' => '&#x0016C;',
'ubreve' => '&#x0016D;',
'Udblac' => '&#x00170;',
'udblac' => '&#x00171;',
'Umacr' => '&#x0016A;',
'umacr' => '&#x0016B;',
'Uogon' => '&#x00172;',
'uogon' => '&#x00173;',
'Uring' => '&#x0016E;',
'uring' => '&#x0016F;',
'Utilde' => '&#x00168;',
'utilde' => '&#x00169;',
'Wcirc' => '&#x00174;',
'wcirc' => '&#x00175;',
'Ycirc' => '&#x00176;',
'ycirc' => '&#x00177;',
'Yuml' => '&#x00178;',
'Zacute' => '&#x00179;',
'zacute' => '&#x0017A;',
'Zcaron' => '&#x0017D;',
'zcaron' => '&#x0017E;',
'Zdot' => '&#x0017B;',
'zdot' => '&#x0017C;',
'apos' => '&#x00027;',
'ast' => '&#x0002A;',
'brvbar' => '&#x000A6;',
'bsol' => '&#x0005C;',
'cent' => '&#x000A2;',
'colon' => '&#x0003A;',
'comma' => '&#x0002C;',
'commat' => '&#x00040;',
'copy' => '&#x000A9;',
'curren' => '&#x000A4;',
'darr' => '&#x02193;',
'deg' => '&#x000B0;',
'divide' => '&#x000F7;',
'dollar' => '&#x00024;',
'equals' => '&#x0003D;',
'excl' => '&#x00021;',
'frac12' => '&#x000BD;',
'frac14' => '&#x000BC;',
'frac18' => '&#x0215B;',
'frac34' => '&#x000BE;',
'frac38' => '&#x0215C;',
'frac58' => '&#x0215D;',
'frac78' => '&#x0215E;',
'gt' => '&#x0003E;',
'half' => '&#x000BD;',
'horbar' => '&#x02015;',
'hyphen' => '&#x02010;',
'iexcl' => '&#x000A1;',
'iquest' => '&#x000BF;',
'laquo' => '&#x000AB;',
'larr' => '&#x02190;',
'lcub' => '&#x0007B;',
'ldquo' => '&#x0201C;',
'lowbar' => '&#x0005F;',
'lpar' => '&#x00028;',
'lsqb' => '&#x0005B;',
'lsquo' => '&#x02018;',
'micro' => '&#x000B5;',
'middot' => '&#x000B7;',
'nbsp' => '&#x000A0;',
'not' => '&#x000AC;',
'num' => '&#x00023;',
'ohm' => '&#x02126;',
'ordf' => '&#x000AA;',
'ordm' => '&#x000BA;',
'para' => '&#x000B6;',
'percnt' => '&#x00025;',
'period' => '&#x0002E;',
'plus' => '&#x0002B;',
'plusmn' => '&#x000B1;',
'pound' => '&#x000A3;',
'quest' => '&#x0003F;',
'quot' => '&#x00022;',
'raquo' => '&#x000BB;',
'rarr' => '&#x02192;',
'rcub' => '&#x0007D;',
'rdquo' => '&#x0201D;',
'reg' => '&#x000AE;',
'rpar' => '&#x00029;',
'rsqb' => '&#x0005D;',
'rsquo' => '&#x02019;',
'sect' => '&#x000A7;',
'semi' => '&#x0003B;',
'shy' => '&#x000AD;',
'sol' => '&#x0002F;',
'sung' => '&#x0266A;',
'sup1' => '&#x000B9;',
'sup2' => '&#x000B2;',
'sup3' => '&#x000B3;',
'times' => '&#x000D7;',
'trade' => '&#x02122;',
'uarr' => '&#x02191;',
'verbar' => '&#x0007C;',
'yen' => '&#x000A5;',
'blank' => '&#x02423;',
'blk12' => '&#x02592;',
'blk14' => '&#x02591;',
'blk34' => '&#x02593;',
'block' => '&#x02588;',
'bull' => '&#x02022;',
'caret' => '&#x02041;',
'check' => '&#x02713;',
'cir' => '&#x025CB;',
'clubs' => '&#x02663;',
'copysr' => '&#x02117;',
'cross' => '&#x02717;',
'Dagger' => '&#x02021;',
'dagger' => '&#x02020;',
'dash' => '&#x02010;',
'diams' => '&#x02666;',
'dlcrop' => '&#x0230D;',
'drcrop' => '&#x0230C;',
'dtri' => '&#x025BF;',
'dtrif' => '&#x025BE;',
'emsp' => '&#x02003;',
'emsp13' => '&#x02004;',
'emsp14' => '&#x02005;',
'ensp' => '&#x02002;',
'female' => '&#x02640;',
'ffilig' => '&#x0FB03;',
'fflig' => '&#x0FB00;',
'ffllig' => '&#x0FB04;',
'filig' => '&#x0FB01;',
'flat' => '&#x0266D;',
'fllig' => '&#x0FB02;',
'frac13' => '&#x02153;',
'frac15' => '&#x02155;',
'frac16' => '&#x02159;',
'frac23' => '&#x02154;',
'frac25' => '&#x02156;',
'frac35' => '&#x02157;',
'frac45' => '&#x02158;',
'frac56' => '&#x0215A;',
'hairsp' => '&#x0200A;',
'hearts' => '&#x02665;',
'hellip' => '&#x02026;',
'hybull' => '&#x02043;',
'incare' => '&#x02105;',
'ldquor' => '&#x0201E;',
'lhblk' => '&#x02584;',
'loz' => '&#x025CA;',
'lozf' => '&#x029EB;',
'lsquor' => '&#x0201A;',
'ltri' => '&#x025C3;',
'ltrif' => '&#x025C2;',
'male' => '&#x02642;',
'malt' => '&#x02720;',
'marker' => '&#x025AE;',
'mdash' => '&#x02014;',
'mldr' => '&#x02026;',
'natur' => '&#x0266E;',
'ndash' => '&#x02013;',
'nldr' => '&#x02025;',
'numsp' => '&#x02007;',
'phone' => '&#x0260E;',
'puncsp' => '&#x02008;',
'rdquor' => '&#x0201D;',
'rect' => '&#x025AD;',
'rsquor' => '&#x02019;',
'rtri' => '&#x025B9;',
'rtrif' => '&#x025B8;',
'rx' => '&#x0211E;',
'sext' => '&#x02736;',
'sharp' => '&#x0266F;',
'spades' => '&#x02660;',
'squ' => '&#x025A1;',
'squf' => '&#x025AA;',
'star' => '&#x02606;',
'starf' => '&#x02605;',
'target' => '&#x02316;',
'telrec' => '&#x02315;',
'thinsp' => '&#x02009;',
'uhblk' => '&#x02580;',
'ulcrop' => '&#x0230F;',
'urcrop' => '&#x0230E;',
'utri' => '&#x025B5;',
'utrif' => '&#x025B4;',
'vellip' => '&#x022EE;',
'af' => '&#x02061;',
'aopf' => '&#x1D552;',
'asympeq' => '&#x0224D;',
'bopf' => '&#x1D553;',
'copf' => '&#x1D554;',
'Cross' => '&#x02A2F;',
'DD' => '&#x02145;',
'dd' => '&#x02146;',
'dopf' => '&#x1D555;',
'DownArrowBar' => '&#x02913;',
'DownBreve' => '&#x00311;',
'DownLeftRightVector' => '&#x02950;',
'DownLeftTeeVector' => '&#x0295E;',
'DownLeftVectorBar' => '&#x02956;',
'DownRightTeeVector' => '&#x0295F;',
'DownRightVectorBar' => '&#x02957;',
'ee' => '&#x02147;',
'EmptySmallSquare' => '&#x025FB;',
'EmptyVerySmallSquare' => '&#x025AB;',
'eopf' => '&#x1D556;',
'Equal' => '&#x02A75;',
'FilledSmallSquare' => '&#x025FC;',
'FilledVerySmallSquare' => '&#x025AA;',
'fopf' => '&#x1D557;',
'gopf' => '&#x1D558;',
'GreaterGreater' => '&#x02AA2;',
'Hat' => '&#x0005E;',
'hopf' => '&#x1D559;',
'HorizontalLine' => '&#x02500;',
'ic' => '&#x02063;',
'ii' => '&#x02148;',
'iopf' => '&#x1D55A;',
'it' => '&#x02062;',
'jopf' => '&#x1D55B;',
'kopf' => '&#x1D55C;',
'larrb' => '&#x021E4;',
'LeftDownTeeVector' => '&#x02961;',
'LeftDownVectorBar' => '&#x02959;',
'LeftRightVector' => '&#x0294E;',
'LeftTeeVector' => '&#x0295A;',
'LeftTriangleBar' => '&#x029CF;',
'LeftUpDownVector' => '&#x02951;',
'LeftUpTeeVector' => '&#x02960;',
'LeftUpVectorBar' => '&#x02958;',
'LeftVectorBar' => '&#x02952;',
'LessLess' => '&#x02AA1;',
'lopf' => '&#x1D55D;',
'mapstodown' => '&#x021A7;',
'mapstoleft' => '&#x021A4;',
'mapstoup' => '&#x021A5;',
'MediumSpace' => '&#x0205F;',
'mopf' => '&#x1D55E;',
'nbump' => '&#x0224E;&#x00338;',
'nbumpe' => '&#x0224F;&#x00338;',
'nesim' => '&#x02242;&#x00338;',
'NewLine' => '&#x0000A;',
'NoBreak' => '&#x02060;',
'nopf' => '&#x1D55F;',
'NotCupCap' => '&#x0226D;',
'NotHumpEqual' => '&#x0224F;&#x00338;',
'NotLeftTriangleBar' => '&#x029CF;&#x00338;',
'NotNestedGreaterGreater' => '&#x02AA2;&#x00338;',
'NotNestedLessLess' => '&#x02AA1;&#x00338;',
'NotRightTriangleBar' => '&#x029D0;&#x00338;',
'NotSquareSubset' => '&#x0228F;&#x00338;',
'NotSquareSuperset' => '&#x02290;&#x00338;',
'NotSucceedsTilde' => '&#x0227F;&#x00338;',
'oopf' => '&#x1D560;',
'OverBar' => '&#x000AF;',
'OverBrace' => '&#x0FE37;',
'OverBracket' => '&#x023B4;',
'OverParenthesis' => '&#x0FE35;',
'planckh' => '&#x0210E;',
'popf' => '&#x1D561;',
'Product' => '&#x0220F;',
'qopf' => '&#x1D562;',
'rarrb' => '&#x021E5;',
'RightDownTeeVector' => '&#x0295D;',
'RightDownVectorBar' => '&#x02955;',
'RightTeeVector' => '&#x0295B;',
'RightTriangleBar' => '&#x029D0;',
'RightUpDownVector' => '&#x0294F;',
'RightUpTeeVector' => '&#x0295C;',
'RightUpVectorBar' => '&#x02954;',
'RightVectorBar' => '&#x02953;',
'ropf' => '&#x1D563;',
'RoundImplies' => '&#x02970;',
'RuleDelayed' => '&#x029F4;',
'sopf' => '&#x1D564;',
'Tab' => '&#x00009;',
'ThickSpace' => '&#x02009;&#x0200A;&#x0200A;',
'topf' => '&#x1D565;',
'UnderBar' => '&#x00332;',
'UnderBrace' => '&#x0FE38;',
'UnderBracket' => '&#x023B5;',
'UnderParenthesis' => '&#x0FE36;',
'uopf' => '&#x1D566;',
'UpArrowBar' => '&#x02912;',
'Upsilon' => '&#x003A5;',
'VerticalLine' => '&#x0007C;',
'VerticalSeparator' => '&#x02758;',
'vopf' => '&#x1D567;',
'wopf' => '&#x1D568;',
'xopf' => '&#x1D569;',
'yopf' => '&#x1D56A;',
'ZeroWidthSpace' => '&#x0200B;',
'zopf' => '&#x1D56B;',
'angle' => '&#x02220;',
'ApplyFunction' => '&#x02061;',
'approx' => '&#x02248;',
'approxeq' => '&#x0224A;',
'Assign' => '&#x02254;',
'backcong' => '&#x0224C;',
'backepsilon' => '&#x003F6;',
'backprime' => '&#x02035;',
'backsim' => '&#x0223D;',
'backsimeq' => '&#x022CD;',
'Backslash' => '&#x02216;',
'barwedge' => '&#x02305;',
'Because' => '&#x02235;',
'because' => '&#x02235;',
'Bernoullis' => '&#x0212C;',
'between' => '&#x0226C;',
'bigcap' => '&#x022C2;',
'bigcirc' => '&#x025EF;',
'bigcup' => '&#x022C3;',
'bigodot' => '&#x02A00;',
'bigoplus' => '&#x02A01;',
'bigotimes' => '&#x02A02;',
'bigsqcup' => '&#x02A06;',
'bigstar' => '&#x02605;',
'bigtriangledown' => '&#x025BD;',
'bigtriangleup' => '&#x025B3;',
'biguplus' => '&#x02A04;',
'bigvee' => '&#x022C1;',
'bigwedge' => '&#x022C0;',
'bkarow' => '&#x0290D;',
'blacklozenge' => '&#x029EB;',
'blacksquare' => '&#x025AA;',
'blacktriangle' => '&#x025B4;',
'blacktriangledown' => '&#x025BE;',
'blacktriangleleft' => '&#x025C2;',
'blacktriangleright' => '&#x025B8;',
'bot' => '&#x022A5;',
'boxminus' => '&#x0229F;',
'boxplus' => '&#x0229E;',
'boxtimes' => '&#x022A0;',
'Breve' => '&#x002D8;',
'bullet' => '&#x02022;',
'Bumpeq' => '&#x0224E;',
'bumpeq' => '&#x0224F;',
'CapitalDifferentialD' => '&#x02145;',
'Cayleys' => '&#x0212D;',
'Cedilla' => '&#x000B8;',
'CenterDot' => '&#x000B7;',
'centerdot' => '&#x000B7;',
'checkmark' => '&#x02713;',
'circeq' => '&#x02257;',
'circlearrowleft' => '&#x021BA;',
'circlearrowright' => '&#x021BB;',
'circledast' => '&#x0229B;',
'circledcirc' => '&#x0229A;',
'circleddash' => '&#x0229D;',
'CircleDot' => '&#x02299;',
'circledR' => '&#x000AE;',
'circledS' => '&#x024C8;',
'CircleMinus' => '&#x02296;',
'CirclePlus' => '&#x02295;',
'CircleTimes' => '&#x02297;',
'ClockwiseContourIntegral' => '&#x02232;',
'CloseCurlyDoubleQuote' => '&#x0201D;',
'CloseCurlyQuote' => '&#x02019;',
'clubsuit' => '&#x02663;',
'coloneq' => '&#x02254;',
'complement' => '&#x02201;',
'complexes' => '&#x02102;',
'Congruent' => '&#x02261;',
'ContourIntegral' => '&#x0222E;',
'Coproduct' => '&#x02210;',
'CounterClockwiseContourIntegral' => '&#x02233;',
'CupCap' => '&#x0224D;',
'curlyeqprec' => '&#x022DE;',
'curlyeqsucc' => '&#x022DF;',
'curlyvee' => '&#x022CE;',
'curlywedge' => '&#x022CF;',
'curvearrowleft' => '&#x021B6;',
'curvearrowright' => '&#x021B7;',
'dbkarow' => '&#x0290F;',
'ddagger' => '&#x02021;',
'ddotseq' => '&#x02A77;',
'Del' => '&#x02207;',
'DiacriticalAcute' => '&#x000B4;',
'DiacriticalDot' => '&#x002D9;',
'DiacriticalDoubleAcute' => '&#x002DD;',
'DiacriticalGrave' => '&#x00060;',
'DiacriticalTilde' => '&#x002DC;',
'Diamond' => '&#x022C4;',
'diamond' => '&#x022C4;',
'diamondsuit' => '&#x02666;',
'DifferentialD' => '&#x02146;',
'digamma' => '&#x003DD;',
'div' => '&#x000F7;',
'divideontimes' => '&#x022C7;',
'doteq' => '&#x02250;',
'doteqdot' => '&#x02251;',
'DotEqual' => '&#x02250;',
'dotminus' => '&#x02238;',
'dotplus' => '&#x02214;',
'dotsquare' => '&#x022A1;',
'doublebarwedge' => '&#x02306;',
'DoubleContourIntegral' => '&#x0222F;',
'DoubleDot' => '&#x000A8;',
'DoubleDownArrow' => '&#x021D3;',
'DoubleLeftArrow' => '&#x021D0;',
'DoubleLeftRightArrow' => '&#x021D4;',
'DoubleLeftTee' => '&#x02AE4;',
'DoubleLongLeftArrow' => '&#x027F8;',
'DoubleLongLeftRightArrow' => '&#x027FA;',
'DoubleLongRightArrow' => '&#x027F9;',
'DoubleRightArrow' => '&#x021D2;',
'DoubleRightTee' => '&#x022A8;',
'DoubleUpArrow' => '&#x021D1;',
'DoubleUpDownArrow' => '&#x021D5;',
'DoubleVerticalBar' => '&#x02225;',
'DownArrow' => '&#x02193;',
'Downarrow' => '&#x021D3;',
'downarrow' => '&#x02193;',
'DownArrowUpArrow' => '&#x021F5;',
'downdownarrows' => '&#x021CA;',
'downharpoonleft' => '&#x021C3;',
'downharpoonright' => '&#x021C2;',
'DownLeftVector' => '&#x021BD;',
'DownRightVector' => '&#x021C1;',
'DownTee' => '&#x022A4;',
'DownTeeArrow' => '&#x021A7;',
'drbkarow' => '&#x02910;',
'Element' => '&#x02208;',
'emptyset' => '&#x02205;',
'eqcirc' => '&#x02256;',
'eqcolon' => '&#x02255;',
'eqsim' => '&#x02242;',
'eqslantgtr' => '&#x02A96;',
'eqslantless' => '&#x02A95;',
'EqualTilde' => '&#x02242;',
'Equilibrium' => '&#x021CC;',
'Exists' => '&#x02203;',
'expectation' => '&#x02130;',
'ExponentialE' => '&#x02147;',
'exponentiale' => '&#x02147;',
'fallingdotseq' => '&#x02252;',
'ForAll' => '&#x02200;',
'Fouriertrf' => '&#x02131;',
'geq' => '&#x02265;',
'geqq' => '&#x02267;',
'geqslant' => '&#x02A7E;',
'gg' => '&#x0226B;',
'ggg' => '&#x022D9;',
'gnapprox' => '&#x02A8A;',
'gneq' => '&#x02A88;',
'gneqq' => '&#x02269;',
'GreaterEqual' => '&#x02265;',
'GreaterEqualLess' => '&#x022DB;',
'GreaterFullEqual' => '&#x02267;',
'GreaterLess' => '&#x02277;',
'GreaterSlantEqual' => '&#x02A7E;',
'GreaterTilde' => '&#x02273;',
'gtrapprox' => '&#x02A86;',
'gtrdot' => '&#x022D7;',
'gtreqless' => '&#x022DB;',
'gtreqqless' => '&#x02A8C;',
'gtrless' => '&#x02277;',
'gtrsim' => '&#x02273;',
'gvertneqq' => '&#x02269;&#x0FE00;',
'Hacek' => '&#x002C7;',
'hbar' => '&#x0210F;',
'heartsuit' => '&#x02665;',
'HilbertSpace' => '&#x0210B;',
'hksearow' => '&#x02925;',
'hkswarow' => '&#x02926;',
'hookleftarrow' => '&#x021A9;',
'hookrightarrow' => '&#x021AA;',
'hslash' => '&#x0210F;',
'HumpDownHump' => '&#x0224E;',
'HumpEqual' => '&#x0224F;',
'iiiint' => '&#x02A0C;',
'iiint' => '&#x0222D;',
'Im' => '&#x02111;',
'ImaginaryI' => '&#x02148;',
'imagline' => '&#x02110;',
'imagpart' => '&#x02111;',
'Implies' => '&#x021D2;',
'in' => '&#x02208;',
'integers' => '&#x02124;',
'Integral' => '&#x0222B;',
'intercal' => '&#x022BA;',
'Intersection' => '&#x022C2;',
'intprod' => '&#x02A3C;',
'InvisibleComma' => '&#x02063;',
'InvisibleTimes' => '&#x02062;',
'langle' => '&#x02329;',
'Laplacetrf' => '&#x02112;',
'lbrace' => '&#x0007B;',
'lbrack' => '&#x0005B;',
'LeftAngleBracket' => '&#x02329;',
'LeftArrow' => '&#x02190;',
'Leftarrow' => '&#x021D0;',
'leftarrow' => '&#x02190;',
'LeftArrowBar' => '&#x021E4;',
'LeftArrowRightArrow' => '&#x021C6;',
'leftarrowtail' => '&#x021A2;',
'LeftCeiling' => '&#x02308;',
'LeftDoubleBracket' => '&#x0301A;',
'LeftDownVector' => '&#x021C3;',
'LeftFloor' => '&#x0230A;',
'leftharpoondown' => '&#x021BD;',
'leftharpoonup' => '&#x021BC;',
'leftleftarrows' => '&#x021C7;',
'LeftRightArrow' => '&#x02194;',
'Leftrightarrow' => '&#x021D4;',
'leftrightarrow' => '&#x02194;',
'leftrightarrows' => '&#x021C6;',
'leftrightharpoons' => '&#x021CB;',
'leftrightsquigarrow' => '&#x021AD;',
'LeftTee' => '&#x022A3;',
'LeftTeeArrow' => '&#x021A4;',
'leftthreetimes' => '&#x022CB;',
'LeftTriangle' => '&#x022B2;',
'LeftTriangleEqual' => '&#x022B4;',
'LeftUpVector' => '&#x021BF;',
'LeftVector' => '&#x021BC;',
'leq' => '&#x02264;',
'leqq' => '&#x02266;',
'leqslant' => '&#x02A7D;',
'lessapprox' => '&#x02A85;',
'lessdot' => '&#x022D6;',
'lesseqgtr' => '&#x022DA;',
'lesseqqgtr' => '&#x02A8B;',
'LessEqualGreater' => '&#x022DA;',
'LessFullEqual' => '&#x02266;',
'LessGreater' => '&#x02276;',
'lessgtr' => '&#x02276;',
'lesssim' => '&#x02272;',
'LessSlantEqual' => '&#x02A7D;',
'LessTilde' => '&#x02272;',
'll' => '&#x0226A;',
'llcorner' => '&#x0231E;',
'Lleftarrow' => '&#x021DA;',
'lmoustache' => '&#x023B0;',
'lnapprox' => '&#x02A89;',
'lneq' => '&#x02A87;',
'lneqq' => '&#x02268;',
'LongLeftArrow' => '&#x027F5;',
'Longleftarrow' => '&#x027F8;',
'longleftarrow' => '&#x027F5;',
'LongLeftRightArrow' => '&#x027F7;',
'Longleftrightarrow' => '&#x027FA;',
'longleftrightarrow' => '&#x027F7;',
'longmapsto' => '&#x027FC;',
'LongRightArrow' => '&#x027F6;',
'Longrightarrow' => '&#x027F9;',
'longrightarrow' => '&#x027F6;',
'looparrowleft' => '&#x021AB;',
'looparrowright' => '&#x021AC;',
'LowerLeftArrow' => '&#x02199;',
'LowerRightArrow' => '&#x02198;',
'lozenge' => '&#x025CA;',
'lrcorner' => '&#x0231F;',
'Lsh' => '&#x021B0;',
'lvertneqq' => '&#x02268;&#x0FE00;',
'maltese' => '&#x02720;',
'mapsto' => '&#x021A6;',
'measuredangle' => '&#x02221;',
'Mellintrf' => '&#x02133;',
'MinusPlus' => '&#x02213;',
'mp' => '&#x02213;',
'multimap' => '&#x022B8;',
'napprox' => '&#x02249;',
'natural' => '&#x0266E;',
'naturals' => '&#x02115;',
'nearrow' => '&#x02197;',
'NegativeMediumSpace' => '&#x0200B;',
'NegativeThickSpace' => '&#x0200B;',
'NegativeThinSpace' => '&#x0200B;',
'NegativeVeryThinSpace' => '&#x0200B;',
'NestedGreaterGreater' => '&#x0226B;',
'NestedLessLess' => '&#x0226A;',
'nexists' => '&#x02204;',
'ngeq' => '&#x02271;',
'ngeqq' => '&#x02267;&#x00338;',
'ngeqslant' => '&#x02A7E;&#x00338;',
'ngtr' => '&#x0226F;',
'nLeftarrow' => '&#x021CD;',
'nleftarrow' => '&#x0219A;',
'nLeftrightarrow' => '&#x021CE;',
'nleftrightarrow' => '&#x021AE;',
'nleq' => '&#x02270;',
'nleqq' => '&#x02266;&#x00338;',
'nleqslant' => '&#x02A7D;&#x00338;',
'nless' => '&#x0226E;',
'NonBreakingSpace' => '&#x000A0;',
'NotCongruent' => '&#x02262;',
'NotDoubleVerticalBar' => '&#x02226;',
'NotElement' => '&#x02209;',
'NotEqual' => '&#x02260;',
'NotEqualTilde' => '&#x02242;&#x00338;',
'NotExists' => '&#x02204;',
'NotGreater' => '&#x0226F;',
'NotGreaterEqual' => '&#x02271;',
'NotGreaterFullEqual' => '&#x02266;&#x00338;',
'NotGreaterGreater' => '&#x0226B;&#x00338;',
'NotGreaterLess' => '&#x02279;',
'NotGreaterSlantEqual' => '&#x02A7E;&#x00338;',
'NotGreaterTilde' => '&#x02275;',
'NotHumpDownHump' => '&#x0224E;&#x00338;',
'NotLeftTriangle' => '&#x022EA;',
'NotLeftTriangleEqual' => '&#x022EC;',
'NotLess' => '&#x0226E;',
'NotLessEqual' => '&#x02270;',
'NotLessGreater' => '&#x02278;',
'NotLessLess' => '&#x0226A;&#x00338;',
'NotLessSlantEqual' => '&#x02A7D;&#x00338;',
'NotLessTilde' => '&#x02274;',
'NotPrecedes' => '&#x02280;',
'NotPrecedesEqual' => '&#x02AAF;&#x00338;',
'NotPrecedesSlantEqual' => '&#x022E0;',
'NotReverseElement' => '&#x0220C;',
'NotRightTriangle' => '&#x022EB;',
'NotRightTriangleEqual' => '&#x022ED;',
'NotSquareSubsetEqual' => '&#x022E2;',
'NotSquareSupersetEqual' => '&#x022E3;',
'NotSubset' => '&#x02282;&#x020D2;',
'NotSubsetEqual' => '&#x02288;',
'NotSucceeds' => '&#x02281;',
'NotSucceedsEqual' => '&#x02AB0;&#x00338;',
'NotSucceedsSlantEqual' => '&#x022E1;',
'NotSuperset' => '&#x02283;&#x020D2;',
'NotSupersetEqual' => '&#x02289;',
'NotTilde' => '&#x02241;',
'NotTildeEqual' => '&#x02244;',
'NotTildeFullEqual' => '&#x02247;',
'NotTildeTilde' => '&#x02249;',
'NotVerticalBar' => '&#x02224;',
'nparallel' => '&#x02226;',
'nprec' => '&#x02280;',
'npreceq' => '&#x02AAF;&#x00338;',
'nRightarrow' => '&#x021CF;',
'nrightarrow' => '&#x0219B;',
'nshortmid' => '&#x02224;',
'nshortparallel' => '&#x02226;',
'nsimeq' => '&#x02244;',
'nsubset' => '&#x02282;&#x020D2;',
'nsubseteq' => '&#x02288;',
'nsubseteqq' => '&#x02AC5;&#x00338;',
'nsucc' => '&#x02281;',
'nsucceq' => '&#x02AB0;&#x00338;',
'nsupset' => '&#x02283;&#x020D2;',
'nsupseteq' => '&#x02289;',
'nsupseteqq' => '&#x02AC6;&#x00338;',
'ntriangleleft' => '&#x022EA;',
'ntrianglelefteq' => '&#x022EC;',
'ntriangleright' => '&#x022EB;',
'ntrianglerighteq' => '&#x022ED;',
'nwarrow' => '&#x02196;',
'oint' => '&#x0222E;',
'OpenCurlyDoubleQuote' => '&#x0201C;',
'OpenCurlyQuote' => '&#x02018;',
'orderof' => '&#x02134;',
'parallel' => '&#x02225;',
'PartialD' => '&#x02202;',
'pitchfork' => '&#x022D4;',
'PlusMinus' => '&#x000B1;',
'pm' => '&#x000B1;',
'Poincareplane' => '&#x0210C;',
'prec' => '&#x0227A;',
'precapprox' => '&#x02AB7;',
'preccurlyeq' => '&#x0227C;',
'Precedes' => '&#x0227A;',
'PrecedesEqual' => '&#x02AAF;',
'PrecedesSlantEqual' => '&#x0227C;',
'PrecedesTilde' => '&#x0227E;',
'preceq' => '&#x02AAF;',
'precnapprox' => '&#x02AB9;',
'precneqq' => '&#x02AB5;',
'precnsim' => '&#x022E8;',
'precsim' => '&#x0227E;',
'primes' => '&#x02119;',
'Proportion' => '&#x02237;',
'Proportional' => '&#x0221D;',
'propto' => '&#x0221D;',
'quaternions' => '&#x0210D;',
'questeq' => '&#x0225F;',
'rangle' => '&#x0232A;',
'rationals' => '&#x0211A;',
'rbrace' => '&#x0007D;',
'rbrack' => '&#x0005D;',
'Re' => '&#x0211C;',
'realine' => '&#x0211B;',
'realpart' => '&#x0211C;',
'reals' => '&#x0211D;',
'ReverseElement' => '&#x0220B;',
'ReverseEquilibrium' => '&#x021CB;',
'ReverseUpEquilibrium' => '&#x0296F;',
'RightAngleBracket' => '&#x0232A;',
'RightArrow' => '&#x02192;',
'Rightarrow' => '&#x021D2;',
'rightarrow' => '&#x02192;',
'RightArrowBar' => '&#x021E5;',
'RightArrowLeftArrow' => '&#x021C4;',
'rightarrowtail' => '&#x021A3;',
'RightCeiling' => '&#x02309;',
'RightDoubleBracket' => '&#x0301B;',
'RightDownVector' => '&#x021C2;',
'RightFloor' => '&#x0230B;',
'rightharpoondown' => '&#x021C1;',
'rightharpoonup' => '&#x021C0;',
'rightleftarrows' => '&#x021C4;',
'rightleftharpoons' => '&#x021CC;',
'rightrightarrows' => '&#x021C9;',
'rightsquigarrow' => '&#x0219D;',
'RightTee' => '&#x022A2;',
'RightTeeArrow' => '&#x021A6;',
'rightthreetimes' => '&#x022CC;',
'RightTriangle' => '&#x022B3;',
'RightTriangleEqual' => '&#x022B5;',
'RightUpVector' => '&#x021BE;',
'RightVector' => '&#x021C0;',
'risingdotseq' => '&#x02253;',
'rmoustache' => '&#x023B1;',
'Rrightarrow' => '&#x021DB;',
'Rsh' => '&#x021B1;',
'searrow' => '&#x02198;',
'setminus' => '&#x02216;',
'ShortDownArrow' => '&#x02193;',
'ShortLeftArrow' => '&#x02190;',
'shortmid' => '&#x02223;',
'shortparallel' => '&#x02225;',
'ShortRightArrow' => '&#x02192;',
'ShortUpArrow' => '&#x02191;',
'simeq' => '&#x02243;',
'SmallCircle' => '&#x02218;',
'smallsetminus' => '&#x02216;',
'spadesuit' => '&#x02660;',
'Sqrt' => '&#x0221A;',
'sqsubset' => '&#x0228F;',
'sqsubseteq' => '&#x02291;',
'sqsupset' => '&#x02290;',
'sqsupseteq' => '&#x02292;',
'Square' => '&#x025A1;',
'SquareIntersection' => '&#x02293;',
'SquareSubset' => '&#x0228F;',
'SquareSubsetEqual' => '&#x02291;',
'SquareSuperset' => '&#x02290;',
'SquareSupersetEqual' => '&#x02292;',
'SquareUnion' => '&#x02294;',
'Star' => '&#x022C6;',
'straightepsilon' => '&#x003F5;',
'straightphi' => '&#x003D5;',
'Subset' => '&#x022D0;',
'subset' => '&#x02282;',
'subseteq' => '&#x02286;',
'subseteqq' => '&#x02AC5;',
'SubsetEqual' => '&#x02286;',
'subsetneq' => '&#x0228A;',
'subsetneqq' => '&#x02ACB;',
'succ' => '&#x0227B;',
'succapprox' => '&#x02AB8;',
'succcurlyeq' => '&#x0227D;',
'Succeeds' => '&#x0227B;',
'SucceedsEqual' => '&#x02AB0;',
'SucceedsSlantEqual' => '&#x0227D;',
'SucceedsTilde' => '&#x0227F;',
'succeq' => '&#x02AB0;',
'succnapprox' => '&#x02ABA;',
'succneqq' => '&#x02AB6;',
'succnsim' => '&#x022E9;',
'succsim' => '&#x0227F;',
'SuchThat' => '&#x0220B;',
'Sum' => '&#x02211;',
'Superset' => '&#x02283;',
'SupersetEqual' => '&#x02287;',
'Supset' => '&#x022D1;',
'supset' => '&#x02283;',
'supseteq' => '&#x02287;',
'supseteqq' => '&#x02AC6;',
'supsetneq' => '&#x0228B;',
'supsetneqq' => '&#x02ACC;',
'swarrow' => '&#x02199;',
'Therefore' => '&#x02234;',
'therefore' => '&#x02234;',
'thickapprox' => '&#x02248;',
'thicksim' => '&#x0223C;',
'ThinSpace' => '&#x02009;',
'Tilde' => '&#x0223C;',
'TildeEqual' => '&#x02243;',
'TildeFullEqual' => '&#x02245;',
'TildeTilde' => '&#x02248;',
'toea' => '&#x02928;',
'tosa' => '&#x02929;',
'triangle' => '&#x025B5;',
'triangledown' => '&#x025BF;',
'triangleleft' => '&#x025C3;',
'trianglelefteq' => '&#x022B4;',
'triangleq' => '&#x0225C;',
'triangleright' => '&#x025B9;',
'trianglerighteq' => '&#x022B5;',
'TripleDot' => '&#x020DB;',
'twoheadleftarrow' => '&#x0219E;',
'twoheadrightarrow' => '&#x021A0;',
'ulcorner' => '&#x0231C;',
'Union' => '&#x022C3;',
'UnionPlus' => '&#x0228E;',
'UpArrow' => '&#x02191;',
'Uparrow' => '&#x021D1;',
'uparrow' => '&#x02191;',
'UpArrowDownArrow' => '&#x021C5;',
'UpDownArrow' => '&#x02195;',
'Updownarrow' => '&#x021D5;',
'updownarrow' => '&#x02195;',
'UpEquilibrium' => '&#x0296E;',
'upharpoonleft' => '&#x021BF;',
'upharpoonright' => '&#x021BE;',
'UpperLeftArrow' => '&#x02196;',
'UpperRightArrow' => '&#x02197;',
'upsilon' => '&#x003C5;',
'UpTee' => '&#x022A5;',
'UpTeeArrow' => '&#x021A5;',
'upuparrows' => '&#x021C8;',
'urcorner' => '&#x0231D;',
'varepsilon' => '&#x003B5;',
'varkappa' => '&#x003F0;',
'varnothing' => '&#x02205;',
'varphi' => '&#x003C6;',
'varpi' => '&#x003D6;',
'varpropto' => '&#x0221D;',
'varrho' => '&#x003F1;',
'varsigma' => '&#x003C2;',
'varsubsetneq' => '&#x0228A;&#x0FE00;',
'varsubsetneqq' => '&#x02ACB;&#x0FE00;',
'varsupsetneq' => '&#x0228B;&#x0FE00;',
'varsupsetneqq' => '&#x02ACC;&#x0FE00;',
'vartheta' => '&#x003D1;',
'vartriangleleft' => '&#x022B2;',
'vartriangleright' => '&#x022B3;',
'Vee' => '&#x022C1;',
'vee' => '&#x02228;',
'Vert' => '&#x02016;',
'vert' => '&#x0007C;',
'VerticalBar' => '&#x02223;',
'VerticalTilde' => '&#x02240;',
'VeryThinSpace' => '&#x0200A;',
'Wedge' => '&#x022C0;',
'wedge' => '&#x02227;',
'wp' => '&#x02118;',
'wr' => '&#x02240;',
'zeetrf' => '&#x02128;'
} unless const_defined? "MATHML_ENTITIES"
#:startdoc:
# Converts XHTML+MathML named entities in string to Numeric Character References
#
# :call-seq:
# string.to_ncr -> string
#
def to_ncr
self.gsub(/&([a-zA-Z0-9]+);/) {|m| $1.convert_to_ncr}
end
# Converts XHTML+MathML named entities in string to Numeric Character References
#
# :call-seq:
# string.to_ncr! -> str or nil
#
# Substitution is done in-place.
#
def to_ncr!
self.gsub!(/&([a-zA-Z0-9]+);/) {|m| $1.convert_to_ncr}
end
# Converts XHTML+MathML named entities in string to UTF-8
#
# :call-seq:
# string.to_utf8 -> string
#
#--
def to_utf8
self.gsub(/&([a-zA-Z0-9]+);/) {|m| $1.convert_to_utf8}
# You might think this is faster, but it isn't
# pieces = self.split(/&([a-zA-Z0-9]+);/)
# 1.step(pieces.length-1, 2) {|i| pieces[i].convert_to_utf8}
# pieces.join
end
#++
# Converts XHTML+MathML named entities in string to UTF-8
#
# :call-seq:
# string.to_ncr! -> str or nil
#
# Substitution is done in-place.
#
def to_utf8!
self.gsub!(/&([a-zA-Z0-9]+);/) {|m| $1.convert_to_utf8}
end
protected
def convert_to_ncr #:nodoc:
if self =~ /^(lt|gt|amp|quot|apos)$/
self.replace "&" + self + ";"
elsif MATHML_ENTITIES.has_key?(self)
self.replace MATHML_ENTITIES[self]
else
self.replace "&amp;" + self + ";"
end
end
def convert_to_utf8 #:nodoc:
if self =~ /^(lt|gt|amp|quot|apos)$/
self.replace "&" + self + ";"
elsif MATHML_ENTITIES.has_key?(self)
self.replace MATHML_ENTITIES[self].split(';').collect {|s| s.gsub(/^&#x([A-F0-9]+)$/, '\1').hex }.pack('U*')
else
self.replace "&amp;" + self + ";"
end
end
end
require 'rexml/element'
module REXML #:nodoc:
class Element
# Convert XHTML+MathML Named Entities in a REXML::Element to Numeric Character References
#
# :call-seq:
# tree.to_ncr -> REXML::Element
#
# REXML, typically, converts NCRs to utf-8 characters, which is what you'll see when you
# access the resulting REXML document.
#
# Note that this method needs to traverse the entire tree, converting text nodes and attributes
# for each element. This can be SLOW. It will often be faster to serialize to a string and then
# use String.to_ncr instead.
#
def to_ncr
self.each_element { |el|
el.texts.each_index {|i|
el.texts[i].value = el.texts[i].to_s.to_ncr
}
el.attributes.each { |name,val|
el.attributes[name] = val.to_ncr
}
el.to_ncr if el.has_elements?
}
return self
end
# Convert XHTML+MathML Named Entities in a REXML::Element to UTF-8
#
# :call-seq:
# tree.to_utf8 -> REXML::Element
#
# Note that this method needs to traverse the entire tree, converting text nodes and attributes
# for each element. This can be SLOW. It will often be faster to serialize to a string and then
# use String.to_utf8 instead.
#
def to_utf8
self.each_element { |el|
el.texts.each_index {|i|
el.texts[i].value = el.texts[i].to_s.to_utf8
}
el.attributes.each { |name,val|
el.attributes[name] = val.to_utf8
}
el.to_utf8 if el.has_elements?
}
return self
end
end
end
module HTML5 #:nodoc: all
module TreeWalkers
private
class << self
def [](name)
case name.to_s.downcase
when 'rexml'
require 'html5/treewalkers/rexml'
REXML::TreeWalker
when 'rexml2'
REXML2::TreeWalker
else
raise "Unknown TreeWalker #{name}"
end
end
alias :get_tree_walker :[]
end
module REXML2
class TreeWalker < HTML5::TreeWalkers::NonRecursiveTreeWalker
private
def node_details(node)
case node
when ::REXML::Document
[:DOCUMENT]
when ::REXML::Element
if !node.name
[:DOCUMENT_FRAGMENT]
else
[:ELEMENT, node.name,
node.attributes.map {|name,value| [name,value.to_utf8]},
node.has_elements? || node.has_text?]
end
when ::REXML::Text
[:TEXT, node.value.to_utf8]
when ::REXML::Comment
[:COMMENT, node.string]
when ::REXML::DocType
[:DOCTYPE, node.name, node.public, node.system]
when ::REXML::XMLDecl
[nil]
else
[:UNKNOWN, node.class.inspect]
end
end
def first_child(node)
node.children.first
end
def next_sibling(node)
node.next_sibling
end
def parent(node)
node.parent
end
end
end
end
end