My own corner of monopam
README.md

html #

HTML character references in OCaml: escape a string for HTML text or a quoted attribute value, and unescape the character references of HTML text as the WHATWG HTML tokenizer decodes them.

# Html.escape {|Tom & Jerry's <b>|};;
- : string = "Tom &amp; Jerry&#39;s &lt;b&gt;"
# Html.unescape "I'm &notin; I tell you";;
- : string = "I'm ∉ I tell you"
# Html.unescape "&#x7FFFFFFFFFFFFFFF;";;
- : string = "�"

unescape follows sections 13.2.5.72 to 13.2.5.80 of the HTML Living Standard:

  • the 2231 named references of WHATWG's entities.json, the longest name that prefixes the text winning, so the legacy names valid without a semicolon (&amp, &not, &eacute) decode;
  • decimal and hexadecimal numeric references, with the C1 controls that Windows-1252 assigns remapped to its characters, and U+0000, surrogates and values above U+10FFFF, however many digits they have, decoded to U+FFFD.

It decodes text content only: in an attribute value the tokenizer keeps a legacy name followed by = or an alphanumeric as written, which unescape does not do. It never raises.

The table is generated at build time from data/entities.json, WHATWG's file byte for byte (SHA-256 d741d877ac77c4194c4ad526b5b4a19aef8dfe411ab840a466891cdbb9f362e6, unchanged since 2016). The tests replay the text-content cases of html5lib-tests' entities.test, namedEntities.test and numericEntities.test.

Installation #

opam install html
  • html5rw is a full WHATWG parser that holds the same table and an entity decoder, but exports no escape, and its standalone decoder raises Invalid_argument on &#x7FFFFFFFFFFFFFFF; and keeps other overflowing numeric references as written.
  • tyxml escapes as it prints and decodes nothing.
  • markup.ml decodes references inside its parser; its table is internal.
  • nox-xml resolves the five XML entities only.

Licence #

ISC. data/entities.json is from the WHATWG HTML Living Standard, which is licensed under CC BY 4.0.