1# 2# 3# Nim's Runtime Library 4# (c) Copyright 2013 Andreas Rumpf 5# 6# See the file "copying.txt", included in this 7# distribution, for details about the copyright. 8# 9 10## **NOTE**: The behaviour might change in future versions as it is not 11## clear what "*wild* HTML the real world uses" really implies. 12## 13## It can be used to parse a wild HTML document and output it as valid XHTML 14## document (well, if you are lucky): 15## 16## .. code-block:: Nim 17## 18## echo loadHtml("mydirty.html") 19## 20## Every tag in the resulting tree is in lower case. 21## 22## **Note:** The resulting `XmlNode` already uses the `clientData` field, 23## so it cannot be used by clients of this library. 24## 25## Example: Transforming hyperlinks 26## ================================ 27## 28## This code demonstrates how you can iterate over all the tags in an HTML file 29## and write back the modified version. In this case we look for hyperlinks 30## ending with the extension `.rst` and convert them to `.html`. 31## 32## .. code-block:: Nim 33## :test: 34## 35## import std/htmlparser 36## import std/xmltree # To use '$' for XmlNode 37## import std/strtabs # To access XmlAttributes 38## import std/os # To use splitFile 39## import std/strutils # To use cmpIgnoreCase 40## 41## proc transformHyperlinks() = 42## let html = loadHtml("input.html") 43## 44## for a in html.findAll("a"): 45## if a.attrs.hasKey "href": 46## let (dir, filename, ext) = splitFile(a.attrs["href"]) 47## if cmpIgnoreCase(ext, ".rst") == 0: 48## a.attrs["href"] = dir / filename & ".html" 49## 50## writeFile("output.html", $html) 51 52import strutils, streams, parsexml, xmltree, unicode, strtabs 53 54type 55 HtmlTag* = enum ## list of all supported HTML tags; order will always be 56 ## alphabetically 57 tagUnknown, ## unknown HTML element 58 tagA, ## the HTML `a` element 59 tagAbbr, ## the deprecated HTML `abbr` element 60 tagAcronym, ## the HTML `acronym` element 61 tagAddress, ## the HTML `address` element 62 tagApplet, ## the deprecated HTML `applet` element 63 tagArea, ## the HTML `area` element 64 tagArticle, ## the HTML `article` element 65 tagAside, ## the HTML `aside` element 66 tagAudio, ## the HTML `audio` element 67 tagB, ## the HTML `b` element 68 tagBase, ## the HTML `base` element 69 tagBdi, ## the HTML `bdi` element 70 tagBdo, ## the deprecated HTML `dbo` element 71 tagBasefont, ## the deprecated HTML `basefont` element 72 tagBig, ## the HTML `big` element 73 tagBlockquote, ## the HTML `blockquote` element 74 tagBody, ## the HTML `body` element 75 tagBr, ## the HTML `br` element 76 tagButton, ## the HTML `button` element 77 tagCanvas, ## the HTML `canvas` element 78 tagCaption, ## the HTML `caption` element 79 tagCenter, ## the deprecated HTML `center` element 80 tagCite, ## the HTML `cite` element 81 tagCode, ## the HTML `code` element 82 tagCol, ## the HTML `col` element 83 tagColgroup, ## the HTML `colgroup` element 84 tagCommand, ## the HTML `command` element 85 tagDatalist, ## the HTML `datalist` element 86 tagDd, ## the HTML `dd` element 87 tagDel, ## the HTML `del` element 88 tagDetails, ## the HTML `details` element 89 tagDfn, ## the HTML `dfn` element 90 tagDialog, ## the HTML `dialog` element 91 tagDiv, ## the HTML `div` element 92 tagDir, ## the deprecated HTLM `dir` element 93 tagDl, ## the HTML `dl` element 94 tagDt, ## the HTML `dt` element 95 tagEm, ## the HTML `em` element 96 tagEmbed, ## the HTML `embed` element 97 tagFieldset, ## the HTML `fieldset` element 98 tagFigcaption, ## the HTML `figcaption` element 99 tagFigure, ## the HTML `figure` element 100 tagFont, ## the deprecated HTML `font` element 101 tagFooter, ## the HTML `footer` element 102 tagForm, ## the HTML `form` element 103 tagFrame, ## the HTML `frame` element 104 tagFrameset, ## the deprecated HTML `frameset` element 105 tagH1, ## the HTML `h1` element 106 tagH2, ## the HTML `h2` element 107 tagH3, ## the HTML `h3` element 108 tagH4, ## the HTML `h4` element 109 tagH5, ## the HTML `h5` element 110 tagH6, ## the HTML `h6` element 111 tagHead, ## the HTML `head` element 112 tagHeader, ## the HTML `header` element 113 tagHgroup, ## the HTML `hgroup` element 114 tagHtml, ## the HTML `html` element 115 tagHr, ## the HTML `hr` element 116 tagI, ## the HTML `i` element 117 tagIframe, ## the deprecated HTML `iframe` element 118 tagImg, ## the HTML `img` element 119 tagInput, ## the HTML `input` element 120 tagIns, ## the HTML `ins` element 121 tagIsindex, ## the deprecated HTML `isindex` element 122 tagKbd, ## the HTML `kbd` element 123 tagKeygen, ## the HTML `keygen` element 124 tagLabel, ## the HTML `label` element 125 tagLegend, ## the HTML `legend` element 126 tagLi, ## the HTML `li` element 127 tagLink, ## the HTML `link` element 128 tagMap, ## the HTML `map` element 129 tagMark, ## the HTML `mark` element 130 tagMenu, ## the deprecated HTML `menu` element 131 tagMeta, ## the HTML `meta` element 132 tagMeter, ## the HTML `meter` element 133 tagNav, ## the HTML `nav` element 134 tagNobr, ## the deprecated HTML `nobr` element 135 tagNoframes, ## the deprecated HTML `noframes` element 136 tagNoscript, ## the HTML `noscript` element 137 tagObject, ## the HTML `object` element 138 tagOl, ## the HTML `ol` element 139 tagOptgroup, ## the HTML `optgroup` element 140 tagOption, ## the HTML `option` element 141 tagOutput, ## the HTML `output` element 142 tagP, ## the HTML `p` element 143 tagParam, ## the HTML `param` element 144 tagPre, ## the HTML `pre` element 145 tagProgress, ## the HTML `progress` element 146 tagQ, ## the HTML `q` element 147 tagRp, ## the HTML `rp` element 148 tagRt, ## the HTML `rt` element 149 tagRuby, ## the HTML `ruby` element 150 tagS, ## the deprecated HTML `s` element 151 tagSamp, ## the HTML `samp` element 152 tagScript, ## the HTML `script` element 153 tagSection, ## the HTML `section` element 154 tagSelect, ## the HTML `select` element 155 tagSmall, ## the HTML `small` element 156 tagSource, ## the HTML `source` element 157 tagSpan, ## the HTML `span` element 158 tagStrike, ## the deprecated HTML `strike` element 159 tagStrong, ## the HTML `strong` element 160 tagStyle, ## the HTML `style` element 161 tagSub, ## the HTML `sub` element 162 tagSummary, ## the HTML `summary` element 163 tagSup, ## the HTML `sup` element 164 tagTable, ## the HTML `table` element 165 tagTbody, ## the HTML `tbody` element 166 tagTd, ## the HTML `td` element 167 tagTextarea, ## the HTML `textarea` element 168 tagTfoot, ## the HTML `tfoot` element 169 tagTh, ## the HTML `th` element 170 tagThead, ## the HTML `thead` element 171 tagTime, ## the HTML `time` element 172 tagTitle, ## the HTML `title` element 173 tagTr, ## the HTML `tr` element 174 tagTrack, ## the HTML `track` element 175 tagTt, ## the HTML `tt` element 176 tagU, ## the deprecated HTML `u` element 177 tagUl, ## the HTML `ul` element 178 tagVar, ## the HTML `var` element 179 tagVideo, ## the HTML `video` element 180 tagWbr ## the HTML `wbr` element 181 182const 183 tagToStr* = [ 184 "a", "abbr", "acronym", "address", "applet", "area", "article", 185 "aside", "audio", 186 "b", "base", "basefont", "bdi", "bdo", "big", "blockquote", "body", 187 "br", "button", "canvas", "caption", "center", "cite", "code", 188 "col", "colgroup", "command", 189 "datalist", "dd", "del", "details", "dfn", "dialog", "div", 190 "dir", "dl", "dt", "em", "embed", "fieldset", 191 "figcaption", "figure", "font", "footer", 192 "form", "frame", "frameset", "h1", "h2", "h3", 193 "h4", "h5", "h6", "head", "header", "hgroup", "html", "hr", 194 "i", "iframe", "img", "input", "ins", "isindex", 195 "kbd", "keygen", "label", "legend", "li", "link", "map", "mark", 196 "menu", "meta", "meter", "nav", "nobr", "noframes", "noscript", 197 "object", "ol", 198 "optgroup", "option", "output", "p", "param", "pre", "progress", "q", 199 "rp", "rt", "ruby", "s", "samp", "script", "section", "select", "small", 200 "source", "span", "strike", "strong", "style", 201 "sub", "summary", "sup", "table", 202 "tbody", "td", "textarea", "tfoot", "th", "thead", "time", 203 "title", "tr", "track", "tt", "u", "ul", "var", "video", "wbr"] 204 InlineTags* = {tagA, tagAbbr, tagAcronym, tagApplet, tagB, tagBasefont, 205 tagBdo, tagBig, tagBr, tagButton, tagCite, tagCode, tagDel, tagDfn, 206 tagEm, tagFont, tagI, tagImg, tagIns, tagInput, tagIframe, tagKbd, 207 tagLabel, tagMap, tagObject, tagQ, tagSamp, tagScript, tagSelect, 208 tagSmall, tagSpan, tagStrong, tagSub, tagSup, tagTextarea, tagTt, 209 tagVar, tagApplet, tagBasefont, tagFont, tagIframe, tagU, tagS, 210 tagStrike, tagWbr} 211 BlockTags* = {tagAddress, tagBlockquote, tagCenter, tagDel, tagDir, tagDiv, 212 tagDl, tagFieldset, tagForm, tagH1, tagH2, tagH3, tagH4, 213 tagH5, tagH6, tagHr, tagIns, tagIsindex, tagMenu, tagNoframes, tagNoscript, 214 tagOl, tagP, tagPre, tagTable, tagUl, tagCenter, tagDir, tagIsindex, 215 tagMenu, tagNoframes} 216 SingleTags* = {tagArea, tagBase, tagBasefont, 217 tagBr, tagCol, tagFrame, tagHr, tagImg, tagIsindex, 218 tagLink, tagMeta, tagParam, tagWbr, tagSource} 219 220proc allLower(s: string): bool = 221 for c in s: 222 if c < 'a' or c > 'z': return false 223 return true 224 225proc toHtmlTag(s: string): HtmlTag = 226 case s 227 of "a": tagA 228 of "abbr": tagAbbr 229 of "acronym": tagAcronym 230 of "address": tagAddress 231 of "applet": tagApplet 232 of "area": tagArea 233 of "article": tagArticle 234 of "aside": tagAside 235 of "audio": tagAudio 236 of "b": tagB 237 of "base": tagBase 238 of "basefont": tagBasefont 239 of "bdi": tagBdi 240 of "bdo": tagBdo 241 of "big": tagBig 242 of "blockquote": tagBlockquote 243 of "body": tagBody 244 of "br": tagBr 245 of "button": tagButton 246 of "canvas": tagCanvas 247 of "caption": tagCaption 248 of "center": tagCenter 249 of "cite": tagCite 250 of "code": tagCode 251 of "col": tagCol 252 of "colgroup": tagColgroup 253 of "command": tagCommand 254 of "datalist": tagDatalist 255 of "dd": tagDd 256 of "del": tagDel 257 of "details": tagDetails 258 of "dfn": tagDfn 259 of "dialog": tagDialog 260 of "div": tagDiv 261 of "dir": tagDir 262 of "dl": tagDl 263 of "dt": tagDt 264 of "em": tagEm 265 of "embed": tagEmbed 266 of "fieldset": tagFieldset 267 of "figcaption": tagFigcaption 268 of "figure": tagFigure 269 of "font": tagFont 270 of "footer": tagFooter 271 of "form": tagForm 272 of "frame": tagFrame 273 of "frameset": tagFrameset 274 of "h1": tagH1 275 of "h2": tagH2 276 of "h3": tagH3 277 of "h4": tagH4 278 of "h5": tagH5 279 of "h6": tagH6 280 of "head": tagHead 281 of "header": tagHeader 282 of "hgroup": tagHgroup 283 of "html": tagHtml 284 of "hr": tagHr 285 of "i": tagI 286 of "iframe": tagIframe 287 of "img": tagImg 288 of "input": tagInput 289 of "ins": tagIns 290 of "isindex": tagIsindex 291 of "kbd": tagKbd 292 of "keygen": tagKeygen 293 of "label": tagLabel 294 of "legend": tagLegend 295 of "li": tagLi 296 of "link": tagLink 297 of "map": tagMap 298 of "mark": tagMark 299 of "menu": tagMenu 300 of "meta": tagMeta 301 of "meter": tagMeter 302 of "nav": tagNav 303 of "nobr": tagNobr 304 of "noframes": tagNoframes 305 of "noscript": tagNoscript 306 of "object": tagObject 307 of "ol": tagOl 308 of "optgroup": tagOptgroup 309 of "option": tagOption 310 of "output": tagOutput 311 of "p": tagP 312 of "param": tagParam 313 of "pre": tagPre 314 of "progress": tagProgress 315 of "q": tagQ 316 of "rp": tagRp 317 of "rt": tagRt 318 of "ruby": tagRuby 319 of "s": tagS 320 of "samp": tagSamp 321 of "script": tagScript 322 of "section": tagSection 323 of "select": tagSelect 324 of "small": tagSmall 325 of "source": tagSource 326 of "span": tagSpan 327 of "strike": tagStrike 328 of "strong": tagStrong 329 of "style": tagStyle 330 of "sub": tagSub 331 of "summary": tagSummary 332 of "sup": tagSup 333 of "table": tagTable 334 of "tbody": tagTbody 335 of "td": tagTd 336 of "textarea": tagTextarea 337 of "tfoot": tagTfoot 338 of "th": tagTh 339 of "thead": tagThead 340 of "time": tagTime 341 of "title": tagTitle 342 of "tr": tagTr 343 of "track": tagTrack 344 of "tt": tagTt 345 of "u": tagU 346 of "ul": tagUl 347 of "var": tagVar 348 of "video": tagVideo 349 of "wbr": tagWbr 350 else: tagUnknown 351 352 353proc htmlTag*(n: XmlNode): HtmlTag = 354 ## Gets `n`'s tag as a `HtmlTag`. 355 if n.clientData == 0: 356 n.clientData = toHtmlTag(n.tag).ord 357 result = HtmlTag(n.clientData) 358 359proc htmlTag*(s: string): HtmlTag = 360 ## Converts `s` to a `HtmlTag`. If `s` is no HTML tag, `tagUnknown` is 361 ## returned. 362 let s = if allLower(s): s else: toLowerAscii(s) 363 result = toHtmlTag(s) 364 365proc runeToEntity*(rune: Rune): string = 366 ## converts a Rune to its numeric HTML entity equivalent. 367 runnableExamples: 368 import std/unicode 369 doAssert runeToEntity(Rune(0)) == "" 370 doAssert runeToEntity(Rune(-1)) == "" 371 doAssert runeToEntity("Ü".runeAt(0)) == "#220" 372 doAssert runeToEntity("∈".runeAt(0)) == "#8712" 373 if rune.ord <= 0: result = "" 374 else: result = '#' & $rune.ord 375 376proc entityToRune*(entity: string): Rune = 377 ## Converts an HTML entity name like `Ü` or values like `Ü` 378 ## or `Ü` to its UTF-8 equivalent. 379 ## Rune(0) is returned if the entity name is unknown. 380 runnableExamples: 381 import std/unicode 382 doAssert entityToRune("") == Rune(0) 383 doAssert entityToRune("a") == Rune(0) 384 doAssert entityToRune("gt") == ">".runeAt(0) 385 doAssert entityToRune("Uuml") == "Ü".runeAt(0) 386 doAssert entityToRune("quest") == "?".runeAt(0) 387 doAssert entityToRune("#x0003F") == "?".runeAt(0) 388 if entity.len < 2: return # smallest entity has length 2 389 if entity[0] == '#': 390 var runeValue = 0 391 case entity[1] 392 of '0'..'9': 393 try: runeValue = parseInt(entity[1..^1]) 394 except: discard 395 of 'x', 'X': # not case sensitive here 396 try: runeValue = parseHexInt(entity[2..^1]) 397 except: discard 398 else: discard # other entities are not defined with prefix `#` 399 if runeValue notin 0..0x10FFFF: runeValue = 0 # only return legal values 400 return Rune(runeValue) 401 case entity # entity names are case sensitive 402 of "Tab": Rune(0x00009) 403 of "NewLine": Rune(0x0000A) 404 of "excl": Rune(0x00021) 405 of "quot", "QUOT": Rune(0x00022) 406 of "num": Rune(0x00023) 407 of "dollar": Rune(0x00024) 408 of "percnt": Rune(0x00025) 409 of "amp", "AMP": Rune(0x00026) 410 of "apos": Rune(0x00027) 411 of "lpar": Rune(0x00028) 412 of "rpar": Rune(0x00029) 413 of "ast", "midast": Rune(0x0002A) 414 of "plus": Rune(0x0002B) 415 of "comma": Rune(0x0002C) 416 of "period": Rune(0x0002E) 417 of "sol": Rune(0x0002F) 418 of "colon": Rune(0x0003A) 419 of "semi": Rune(0x0003B) 420 of "lt", "LT": Rune(0x0003C) 421 of "equals": Rune(0x0003D) 422 of "gt", "GT": Rune(0x0003E) 423 of "quest": Rune(0x0003F) 424 of "commat": Rune(0x00040) 425 of "lsqb", "lbrack": Rune(0x0005B) 426 of "bsol": Rune(0x0005C) 427 of "rsqb", "rbrack": Rune(0x0005D) 428 of "Hat": Rune(0x0005E) 429 of "lowbar": Rune(0x0005F) 430 of "grave", "DiacriticalGrave": Rune(0x00060) 431 of "lcub", "lbrace": Rune(0x0007B) 432 of "verbar", "vert", "VerticalLine": Rune(0x0007C) 433 of "rcub", "rbrace": Rune(0x0007D) 434 of "nbsp", "NonBreakingSpace": Rune(0x000A0) 435 of "iexcl": Rune(0x000A1) 436 of "cent": Rune(0x000A2) 437 of "pound": Rune(0x000A3) 438 of "curren": Rune(0x000A4) 439 of "yen": Rune(0x000A5) 440 of "brvbar": Rune(0x000A6) 441 of "sect": Rune(0x000A7) 442 of "Dot", "die", "DoubleDot", "uml": Rune(0x000A8) 443 of "copy", "COPY": Rune(0x000A9) 444 of "ordf": Rune(0x000AA) 445 of "laquo": Rune(0x000AB) 446 of "not": Rune(0x000AC) 447 of "shy": Rune(0x000AD) 448 of "reg", "circledR", "REG": Rune(0x000AE) 449 of "macr", "OverBar", "strns": Rune(0x000AF) 450 of "deg": Rune(0x000B0) 451 of "plusmn", "pm", "PlusMinus": Rune(0x000B1) 452 of "sup2": Rune(0x000B2) 453 of "sup3": Rune(0x000B3) 454 of "acute", "DiacriticalAcute": Rune(0x000B4) 455 of "micro": Rune(0x000B5) 456 of "para": Rune(0x000B6) 457 of "middot", "centerdot", "CenterDot": Rune(0x000B7) 458 of "cedil", "Cedilla": Rune(0x000B8) 459 of "sup1": Rune(0x000B9) 460 of "ordm": Rune(0x000BA) 461 of "raquo": Rune(0x000BB) 462 of "frac14": Rune(0x000BC) 463 of "frac12", "half": Rune(0x000BD) 464 of "frac34": Rune(0x000BE) 465 of "iquest": Rune(0x000BF) 466 of "Agrave": Rune(0x000C0) 467 of "Aacute": Rune(0x000C1) 468 of "Acirc": Rune(0x000C2) 469 of "Atilde": Rune(0x000C3) 470 of "Auml": Rune(0x000C4) 471 of "Aring": Rune(0x000C5) 472 of "AElig": Rune(0x000C6) 473 of "Ccedil": Rune(0x000C7) 474 of "Egrave": Rune(0x000C8) 475 of "Eacute": Rune(0x000C9) 476 of "Ecirc": Rune(0x000CA) 477 of "Euml": Rune(0x000CB) 478 of "Igrave": Rune(0x000CC) 479 of "Iacute": Rune(0x000CD) 480 of "Icirc": Rune(0x000CE) 481 of "Iuml": Rune(0x000CF) 482 of "ETH": Rune(0x000D0) 483 of "Ntilde": Rune(0x000D1) 484 of "Ograve": Rune(0x000D2) 485 of "Oacute": Rune(0x000D3) 486 of "Ocirc": Rune(0x000D4) 487 of "Otilde": Rune(0x000D5) 488 of "Ouml": Rune(0x000D6) 489 of "times": Rune(0x000D7) 490 of "Oslash": Rune(0x000D8) 491 of "Ugrave": Rune(0x000D9) 492 of "Uacute": Rune(0x000DA) 493 of "Ucirc": Rune(0x000DB) 494 of "Uuml": Rune(0x000DC) 495 of "Yacute": Rune(0x000DD) 496 of "THORN": Rune(0x000DE) 497 of "szlig": Rune(0x000DF) 498 of "agrave": Rune(0x000E0) 499 of "aacute": Rune(0x000E1) 500 of "acirc": Rune(0x000E2) 501 of "atilde": Rune(0x000E3) 502 of "auml": Rune(0x000E4) 503 of "aring": Rune(0x000E5) 504 of "aelig": Rune(0x000E6) 505 of "ccedil": Rune(0x000E7) 506 of "egrave": Rune(0x000E8) 507 of "eacute": Rune(0x000E9) 508 of "ecirc": Rune(0x000EA) 509 of "euml": Rune(0x000EB) 510 of "igrave": Rune(0x000EC) 511 of "iacute": Rune(0x000ED) 512 of "icirc": Rune(0x000EE) 513 of "iuml": Rune(0x000EF) 514 of "eth": Rune(0x000F0) 515 of "ntilde": Rune(0x000F1) 516 of "ograve": Rune(0x000F2) 517 of "oacute": Rune(0x000F3) 518 of "ocirc": Rune(0x000F4) 519 of "otilde": Rune(0x000F5) 520 of "ouml": Rune(0x000F6) 521 of "divide", "div": Rune(0x000F7) 522 of "oslash": Rune(0x000F8) 523 of "ugrave": Rune(0x000F9) 524 of "uacute": Rune(0x000FA) 525 of "ucirc": Rune(0x000FB) 526 of "uuml": Rune(0x000FC) 527 of "yacute": Rune(0x000FD) 528 of "thorn": Rune(0x000FE) 529 of "yuml": Rune(0x000FF) 530 of "Amacr": Rune(0x00100) 531 of "amacr": Rune(0x00101) 532 of "Abreve": Rune(0x00102) 533 of "abreve": Rune(0x00103) 534 of "Aogon": Rune(0x00104) 535 of "aogon": Rune(0x00105) 536 of "Cacute": Rune(0x00106) 537 of "cacute": Rune(0x00107) 538 of "Ccirc": Rune(0x00108) 539 of "ccirc": Rune(0x00109) 540 of "Cdot": Rune(0x0010A) 541 of "cdot": Rune(0x0010B) 542 of "Ccaron": Rune(0x0010C) 543 of "ccaron": Rune(0x0010D) 544 of "Dcaron": Rune(0x0010E) 545 of "dcaron": Rune(0x0010F) 546 of "Dstrok": Rune(0x00110) 547 of "dstrok": Rune(0x00111) 548 of "Emacr": Rune(0x00112) 549 of "emacr": Rune(0x00113) 550 of "Edot": Rune(0x00116) 551 of "edot": Rune(0x00117) 552 of "Eogon": Rune(0x00118) 553 of "eogon": Rune(0x00119) 554 of "Ecaron": Rune(0x0011A) 555 of "ecaron": Rune(0x0011B) 556 of "Gcirc": Rune(0x0011C) 557 of "gcirc": Rune(0x0011D) 558 of "Gbreve": Rune(0x0011E) 559 of "gbreve": Rune(0x0011F) 560 of "Gdot": Rune(0x00120) 561 of "gdot": Rune(0x00121) 562 of "Gcedil": Rune(0x00122) 563 of "Hcirc": Rune(0x00124) 564 of "hcirc": Rune(0x00125) 565 of "Hstrok": Rune(0x00126) 566 of "hstrok": Rune(0x00127) 567 of "Itilde": Rune(0x00128) 568 of "itilde": Rune(0x00129) 569 of "Imacr": Rune(0x0012A) 570 of "imacr": Rune(0x0012B) 571 of "Iogon": Rune(0x0012E) 572 of "iogon": Rune(0x0012F) 573 of "Idot": Rune(0x00130) 574 of "imath", "inodot": Rune(0x00131) 575 of "IJlig": Rune(0x00132) 576 of "ijlig": Rune(0x00133) 577 of "Jcirc": Rune(0x00134) 578 of "jcirc": Rune(0x00135) 579 of "Kcedil": Rune(0x00136) 580 of "kcedil": Rune(0x00137) 581 of "kgreen": Rune(0x00138) 582 of "Lacute": Rune(0x00139) 583 of "lacute": Rune(0x0013A) 584 of "Lcedil": Rune(0x0013B) 585 of "lcedil": Rune(0x0013C) 586 of "Lcaron": Rune(0x0013D) 587 of "lcaron": Rune(0x0013E) 588 of "Lmidot": Rune(0x0013F) 589 of "lmidot": Rune(0x00140) 590 of "Lstrok": Rune(0x00141) 591 of "lstrok": Rune(0x00142) 592 of "Nacute": Rune(0x00143) 593 of "nacute": Rune(0x00144) 594 of "Ncedil": Rune(0x00145) 595 of "ncedil": Rune(0x00146) 596 of "Ncaron": Rune(0x00147) 597 of "ncaron": Rune(0x00148) 598 of "napos": Rune(0x00149) 599 of "ENG": Rune(0x0014A) 600 of "eng": Rune(0x0014B) 601 of "Omacr": Rune(0x0014C) 602 of "omacr": Rune(0x0014D) 603 of "Odblac": Rune(0x00150) 604 of "odblac": Rune(0x00151) 605 of "OElig": Rune(0x00152) 606 of "oelig": Rune(0x00153) 607 of "Racute": Rune(0x00154) 608 of "racute": Rune(0x00155) 609 of "Rcedil": Rune(0x00156) 610 of "rcedil": Rune(0x00157) 611 of "Rcaron": Rune(0x00158) 612 of "rcaron": Rune(0x00159) 613 of "Sacute": Rune(0x0015A) 614 of "sacute": Rune(0x0015B) 615 of "Scirc": Rune(0x0015C) 616 of "scirc": Rune(0x0015D) 617 of "Scedil": Rune(0x0015E) 618 of "scedil": Rune(0x0015F) 619 of "Scaron": Rune(0x00160) 620 of "scaron": Rune(0x00161) 621 of "Tcedil": Rune(0x00162) 622 of "tcedil": Rune(0x00163) 623 of "Tcaron": Rune(0x00164) 624 of "tcaron": Rune(0x00165) 625 of "Tstrok": Rune(0x00166) 626 of "tstrok": Rune(0x00167) 627 of "Utilde": Rune(0x00168) 628 of "utilde": Rune(0x00169) 629 of "Umacr": Rune(0x0016A) 630 of "umacr": Rune(0x0016B) 631 of "Ubreve": Rune(0x0016C) 632 of "ubreve": Rune(0x0016D) 633 of "Uring": Rune(0x0016E) 634 of "uring": Rune(0x0016F) 635 of "Udblac": Rune(0x00170) 636 of "udblac": Rune(0x00171) 637 of "Uogon": Rune(0x00172) 638 of "uogon": Rune(0x00173) 639 of "Wcirc": Rune(0x00174) 640 of "wcirc": Rune(0x00175) 641 of "Ycirc": Rune(0x00176) 642 of "ycirc": Rune(0x00177) 643 of "Yuml": Rune(0x00178) 644 of "Zacute": Rune(0x00179) 645 of "zacute": Rune(0x0017A) 646 of "Zdot": Rune(0x0017B) 647 of "zdot": Rune(0x0017C) 648 of "Zcaron": Rune(0x0017D) 649 of "zcaron": Rune(0x0017E) 650 of "fnof": Rune(0x00192) 651 of "imped": Rune(0x001B5) 652 of "gacute": Rune(0x001F5) 653 of "jmath": Rune(0x00237) 654 of "circ": Rune(0x002C6) 655 of "caron", "Hacek": Rune(0x002C7) 656 of "breve", "Breve": Rune(0x002D8) 657 of "dot", "DiacriticalDot": Rune(0x002D9) 658 of "ring": Rune(0x002DA) 659 of "ogon": Rune(0x002DB) 660 of "tilde", "DiacriticalTilde": Rune(0x002DC) 661 of "dblac", "DiacriticalDoubleAcute": Rune(0x002DD) 662 of "DownBreve": Rune(0x00311) 663 of "UnderBar": Rune(0x00332) 664 of "Alpha": Rune(0x00391) 665 of "Beta": Rune(0x00392) 666 of "Gamma": Rune(0x00393) 667 of "Delta": Rune(0x00394) 668 of "Epsilon": Rune(0x00395) 669 of "Zeta": Rune(0x00396) 670 of "Eta": Rune(0x00397) 671 of "Theta": Rune(0x00398) 672 of "Iota": Rune(0x00399) 673 of "Kappa": Rune(0x0039A) 674 of "Lambda": Rune(0x0039B) 675 of "Mu": Rune(0x0039C) 676 of "Nu": Rune(0x0039D) 677 of "Xi": Rune(0x0039E) 678 of "Omicron": Rune(0x0039F) 679 of "Pi": Rune(0x003A0) 680 of "Rho": Rune(0x003A1) 681 of "Sigma": Rune(0x003A3) 682 of "Tau": Rune(0x003A4) 683 of "Upsilon": Rune(0x003A5) 684 of "Phi": Rune(0x003A6) 685 of "Chi": Rune(0x003A7) 686 of "Psi": Rune(0x003A8) 687 of "Omega": Rune(0x003A9) 688 of "alpha": Rune(0x003B1) 689 of "beta": Rune(0x003B2) 690 of "gamma": Rune(0x003B3) 691 of "delta": Rune(0x003B4) 692 of "epsiv", "varepsilon", "epsilon": Rune(0x003B5) 693 of "zeta": Rune(0x003B6) 694 of "eta": Rune(0x003B7) 695 of "theta": Rune(0x003B8) 696 of "iota": Rune(0x003B9) 697 of "kappa": Rune(0x003BA) 698 of "lambda": Rune(0x003BB) 699 of "mu": Rune(0x003BC) 700 of "nu": Rune(0x003BD) 701 of "xi": Rune(0x003BE) 702 of "omicron": Rune(0x003BF) 703 of "pi": Rune(0x003C0) 704 of "rho": Rune(0x003C1) 705 of "sigmav", "varsigma", "sigmaf": Rune(0x003C2) 706 of "sigma": Rune(0x003C3) 707 of "tau": Rune(0x003C4) 708 of "upsi", "upsilon": Rune(0x003C5) 709 of "phi", "phiv", "varphi": Rune(0x003C6) 710 of "chi": Rune(0x003C7) 711 of "psi": Rune(0x003C8) 712 of "omega": Rune(0x003C9) 713 of "thetav", "vartheta", "thetasym": Rune(0x003D1) 714 of "Upsi", "upsih": Rune(0x003D2) 715 of "straightphi": Rune(0x003D5) 716 of "piv", "varpi": Rune(0x003D6) 717 of "Gammad": Rune(0x003DC) 718 of "gammad", "digamma": Rune(0x003DD) 719 of "kappav", "varkappa": Rune(0x003F0) 720 of "rhov", "varrho": Rune(0x003F1) 721 of "epsi", "straightepsilon": Rune(0x003F5) 722 of "bepsi", "backepsilon": Rune(0x003F6) 723 of "IOcy": Rune(0x00401) 724 of "DJcy": Rune(0x00402) 725 of "GJcy": Rune(0x00403) 726 of "Jukcy": Rune(0x00404) 727 of "DScy": Rune(0x00405) 728 of "Iukcy": Rune(0x00406) 729 of "YIcy": Rune(0x00407) 730 of "Jsercy": Rune(0x00408) 731 of "LJcy": Rune(0x00409) 732 of "NJcy": Rune(0x0040A) 733 of "TSHcy": Rune(0x0040B) 734 of "KJcy": Rune(0x0040C) 735 of "Ubrcy": Rune(0x0040E) 736 of "DZcy": Rune(0x0040F) 737 of "Acy": Rune(0x00410) 738 of "Bcy": Rune(0x00411) 739 of "Vcy": Rune(0x00412) 740 of "Gcy": Rune(0x00413) 741 of "Dcy": Rune(0x00414) 742 of "IEcy": Rune(0x00415) 743 of "ZHcy": Rune(0x00416) 744 of "Zcy": Rune(0x00417) 745 of "Icy": Rune(0x00418) 746 of "Jcy": Rune(0x00419) 747 of "Kcy": Rune(0x0041A) 748 of "Lcy": Rune(0x0041B) 749 of "Mcy": Rune(0x0041C) 750 of "Ncy": Rune(0x0041D) 751 of "Ocy": Rune(0x0041E) 752 of "Pcy": Rune(0x0041F) 753 of "Rcy": Rune(0x00420) 754 of "Scy": Rune(0x00421) 755 of "Tcy": Rune(0x00422) 756 of "Ucy": Rune(0x00423) 757 of "Fcy": Rune(0x00424) 758 of "KHcy": Rune(0x00425) 759 of "TScy": Rune(0x00426) 760 of "CHcy": Rune(0x00427) 761 of "SHcy": Rune(0x00428) 762 of "SHCHcy": Rune(0x00429) 763 of "HARDcy": Rune(0x0042A) 764 of "Ycy": Rune(0x0042B) 765 of "SOFTcy": Rune(0x0042C) 766 of "Ecy": Rune(0x0042D) 767 of "YUcy": Rune(0x0042E) 768 of "YAcy": Rune(0x0042F) 769 of "acy": Rune(0x00430) 770 of "bcy": Rune(0x00431) 771 of "vcy": Rune(0x00432) 772 of "gcy": Rune(0x00433) 773 of "dcy": Rune(0x00434) 774 of "iecy": Rune(0x00435) 775 of "zhcy": Rune(0x00436) 776 of "zcy": Rune(0x00437) 777 of "icy": Rune(0x00438) 778 of "jcy": Rune(0x00439) 779 of "kcy": Rune(0x0043A) 780 of "lcy": Rune(0x0043B) 781 of "mcy": Rune(0x0043C) 782 of "ncy": Rune(0x0043D) 783 of "ocy": Rune(0x0043E) 784 of "pcy": Rune(0x0043F) 785 of "rcy": Rune(0x00440) 786 of "scy": Rune(0x00441) 787 of "tcy": Rune(0x00442) 788 of "ucy": Rune(0x00443) 789 of "fcy": Rune(0x00444) 790 of "khcy": Rune(0x00445) 791 of "tscy": Rune(0x00446) 792 of "chcy": Rune(0x00447) 793 of "shcy": Rune(0x00448) 794 of "shchcy": Rune(0x00449) 795 of "hardcy": Rune(0x0044A) 796 of "ycy": Rune(0x0044B) 797 of "softcy": Rune(0x0044C) 798 of "ecy": Rune(0x0044D) 799 of "yucy": Rune(0x0044E) 800 of "yacy": Rune(0x0044F) 801 of "iocy": Rune(0x00451) 802 of "djcy": Rune(0x00452) 803 of "gjcy": Rune(0x00453) 804 of "jukcy": Rune(0x00454) 805 of "dscy": Rune(0x00455) 806 of "iukcy": Rune(0x00456) 807 of "yicy": Rune(0x00457) 808 of "jsercy": Rune(0x00458) 809 of "ljcy": Rune(0x00459) 810 of "njcy": Rune(0x0045A) 811 of "tshcy": Rune(0x0045B) 812 of "kjcy": Rune(0x0045C) 813 of "ubrcy": Rune(0x0045E) 814 of "dzcy": Rune(0x0045F) 815 of "ensp": Rune(0x02002) 816 of "emsp": Rune(0x02003) 817 of "emsp13": Rune(0x02004) 818 of "emsp14": Rune(0x02005) 819 of "numsp": Rune(0x02007) 820 of "puncsp": Rune(0x02008) 821 of "thinsp", "ThinSpace": Rune(0x02009) 822 of "hairsp", "VeryThinSpace": Rune(0x0200A) 823 of "ZeroWidthSpace", "NegativeVeryThinSpace", "NegativeThinSpace", 824 "NegativeMediumSpace", "NegativeThickSpace": Rune(0x0200B) 825 of "zwnj": Rune(0x0200C) 826 of "zwj": Rune(0x0200D) 827 of "lrm": Rune(0x0200E) 828 of "rlm": Rune(0x0200F) 829 of "hyphen", "dash": Rune(0x02010) 830 of "ndash": Rune(0x02013) 831 of "mdash": Rune(0x02014) 832 of "horbar": Rune(0x02015) 833 of "Verbar", "Vert": Rune(0x02016) 834 of "lsquo", "OpenCurlyQuote": Rune(0x02018) 835 of "rsquo", "rsquor", "CloseCurlyQuote": Rune(0x02019) 836 of "lsquor", "sbquo": Rune(0x0201A) 837 of "ldquo", "OpenCurlyDoubleQuote": Rune(0x0201C) 838 of "rdquo", "rdquor", "CloseCurlyDoubleQuote": Rune(0x0201D) 839 of "ldquor", "bdquo": Rune(0x0201E) 840 of "dagger": Rune(0x02020) 841 of "Dagger", "ddagger": Rune(0x02021) 842 of "bull", "bullet": Rune(0x02022) 843 of "nldr": Rune(0x02025) 844 of "hellip", "mldr": Rune(0x02026) 845 of "permil": Rune(0x02030) 846 of "pertenk": Rune(0x02031) 847 of "prime": Rune(0x02032) 848 of "Prime": Rune(0x02033) 849 of "tprime": Rune(0x02034) 850 of "bprime", "backprime": Rune(0x02035) 851 of "lsaquo": Rune(0x02039) 852 of "rsaquo": Rune(0x0203A) 853 of "oline": Rune(0x0203E) 854 of "caret": Rune(0x02041) 855 of "hybull": Rune(0x02043) 856 of "frasl": Rune(0x02044) 857 of "bsemi": Rune(0x0204F) 858 of "qprime": Rune(0x02057) 859 of "MediumSpace": Rune(0x0205F) 860 of "NoBreak": Rune(0x02060) 861 of "ApplyFunction", "af": Rune(0x02061) 862 of "InvisibleTimes", "it": Rune(0x02062) 863 of "InvisibleComma", "ic": Rune(0x02063) 864 of "euro": Rune(0x020AC) 865 of "tdot", "TripleDot": Rune(0x020DB) 866 of "DotDot": Rune(0x020DC) 867 of "Copf", "complexes": Rune(0x02102) 868 of "incare": Rune(0x02105) 869 of "gscr": Rune(0x0210A) 870 of "hamilt", "HilbertSpace", "Hscr": Rune(0x0210B) 871 of "Hfr", "Poincareplane": Rune(0x0210C) 872 of "quaternions", "Hopf": Rune(0x0210D) 873 of "planckh": Rune(0x0210E) 874 of "planck", "hbar", "plankv", "hslash": Rune(0x0210F) 875 of "Iscr", "imagline": Rune(0x02110) 876 of "image", "Im", "imagpart", "Ifr": Rune(0x02111) 877 of "Lscr", "lagran", "Laplacetrf": Rune(0x02112) 878 of "ell": Rune(0x02113) 879 of "Nopf", "naturals": Rune(0x02115) 880 of "numero": Rune(0x02116) 881 of "copysr": Rune(0x02117) 882 of "weierp", "wp": Rune(0x02118) 883 of "Popf", "primes": Rune(0x02119) 884 of "rationals", "Qopf": Rune(0x0211A) 885 of "Rscr", "realine": Rune(0x0211B) 886 of "real", "Re", "realpart", "Rfr": Rune(0x0211C) 887 of "reals", "Ropf": Rune(0x0211D) 888 of "rx": Rune(0x0211E) 889 of "trade", "TRADE": Rune(0x02122) 890 of "integers", "Zopf": Rune(0x02124) 891 of "ohm": Rune(0x02126) 892 of "mho": Rune(0x02127) 893 of "Zfr", "zeetrf": Rune(0x02128) 894 of "iiota": Rune(0x02129) 895 of "angst": Rune(0x0212B) 896 of "bernou", "Bernoullis", "Bscr": Rune(0x0212C) 897 of "Cfr", "Cayleys": Rune(0x0212D) 898 of "escr": Rune(0x0212F) 899 of "Escr", "expectation": Rune(0x02130) 900 of "Fscr", "Fouriertrf": Rune(0x02131) 901 of "phmmat", "Mellintrf", "Mscr": Rune(0x02133) 902 of "order", "orderof", "oscr": Rune(0x02134) 903 of "alefsym", "aleph": Rune(0x02135) 904 of "beth": Rune(0x02136) 905 of "gimel": Rune(0x02137) 906 of "daleth": Rune(0x02138) 907 of "CapitalDifferentialD", "DD": Rune(0x02145) 908 of "DifferentialD", "dd": Rune(0x02146) 909 of "ExponentialE", "exponentiale", "ee": Rune(0x02147) 910 of "ImaginaryI", "ii": Rune(0x02148) 911 of "frac13": Rune(0x02153) 912 of "frac23": Rune(0x02154) 913 of "frac15": Rune(0x02155) 914 of "frac25": Rune(0x02156) 915 of "frac35": Rune(0x02157) 916 of "frac45": Rune(0x02158) 917 of "frac16": Rune(0x02159) 918 of "frac56": Rune(0x0215A) 919 of "frac18": Rune(0x0215B) 920 of "frac38": Rune(0x0215C) 921 of "frac58": Rune(0x0215D) 922 of "frac78": Rune(0x0215E) 923 of "larr", "leftarrow", "LeftArrow", "slarr", 924 "ShortLeftArrow": Rune(0x02190) 925 of "uarr", "uparrow", "UpArrow", "ShortUpArrow": Rune(0x02191) 926 of "rarr", "rightarrow", "RightArrow", "srarr", 927 "ShortRightArrow": Rune(0x02192) 928 of "darr", "downarrow", "DownArrow", 929 "ShortDownArrow": Rune(0x02193) 930 of "harr", "leftrightarrow", "LeftRightArrow": Rune(0x02194) 931 of "varr", "updownarrow", "UpDownArrow": Rune(0x02195) 932 of "nwarr", "UpperLeftArrow", "nwarrow": Rune(0x02196) 933 of "nearr", "UpperRightArrow", "nearrow": Rune(0x02197) 934 of "searr", "searrow", "LowerRightArrow": Rune(0x02198) 935 of "swarr", "swarrow", "LowerLeftArrow": Rune(0x02199) 936 of "nlarr", "nleftarrow": Rune(0x0219A) 937 of "nrarr", "nrightarrow": Rune(0x0219B) 938 of "rarrw", "rightsquigarrow": Rune(0x0219D) 939 of "Larr", "twoheadleftarrow": Rune(0x0219E) 940 of "Uarr": Rune(0x0219F) 941 of "Rarr", "twoheadrightarrow": Rune(0x021A0) 942 of "Darr": Rune(0x021A1) 943 of "larrtl", "leftarrowtail": Rune(0x021A2) 944 of "rarrtl", "rightarrowtail": Rune(0x021A3) 945 of "LeftTeeArrow", "mapstoleft": Rune(0x021A4) 946 of "UpTeeArrow", "mapstoup": Rune(0x021A5) 947 of "map", "RightTeeArrow", "mapsto": Rune(0x021A6) 948 of "DownTeeArrow", "mapstodown": Rune(0x021A7) 949 of "larrhk", "hookleftarrow": Rune(0x021A9) 950 of "rarrhk", "hookrightarrow": Rune(0x021AA) 951 of "larrlp", "looparrowleft": Rune(0x021AB) 952 of "rarrlp", "looparrowright": Rune(0x021AC) 953 of "harrw", "leftrightsquigarrow": Rune(0x021AD) 954 of "nharr", "nleftrightarrow": Rune(0x021AE) 955 of "lsh", "Lsh": Rune(0x021B0) 956 of "rsh", "Rsh": Rune(0x021B1) 957 of "ldsh": Rune(0x021B2) 958 of "rdsh": Rune(0x021B3) 959 of "crarr": Rune(0x021B5) 960 of "cularr", "curvearrowleft": Rune(0x021B6) 961 of "curarr", "curvearrowright": Rune(0x021B7) 962 of "olarr", "circlearrowleft": Rune(0x021BA) 963 of "orarr", "circlearrowright": Rune(0x021BB) 964 of "lharu", "LeftVector", "leftharpoonup": Rune(0x021BC) 965 of "lhard", "leftharpoondown", "DownLeftVector": Rune(0x021BD) 966 of "uharr", "upharpoonright", "RightUpVector": Rune(0x021BE) 967 of "uharl", "upharpoonleft", "LeftUpVector": Rune(0x021BF) 968 of "rharu", "RightVector", "rightharpoonup": Rune(0x021C0) 969 of "rhard", "rightharpoondown", "DownRightVector": Rune(0x021C1) 970 of "dharr", "RightDownVector", "downharpoonright": Rune(0x021C2) 971 of "dharl", "LeftDownVector", "downharpoonleft": Rune(0x021C3) 972 of "rlarr", "rightleftarrows", "RightArrowLeftArrow": Rune(0x021C4) 973 of "udarr", "UpArrowDownArrow": Rune(0x021C5) 974 of "lrarr", "leftrightarrows", "LeftArrowRightArrow": Rune(0x021C6) 975 of "llarr", "leftleftarrows": Rune(0x021C7) 976 of "uuarr", "upuparrows": Rune(0x021C8) 977 of "rrarr", "rightrightarrows": Rune(0x021C9) 978 of "ddarr", "downdownarrows": Rune(0x021CA) 979 of "lrhar", "ReverseEquilibrium", 980 "leftrightharpoons": Rune(0x021CB) 981 of "rlhar", "rightleftharpoons", "Equilibrium": Rune(0x021CC) 982 of "nlArr", "nLeftarrow": Rune(0x021CD) 983 of "nhArr", "nLeftrightarrow": Rune(0x021CE) 984 of "nrArr", "nRightarrow": Rune(0x021CF) 985 of "lArr", "Leftarrow", "DoubleLeftArrow": Rune(0x021D0) 986 of "uArr", "Uparrow", "DoubleUpArrow": Rune(0x021D1) 987 of "rArr", "Rightarrow", "Implies", 988 "DoubleRightArrow": Rune(0x021D2) 989 of "dArr", "Downarrow", "DoubleDownArrow": Rune(0x021D3) 990 of "hArr", "Leftrightarrow", "DoubleLeftRightArrow", 991 "iff": Rune(0x021D4) 992 of "vArr", "Updownarrow", "DoubleUpDownArrow": Rune(0x021D5) 993 of "nwArr": Rune(0x021D6) 994 of "neArr": Rune(0x021D7) 995 of "seArr": Rune(0x021D8) 996 of "swArr": Rune(0x021D9) 997 of "lAarr", "Lleftarrow": Rune(0x021DA) 998 of "rAarr", "Rrightarrow": Rune(0x021DB) 999 of "zigrarr": Rune(0x021DD) 1000 of "larrb", "LeftArrowBar": Rune(0x021E4) 1001 of "rarrb", "RightArrowBar": Rune(0x021E5) 1002 of "duarr", "DownArrowUpArrow": Rune(0x021F5) 1003 of "loarr": Rune(0x021FD) 1004 of "roarr": Rune(0x021FE) 1005 of "hoarr": Rune(0x021FF) 1006 of "forall", "ForAll": Rune(0x02200) 1007 of "comp", "complement": Rune(0x02201) 1008 of "part", "PartialD": Rune(0x02202) 1009 of "exist", "Exists": Rune(0x02203) 1010 of "nexist", "NotExists", "nexists": Rune(0x02204) 1011 of "empty", "emptyset", "emptyv", "varnothing": Rune(0x02205) 1012 of "nabla", "Del": Rune(0x02207) 1013 of "isin", "isinv", "Element", "in": Rune(0x02208) 1014 of "notin", "NotElement", "notinva": Rune(0x02209) 1015 of "niv", "ReverseElement", "ni", "SuchThat": Rune(0x0220B) 1016 of "notni", "notniva", "NotReverseElement": Rune(0x0220C) 1017 of "prod", "Product": Rune(0x0220F) 1018 of "coprod", "Coproduct": Rune(0x02210) 1019 of "sum", "Sum": Rune(0x02211) 1020 of "minus": Rune(0x02212) 1021 of "mnplus", "mp", "MinusPlus": Rune(0x02213) 1022 of "plusdo", "dotplus": Rune(0x02214) 1023 of "setmn", "setminus", "Backslash", "ssetmn", 1024 "smallsetminus": Rune(0x02216) 1025 of "lowast": Rune(0x02217) 1026 of "compfn", "SmallCircle": Rune(0x02218) 1027 of "radic", "Sqrt": Rune(0x0221A) 1028 of "prop", "propto", "Proportional", "vprop", 1029 "varpropto": Rune(0x0221D) 1030 of "infin": Rune(0x0221E) 1031 of "angrt": Rune(0x0221F) 1032 of "ang", "angle": Rune(0x02220) 1033 of "angmsd", "measuredangle": Rune(0x02221) 1034 of "angsph": Rune(0x02222) 1035 of "mid", "VerticalBar", "smid", "shortmid": Rune(0x02223) 1036 of "nmid", "NotVerticalBar", "nsmid", "nshortmid": Rune(0x02224) 1037 of "par", "parallel", "DoubleVerticalBar", "spar", 1038 "shortparallel": Rune(0x02225) 1039 of "npar", "nparallel", "NotDoubleVerticalBar", "nspar", 1040 "nshortparallel": Rune(0x02226) 1041 of "and", "wedge": Rune(0x02227) 1042 of "or", "vee": Rune(0x02228) 1043 of "cap": Rune(0x02229) 1044 of "cup": Rune(0x0222A) 1045 of "int", "Integral": Rune(0x0222B) 1046 of "Int": Rune(0x0222C) 1047 of "tint", "iiint": Rune(0x0222D) 1048 of "conint", "oint", "ContourIntegral": Rune(0x0222E) 1049 of "Conint", "DoubleContourIntegral": Rune(0x0222F) 1050 of "Cconint": Rune(0x02230) 1051 of "cwint": Rune(0x02231) 1052 of "cwconint", "ClockwiseContourIntegral": Rune(0x02232) 1053 of "awconint", "CounterClockwiseContourIntegral": Rune(0x02233) 1054 of "there4", "therefore", "Therefore": Rune(0x02234) 1055 of "becaus", "because", "Because": Rune(0x02235) 1056 of "ratio": Rune(0x02236) 1057 of "Colon", "Proportion": Rune(0x02237) 1058 of "minusd", "dotminus": Rune(0x02238) 1059 of "mDDot": Rune(0x0223A) 1060 of "homtht": Rune(0x0223B) 1061 of "sim", "Tilde", "thksim", "thicksim": Rune(0x0223C) 1062 of "bsim", "backsim": Rune(0x0223D) 1063 of "ac", "mstpos": Rune(0x0223E) 1064 of "acd": Rune(0x0223F) 1065 of "wreath", "VerticalTilde", "wr": Rune(0x02240) 1066 of "nsim", "NotTilde": Rune(0x02241) 1067 of "esim", "EqualTilde", "eqsim": Rune(0x02242) 1068 of "sime", "TildeEqual", "simeq": Rune(0x02243) 1069 of "nsime", "nsimeq", "NotTildeEqual": Rune(0x02244) 1070 of "cong", "TildeFullEqual": Rune(0x02245) 1071 of "simne": Rune(0x02246) 1072 of "ncong", "NotTildeFullEqual": Rune(0x02247) 1073 of "asymp", "ap", "TildeTilde", "approx", "thkap", 1074 "thickapprox": Rune(0x02248) 1075 of "nap", "NotTildeTilde", "napprox": Rune(0x02249) 1076 of "ape", "approxeq": Rune(0x0224A) 1077 of "apid": Rune(0x0224B) 1078 of "bcong", "backcong": Rune(0x0224C) 1079 of "asympeq", "CupCap": Rune(0x0224D) 1080 of "bump", "HumpDownHump", "Bumpeq": Rune(0x0224E) 1081 of "bumpe", "HumpEqual", "bumpeq": Rune(0x0224F) 1082 of "esdot", "DotEqual", "doteq": Rune(0x02250) 1083 of "eDot", "doteqdot": Rune(0x02251) 1084 of "efDot", "fallingdotseq": Rune(0x02252) 1085 of "erDot", "risingdotseq": Rune(0x02253) 1086 of "colone", "coloneq", "Assign": Rune(0x02254) 1087 of "ecolon", "eqcolon": Rune(0x02255) 1088 of "ecir", "eqcirc": Rune(0x02256) 1089 of "cire", "circeq": Rune(0x02257) 1090 of "wedgeq": Rune(0x02259) 1091 of "veeeq": Rune(0x0225A) 1092 of "trie", "triangleq": Rune(0x0225C) 1093 of "equest", "questeq": Rune(0x0225F) 1094 of "ne", "NotEqual": Rune(0x02260) 1095 of "equiv", "Congruent": Rune(0x02261) 1096 of "nequiv", "NotCongruent": Rune(0x02262) 1097 of "le", "leq": Rune(0x02264) 1098 of "ge", "GreaterEqual", "geq": Rune(0x02265) 1099 of "lE", "LessFullEqual", "leqq": Rune(0x02266) 1100 of "gE", "GreaterFullEqual", "geqq": Rune(0x02267) 1101 of "lnE", "lneqq": Rune(0x02268) 1102 of "gnE", "gneqq": Rune(0x02269) 1103 of "Lt", "NestedLessLess", "ll": Rune(0x0226A) 1104 of "Gt", "NestedGreaterGreater", "gg": Rune(0x0226B) 1105 of "twixt", "between": Rune(0x0226C) 1106 of "NotCupCap": Rune(0x0226D) 1107 of "nlt", "NotLess", "nless": Rune(0x0226E) 1108 of "ngt", "NotGreater", "ngtr": Rune(0x0226F) 1109 of "nle", "NotLessEqual", "nleq": Rune(0x02270) 1110 of "nge", "NotGreaterEqual", "ngeq": Rune(0x02271) 1111 of "lsim", "LessTilde", "lesssim": Rune(0x02272) 1112 of "gsim", "gtrsim", "GreaterTilde": Rune(0x02273) 1113 of "nlsim", "NotLessTilde": Rune(0x02274) 1114 of "ngsim", "NotGreaterTilde": Rune(0x02275) 1115 of "lg", "lessgtr", "LessGreater": Rune(0x02276) 1116 of "gl", "gtrless", "GreaterLess": Rune(0x02277) 1117 of "ntlg", "NotLessGreater": Rune(0x02278) 1118 of "ntgl", "NotGreaterLess": Rune(0x02279) 1119 of "pr", "Precedes", "prec": Rune(0x0227A) 1120 of "sc", "Succeeds", "succ": Rune(0x0227B) 1121 of "prcue", "PrecedesSlantEqual", "preccurlyeq": Rune(0x0227C) 1122 of "sccue", "SucceedsSlantEqual", "succcurlyeq": Rune(0x0227D) 1123 of "prsim", "precsim", "PrecedesTilde": Rune(0x0227E) 1124 of "scsim", "succsim", "SucceedsTilde": Rune(0x0227F) 1125 of "npr", "nprec", "NotPrecedes": Rune(0x02280) 1126 of "nsc", "nsucc", "NotSucceeds": Rune(0x02281) 1127 of "sub", "subset": Rune(0x02282) 1128 of "sup", "supset", "Superset": Rune(0x02283) 1129 of "nsub": Rune(0x02284) 1130 of "nsup": Rune(0x02285) 1131 of "sube", "SubsetEqual", "subseteq": Rune(0x02286) 1132 of "supe", "supseteq", "SupersetEqual": Rune(0x02287) 1133 of "nsube", "nsubseteq", "NotSubsetEqual": Rune(0x02288) 1134 of "nsupe", "nsupseteq", "NotSupersetEqual": Rune(0x02289) 1135 of "subne", "subsetneq": Rune(0x0228A) 1136 of "supne", "supsetneq": Rune(0x0228B) 1137 of "cupdot": Rune(0x0228D) 1138 of "uplus", "UnionPlus": Rune(0x0228E) 1139 of "sqsub", "SquareSubset", "sqsubset": Rune(0x0228F) 1140 of "sqsup", "SquareSuperset", "sqsupset": Rune(0x02290) 1141 of "sqsube", "SquareSubsetEqual", "sqsubseteq": Rune(0x02291) 1142 of "sqsupe", "SquareSupersetEqual", "sqsupseteq": Rune(0x02292) 1143 of "sqcap", "SquareIntersection": Rune(0x02293) 1144 of "sqcup", "SquareUnion": Rune(0x02294) 1145 of "oplus", "CirclePlus": Rune(0x02295) 1146 of "ominus", "CircleMinus": Rune(0x02296) 1147 of "otimes", "CircleTimes": Rune(0x02297) 1148 of "osol": Rune(0x02298) 1149 of "odot", "CircleDot": Rune(0x02299) 1150 of "ocir", "circledcirc": Rune(0x0229A) 1151 of "oast", "circledast": Rune(0x0229B) 1152 of "odash", "circleddash": Rune(0x0229D) 1153 of "plusb", "boxplus": Rune(0x0229E) 1154 of "minusb", "boxminus": Rune(0x0229F) 1155 of "timesb", "boxtimes": Rune(0x022A0) 1156 of "sdotb", "dotsquare": Rune(0x022A1) 1157 of "vdash", "RightTee": Rune(0x022A2) 1158 of "dashv", "LeftTee": Rune(0x022A3) 1159 of "top", "DownTee": Rune(0x022A4) 1160 of "bottom", "bot", "perp", "UpTee": Rune(0x022A5) 1161 of "models": Rune(0x022A7) 1162 of "vDash", "DoubleRightTee": Rune(0x022A8) 1163 of "Vdash": Rune(0x022A9) 1164 of "Vvdash": Rune(0x022AA) 1165 of "VDash": Rune(0x022AB) 1166 of "nvdash": Rune(0x022AC) 1167 of "nvDash": Rune(0x022AD) 1168 of "nVdash": Rune(0x022AE) 1169 of "nVDash": Rune(0x022AF) 1170 of "prurel": Rune(0x022B0) 1171 of "vltri", "vartriangleleft", "LeftTriangle": Rune(0x022B2) 1172 of "vrtri", "vartriangleright", "RightTriangle": Rune(0x022B3) 1173 of "ltrie", "trianglelefteq", "LeftTriangleEqual": Rune(0x022B4) 1174 of "rtrie", "trianglerighteq", "RightTriangleEqual": Rune(0x022B5) 1175 of "origof": Rune(0x022B6) 1176 of "imof": Rune(0x022B7) 1177 of "mumap", "multimap": Rune(0x022B8) 1178 of "hercon": Rune(0x022B9) 1179 of "intcal", "intercal": Rune(0x022BA) 1180 of "veebar": Rune(0x022BB) 1181 of "barvee": Rune(0x022BD) 1182 of "angrtvb": Rune(0x022BE) 1183 of "lrtri": Rune(0x022BF) 1184 of "xwedge", "Wedge", "bigwedge": Rune(0x022C0) 1185 of "xvee", "Vee", "bigvee": Rune(0x022C1) 1186 of "xcap", "Intersection", "bigcap": Rune(0x022C2) 1187 of "xcup", "Union", "bigcup": Rune(0x022C3) 1188 of "diam", "diamond", "Diamond": Rune(0x022C4) 1189 of "sdot": Rune(0x022C5) 1190 of "sstarf", "Star": Rune(0x022C6) 1191 of "divonx", "divideontimes": Rune(0x022C7) 1192 of "bowtie": Rune(0x022C8) 1193 of "ltimes": Rune(0x022C9) 1194 of "rtimes": Rune(0x022CA) 1195 of "lthree", "leftthreetimes": Rune(0x022CB) 1196 of "rthree", "rightthreetimes": Rune(0x022CC) 1197 of "bsime", "backsimeq": Rune(0x022CD) 1198 of "cuvee", "curlyvee": Rune(0x022CE) 1199 of "cuwed", "curlywedge": Rune(0x022CF) 1200 of "Sub", "Subset": Rune(0x022D0) 1201 of "Sup", "Supset": Rune(0x022D1) 1202 of "Cap": Rune(0x022D2) 1203 of "Cup": Rune(0x022D3) 1204 of "fork", "pitchfork": Rune(0x022D4) 1205 of "epar": Rune(0x022D5) 1206 of "ltdot", "lessdot": Rune(0x022D6) 1207 of "gtdot", "gtrdot": Rune(0x022D7) 1208 of "Ll": Rune(0x022D8) 1209 of "Gg", "ggg": Rune(0x022D9) 1210 of "leg", "LessEqualGreater", "lesseqgtr": Rune(0x022DA) 1211 of "gel", "gtreqless", "GreaterEqualLess": Rune(0x022DB) 1212 of "cuepr", "curlyeqprec": Rune(0x022DE) 1213 of "cuesc", "curlyeqsucc": Rune(0x022DF) 1214 of "nprcue", "NotPrecedesSlantEqual": Rune(0x022E0) 1215 of "nsccue", "NotSucceedsSlantEqual": Rune(0x022E1) 1216 of "nsqsube", "NotSquareSubsetEqual": Rune(0x022E2) 1217 of "nsqsupe", "NotSquareSupersetEqual": Rune(0x022E3) 1218 of "lnsim": Rune(0x022E6) 1219 of "gnsim": Rune(0x022E7) 1220 of "prnsim", "precnsim": Rune(0x022E8) 1221 of "scnsim", "succnsim": Rune(0x022E9) 1222 of "nltri", "ntriangleleft", "NotLeftTriangle": Rune(0x022EA) 1223 of "nrtri", "ntriangleright", "NotRightTriangle": Rune(0x022EB) 1224 of "nltrie", "ntrianglelefteq", 1225 "NotLeftTriangleEqual": Rune(0x022EC) 1226 of "nrtrie", "ntrianglerighteq", 1227 "NotRightTriangleEqual": Rune(0x022ED) 1228 of "vellip": Rune(0x022EE) 1229 of "ctdot": Rune(0x022EF) 1230 of "utdot": Rune(0x022F0) 1231 of "dtdot": Rune(0x022F1) 1232 of "disin": Rune(0x022F2) 1233 of "isinsv": Rune(0x022F3) 1234 of "isins": Rune(0x022F4) 1235 of "isindot": Rune(0x022F5) 1236 of "notinvc": Rune(0x022F6) 1237 of "notinvb": Rune(0x022F7) 1238 of "isinE": Rune(0x022F9) 1239 of "nisd": Rune(0x022FA) 1240 of "xnis": Rune(0x022FB) 1241 of "nis": Rune(0x022FC) 1242 of "notnivc": Rune(0x022FD) 1243 of "notnivb": Rune(0x022FE) 1244 of "barwed", "barwedge": Rune(0x02305) 1245 of "Barwed", "doublebarwedge": Rune(0x02306) 1246 of "lceil", "LeftCeiling": Rune(0x02308) 1247 of "rceil", "RightCeiling": Rune(0x02309) 1248 of "lfloor", "LeftFloor": Rune(0x0230A) 1249 of "rfloor", "RightFloor": Rune(0x0230B) 1250 of "drcrop": Rune(0x0230C) 1251 of "dlcrop": Rune(0x0230D) 1252 of "urcrop": Rune(0x0230E) 1253 of "ulcrop": Rune(0x0230F) 1254 of "bnot": Rune(0x02310) 1255 of "profline": Rune(0x02312) 1256 of "profsurf": Rune(0x02313) 1257 of "telrec": Rune(0x02315) 1258 of "target": Rune(0x02316) 1259 of "ulcorn", "ulcorner": Rune(0x0231C) 1260 of "urcorn", "urcorner": Rune(0x0231D) 1261 of "dlcorn", "llcorner": Rune(0x0231E) 1262 of "drcorn", "lrcorner": Rune(0x0231F) 1263 of "frown", "sfrown": Rune(0x02322) 1264 of "smile", "ssmile": Rune(0x02323) 1265 of "cylcty": Rune(0x0232D) 1266 of "profalar": Rune(0x0232E) 1267 of "topbot": Rune(0x02336) 1268 of "ovbar": Rune(0x0233D) 1269 of "solbar": Rune(0x0233F) 1270 of "angzarr": Rune(0x0237C) 1271 of "lmoust", "lmoustache": Rune(0x023B0) 1272 of "rmoust", "rmoustache": Rune(0x023B1) 1273 of "tbrk", "OverBracket": Rune(0x023B4) 1274 of "bbrk", "UnderBracket": Rune(0x023B5) 1275 of "bbrktbrk": Rune(0x023B6) 1276 of "OverParenthesis": Rune(0x023DC) 1277 of "UnderParenthesis": Rune(0x023DD) 1278 of "OverBrace": Rune(0x023DE) 1279 of "UnderBrace": Rune(0x023DF) 1280 of "trpezium": Rune(0x023E2) 1281 of "elinters": Rune(0x023E7) 1282 of "blank": Rune(0x02423) 1283 of "oS", "circledS": Rune(0x024C8) 1284 of "boxh", "HorizontalLine": Rune(0x02500) 1285 of "boxv": Rune(0x02502) 1286 of "boxdr": Rune(0x0250C) 1287 of "boxdl": Rune(0x02510) 1288 of "boxur": Rune(0x02514) 1289 of "boxul": Rune(0x02518) 1290 of "boxvr": Rune(0x0251C) 1291 of "boxvl": Rune(0x02524) 1292 of "boxhd": Rune(0x0252C) 1293 of "boxhu": Rune(0x02534) 1294 of "boxvh": Rune(0x0253C) 1295 of "boxH": Rune(0x02550) 1296 of "boxV": Rune(0x02551) 1297 of "boxdR": Rune(0x02552) 1298 of "boxDr": Rune(0x02553) 1299 of "boxDR": Rune(0x02554) 1300 of "boxdL": Rune(0x02555) 1301 of "boxDl": Rune(0x02556) 1302 of "boxDL": Rune(0x02557) 1303 of "boxuR": Rune(0x02558) 1304 of "boxUr": Rune(0x02559) 1305 of "boxUR": Rune(0x0255A) 1306 of "boxuL": Rune(0x0255B) 1307 of "boxUl": Rune(0x0255C) 1308 of "boxUL": Rune(0x0255D) 1309 of "boxvR": Rune(0x0255E) 1310 of "boxVr": Rune(0x0255F) 1311 of "boxVR": Rune(0x02560) 1312 of "boxvL": Rune(0x02561) 1313 of "boxVl": Rune(0x02562) 1314 of "boxVL": Rune(0x02563) 1315 of "boxHd": Rune(0x02564) 1316 of "boxhD": Rune(0x02565) 1317 of "boxHD": Rune(0x02566) 1318 of "boxHu": Rune(0x02567) 1319 of "boxhU": Rune(0x02568) 1320 of "boxHU": Rune(0x02569) 1321 of "boxvH": Rune(0x0256A) 1322 of "boxVh": Rune(0x0256B) 1323 of "boxVH": Rune(0x0256C) 1324 of "uhblk": Rune(0x02580) 1325 of "lhblk": Rune(0x02584) 1326 of "block": Rune(0x02588) 1327 of "blk14": Rune(0x02591) 1328 of "blk12": Rune(0x02592) 1329 of "blk34": Rune(0x02593) 1330 of "squ", "square", "Square": Rune(0x025A1) 1331 of "squf", "squarf", "blacksquare", 1332 "FilledVerySmallSquare": Rune(0x025AA) 1333 of "EmptyVerySmallSquare": Rune(0x025AB) 1334 of "rect": Rune(0x025AD) 1335 of "marker": Rune(0x025AE) 1336 of "fltns": Rune(0x025B1) 1337 of "xutri", "bigtriangleup": Rune(0x025B3) 1338 of "utrif", "blacktriangle": Rune(0x025B4) 1339 of "utri", "triangle": Rune(0x025B5) 1340 of "rtrif", "blacktriangleright": Rune(0x025B8) 1341 of "rtri", "triangleright": Rune(0x025B9) 1342 of "xdtri", "bigtriangledown": Rune(0x025BD) 1343 of "dtrif", "blacktriangledown": Rune(0x025BE) 1344 of "dtri", "triangledown": Rune(0x025BF) 1345 of "ltrif", "blacktriangleleft": Rune(0x025C2) 1346 of "ltri", "triangleleft": Rune(0x025C3) 1347 of "loz", "lozenge": Rune(0x025CA) 1348 of "cir": Rune(0x025CB) 1349 of "tridot": Rune(0x025EC) 1350 of "xcirc", "bigcirc": Rune(0x025EF) 1351 of "ultri": Rune(0x025F8) 1352 of "urtri": Rune(0x025F9) 1353 of "lltri": Rune(0x025FA) 1354 of "EmptySmallSquare": Rune(0x025FB) 1355 of "FilledSmallSquare": Rune(0x025FC) 1356 of "starf", "bigstar": Rune(0x02605) 1357 of "star": Rune(0x02606) 1358 of "phone": Rune(0x0260E) 1359 of "female": Rune(0x02640) 1360 of "male": Rune(0x02642) 1361 of "spades", "spadesuit": Rune(0x02660) 1362 of "clubs", "clubsuit": Rune(0x02663) 1363 of "hearts", "heartsuit": Rune(0x02665) 1364 of "diams", "diamondsuit": Rune(0x02666) 1365 of "sung": Rune(0x0266A) 1366 of "flat": Rune(0x0266D) 1367 of "natur", "natural": Rune(0x0266E) 1368 of "sharp": Rune(0x0266F) 1369 of "check", "checkmark": Rune(0x02713) 1370 of "cross": Rune(0x02717) 1371 of "malt", "maltese": Rune(0x02720) 1372 of "sext": Rune(0x02736) 1373 of "VerticalSeparator": Rune(0x02758) 1374 of "lbbrk": Rune(0x02772) 1375 of "rbbrk": Rune(0x02773) 1376 of "lobrk", "LeftDoubleBracket": Rune(0x027E6) 1377 of "robrk", "RightDoubleBracket": Rune(0x027E7) 1378 of "lang", "LeftAngleBracket", "langle": Rune(0x027E8) 1379 of "rang", "RightAngleBracket", "rangle": Rune(0x027E9) 1380 of "Lang": Rune(0x027EA) 1381 of "Rang": Rune(0x027EB) 1382 of "loang": Rune(0x027EC) 1383 of "roang": Rune(0x027ED) 1384 of "xlarr", "longleftarrow", "LongLeftArrow": Rune(0x027F5) 1385 of "xrarr", "longrightarrow", "LongRightArrow": Rune(0x027F6) 1386 of "xharr", "longleftrightarrow", 1387 "LongLeftRightArrow": Rune(0x027F7) 1388 of "xlArr", "Longleftarrow", "DoubleLongLeftArrow": Rune(0x027F8) 1389 of "xrArr", "Longrightarrow", "DoubleLongRightArrow": Rune(0x027F9) 1390 of "xhArr", "Longleftrightarrow", 1391 "DoubleLongLeftRightArrow": Rune(0x027FA) 1392 of "xmap", "longmapsto": Rune(0x027FC) 1393 of "dzigrarr": Rune(0x027FF) 1394 of "nvlArr": Rune(0x02902) 1395 of "nvrArr": Rune(0x02903) 1396 of "nvHarr": Rune(0x02904) 1397 of "Map": Rune(0x02905) 1398 of "lbarr": Rune(0x0290C) 1399 of "rbarr", "bkarow": Rune(0x0290D) 1400 of "lBarr": Rune(0x0290E) 1401 of "rBarr", "dbkarow": Rune(0x0290F) 1402 of "RBarr", "drbkarow": Rune(0x02910) 1403 of "DDotrahd": Rune(0x02911) 1404 of "UpArrowBar": Rune(0x02912) 1405 of "DownArrowBar": Rune(0x02913) 1406 of "Rarrtl": Rune(0x02916) 1407 of "latail": Rune(0x02919) 1408 of "ratail": Rune(0x0291A) 1409 of "lAtail": Rune(0x0291B) 1410 of "rAtail": Rune(0x0291C) 1411 of "larrfs": Rune(0x0291D) 1412 of "rarrfs": Rune(0x0291E) 1413 of "larrbfs": Rune(0x0291F) 1414 of "rarrbfs": Rune(0x02920) 1415 of "nwarhk": Rune(0x02923) 1416 of "nearhk": Rune(0x02924) 1417 of "searhk", "hksearow": Rune(0x02925) 1418 of "swarhk", "hkswarow": Rune(0x02926) 1419 of "nwnear": Rune(0x02927) 1420 of "nesear", "toea": Rune(0x02928) 1421 of "seswar", "tosa": Rune(0x02929) 1422 of "swnwar": Rune(0x0292A) 1423 of "rarrc": Rune(0x02933) 1424 of "cudarrr": Rune(0x02935) 1425 of "ldca": Rune(0x02936) 1426 of "rdca": Rune(0x02937) 1427 of "cudarrl": Rune(0x02938) 1428 of "larrpl": Rune(0x02939) 1429 of "curarrm": Rune(0x0293C) 1430 of "cularrp": Rune(0x0293D) 1431 of "rarrpl": Rune(0x02945) 1432 of "harrcir": Rune(0x02948) 1433 of "Uarrocir": Rune(0x02949) 1434 of "lurdshar": Rune(0x0294A) 1435 of "ldrushar": Rune(0x0294B) 1436 of "LeftRightVector": Rune(0x0294E) 1437 of "RightUpDownVector": Rune(0x0294F) 1438 of "DownLeftRightVector": Rune(0x02950) 1439 of "LeftUpDownVector": Rune(0x02951) 1440 of "LeftVectorBar": Rune(0x02952) 1441 of "RightVectorBar": Rune(0x02953) 1442 of "RightUpVectorBar": Rune(0x02954) 1443 of "RightDownVectorBar": Rune(0x02955) 1444 of "DownLeftVectorBar": Rune(0x02956) 1445 of "DownRightVectorBar": Rune(0x02957) 1446 of "LeftUpVectorBar": Rune(0x02958) 1447 of "LeftDownVectorBar": Rune(0x02959) 1448 of "LeftTeeVector": Rune(0x0295A) 1449 of "RightTeeVector": Rune(0x0295B) 1450 of "RightUpTeeVector": Rune(0x0295C) 1451 of "RightDownTeeVector": Rune(0x0295D) 1452 of "DownLeftTeeVector": Rune(0x0295E) 1453 of "DownRightTeeVector": Rune(0x0295F) 1454 of "LeftUpTeeVector": Rune(0x02960) 1455 of "LeftDownTeeVector": Rune(0x02961) 1456 of "lHar": Rune(0x02962) 1457 of "uHar": Rune(0x02963) 1458 of "rHar": Rune(0x02964) 1459 of "dHar": Rune(0x02965) 1460 of "luruhar": Rune(0x02966) 1461 of "ldrdhar": Rune(0x02967) 1462 of "ruluhar": Rune(0x02968) 1463 of "rdldhar": Rune(0x02969) 1464 of "lharul": Rune(0x0296A) 1465 of "llhard": Rune(0x0296B) 1466 of "rharul": Rune(0x0296C) 1467 of "lrhard": Rune(0x0296D) 1468 of "udhar", "UpEquilibrium": Rune(0x0296E) 1469 of "duhar", "ReverseUpEquilibrium": Rune(0x0296F) 1470 of "RoundImplies": Rune(0x02970) 1471 of "erarr": Rune(0x02971) 1472 of "simrarr": Rune(0x02972) 1473 of "larrsim": Rune(0x02973) 1474 of "rarrsim": Rune(0x02974) 1475 of "rarrap": Rune(0x02975) 1476 of "ltlarr": Rune(0x02976) 1477 of "gtrarr": Rune(0x02978) 1478 of "subrarr": Rune(0x02979) 1479 of "suplarr": Rune(0x0297B) 1480 of "lfisht": Rune(0x0297C) 1481 of "rfisht": Rune(0x0297D) 1482 of "ufisht": Rune(0x0297E) 1483 of "dfisht": Rune(0x0297F) 1484 of "lopar": Rune(0x02985) 1485 of "ropar": Rune(0x02986) 1486 of "lbrke": Rune(0x0298B) 1487 of "rbrke": Rune(0x0298C) 1488 of "lbrkslu": Rune(0x0298D) 1489 of "rbrksld": Rune(0x0298E) 1490 of "lbrksld": Rune(0x0298F) 1491 of "rbrkslu": Rune(0x02990) 1492 of "langd": Rune(0x02991) 1493 of "rangd": Rune(0x02992) 1494 of "lparlt": Rune(0x02993) 1495 of "rpargt": Rune(0x02994) 1496 of "gtlPar": Rune(0x02995) 1497 of "ltrPar": Rune(0x02996) 1498 of "vzigzag": Rune(0x0299A) 1499 of "vangrt": Rune(0x0299C) 1500 of "angrtvbd": Rune(0x0299D) 1501 of "ange": Rune(0x029A4) 1502 of "range": Rune(0x029A5) 1503 of "dwangle": Rune(0x029A6) 1504 of "uwangle": Rune(0x029A7) 1505 of "angmsdaa": Rune(0x029A8) 1506 of "angmsdab": Rune(0x029A9) 1507 of "angmsdac": Rune(0x029AA) 1508 of "angmsdad": Rune(0x029AB) 1509 of "angmsdae": Rune(0x029AC) 1510 of "angmsdaf": Rune(0x029AD) 1511 of "angmsdag": Rune(0x029AE) 1512 of "angmsdah": Rune(0x029AF) 1513 of "bemptyv": Rune(0x029B0) 1514 of "demptyv": Rune(0x029B1) 1515 of "cemptyv": Rune(0x029B2) 1516 of "raemptyv": Rune(0x029B3) 1517 of "laemptyv": Rune(0x029B4) 1518 of "ohbar": Rune(0x029B5) 1519 of "omid": Rune(0x029B6) 1520 of "opar": Rune(0x029B7) 1521 of "operp": Rune(0x029B9) 1522 of "olcross": Rune(0x029BB) 1523 of "odsold": Rune(0x029BC) 1524 of "olcir": Rune(0x029BE) 1525 of "ofcir": Rune(0x029BF) 1526 of "olt": Rune(0x029C0) 1527 of "ogt": Rune(0x029C1) 1528 of "cirscir": Rune(0x029C2) 1529 of "cirE": Rune(0x029C3) 1530 of "solb": Rune(0x029C4) 1531 of "bsolb": Rune(0x029C5) 1532 of "boxbox": Rune(0x029C9) 1533 of "trisb": Rune(0x029CD) 1534 of "rtriltri": Rune(0x029CE) 1535 of "LeftTriangleBar": Rune(0x029CF) 1536 of "RightTriangleBar": Rune(0x029D0) 1537 of "race": Rune(0x029DA) 1538 of "iinfin": Rune(0x029DC) 1539 of "infintie": Rune(0x029DD) 1540 of "nvinfin": Rune(0x029DE) 1541 of "eparsl": Rune(0x029E3) 1542 of "smeparsl": Rune(0x029E4) 1543 of "eqvparsl": Rune(0x029E5) 1544 of "lozf", "blacklozenge": Rune(0x029EB) 1545 of "RuleDelayed": Rune(0x029F4) 1546 of "dsol": Rune(0x029F6) 1547 of "xodot", "bigodot": Rune(0x02A00) 1548 of "xoplus", "bigoplus": Rune(0x02A01) 1549 of "xotime", "bigotimes": Rune(0x02A02) 1550 of "xuplus", "biguplus": Rune(0x02A04) 1551 of "xsqcup", "bigsqcup": Rune(0x02A06) 1552 of "qint", "iiiint": Rune(0x02A0C) 1553 of "fpartint": Rune(0x02A0D) 1554 of "cirfnint": Rune(0x02A10) 1555 of "awint": Rune(0x02A11) 1556 of "rppolint": Rune(0x02A12) 1557 of "scpolint": Rune(0x02A13) 1558 of "npolint": Rune(0x02A14) 1559 of "pointint": Rune(0x02A15) 1560 of "quatint": Rune(0x02A16) 1561 of "intlarhk": Rune(0x02A17) 1562 of "pluscir": Rune(0x02A22) 1563 of "plusacir": Rune(0x02A23) 1564 of "simplus": Rune(0x02A24) 1565 of "plusdu": Rune(0x02A25) 1566 of "plussim": Rune(0x02A26) 1567 of "plustwo": Rune(0x02A27) 1568 of "mcomma": Rune(0x02A29) 1569 of "minusdu": Rune(0x02A2A) 1570 of "loplus": Rune(0x02A2D) 1571 of "roplus": Rune(0x02A2E) 1572 of "Cross": Rune(0x02A2F) 1573 of "timesd": Rune(0x02A30) 1574 of "timesbar": Rune(0x02A31) 1575 of "smashp": Rune(0x02A33) 1576 of "lotimes": Rune(0x02A34) 1577 of "rotimes": Rune(0x02A35) 1578 of "otimesas": Rune(0x02A36) 1579 of "Otimes": Rune(0x02A37) 1580 of "odiv": Rune(0x02A38) 1581 of "triplus": Rune(0x02A39) 1582 of "triminus": Rune(0x02A3A) 1583 of "tritime": Rune(0x02A3B) 1584 of "iprod", "intprod": Rune(0x02A3C) 1585 of "amalg": Rune(0x02A3F) 1586 of "capdot": Rune(0x02A40) 1587 of "ncup": Rune(0x02A42) 1588 of "ncap": Rune(0x02A43) 1589 of "capand": Rune(0x02A44) 1590 of "cupor": Rune(0x02A45) 1591 of "cupcap": Rune(0x02A46) 1592 of "capcup": Rune(0x02A47) 1593 of "cupbrcap": Rune(0x02A48) 1594 of "capbrcup": Rune(0x02A49) 1595 of "cupcup": Rune(0x02A4A) 1596 of "capcap": Rune(0x02A4B) 1597 of "ccups": Rune(0x02A4C) 1598 of "ccaps": Rune(0x02A4D) 1599 of "ccupssm": Rune(0x02A50) 1600 of "And": Rune(0x02A53) 1601 of "Or": Rune(0x02A54) 1602 of "andand": Rune(0x02A55) 1603 of "oror": Rune(0x02A56) 1604 of "orslope": Rune(0x02A57) 1605 of "andslope": Rune(0x02A58) 1606 of "andv": Rune(0x02A5A) 1607 of "orv": Rune(0x02A5B) 1608 of "andd": Rune(0x02A5C) 1609 of "ord": Rune(0x02A5D) 1610 of "wedbar": Rune(0x02A5F) 1611 of "sdote": Rune(0x02A66) 1612 of "simdot": Rune(0x02A6A) 1613 of "congdot": Rune(0x02A6D) 1614 of "easter": Rune(0x02A6E) 1615 of "apacir": Rune(0x02A6F) 1616 of "apE": Rune(0x02A70) 1617 of "eplus": Rune(0x02A71) 1618 of "pluse": Rune(0x02A72) 1619 of "Esim": Rune(0x02A73) 1620 of "Colone": Rune(0x02A74) 1621 of "Equal": Rune(0x02A75) 1622 of "eDDot", "ddotseq": Rune(0x02A77) 1623 of "equivDD": Rune(0x02A78) 1624 of "ltcir": Rune(0x02A79) 1625 of "gtcir": Rune(0x02A7A) 1626 of "ltquest": Rune(0x02A7B) 1627 of "gtquest": Rune(0x02A7C) 1628 of "les", "LessSlantEqual", "leqslant": Rune(0x02A7D) 1629 of "ges", "GreaterSlantEqual", "geqslant": Rune(0x02A7E) 1630 of "lesdot": Rune(0x02A7F) 1631 of "gesdot": Rune(0x02A80) 1632 of "lesdoto": Rune(0x02A81) 1633 of "gesdoto": Rune(0x02A82) 1634 of "lesdotor": Rune(0x02A83) 1635 of "gesdotol": Rune(0x02A84) 1636 of "lap", "lessapprox": Rune(0x02A85) 1637 of "gap", "gtrapprox": Rune(0x02A86) 1638 of "lne", "lneq": Rune(0x02A87) 1639 of "gne", "gneq": Rune(0x02A88) 1640 of "lnap", "lnapprox": Rune(0x02A89) 1641 of "gnap", "gnapprox": Rune(0x02A8A) 1642 of "lEg", "lesseqqgtr": Rune(0x02A8B) 1643 of "gEl", "gtreqqless": Rune(0x02A8C) 1644 of "lsime": Rune(0x02A8D) 1645 of "gsime": Rune(0x02A8E) 1646 of "lsimg": Rune(0x02A8F) 1647 of "gsiml": Rune(0x02A90) 1648 of "lgE": Rune(0x02A91) 1649 of "glE": Rune(0x02A92) 1650 of "lesges": Rune(0x02A93) 1651 of "gesles": Rune(0x02A94) 1652 of "els", "eqslantless": Rune(0x02A95) 1653 of "egs", "eqslantgtr": Rune(0x02A96) 1654 of "elsdot": Rune(0x02A97) 1655 of "egsdot": Rune(0x02A98) 1656 of "el": Rune(0x02A99) 1657 of "eg": Rune(0x02A9A) 1658 of "siml": Rune(0x02A9D) 1659 of "simg": Rune(0x02A9E) 1660 of "simlE": Rune(0x02A9F) 1661 of "simgE": Rune(0x02AA0) 1662 of "LessLess": Rune(0x02AA1) 1663 of "GreaterGreater": Rune(0x02AA2) 1664 of "glj": Rune(0x02AA4) 1665 of "gla": Rune(0x02AA5) 1666 of "ltcc": Rune(0x02AA6) 1667 of "gtcc": Rune(0x02AA7) 1668 of "lescc": Rune(0x02AA8) 1669 of "gescc": Rune(0x02AA9) 1670 of "smt": Rune(0x02AAA) 1671 of "lat": Rune(0x02AAB) 1672 of "smte": Rune(0x02AAC) 1673 of "late": Rune(0x02AAD) 1674 of "bumpE": Rune(0x02AAE) 1675 of "pre", "preceq", "PrecedesEqual": Rune(0x02AAF) 1676 of "sce", "succeq", "SucceedsEqual": Rune(0x02AB0) 1677 of "prE": Rune(0x02AB3) 1678 of "scE": Rune(0x02AB4) 1679 of "prnE", "precneqq": Rune(0x02AB5) 1680 of "scnE", "succneqq": Rune(0x02AB6) 1681 of "prap", "precapprox": Rune(0x02AB7) 1682 of "scap", "succapprox": Rune(0x02AB8) 1683 of "prnap", "precnapprox": Rune(0x02AB9) 1684 of "scnap", "succnapprox": Rune(0x02ABA) 1685 of "Pr": Rune(0x02ABB) 1686 of "Sc": Rune(0x02ABC) 1687 of "subdot": Rune(0x02ABD) 1688 of "supdot": Rune(0x02ABE) 1689 of "subplus": Rune(0x02ABF) 1690 of "supplus": Rune(0x02AC0) 1691 of "submult": Rune(0x02AC1) 1692 of "supmult": Rune(0x02AC2) 1693 of "subedot": Rune(0x02AC3) 1694 of "supedot": Rune(0x02AC4) 1695 of "subE", "subseteqq": Rune(0x02AC5) 1696 of "supE", "supseteqq": Rune(0x02AC6) 1697 of "subsim": Rune(0x02AC7) 1698 of "supsim": Rune(0x02AC8) 1699 of "subnE", "subsetneqq": Rune(0x02ACB) 1700 of "supnE", "supsetneqq": Rune(0x02ACC) 1701 of "csub": Rune(0x02ACF) 1702 of "csup": Rune(0x02AD0) 1703 of "csube": Rune(0x02AD1) 1704 of "csupe": Rune(0x02AD2) 1705 of "subsup": Rune(0x02AD3) 1706 of "supsub": Rune(0x02AD4) 1707 of "subsub": Rune(0x02AD5) 1708 of "supsup": Rune(0x02AD6) 1709 of "suphsub": Rune(0x02AD7) 1710 of "supdsub": Rune(0x02AD8) 1711 of "forkv": Rune(0x02AD9) 1712 of "topfork": Rune(0x02ADA) 1713 of "mlcp": Rune(0x02ADB) 1714 of "Dashv", "DoubleLeftTee": Rune(0x02AE4) 1715 of "Vdashl": Rune(0x02AE6) 1716 of "Barv": Rune(0x02AE7) 1717 of "vBar": Rune(0x02AE8) 1718 of "vBarv": Rune(0x02AE9) 1719 of "Vbar": Rune(0x02AEB) 1720 of "Not": Rune(0x02AEC) 1721 of "bNot": Rune(0x02AED) 1722 of "rnmid": Rune(0x02AEE) 1723 of "cirmid": Rune(0x02AEF) 1724 of "midcir": Rune(0x02AF0) 1725 of "topcir": Rune(0x02AF1) 1726 of "nhpar": Rune(0x02AF2) 1727 of "parsim": Rune(0x02AF3) 1728 of "parsl": Rune(0x02AFD) 1729 of "fflig": Rune(0x0FB00) 1730 of "filig": Rune(0x0FB01) 1731 of "fllig": Rune(0x0FB02) 1732 of "ffilig": Rune(0x0FB03) 1733 of "ffllig": Rune(0x0FB04) 1734 of "Ascr": Rune(0x1D49C) 1735 of "Cscr": Rune(0x1D49E) 1736 of "Dscr": Rune(0x1D49F) 1737 of "Gscr": Rune(0x1D4A2) 1738 of "Jscr": Rune(0x1D4A5) 1739 of "Kscr": Rune(0x1D4A6) 1740 of "Nscr": Rune(0x1D4A9) 1741 of "Oscr": Rune(0x1D4AA) 1742 of "Pscr": Rune(0x1D4AB) 1743 of "Qscr": Rune(0x1D4AC) 1744 of "Sscr": Rune(0x1D4AE) 1745 of "Tscr": Rune(0x1D4AF) 1746 of "Uscr": Rune(0x1D4B0) 1747 of "Vscr": Rune(0x1D4B1) 1748 of "Wscr": Rune(0x1D4B2) 1749 of "Xscr": Rune(0x1D4B3) 1750 of "Yscr": Rune(0x1D4B4) 1751 of "Zscr": Rune(0x1D4B5) 1752 of "ascr": Rune(0x1D4B6) 1753 of "bscr": Rune(0x1D4B7) 1754 of "cscr": Rune(0x1D4B8) 1755 of "dscr": Rune(0x1D4B9) 1756 of "fscr": Rune(0x1D4BB) 1757 of "hscr": Rune(0x1D4BD) 1758 of "iscr": Rune(0x1D4BE) 1759 of "jscr": Rune(0x1D4BF) 1760 of "kscr": Rune(0x1D4C0) 1761 of "lscr": Rune(0x1D4C1) 1762 of "mscr": Rune(0x1D4C2) 1763 of "nscr": Rune(0x1D4C3) 1764 of "pscr": Rune(0x1D4C5) 1765 of "qscr": Rune(0x1D4C6) 1766 of "rscr": Rune(0x1D4C7) 1767 of "sscr": Rune(0x1D4C8) 1768 of "tscr": Rune(0x1D4C9) 1769 of "uscr": Rune(0x1D4CA) 1770 of "vscr": Rune(0x1D4CB) 1771 of "wscr": Rune(0x1D4CC) 1772 of "xscr": Rune(0x1D4CD) 1773 of "yscr": Rune(0x1D4CE) 1774 of "zscr": Rune(0x1D4CF) 1775 of "Afr": Rune(0x1D504) 1776 of "Bfr": Rune(0x1D505) 1777 of "Dfr": Rune(0x1D507) 1778 of "Efr": Rune(0x1D508) 1779 of "Ffr": Rune(0x1D509) 1780 of "Gfr": Rune(0x1D50A) 1781 of "Jfr": Rune(0x1D50D) 1782 of "Kfr": Rune(0x1D50E) 1783 of "Lfr": Rune(0x1D50F) 1784 of "Mfr": Rune(0x1D510) 1785 of "Nfr": Rune(0x1D511) 1786 of "Ofr": Rune(0x1D512) 1787 of "Pfr": Rune(0x1D513) 1788 of "Qfr": Rune(0x1D514) 1789 of "Sfr": Rune(0x1D516) 1790 of "Tfr": Rune(0x1D517) 1791 of "Ufr": Rune(0x1D518) 1792 of "Vfr": Rune(0x1D519) 1793 of "Wfr": Rune(0x1D51A) 1794 of "Xfr": Rune(0x1D51B) 1795 of "Yfr": Rune(0x1D51C) 1796 of "afr": Rune(0x1D51E) 1797 of "bfr": Rune(0x1D51F) 1798 of "cfr": Rune(0x1D520) 1799 of "dfr": Rune(0x1D521) 1800 of "efr": Rune(0x1D522) 1801 of "ffr": Rune(0x1D523) 1802 of "gfr": Rune(0x1D524) 1803 of "hfr": Rune(0x1D525) 1804 of "ifr": Rune(0x1D526) 1805 of "jfr": Rune(0x1D527) 1806 of "kfr": Rune(0x1D528) 1807 of "lfr": Rune(0x1D529) 1808 of "mfr": Rune(0x1D52A) 1809 of "nfr": Rune(0x1D52B) 1810 of "ofr": Rune(0x1D52C) 1811 of "pfr": Rune(0x1D52D) 1812 of "qfr": Rune(0x1D52E) 1813 of "rfr": Rune(0x1D52F) 1814 of "sfr": Rune(0x1D530) 1815 of "tfr": Rune(0x1D531) 1816 of "ufr": Rune(0x1D532) 1817 of "vfr": Rune(0x1D533) 1818 of "wfr": Rune(0x1D534) 1819 of "xfr": Rune(0x1D535) 1820 of "yfr": Rune(0x1D536) 1821 of "zfr": Rune(0x1D537) 1822 of "Aopf": Rune(0x1D538) 1823 of "Bopf": Rune(0x1D539) 1824 of "Dopf": Rune(0x1D53B) 1825 of "Eopf": Rune(0x1D53C) 1826 of "Fopf": Rune(0x1D53D) 1827 of "Gopf": Rune(0x1D53E) 1828 of "Iopf": Rune(0x1D540) 1829 of "Jopf": Rune(0x1D541) 1830 of "Kopf": Rune(0x1D542) 1831 of "Lopf": Rune(0x1D543) 1832 of "Mopf": Rune(0x1D544) 1833 of "Oopf": Rune(0x1D546) 1834 of "Sopf": Rune(0x1D54A) 1835 of "Topf": Rune(0x1D54B) 1836 of "Uopf": Rune(0x1D54C) 1837 of "Vopf": Rune(0x1D54D) 1838 of "Wopf": Rune(0x1D54E) 1839 of "Xopf": Rune(0x1D54F) 1840 of "Yopf": Rune(0x1D550) 1841 of "aopf": Rune(0x1D552) 1842 of "bopf": Rune(0x1D553) 1843 of "copf": Rune(0x1D554) 1844 of "dopf": Rune(0x1D555) 1845 of "eopf": Rune(0x1D556) 1846 of "fopf": Rune(0x1D557) 1847 of "gopf": Rune(0x1D558) 1848 of "hopf": Rune(0x1D559) 1849 of "iopf": Rune(0x1D55A) 1850 of "jopf": Rune(0x1D55B) 1851 of "kopf": Rune(0x1D55C) 1852 of "lopf": Rune(0x1D55D) 1853 of "mopf": Rune(0x1D55E) 1854 of "nopf": Rune(0x1D55F) 1855 of "oopf": Rune(0x1D560) 1856 of "popf": Rune(0x1D561) 1857 of "qopf": Rune(0x1D562) 1858 of "ropf": Rune(0x1D563) 1859 of "sopf": Rune(0x1D564) 1860 of "topf": Rune(0x1D565) 1861 of "uopf": Rune(0x1D566) 1862 of "vopf": Rune(0x1D567) 1863 of "wopf": Rune(0x1D568) 1864 of "xopf": Rune(0x1D569) 1865 of "yopf": Rune(0x1D56A) 1866 of "zopf": Rune(0x1D56B) 1867 else: Rune(0) 1868 1869proc entityToUtf8*(entity: string): string = 1870 ## Converts an HTML entity name like `Ü` or values like `Ü` 1871 ## or `Ü` to its UTF-8 equivalent. 1872 ## "" is returned if the entity name is unknown. The HTML parser 1873 ## already converts entities to UTF-8. 1874 runnableExamples: 1875 const sigma = "Σ" 1876 doAssert entityToUtf8("") == "" 1877 doAssert entityToUtf8("a") == "" 1878 doAssert entityToUtf8("gt") == ">" 1879 doAssert entityToUtf8("Uuml") == "Ü" 1880 doAssert entityToUtf8("quest") == "?" 1881 doAssert entityToUtf8("#63") == "?" 1882 doAssert entityToUtf8("Sigma") == sigma 1883 doAssert entityToUtf8("#931") == sigma 1884 doAssert entityToUtf8("#0931") == sigma 1885 doAssert entityToUtf8("#x3A3") == sigma 1886 doAssert entityToUtf8("#x03A3") == sigma 1887 doAssert entityToUtf8("#x3a3") == sigma 1888 doAssert entityToUtf8("#X3a3") == sigma 1889 let rune = entityToRune(entity) 1890 if rune.ord <= 0: result = "" 1891 else: result = toUTF8(rune) 1892 1893proc addNode(father, son: XmlNode) = 1894 if son != nil: add(father, son) 1895 1896proc parse(x: var XmlParser, errors: var seq[string]): XmlNode {.gcsafe.} 1897 1898proc expected(x: var XmlParser, n: XmlNode): string = 1899 result = errorMsg(x, "</" & n.tag & "> expected") 1900 1901template elemName(x: untyped): untyped = rawData(x) 1902 1903template adderr(x: untyped) = 1904 errors.add(x) 1905 1906proc untilElementEnd(x: var XmlParser, result: XmlNode, 1907 errors: var seq[string]) = 1908 # we parsed e.g. `<br>` and don't really expect a `</br>`: 1909 if result.htmlTag in SingleTags: 1910 if x.kind != xmlElementEnd or cmpIgnoreCase(x.elemName, result.tag) != 0: 1911 return 1912 while true: 1913 case x.kind 1914 of xmlElementStart, xmlElementOpen: 1915 case result.htmlTag 1916 of tagP, tagInput, tagOption: 1917 # some tags are common to have no `</end>`, like `<li>` but 1918 # allow `<p>` in `<dd>`, `<dt>` and `<li>` in next case 1919 if htmlTag(x.elemName) in {tagLi, tagP, tagDt, tagDd, tagInput, 1920 tagOption}: 1921 adderr(expected(x, result)) 1922 break 1923 of tagDd, tagDt, tagLi: 1924 if htmlTag(x.elemName) in {tagLi, tagDt, tagDd, tagInput, 1925 tagOption}: 1926 adderr(expected(x, result)) 1927 break 1928 of tagTd, tagTh: 1929 if htmlTag(x.elemName) in {tagTr, tagTd, tagTh, tagTfoot, tagThead}: 1930 adderr(expected(x, result)) 1931 break 1932 of tagTr: 1933 if htmlTag(x.elemName) == tagTr: 1934 adderr(expected(x, result)) 1935 break 1936 of tagOptgroup: 1937 if htmlTag(x.elemName) in {tagOption, tagOptgroup}: 1938 adderr(expected(x, result)) 1939 break 1940 else: discard 1941 result.addNode(parse(x, errors)) 1942 of xmlElementEnd: 1943 if cmpIgnoreCase(x.elemName, result.tag) != 0: 1944 #echo "5; expected: ", result.htmltag, " ", x.elemName 1945 adderr(expected(x, result)) 1946 # this seems to do better match error corrections in browsers: 1947 while x.kind in {xmlElementEnd, xmlWhitespace}: 1948 if x.kind == xmlElementEnd and cmpIgnoreCase(x.elemName, 1949 result.tag) == 0: 1950 break 1951 next(x) 1952 next(x) 1953 break 1954 of xmlEof: 1955 adderr(expected(x, result)) 1956 break 1957 else: 1958 result.addNode(parse(x, errors)) 1959 1960proc parse(x: var XmlParser, errors: var seq[string]): XmlNode = 1961 case x.kind 1962 of xmlComment: 1963 result = newComment(x.rawData) 1964 next(x) 1965 of xmlCharData, xmlWhitespace: 1966 result = newText(x.rawData) 1967 next(x) 1968 of xmlPI, xmlSpecial: 1969 # we just ignore processing instructions for now 1970 next(x) 1971 of xmlError: 1972 adderr(errorMsg(x)) 1973 next(x) 1974 of xmlElementStart: 1975 result = newElement(toLowerAscii(x.elemName)) 1976 next(x) 1977 untilElementEnd(x, result, errors) 1978 of xmlElementEnd: 1979 adderr(errorMsg(x, "unexpected ending tag: " & x.elemName)) 1980 of xmlElementOpen: 1981 result = newElement(toLowerAscii(x.elemName)) 1982 next(x) 1983 result.attrs = newStringTable() 1984 while true: 1985 case x.kind 1986 of xmlAttribute: 1987 result.attrs[x.rawData] = x.rawData2 1988 next(x) 1989 of xmlElementClose: 1990 next(x) 1991 break 1992 of xmlError: 1993 adderr(errorMsg(x)) 1994 next(x) 1995 break 1996 else: 1997 adderr(errorMsg(x, "'>' expected")) 1998 next(x) 1999 break 2000 untilElementEnd(x, result, errors) 2001 of xmlAttribute, xmlElementClose: 2002 adderr(errorMsg(x, "<some_tag> expected")) 2003 next(x) 2004 of xmlCData: 2005 result = newCData(x.rawData) 2006 next(x) 2007 of xmlEntity: 2008 var u = entityToUtf8(x.rawData) 2009 if u.len != 0: result = newText(u) 2010 next(x) 2011 of xmlEof: discard 2012 2013proc parseHtml*(s: Stream, filename: string, 2014 errors: var seq[string]): XmlNode = 2015 ## Parses the XML from stream `s` and returns a `XmlNode`. Every 2016 ## occurred parsing error is added to the `errors` sequence. 2017 var x: XmlParser 2018 open(x, s, filename, {reportComments, reportWhitespace, allowUnquotedAttribs, 2019 allowEmptyAttribs}) 2020 next(x) 2021 # skip the DOCTYPE: 2022 if x.kind == xmlSpecial: next(x) 2023 2024 result = newElement("document") 2025 result.addNode(parse(x, errors)) 2026 #if x.kind != xmlEof: 2027 # adderr(errorMsg(x, "EOF expected")) 2028 while x.kind != xmlEof: 2029 var oldPos = x.bufpos # little hack to see if we made any progress 2030 result.addNode(parse(x, errors)) 2031 if x.bufpos == oldPos: 2032 # force progress! 2033 next(x) 2034 close(x) 2035 if result.len == 1: 2036 result = result[0] 2037 2038proc parseHtml*(s: Stream): XmlNode = 2039 ## Parses the HTML from stream `s` and returns a `XmlNode`. All parsing 2040 ## errors are ignored. 2041 var errors: seq[string] = @[] 2042 result = parseHtml(s, "unknown_html_doc", errors) 2043 2044proc parseHtml*(html: string): XmlNode = 2045 ## Parses the HTML from string `html` and returns a `XmlNode`. All parsing 2046 ## errors are ignored. 2047 parseHtml(newStringStream(html)) 2048 2049proc loadHtml*(path: string, errors: var seq[string]): XmlNode = 2050 ## Loads and parses HTML from file specified by `path`, and returns 2051 ## a `XmlNode`. Every occurred parsing error is added to 2052 ## the `errors` sequence. 2053 var s = newFileStream(path, fmRead) 2054 if s == nil: raise newException(IOError, "Unable to read file: " & path) 2055 result = parseHtml(s, path, errors) 2056 2057proc loadHtml*(path: string): XmlNode = 2058 ## Loads and parses HTML from file specified by `path`, and returns 2059 ## a `XmlNode`. All parsing errors are ignored. 2060 var errors: seq[string] = @[] 2061 result = loadHtml(path, errors) 2062 2063when not defined(testing) and isMainModule: 2064 import os 2065 2066 var errors: seq[string] = @[] 2067 var x = loadHtml(paramStr(1), errors) 2068 for e in items(errors): echo e 2069 2070 var f: File 2071 if open(f, "test.txt", fmWrite): 2072 f.write($x) 2073 f.close() 2074 else: 2075 quit("cannot write test.txt") 2076