summaryrefslogtreecommitdiffstats
path: root/wp-includes/html-api
diff options
context:
space:
mode:
Diffstat (limited to 'wp-includes/html-api')
-rw-r--r--wp-includes/html-api/class-wp-html-decoder.php461
-rw-r--r--wp-includes/html-api/class-wp-html-open-elements.php81
-rw-r--r--wp-includes/html-api/class-wp-html-processor.php617
-rw-r--r--wp-includes/html-api/class-wp-html-stack-event.php82
-rw-r--r--wp-includes/html-api/class-wp-html-tag-processor.php40
-rw-r--r--wp-includes/html-api/html5-named-character-references.php1313
6 files changed, 2538 insertions, 56 deletions
diff --git a/wp-includes/html-api/class-wp-html-decoder.php b/wp-includes/html-api/class-wp-html-decoder.php
new file mode 100644
index 0000000..7897600
--- /dev/null
+++ b/wp-includes/html-api/class-wp-html-decoder.php
@@ -0,0 +1,461 @@
+<?php
+
+/**
+ * HTML API: WP_HTML_Decoder class
+ *
+ * Decodes spans of raw text found inside HTML content.
+ *
+ * @package WordPress
+ * @subpackage HTML-API
+ * @since 6.6.0
+ */
+class WP_HTML_Decoder {
+ /**
+ * Indicates if an attribute value starts with a given raw string value.
+ *
+ * Use this method to determine if an attribute value starts with a given string, regardless
+ * of how it might be encoded in HTML. For instance, `http:` could be represented as `http:`
+ * or as `http&colon;` or as `&#x68;ttp:` or as `h&#116;tp&colon;`, or in many other ways.
+ *
+ * Example:
+ *
+ * $value = 'http&colon;//wordpress.org/';
+ * true === WP_HTML_Decoder::attribute_starts_with( $value, 'http:', 'ascii-case-insensitive' );
+ * false === WP_HTML_Decoder::attribute_starts_with( $value, 'https:', 'ascii-case-insensitive' );
+ *
+ * @since 6.6.0
+ *
+ * @param string $haystack String containing the raw non-decoded attribute value.
+ * @param string $search_text Does the attribute value start with this plain string.
+ * @param string $case_sensitivity Optional. Pass 'ascii-case-insensitive' to ignore ASCII case when matching.
+ * Default 'case-sensitive'.
+ * @return bool Whether the attribute value starts with the given string.
+ */
+ public static function attribute_starts_with( $haystack, $search_text, $case_sensitivity = 'case-sensitive' ) {
+ $search_length = strlen( $search_text );
+ $loose_case = 'ascii-case-insensitive' === $case_sensitivity;
+ $haystack_end = strlen( $haystack );
+ $search_at = 0;
+ $haystack_at = 0;
+
+ while ( $search_at < $search_length && $haystack_at < $haystack_end ) {
+ $chars_match = $loose_case
+ ? strtolower( $haystack[ $haystack_at ] ) === strtolower( $search_text[ $search_at ] )
+ : $haystack[ $haystack_at ] === $search_text[ $search_at ];
+
+ $is_introducer = '&' === $haystack[ $haystack_at ];
+ $next_chunk = $is_introducer
+ ? self::read_character_reference( 'attribute', $haystack, $haystack_at, $token_length )
+ : null;
+
+ // If there's no character reference and the characters don't match, the match fails.
+ if ( null === $next_chunk && ! $chars_match ) {
+ return false;
+ }
+
+ // If there's no character reference but the character do match, then it could still match.
+ if ( null === $next_chunk && $chars_match ) {
+ ++$haystack_at;
+ ++$search_at;
+ continue;
+ }
+
+ // If there is a character reference, then the decoded value must exactly match what follows in the search string.
+ if ( 0 !== substr_compare( $search_text, $next_chunk, $search_at, strlen( $next_chunk ), $loose_case ) ) {
+ return false;
+ }
+
+ // The character reference matched, so continue checking.
+ $haystack_at += $token_length;
+ $search_at += strlen( $next_chunk );
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns a string containing the decoded value of a given HTML text node.
+ *
+ * Text nodes appear in HTML DATA sections, which are the text segments inside
+ * and around tags, excepting SCRIPT and STYLE elements (and some others),
+ * whose inner text is not decoded. Use this function to read the decoded
+ * value of such a text span in an HTML document.
+ *
+ * Example:
+ *
+ * '“😄”' === WP_HTML_Decode::decode_text_node( '&#x93;&#x1f604;&#x94' );
+ *
+ * @since 6.6.0
+ *
+ * @param string $text Text containing raw and non-decoded text node to decode.
+ * @return string Decoded UTF-8 value of given text node.
+ */
+ public static function decode_text_node( $text ) {
+ return static::decode( 'data', $text );
+ }
+
+ /**
+ * Returns a string containing the decoded value of a given HTML attribute.
+ *
+ * Text found inside an HTML attribute has different parsing rules than for
+ * text found inside other markup, or DATA segments. Use this function to
+ * read the decoded value of an HTML string inside a quoted attribute.
+ *
+ * Example:
+ *
+ * '“😄”' === WP_HTML_Decode::decode_attribute( '&#x93;&#x1f604;&#x94' );
+ *
+ * @since 6.6.0
+ *
+ * @param string $text Text containing raw and non-decoded attribute value to decode.
+ * @return string Decoded UTF-8 value of given attribute value.
+ */
+ public static function decode_attribute( $text ) {
+ return static::decode( 'attribute', $text );
+ }
+
+ /**
+ * Decodes a span of HTML text, depending on the context in which it's found.
+ *
+ * This is a low-level method; prefer calling WP_HTML_Decoder::decode_attribute() or
+ * WP_HTML_Decoder::decode_text_node() instead. It's provided for cases where this
+ * may be difficult to do from calling code.
+ *
+ * Example:
+ *
+ * '©' = WP_HTML_Decoder::decode( 'data', '&copy;' );
+ *
+ * @since 6.6.0
+ *
+ * @access private
+ *
+ * @param string $context `attribute` for decoding attribute values, `data` otherwise.
+ * @param string $text Text document containing span of text to decode.
+ * @return string Decoded UTF-8 string.
+ */
+ public static function decode( $context, $text ) {
+ $decoded = '';
+ $end = strlen( $text );
+ $at = 0;
+ $was_at = 0;
+
+ while ( $at < $end ) {
+ $next_character_reference_at = strpos( $text, '&', $at );
+ if ( false === $next_character_reference_at || $next_character_reference_at >= $end ) {
+ break;
+ }
+
+ $character_reference = self::read_character_reference( $context, $text, $next_character_reference_at, $token_length );
+ if ( isset( $character_reference ) ) {
+ $at = $next_character_reference_at;
+ $decoded .= substr( $text, $was_at, $at - $was_at );
+ $decoded .= $character_reference;
+ $at += $token_length;
+ $was_at = $at;
+ continue;
+ }
+
+ ++$at;
+ }
+
+ if ( 0 === $was_at ) {
+ return $text;
+ }
+
+ if ( $was_at < $end ) {
+ $decoded .= substr( $text, $was_at, $end - $was_at );
+ }
+
+ return $decoded;
+ }
+
+ /**
+ * Attempt to read a character reference at the given location in a given string,
+ * depending on the context in which it's found.
+ *
+ * If a character reference is found, this function will return the translated value
+ * that the reference maps to. It will then set `$match_byte_length` the
+ * number of bytes of input it read while consuming the character reference. This
+ * gives calling code the opportunity to advance its cursor when traversing a string
+ * and decoding.
+ *
+ * Example:
+ *
+ * null === WP_HTML_Decoder::read_character_reference( 'attribute', 'Ships&hellip;', 0 );
+ * '…' === WP_HTML_Decoder::read_character_reference( 'attribute', 'Ships&hellip;', 5, $token_length );
+ * 8 === $token_length; // `&hellip;`
+ *
+ * null === WP_HTML_Decoder::read_character_reference( 'attribute', '&notin', 0 );
+ * '∉' === WP_HTML_Decoder::read_character_reference( 'attribute', '&notin;', 0, $token_length );
+ * 7 === $token_length; // `&notin;`
+ *
+ * '¬' === WP_HTML_Decoder::read_character_reference( 'data', '&notin', 0, $token_length );
+ * 4 === $token_length; // `&not`
+ * '∉' === WP_HTML_Decoder::read_character_reference( 'data', '&notin;', 0, $token_length );
+ * 7 === $token_length; // `&notin;`
+ *
+ * @since 6.6.0
+ *
+ * @param string $context `attribute` for decoding attribute values, `data` otherwise.
+ * @param string $text Text document containing span of text to decode.
+ * @param int $at Optional. Byte offset into text where span begins, defaults to the beginning (0).
+ * @param int &$match_byte_length Optional. Set to byte-length of character reference if provided and if a match
+ * is found, otherwise not set. Default null.
+ * @return string|false Decoded character reference in UTF-8 if found, otherwise `false`.
+ */
+ public static function read_character_reference( $context, $text, $at = 0, &$match_byte_length = null ) {
+ /**
+ * Mappings for HTML5 named character references.
+ *
+ * @var WP_Token_Map $html5_named_character_references
+ */
+ global $html5_named_character_references;
+
+ $length = strlen( $text );
+ if ( $at + 1 >= $length ) {
+ return null;
+ }
+
+ if ( '&' !== $text[ $at ] ) {
+ return null;
+ }
+
+ /*
+ * Numeric character references.
+ *
+ * When truncated, these will encode the code point found by parsing the
+ * digits that are available. For example, when `&#x1f170;` is truncated
+ * to `&#x1f1` it will encode `DZ`. It does not:
+ * - know how to parse the original `🅰`.
+ * - fail to parse and return plaintext `&#x1f1`.
+ * - fail to parse and return the replacement character `�`
+ */
+ if ( '#' === $text[ $at + 1 ] ) {
+ if ( $at + 2 >= $length ) {
+ return null;
+ }
+
+ /** Tracks inner parsing within the numeric character reference. */
+ $digits_at = $at + 2;
+
+ if ( 'x' === $text[ $digits_at ] || 'X' === $text[ $digits_at ] ) {
+ $numeric_base = 16;
+ $numeric_digits = '0123456789abcdefABCDEF';
+ $max_digits = 6; // &#x10FFFF;
+ ++$digits_at;
+ } else {
+ $numeric_base = 10;
+ $numeric_digits = '0123456789';
+ $max_digits = 7; // &#1114111;
+ }
+
+ // Cannot encode invalid Unicode code points. Max is to U+10FFFF.
+ $zero_count = strspn( $text, '0', $digits_at );
+ $digit_count = strspn( $text, $numeric_digits, $digits_at + $zero_count );
+ $after_digits = $digits_at + $zero_count + $digit_count;
+ $has_semicolon = $after_digits < $length && ';' === $text[ $after_digits ];
+ $end_of_span = $has_semicolon ? $after_digits + 1 : $after_digits;
+
+ // `&#` or `&#x` without digits returns into plaintext.
+ if ( 0 === $digit_count && 0 === $zero_count ) {
+ return null;
+ }
+
+ // Whereas `&#` and only zeros is invalid.
+ if ( 0 === $digit_count ) {
+ $match_byte_length = $end_of_span - $at;
+ return '�';
+ }
+
+ // If there are too many digits then it's not worth parsing. It's invalid.
+ if ( $digit_count > $max_digits ) {
+ $match_byte_length = $end_of_span - $at;
+ return '�';
+ }
+
+ $digits = substr( $text, $digits_at + $zero_count, $digit_count );
+ $code_point = intval( $digits, $numeric_base );
+
+ /*
+ * Noncharacters, 0x0D, and non-ASCII-whitespace control characters.
+ *
+ * > A noncharacter is a code point that is in the range U+FDD0 to U+FDEF,
+ * > inclusive, or U+FFFE, U+FFFF, U+1FFFE, U+1FFFF, U+2FFFE, U+2FFFF,
+ * > U+3FFFE, U+3FFFF, U+4FFFE, U+4FFFF, U+5FFFE, U+5FFFF, U+6FFFE,
+ * > U+6FFFF, U+7FFFE, U+7FFFF, U+8FFFE, U+8FFFF, U+9FFFE, U+9FFFF,
+ * > U+AFFFE, U+AFFFF, U+BFFFE, U+BFFFF, U+CFFFE, U+CFFFF, U+DFFFE,
+ * > U+DFFFF, U+EFFFE, U+EFFFF, U+FFFFE, U+FFFFF, U+10FFFE, or U+10FFFF.
+ *
+ * A C0 control is a code point that is in the range of U+00 to U+1F,
+ * but ASCII whitespace includes U+09, U+0A, U+0C, and U+0D.
+ *
+ * These characters are invalid but still decode as any valid character.
+ * This comment is here to note and explain why there's no check to
+ * remove these characters or replace them.
+ *
+ * @see https://infra.spec.whatwg.org/#noncharacter
+ */
+
+ /*
+ * Code points in the C1 controls area need to be remapped as if they
+ * were stored in Windows-1252. Note! This transformation only happens
+ * for numeric character references. The raw code points in the byte
+ * stream are not translated.
+ *
+ * > If the number is one of the numbers in the first column of
+ * > the following table, then find the row with that number in
+ * > the first column, and set the character reference code to
+ * > the number in the second column of that row.
+ */
+ if ( $code_point >= 0x80 && $code_point <= 0x9F ) {
+ $windows_1252_mapping = array(
+ 0x20AC, // 0x80 -> EURO SIGN (€).
+ 0x81, // 0x81 -> (no change).
+ 0x201A, // 0x82 -> SINGLE LOW-9 QUOTATION MARK (‚).
+ 0x0192, // 0x83 -> LATIN SMALL LETTER F WITH HOOK (ƒ).
+ 0x201E, // 0x84 -> DOUBLE LOW-9 QUOTATION MARK („).
+ 0x2026, // 0x85 -> HORIZONTAL ELLIPSIS (…).
+ 0x2020, // 0x86 -> DAGGER (†).
+ 0x2021, // 0x87 -> DOUBLE DAGGER (‡).
+ 0x02C6, // 0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT (ˆ).
+ 0x2030, // 0x89 -> PER MILLE SIGN (‰).
+ 0x0160, // 0x8A -> LATIN CAPITAL LETTER S WITH CARON (Š).
+ 0x2039, // 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK (‹).
+ 0x0152, // 0x8C -> LATIN CAPITAL LIGATURE OE (Œ).
+ 0x8D, // 0x8D -> (no change).
+ 0x017D, // 0x8E -> LATIN CAPITAL LETTER Z WITH CARON (Ž).
+ 0x8F, // 0x8F -> (no change).
+ 0x90, // 0x90 -> (no change).
+ 0x2018, // 0x91 -> LEFT SINGLE QUOTATION MARK (‘).
+ 0x2019, // 0x92 -> RIGHT SINGLE QUOTATION MARK (’).
+ 0x201C, // 0x93 -> LEFT DOUBLE QUOTATION MARK (“).
+ 0x201D, // 0x94 -> RIGHT DOUBLE QUOTATION MARK (”).
+ 0x2022, // 0x95 -> BULLET (•).
+ 0x2013, // 0x96 -> EN DASH (–).
+ 0x2014, // 0x97 -> EM DASH (—).
+ 0x02DC, // 0x98 -> SMALL TILDE (˜).
+ 0x2122, // 0x99 -> TRADE MARK SIGN (™).
+ 0x0161, // 0x9A -> LATIN SMALL LETTER S WITH CARON (š).
+ 0x203A, // 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (›).
+ 0x0153, // 0x9C -> LATIN SMALL LIGATURE OE (œ).
+ 0x9D, // 0x9D -> (no change).
+ 0x017E, // 0x9E -> LATIN SMALL LETTER Z WITH CARON (ž).
+ 0x0178, // 0x9F -> LATIN CAPITAL LETTER Y WITH DIAERESIS (Ÿ).
+ );
+
+ $code_point = $windows_1252_mapping[ $code_point - 0x80 ];
+ }
+
+ $match_byte_length = $end_of_span - $at;
+ return self::code_point_to_utf8_bytes( $code_point );
+ }
+
+ /** Tracks inner parsing within the named character reference. */
+ $name_at = $at + 1;
+ // Minimum named character reference is two characters. E.g. `GT`.
+ if ( $name_at + 2 > $length ) {
+ return null;
+ }
+
+ $name_length = 0;
+ $replacement = $html5_named_character_references->read_token( $text, $name_at, $name_length );
+ if ( false === $replacement ) {
+ return null;
+ }
+
+ $after_name = $name_at + $name_length;
+
+ // If the match ended with a semicolon then it should always be decoded.
+ if ( ';' === $text[ $name_at + $name_length - 1 ] ) {
+ $match_byte_length = $after_name - $at;
+ return $replacement;
+ }
+
+ /*
+ * At this point though there's a match for an entry in the named
+ * character reference table but the match doesn't end in `;`.
+ * It may be allowed if it's followed by something unambiguous.
+ */
+ $ambiguous_follower = (
+ $after_name < $length &&
+ $name_at < $length &&
+ (
+ ctype_alnum( $text[ $after_name ] ) ||
+ '=' === $text[ $after_name ]
+ )
+ );
+
+ // It's non-ambiguous, safe to leave it in.
+ if ( ! $ambiguous_follower ) {
+ $match_byte_length = $after_name - $at;
+ return $replacement;
+ }
+
+ // It's ambiguous, which isn't allowed inside attributes.
+ if ( 'attribute' === $context ) {
+ return null;
+ }
+
+ $match_byte_length = $after_name - $at;
+ return $replacement;
+ }
+
+ /**
+ * Encode a code point number into the UTF-8 encoding.
+ *
+ * This encoder implements the UTF-8 encoding algorithm for converting
+ * a code point into a byte sequence. If it receives an invalid code
+ * point it will return the Unicode Replacement Character U+FFFD `�`.
+ *
+ * Example:
+ *
+ * '🅰' === WP_HTML_Decoder::code_point_to_utf8_bytes( 0x1f170 );
+ *
+ * // Half of a surrogate pair is an invalid code point.
+ * '�' === WP_HTML_Decoder::code_point_to_utf8_bytes( 0xd83c );
+ *
+ * @since 6.6.0
+ *
+ * @see https://www.rfc-editor.org/rfc/rfc3629 For the UTF-8 standard.
+ *
+ * @param int $code_point Which code point to convert.
+ * @return string Converted code point, or `�` if invalid.
+ */
+ public static function code_point_to_utf8_bytes( $code_point ) {
+ // Pre-check to ensure a valid code point.
+ if (
+ $code_point <= 0 ||
+ ( $code_point >= 0xD800 && $code_point <= 0xDFFF ) ||
+ $code_point > 0x10FFFF
+ ) {
+ return '�';
+ }
+
+ if ( $code_point <= 0x7F ) {
+ return chr( $code_point );
+ }
+
+ if ( $code_point <= 0x7FF ) {
+ $byte1 = ( $code_point >> 6 ) | 0xC0;
+ $byte2 = $code_point & 0x3F | 0x80;
+
+ return pack( 'CC', $byte1, $byte2 );
+ }
+
+ if ( $code_point <= 0xFFFF ) {
+ $byte1 = ( $code_point >> 12 ) | 0xE0;
+ $byte2 = ( $code_point >> 6 ) & 0x3F | 0x80;
+ $byte3 = $code_point & 0x3F | 0x80;
+
+ return pack( 'CCC', $byte1, $byte2, $byte3 );
+ }
+
+ // Any values above U+10FFFF are eliminated above in the pre-check.
+ $byte1 = ( $code_point >> 18 ) | 0xF0;
+ $byte2 = ( $code_point >> 12 ) & 0x3F | 0x80;
+ $byte3 = ( $code_point >> 6 ) & 0x3F | 0x80;
+ $byte4 = $code_point & 0x3F | 0x80;
+
+ return pack( 'CCCC', $byte1, $byte2, $byte3, $byte4 );
+ }
+}
diff --git a/wp-includes/html-api/class-wp-html-open-elements.php b/wp-includes/html-api/class-wp-html-open-elements.php
index 1234abc..1547980 100644
--- a/wp-includes/html-api/class-wp-html-open-elements.php
+++ b/wp-includes/html-api/class-wp-html-open-elements.php
@@ -52,6 +52,56 @@ class WP_HTML_Open_Elements {
private $has_p_in_button_scope = false;
/**
+ * A function that will be called when an item is popped off the stack of open elements.
+ *
+ * The function will be called with the popped item as its argument.
+ *
+ * @since 6.6.0
+ *
+ * @var Closure
+ */
+ private $pop_handler = null;
+
+ /**
+ * A function that will be called when an item is pushed onto the stack of open elements.
+ *
+ * The function will be called with the pushed item as its argument.
+ *
+ * @since 6.6.0
+ *
+ * @var Closure
+ */
+ private $push_handler = null;
+
+ /**
+ * Sets a pop handler that will be called when an item is popped off the stack of
+ * open elements.
+ *
+ * The function will be called with the pushed item as its argument.
+ *
+ * @since 6.6.0
+ *
+ * @param Closure $handler The handler function.
+ */
+ public function set_pop_handler( Closure $handler ) {
+ $this->pop_handler = $handler;
+ }
+
+ /**
+ * Sets a push handler that will be called when an item is pushed onto the stack of
+ * open elements.
+ *
+ * The function will be called with the pushed item as its argument.
+ *
+ * @since 6.6.0
+ *
+ * @param Closure $handler The handler function.
+ */
+ public function set_push_handler( Closure $handler ) {
+ $this->push_handler = $handler;
+ }
+
+ /**
* Reports if a specific node is in the stack of open elements.
*
* @since 6.4.0
@@ -258,11 +308,15 @@ class WP_HTML_Open_Elements {
*/
public function pop() {
$item = array_pop( $this->stack );
-
if ( null === $item ) {
return false;
}
+ if ( 'context-node' === $item->bookmark_name ) {
+ $this->stack[] = $item;
+ return false;
+ }
+
$this->after_element_pop( $item );
return true;
}
@@ -279,6 +333,10 @@ class WP_HTML_Open_Elements {
*/
public function pop_until( $tag_name ) {
foreach ( $this->walk_up() as $item ) {
+ if ( 'context-node' === $item->bookmark_name ) {
+ return true;
+ }
+
$this->pop();
if (
@@ -319,6 +377,10 @@ class WP_HTML_Open_Elements {
* @return bool Whether the node was found and removed from the stack of open elements.
*/
public function remove_node( $token ) {
+ if ( 'context-node' === $token->bookmark_name ) {
+ return false;
+ }
+
foreach ( $this->walk_up() as $position_from_end => $item ) {
if ( $token->bookmark_name !== $item->bookmark_name ) {
continue;
@@ -429,6 +491,10 @@ class WP_HTML_Open_Elements {
$this->has_p_in_button_scope = true;
break;
}
+
+ if ( null !== $this->push_handler ) {
+ ( $this->push_handler )( $item );
+ }
}
/**
@@ -458,5 +524,18 @@ class WP_HTML_Open_Elements {
$this->has_p_in_button_scope = $this->has_element_in_button_scope( 'P' );
break;
}
+
+ if ( null !== $this->pop_handler ) {
+ ( $this->pop_handler )( $item );
+ }
+ }
+
+ /**
+ * Wakeup magic method.
+ *
+ * @since 6.6.0
+ */
+ public function __wakeup() {
+ throw new \LogicException( __CLASS__ . ' should never be unserialized' );
}
}
diff --git a/wp-includes/html-api/class-wp-html-processor.php b/wp-includes/html-api/class-wp-html-processor.php
index c76cc19..29f1c7a 100644
--- a/wp-includes/html-api/class-wp-html-processor.php
+++ b/wp-includes/html-api/class-wp-html-processor.php
@@ -201,6 +201,52 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
*/
private $release_internal_bookmark_on_destruct = null;
+ /**
+ * Stores stack events which arise during parsing of the
+ * HTML document, which will then supply the "match" events.
+ *
+ * @since 6.6.0
+ *
+ * @var WP_HTML_Stack_Event[]
+ */
+ private $element_queue = array();
+
+ /**
+ * Current stack event, if set, representing a matched token.
+ *
+ * Because the parser may internally point to a place further along in a document
+ * than the nodes which have already been processed (some "virtual" nodes may have
+ * appeared while scanning the HTML document), this will point at the "current" node
+ * being processed. It comes from the front of the element queue.
+ *
+ * @since 6.6.0
+ *
+ * @var ?WP_HTML_Stack_Event
+ */
+ private $current_element = null;
+
+ /**
+ * Context node if created as a fragment parser.
+ *
+ * @var ?WP_HTML_Token
+ */
+ private $context_node = null;
+
+ /**
+ * Whether the parser has yet processed the context node,
+ * if created as a fragment parser.
+ *
+ * The context node will be initially pushed onto the stack of open elements,
+ * but when created as a fragment parser, this context element (and the implicit
+ * HTML document node above it) should not be exposed as a matched token or node.
+ *
+ * This boolean indicates whether the processor should skip over the current
+ * node in its initial search for the first node created from the input HTML.
+ *
+ * @var bool
+ */
+ private $has_seen_context_node = false;
+
/*
* Public Interface Functions
*/
@@ -230,18 +276,19 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
* - The only supported document encoding is `UTF-8`, which is the default value.
*
* @since 6.4.0
+ * @since 6.6.0 Returns `static` instead of `self` so it can create subclass instances.
*
* @param string $html Input HTML fragment to process.
* @param string $context Context element for the fragment, must be default of `<body>`.
* @param string $encoding Text encoding of the document; must be default of 'UTF-8'.
- * @return WP_HTML_Processor|null The created processor if successful, otherwise null.
+ * @return static|null The created processor if successful, otherwise null.
*/
public static function create_fragment( $html, $context = '<body>', $encoding = 'UTF-8' ) {
if ( '<body>' !== $context || 'UTF-8' !== $encoding ) {
return null;
}
- $processor = new self( $html, self::CONSTRUCTOR_UNLOCK_CODE );
+ $processor = new static( $html, self::CONSTRUCTOR_UNLOCK_CODE );
$processor->state->context_node = array( 'BODY', array() );
$processor->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY;
@@ -257,14 +304,15 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
)
);
- $processor->state->stack_of_open_elements->push(
- new WP_HTML_Token(
- 'context-node',
- $processor->state->context_node[0],
- false
- )
+ $context_node = new WP_HTML_Token(
+ 'context-node',
+ $processor->state->context_node[0],
+ false
);
+ $processor->state->stack_of_open_elements->push( $context_node );
+ $processor->context_node = $context_node;
+
return $processor;
}
@@ -299,6 +347,24 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
$this->state = new WP_HTML_Processor_State();
+ $this->state->stack_of_open_elements->set_push_handler(
+ function ( WP_HTML_Token $token ) {
+ $is_virtual = ! isset( $this->state->current_token ) || $this->is_tag_closer();
+ $same_node = isset( $this->state->current_token ) && $token->node_name === $this->state->current_token->node_name;
+ $provenance = ( ! $same_node || $is_virtual ) ? 'virtual' : 'real';
+ $this->element_queue[] = new WP_HTML_Stack_Event( $token, WP_HTML_Stack_Event::PUSH, $provenance );
+ }
+ );
+
+ $this->state->stack_of_open_elements->set_pop_handler(
+ function ( WP_HTML_Token $token ) {
+ $is_virtual = ! isset( $this->state->current_token ) || ! $this->is_tag_closer();
+ $same_node = isset( $this->state->current_token ) && $token->node_name === $this->state->current_token->node_name;
+ $provenance = ( ! $same_node || $is_virtual ) ? 'virtual' : 'real';
+ $this->element_queue[] = new WP_HTML_Stack_Event( $token, WP_HTML_Stack_Event::POP, $provenance );
+ }
+ );
+
/*
* Create this wrapper so that it's possible to pass
* a private method into WP_HTML_Token classes without
@@ -342,6 +408,7 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
* @todo Support matching the class name and tag name.
*
* @since 6.4.0
+ * @since 6.6.0 Visits all tokens, including virtual ones.
*
* @throws Exception When unable to allocate a bookmark for the next token in the input HTML document.
*
@@ -349,6 +416,7 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
* Optional. Which tag name to find, having which class, etc. Default is to find any tag.
*
* @type string|null $tag_name Which tag to find, or `null` for "any tag."
+ * @type string $tag_closers 'visit' to pause at tag closers, 'skip' or unset to only visit openers.
* @type int|null $match_offset Find the Nth tag matching all search criteria.
* 1 for "first" tag, 3 for "third," etc.
* Defaults to first tag.
@@ -359,13 +427,15 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
* @return bool Whether a tag was matched.
*/
public function next_tag( $query = null ) {
+ $visit_closers = isset( $query['tag_closers'] ) && 'visit' === $query['tag_closers'];
+
if ( null === $query ) {
- while ( $this->step() ) {
+ while ( $this->next_token() ) {
if ( '#tag' !== $this->get_token_type() ) {
continue;
}
- if ( ! $this->is_tag_closer() ) {
+ if ( ! $this->is_tag_closer() || $visit_closers ) {
return true;
}
}
@@ -386,13 +456,21 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
return false;
}
+ $needs_class = ( isset( $query['class_name'] ) && is_string( $query['class_name'] ) )
+ ? $query['class_name']
+ : null;
+
if ( ! ( array_key_exists( 'breadcrumbs', $query ) && is_array( $query['breadcrumbs'] ) ) ) {
- while ( $this->step() ) {
+ while ( $this->next_token() ) {
if ( '#tag' !== $this->get_token_type() ) {
continue;
}
- if ( ! $this->is_tag_closer() ) {
+ if ( isset( $needs_class ) && ! $this->has_class( $needs_class ) ) {
+ continue;
+ }
+
+ if ( ! $this->is_tag_closer() || $visit_closers ) {
return true;
}
}
@@ -400,20 +478,15 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
return false;
}
- if ( isset( $query['tag_closers'] ) && 'visit' === $query['tag_closers'] ) {
- _doing_it_wrong(
- __METHOD__,
- __( 'Cannot visit tag closers in HTML Processor.' ),
- '6.4.0'
- );
- return false;
- }
-
$breadcrumbs = $query['breadcrumbs'];
$match_offset = isset( $query['match_offset'] ) ? (int) $query['match_offset'] : 1;
- while ( $match_offset > 0 && $this->step() ) {
- if ( '#tag' !== $this->get_token_type() ) {
+ while ( $match_offset > 0 && $this->next_token() ) {
+ if ( '#tag' !== $this->get_token_type() || $this->is_tag_closer() ) {
+ continue;
+ }
+
+ if ( isset( $needs_class ) && ! $this->has_class( $needs_class ) ) {
continue;
}
@@ -440,7 +513,92 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
* @return bool
*/
public function next_token() {
- return $this->step();
+ $this->current_element = null;
+
+ if ( isset( $this->last_error ) ) {
+ return false;
+ }
+
+ if ( 'done' !== $this->has_seen_context_node && 0 === count( $this->element_queue ) && ! $this->step() ) {
+ while ( 'context-node' !== $this->state->stack_of_open_elements->current_node()->bookmark_name && $this->state->stack_of_open_elements->pop() ) {
+ continue;
+ }
+ $this->has_seen_context_node = 'done';
+ return $this->next_token();
+ }
+
+ $this->current_element = array_shift( $this->element_queue );
+ while ( isset( $this->context_node ) && ! $this->has_seen_context_node ) {
+ if ( isset( $this->current_element ) ) {
+ if ( $this->context_node === $this->current_element->token && WP_HTML_Stack_Event::PUSH === $this->current_element->operation ) {
+ $this->has_seen_context_node = true;
+ return $this->next_token();
+ }
+ }
+ $this->current_element = array_shift( $this->element_queue );
+ }
+
+ if ( ! isset( $this->current_element ) ) {
+ if ( 'done' === $this->has_seen_context_node ) {
+ return false;
+ } else {
+ return $this->next_token();
+ }
+ }
+
+ if ( isset( $this->context_node ) && WP_HTML_Stack_Event::POP === $this->current_element->operation && $this->context_node === $this->current_element->token ) {
+ $this->element_queue = array();
+ $this->current_element = null;
+ return false;
+ }
+
+ // Avoid sending close events for elements which don't expect a closing.
+ if (
+ WP_HTML_Stack_Event::POP === $this->current_element->operation &&
+ ! static::expects_closer( $this->current_element->token )
+ ) {
+ return $this->next_token();
+ }
+
+ return true;
+ }
+
+
+ /**
+ * Indicates if the current tag token is a tag closer.
+ *
+ * Example:
+ *
+ * $p = WP_HTML_Processor::create_fragment( '<div></div>' );
+ * $p->next_tag( array( 'tag_name' => 'div', 'tag_closers' => 'visit' ) );
+ * $p->is_tag_closer() === false;
+ *
+ * $p->next_tag( array( 'tag_name' => 'div', 'tag_closers' => 'visit' ) );
+ * $p->is_tag_closer() === true;
+ *
+ * @since 6.6.0 Subclassed for HTML Processor.
+ *
+ * @return bool Whether the current tag is a tag closer.
+ */
+ public function is_tag_closer() {
+ return $this->is_virtual()
+ ? ( WP_HTML_Stack_Event::POP === $this->current_element->operation && '#tag' === $this->get_token_type() )
+ : parent::is_tag_closer();
+ }
+
+ /**
+ * Indicates if the currently-matched token is virtual, created by a stack operation
+ * while processing HTML, rather than a token found in the HTML text itself.
+ *
+ * @since 6.6.0
+ *
+ * @return bool Whether the current token is virtual.
+ */
+ private function is_virtual() {
+ return (
+ isset( $this->current_element->provenance ) &&
+ 'virtual' === $this->current_element->provenance
+ );
}
/**
@@ -497,6 +655,45 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
}
/**
+ * Indicates if the currently-matched node expects a closing
+ * token, or if it will self-close on the next step.
+ *
+ * Most HTML elements expect a closer, such as a P element or
+ * a DIV element. Others, like an IMG element are void and don't
+ * have a closing tag. Special elements, such as SCRIPT and STYLE,
+ * are treated just like void tags. Text nodes and self-closing
+ * foreign content will also act just like a void tag, immediately
+ * closing as soon as the processor advances to the next token.
+ *
+ * @since 6.6.0
+ *
+ * @todo When adding support for foreign content, ensure that
+ * this returns false for self-closing elements in the
+ * SVG and MathML namespace.
+ *
+ * @param ?WP_HTML_Token $node Node to examine instead of current node, if provided.
+ * @return bool Whether to expect a closer for the currently-matched node,
+ * or `null` if not matched on any token.
+ */
+ public function expects_closer( $node = null ) {
+ $token_name = $node->node_name ?? $this->get_token_name();
+ if ( ! isset( $token_name ) ) {
+ return null;
+ }
+
+ return ! (
+ // Comments, text nodes, and other atomic tokens.
+ '#' === $token_name[0] ||
+ // Doctype declarations.
+ 'html' === $token_name ||
+ // Void elements.
+ self::is_void( $token_name ) ||
+ // Special atomic elements.
+ in_array( $token_name, array( 'IFRAME', 'NOEMBED', 'NOFRAMES', 'SCRIPT', 'STYLE', 'TEXTAREA', 'TITLE', 'XMP' ), true )
+ );
+ }
+
+ /**
* Steps through the HTML document and stop at the next tag, if any.
*
* @since 6.4.0
@@ -531,16 +728,7 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
* is provided in the opening tag, otherwise it expects a tag closer.
*/
$top_node = $this->state->stack_of_open_elements->current_node();
- if (
- $top_node && (
- // Void elements.
- self::is_void( $top_node->node_name ) ||
- // Comments, text nodes, and other atomic tokens.
- '#' === $top_node->node_name[0] ||
- // Doctype declarations.
- 'html' === $top_node->node_name
- )
- ) {
+ if ( isset( $top_node ) && ! static::expects_closer( $top_node ) ) {
$this->state->stack_of_open_elements->pop();
}
}
@@ -604,14 +792,79 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
*/
public function get_breadcrumbs() {
$breadcrumbs = array();
+
foreach ( $this->state->stack_of_open_elements->walk_down() as $stack_item ) {
$breadcrumbs[] = $stack_item->node_name;
}
+ if ( ! $this->is_virtual() ) {
+ return $breadcrumbs;
+ }
+
+ foreach ( $this->element_queue as $queue_item ) {
+ if ( $this->current_element->token->bookmark_name === $queue_item->token->bookmark_name ) {
+ break;
+ }
+
+ if ( 'context-node' === $queue_item->token->bookmark_name ) {
+ break;
+ }
+
+ if ( 'real' === $queue_item->provenance ) {
+ break;
+ }
+
+ if ( WP_HTML_Stack_Event::PUSH === $queue_item->operation ) {
+ $breadcrumbs[] = $queue_item->token->node_name;
+ } else {
+ array_pop( $breadcrumbs );
+ }
+ }
+
+ if ( null !== parent::get_token_name() && ! parent::is_tag_closer() ) {
+ array_pop( $breadcrumbs );
+ }
+
+ // Add the virtual node we're at.
+ if ( WP_HTML_Stack_Event::PUSH === $this->current_element->operation ) {
+ $breadcrumbs[] = $this->current_element->token->node_name;
+ }
+
return $breadcrumbs;
}
/**
+ * Returns the nesting depth of the current location in the document.
+ *
+ * Example:
+ *
+ * $processor = WP_HTML_Processor::create_fragment( '<div><p></p></div>' );
+ * // The processor starts in the BODY context, meaning it has depth from the start: HTML > BODY.
+ * 2 === $processor->get_current_depth();
+ *
+ * // Opening the DIV element increases the depth.
+ * $processor->next_token();
+ * 3 === $processor->get_current_depth();
+ *
+ * // Opening the P element increases the depth.
+ * $processor->next_token();
+ * 4 === $processor->get_current_depth();
+ *
+ * // The P element is closed during `next_token()` so the depth is decreased to reflect that.
+ * $processor->next_token();
+ * 3 === $processor->get_current_depth();
+ *
+ * @since 6.6.0
+ *
+ * @return int Nesting-depth of current location in the document.
+ */
+ public function get_current_depth() {
+ return $this->is_virtual()
+ ? count( $this->get_breadcrumbs() )
+ : $this->state->stack_of_open_elements->count();
+ }
+
+ /**
* Parses next element in the 'in body' insertion mode.
*
* This internal function performs the 'in body' insertion mode
@@ -629,7 +882,7 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
private function step_in_body() {
$token_name = $this->get_token_name();
$token_type = $this->get_token_type();
- $op_sigil = '#tag' === $token_type ? ( $this->is_tag_closer() ? '-' : '+' ) : '';
+ $op_sigil = '#tag' === $token_type ? ( parent::is_tag_closer() ? '-' : '+' ) : '';
$op = "{$op_sigil}{$token_name}";
switch ( $op ) {
@@ -1152,7 +1405,7 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
throw new WP_HTML_Unsupported_Exception( "Cannot process {$token_name} element." );
}
- if ( ! $this->is_tag_closer() ) {
+ if ( ! parent::is_tag_closer() ) {
/*
* > Any other start tag
*/
@@ -1248,6 +1501,10 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
return null;
}
+ if ( $this->is_virtual() ) {
+ return $this->current_element->token->node_name;
+ }
+
$tag_name = parent::get_tag();
switch ( $tag_name ) {
@@ -1264,6 +1521,286 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
}
/**
+ * Indicates if the currently matched tag contains the self-closing flag.
+ *
+ * No HTML elements ought to have the self-closing flag and for those, the self-closing
+ * flag will be ignored. For void elements this is benign because they "self close"
+ * automatically. For non-void HTML elements though problems will appear if someone
+ * intends to use a self-closing element in place of that element with an empty body.
+ * For HTML foreign elements and custom elements the self-closing flag determines if
+ * they self-close or not.
+ *
+ * This function does not determine if a tag is self-closing,
+ * but only if the self-closing flag is present in the syntax.
+ *
+ * @since 6.6.0 Subclassed for the HTML Processor.
+ *
+ * @return bool Whether the currently matched tag contains the self-closing flag.
+ */
+ public function has_self_closing_flag() {
+ return $this->is_virtual() ? false : parent::has_self_closing_flag();
+ }
+
+ /**
+ * Returns the node name represented by the token.
+ *
+ * This matches the DOM API value `nodeName`. Some values
+ * are static, such as `#text` for a text node, while others
+ * are dynamically generated from the token itself.
+ *
+ * Dynamic names:
+ * - Uppercase tag name for tag matches.
+ * - `html` for DOCTYPE declarations.
+ *
+ * Note that if the Tag Processor is not matched on a token
+ * then this function will return `null`, either because it
+ * hasn't yet found a token or because it reached the end
+ * of the document without matching a token.
+ *
+ * @since 6.6.0 Subclassed for the HTML Processor.
+ *
+ * @return string|null Name of the matched token.
+ */
+ public function get_token_name() {
+ return $this->is_virtual()
+ ? $this->current_element->token->node_name
+ : parent::get_token_name();
+ }
+
+ /**
+ * Indicates the kind of matched token, if any.
+ *
+ * This differs from `get_token_name()` in that it always
+ * returns a static string indicating the type, whereas
+ * `get_token_name()` may return values derived from the
+ * token itself, such as a tag name or processing
+ * instruction tag.
+ *
+ * Possible values:
+ * - `#tag` when matched on a tag.
+ * - `#text` when matched on a text node.
+ * - `#cdata-section` when matched on a CDATA node.
+ * - `#comment` when matched on a comment.
+ * - `#doctype` when matched on a DOCTYPE declaration.
+ * - `#presumptuous-tag` when matched on an empty tag closer.
+ * - `#funky-comment` when matched on a funky comment.
+ *
+ * @since 6.6.0 Subclassed for the HTML Processor.
+ *
+ * @return string|null What kind of token is matched, or null.
+ */
+ public function get_token_type() {
+ if ( $this->is_virtual() ) {
+ /*
+ * This logic comes from the Tag Processor.
+ *
+ * @todo It would be ideal not to repeat this here, but it's not clearly
+ * better to allow passing a token name to `get_token_type()`.
+ */
+ $node_name = $this->current_element->token->node_name;
+ $starting_char = $node_name[0];
+ if ( 'A' <= $starting_char && 'Z' >= $starting_char ) {
+ return '#tag';
+ }
+
+ if ( 'html' === $node_name ) {
+ return '#doctype';
+ }
+
+ return $node_name;
+ }
+
+ return parent::get_token_type();
+ }
+
+ /**
+ * Returns the value of a requested attribute from a matched tag opener if that attribute exists.
+ *
+ * Example:
+ *
+ * $p = WP_HTML_Processor::create_fragment( '<div enabled class="test" data-test-id="14">Test</div>' );
+ * $p->next_token() === true;
+ * $p->get_attribute( 'data-test-id' ) === '14';
+ * $p->get_attribute( 'enabled' ) === true;
+ * $p->get_attribute( 'aria-label' ) === null;
+ *
+ * $p->next_tag() === false;
+ * $p->get_attribute( 'class' ) === null;
+ *
+ * @since 6.6.0 Subclassed for HTML Processor.
+ *
+ * @param string $name Name of attribute whose value is requested.
+ * @return string|true|null Value of attribute or `null` if not available. Boolean attributes return `true`.
+ */
+ public function get_attribute( $name ) {
+ return $this->is_virtual() ? null : parent::get_attribute( $name );
+ }
+
+ /**
+ * Updates or creates a new attribute on the currently matched tag with the passed value.
+ *
+ * For boolean attributes special handling is provided:
+ * - When `true` is passed as the value, then only the attribute name is added to the tag.
+ * - When `false` is passed, the attribute gets removed if it existed before.
+ *
+ * For string attributes, the value is escaped using the `esc_attr` function.
+ *
+ * @since 6.6.0 Subclassed for the HTML Processor.
+ *
+ * @param string $name The attribute name to target.
+ * @param string|bool $value The new attribute value.
+ * @return bool Whether an attribute value was set.
+ */
+ public function set_attribute( $name, $value ) {
+ return $this->is_virtual() ? false : parent::set_attribute( $name, $value );
+ }
+
+ /**
+ * Remove an attribute from the currently-matched tag.
+ *
+ * @since 6.6.0 Subclassed for HTML Processor.
+ *
+ * @param string $name The attribute name to remove.
+ * @return bool Whether an attribute was removed.
+ */
+ public function remove_attribute( $name ) {
+ return $this->is_virtual() ? false : parent::remove_attribute( $name );
+ }
+
+ /**
+ * Gets lowercase names of all attributes matching a given prefix in the current tag.
+ *
+ * Note that matching is case-insensitive. This is in accordance with the spec:
+ *
+ * > There must never be two or more attributes on
+ * > the same start tag whose names are an ASCII
+ * > case-insensitive match for each other.
+ * - HTML 5 spec
+ *
+ * Example:
+ *
+ * $p = new WP_HTML_Tag_Processor( '<div data-ENABLED class="test" DATA-test-id="14">Test</div>' );
+ * $p->next_tag( array( 'class_name' => 'test' ) ) === true;
+ * $p->get_attribute_names_with_prefix( 'data-' ) === array( 'data-enabled', 'data-test-id' );
+ *
+ * $p->next_tag() === false;
+ * $p->get_attribute_names_with_prefix( 'data-' ) === null;
+ *
+ * @since 6.6.0 Subclassed for the HTML Processor.
+ *
+ * @see https://html.spec.whatwg.org/multipage/syntax.html#attributes-2:ascii-case-insensitive
+ *
+ * @param string $prefix Prefix of requested attribute names.
+ * @return array|null List of attribute names, or `null` when no tag opener is matched.
+ */
+ public function get_attribute_names_with_prefix( $prefix ) {
+ return $this->is_virtual() ? null : parent::get_attribute_names_with_prefix( $prefix );
+ }
+
+ /**
+ * Adds a new class name to the currently matched tag.
+ *
+ * @since 6.6.0 Subclassed for the HTML Processor.
+ *
+ * @param string $class_name The class name to add.
+ * @return bool Whether the class was set to be added.
+ */
+ public function add_class( $class_name ) {
+ return $this->is_virtual() ? false : parent::add_class( $class_name );
+ }
+
+ /**
+ * Removes a class name from the currently matched tag.
+ *
+ * @since 6.6.0 Subclassed for the HTML Processor.
+ *
+ * @param string $class_name The class name to remove.
+ * @return bool Whether the class was set to be removed.
+ */
+ public function remove_class( $class_name ) {
+ return $this->is_virtual() ? false : parent::remove_class( $class_name );
+ }
+
+ /**
+ * Returns if a matched tag contains the given ASCII case-insensitive class name.
+ *
+ * @since 6.6.0 Subclassed for the HTML Processor.
+ *
+ * @param string $wanted_class Look for this CSS class name, ASCII case-insensitive.
+ * @return bool|null Whether the matched tag contains the given class name, or null if not matched.
+ */
+ public function has_class( $wanted_class ) {
+ return $this->is_virtual() ? null : parent::has_class( $wanted_class );
+ }
+
+ /**
+ * Generator for a foreach loop to step through each class name for the matched tag.
+ *
+ * This generator function is designed to be used inside a "foreach" loop.
+ *
+ * Example:
+ *
+ * $p = WP_HTML_Processor::create_fragment( "<div class='free &lt;egg&lt;\tlang-en'>" );
+ * $p->next_tag();
+ * foreach ( $p->class_list() as $class_name ) {
+ * echo "{$class_name} ";
+ * }
+ * // Outputs: "free <egg> lang-en "
+ *
+ * @since 6.6.0 Subclassed for the HTML Processor.
+ */
+ public function class_list() {
+ return $this->is_virtual() ? null : parent::class_list();
+ }
+
+ /**
+ * Returns the modifiable text for a matched token, or an empty string.
+ *
+ * Modifiable text is text content that may be read and changed without
+ * changing the HTML structure of the document around it. This includes
+ * the contents of `#text` nodes in the HTML as well as the inner
+ * contents of HTML comments, Processing Instructions, and others, even
+ * though these nodes aren't part of a parsed DOM tree. They also contain
+ * the contents of SCRIPT and STYLE tags, of TEXTAREA tags, and of any
+ * other section in an HTML document which cannot contain HTML markup (DATA).
+ *
+ * If a token has no modifiable text then an empty string is returned to
+ * avoid needless crashing or type errors. An empty string does not mean
+ * that a token has modifiable text, and a token with modifiable text may
+ * have an empty string (e.g. a comment with no contents).
+ *
+ * @since 6.6.0 Subclassed for the HTML Processor.
+ *
+ * @return string
+ */
+ public function get_modifiable_text() {
+ return $this->is_virtual() ? '' : parent::get_modifiable_text();
+ }
+
+ /**
+ * Indicates what kind of comment produced the comment node.
+ *
+ * Because there are different kinds of HTML syntax which produce
+ * comments, the Tag Processor tracks and exposes this as a type
+ * for the comment. Nominally only regular HTML comments exist as
+ * they are commonly known, but a number of unrelated syntax errors
+ * also produce comments.
+ *
+ * @see self::COMMENT_AS_ABRUPTLY_CLOSED_COMMENT
+ * @see self::COMMENT_AS_CDATA_LOOKALIKE
+ * @see self::COMMENT_AS_INVALID_HTML
+ * @see self::COMMENT_AS_HTML_COMMENT
+ * @see self::COMMENT_AS_PI_NODE_LOOKALIKE
+ *
+ * @since 6.6.0 Subclassed for the HTML Processor.
+ *
+ * @return string|null
+ */
+ public function get_comment_type() {
+ return $this->is_virtual() ? null : parent::get_comment_type();
+ }
+
+ /**
* Removes a bookmark that is no longer needed.
*
* Releasing a bookmark frees up the small
@@ -1304,6 +1841,7 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
? $this->bookmarks[ $this->state->current_token->bookmark_name ]->start
: 0;
$bookmark_starts_at = $this->bookmarks[ $actual_bookmark_name ]->start;
+ $bookmark_length = $this->bookmarks[ $actual_bookmark_name ]->length;
$direction = $bookmark_starts_at > $processor_started_at ? 'forward' : 'backward';
/*
@@ -1359,6 +1897,8 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
parent::seek( 'context-node' );
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY;
$this->state->frameset_ok = true;
+ $this->element_queue = array();
+ $this->current_element = null;
}
// When moving forwards, reparse the document until reaching the same location as the original bookmark.
@@ -1366,8 +1906,11 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
return true;
}
- while ( $this->step() ) {
+ while ( $this->next_token() ) {
if ( $bookmark_starts_at === $this->bookmarks[ $this->state->current_token->bookmark_name ]->start ) {
+ while ( isset( $this->current_element ) && WP_HTML_Stack_Event::POP === $this->current_element->operation ) {
+ $this->current_element = array_shift( $this->element_queue );
+ }
return true;
}
}
diff --git a/wp-includes/html-api/class-wp-html-stack-event.php b/wp-includes/html-api/class-wp-html-stack-event.php
new file mode 100644
index 0000000..aa4763c
--- /dev/null
+++ b/wp-includes/html-api/class-wp-html-stack-event.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * HTML API: WP_HTML_Stack_Event class
+ *
+ * @package WordPress
+ * @subpackage HTML-API
+ * @since 6.6.0
+ */
+
+/**
+ * Core class used by the HTML Processor as a record for stack operations.
+ *
+ * This class is for internal usage of the WP_HTML_Processor class.
+ *
+ * @access private
+ * @since 6.6.0
+ *
+ * @see WP_HTML_Processor
+ */
+class WP_HTML_Stack_Event {
+ /**
+ * Refers to popping an element off of the stack of open elements.
+ *
+ * @since 6.6.0
+ */
+ const POP = 'pop';
+
+ /**
+ * Refers to pushing an element onto the stack of open elements.
+ *
+ * @since 6.6.0
+ */
+ const PUSH = 'push';
+
+ /**
+ * References the token associated with the stack push event,
+ * even if this is a pop event for that element.
+ *
+ * @since 6.6.0
+ *
+ * @var WP_HTML_Token
+ */
+ public $token;
+
+ /**
+ * Indicates which kind of stack operation this event represents.
+ *
+ * May be one of the class constants.
+ *
+ * @since 6.6.0
+ *
+ * @see self::POP
+ * @see self::PUSH
+ *
+ * @var string
+ */
+ public $operation;
+
+ /**
+ * Indicates if the stack element is a real or virtual node.
+ *
+ * @since 6.6.0
+ *
+ * @var string
+ */
+ public $provenance;
+
+ /**
+ * Constructor function.
+ *
+ * @since 6.6.0
+ *
+ * @param WP_HTML_Token $token Token associated with stack event, always an opening token.
+ * @param string $operation One of self::PUSH or self::POP.
+ * @param string $provenance "virtual" or "real".
+ */
+ public function __construct( $token, $operation, $provenance ) {
+ $this->token = $token;
+ $this->operation = $operation;
+ $this->provenance = $provenance;
+ }
+}
diff --git a/wp-includes/html-api/class-wp-html-tag-processor.php b/wp-includes/html-api/class-wp-html-tag-processor.php
index bf7e026..8fc7593 100644
--- a/wp-includes/html-api/class-wp-html-tag-processor.php
+++ b/wp-includes/html-api/class-wp-html-tag-processor.php
@@ -15,10 +15,6 @@
* - Prune the whitespace when removing classes/attributes: e.g. "a b c" -> "c" not " c".
* This would increase the size of the changes for some operations but leave more
* natural-looking output HTML.
- * - Properly decode HTML character references in `get_attribute()`. PHP's
- * `html_entity_decode()` is wrong in a couple ways: it doesn't account for the
- * no-ambiguous-ampersand rule, and it improperly handles the way semicolons may
- * or may not terminate a character reference.
*
* @package WordPress
* @subpackage HTML-API
@@ -298,8 +294,8 @@
*
* The special elements are:
* - `SCRIPT` whose contents are treated as raw plaintext but supports a legacy
- * style of including Javascript inside of HTML comments to avoid accidentally
- * closing the SCRIPT from inside a Javascript string. E.g. `console.log( '</script>' )`.
+ * style of including JavaScript inside of HTML comments to avoid accidentally
+ * closing the SCRIPT from inside a JavaScript string. E.g. `console.log( '</script>' )`.
* - `TITLE` and `TEXTAREA` whose contents are treated as plaintext and then any
* character references are decoded. E.g. `1 &lt; 2 < 3` becomes `1 < 2 < 3`.
* - `IFRAME`, `NOSCRIPT`, `NOEMBED`, `NOFRAME`, `STYLE` whose contents are treated as
@@ -926,8 +922,8 @@ class WP_HTML_Tag_Processor {
return false;
}
$this->parser_state = self::STATE_MATCHED_TAG;
- $this->token_length = $tag_ends_at - $this->token_starts_at;
$this->bytes_already_parsed = $tag_ends_at + 1;
+ $this->token_length = $this->bytes_already_parsed - $this->token_starts_at;
/*
* For non-DATA sections which might contain text that looks like HTML tags but
@@ -1013,7 +1009,7 @@ class WP_HTML_Tag_Processor {
*/
$this->token_starts_at = $was_at;
$this->token_length = $this->bytes_already_parsed - $this->token_starts_at;
- $this->text_starts_at = $tag_ends_at + 1;
+ $this->text_starts_at = $tag_ends_at;
$this->text_length = $this->tag_name_starts_at - $this->text_starts_at;
$this->tag_name_starts_at = $tag_name_starts_at;
$this->tag_name_length = $tag_name_length;
@@ -1629,7 +1625,7 @@ class WP_HTML_Tag_Processor {
* `<!` transitions to markup declaration open state
* https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state
*/
- if ( '!' === $html[ $at + 1 ] ) {
+ if ( ! $this->is_closing_tag && '!' === $html[ $at + 1 ] ) {
/*
* `<!--` transitions to a comment state – apply further comment rules.
* https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state
@@ -1809,6 +1805,12 @@ class WP_HTML_Tag_Processor {
* See https://html.spec.whatwg.org/#parse-error-missing-end-tag-name
*/
if ( '>' === $html[ $at + 1 ] ) {
+ // `<>` is interpreted as plaintext.
+ if ( ! $this->is_closing_tag ) {
+ ++$at;
+ continue;
+ }
+
$this->parser_state = self::STATE_PRESUMPTUOUS_TAG;
$this->token_length = $at + 2 - $this->token_starts_at;
$this->bytes_already_parsed = $at + 2;
@@ -1819,7 +1821,7 @@ class WP_HTML_Tag_Processor {
* `<?` transitions to a bogus comment state – skip to the nearest >
* See https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state
*/
- if ( '?' === $html[ $at + 1 ] ) {
+ if ( ! $this->is_closing_tag && '?' === $html[ $at + 1 ] ) {
$closer_at = strpos( $html, '>', $at + 2 );
if ( false === $closer_at ) {
$this->parser_state = self::STATE_INCOMPLETE_INPUT;
@@ -1891,7 +1893,7 @@ class WP_HTML_Tag_Processor {
return false;
}
- $closer_at = strpos( $html, '>', $at + 3 );
+ $closer_at = strpos( $html, '>', $at + 2 );
if ( false === $closer_at ) {
$this->parser_state = self::STATE_INCOMPLETE_INPUT;
@@ -2071,7 +2073,7 @@ class WP_HTML_Tag_Processor {
/*
* Purge updates if there are too many. The actual count isn't
* scientific, but a few values from 100 to a few thousand were
- * tests to find a practially-useful limit.
+ * tests to find a practically-useful limit.
*
* If the update queue grows too big, then the Tag Processor
* will spend more time iterating through them and lose the
@@ -2263,7 +2265,7 @@ class WP_HTML_Tag_Processor {
* @param int $shift_this_point Accumulate and return shift for this position.
* @return int How many bytes the given pointer moved in response to the updates.
*/
- private function apply_attributes_updates( $shift_this_point = 0 ) {
+ private function apply_attributes_updates( $shift_this_point ) {
if ( ! count( $this->lexical_updates ) ) {
return 0;
}
@@ -2493,7 +2495,7 @@ class WP_HTML_Tag_Processor {
* 3. Double-quoting ends at the last character in the update.
*/
$enqueued_value = substr( $enqueued_text, $equals_at + 2, -1 );
- return html_entity_decode( $enqueued_value );
+ return WP_HTML_Decoder::decode_attribute( $enqueued_value );
}
/**
@@ -2566,7 +2568,7 @@ class WP_HTML_Tag_Processor {
$raw_value = substr( $this->html, $attribute->value_starts_at, $attribute->value_length );
- return html_entity_decode( $raw_value );
+ return WP_HTML_Decoder::decode_attribute( $raw_value );
}
/**
@@ -2681,7 +2683,7 @@ class WP_HTML_Tag_Processor {
* <figure />
* ^ this appears one character before the end of the closing ">".
*/
- return '/' === $this->html[ $this->token_starts_at + $this->token_length - 1 ];
+ return '/' === $this->html[ $this->token_starts_at + $this->token_length - 2 ];
}
/**
@@ -2785,6 +2787,8 @@ class WP_HTML_Tag_Processor {
case self::STATE_FUNKY_COMMENT:
return '#funky-comment';
}
+
+ return null;
}
/**
@@ -2866,7 +2870,7 @@ class WP_HTML_Tag_Processor {
return $text;
}
- $decoded = html_entity_decode( $text, ENT_QUOTES | ENT_HTML5 | ENT_SUBSTITUTE );
+ $decoded = WP_HTML_Decoder::decode_text_node( $text );
/*
* TEXTAREA skips a leading newline, but this newline may appear not only as the
@@ -3200,7 +3204,7 @@ class WP_HTML_Tag_Processor {
* Keep track of the position right before the current tag. This will
* be necessary for reparsing the current tag after updating the HTML.
*/
- $before_current_tag = $this->token_starts_at;
+ $before_current_tag = $this->token_starts_at ?? 0;
/*
* 1. Apply the enqueued edits and update all the pointers to reflect those changes.
diff --git a/wp-includes/html-api/html5-named-character-references.php b/wp-includes/html-api/html5-named-character-references.php
new file mode 100644
index 0000000..9466f0a
--- /dev/null
+++ b/wp-includes/html-api/html5-named-character-references.php
@@ -0,0 +1,1313 @@
+<?php
+
+/**
+ * Auto-generated class for looking up HTML named character references.
+ *
+ * ⚠️ !!! THIS ENTIRE FILE IS AUTOMATICALLY GENERATED !!! ⚠️
+ * Do not modify this file directly.
+ *
+ * To regenerate, run the generation script directly.
+ *
+ * Example:
+ *
+ * php tests/phpunit/data/html5-entities/generate-html5-named-character-references.php
+ *
+ * @package WordPress
+ * @since 6.6.0
+ */
+
+// phpcs:disable
+
+global $html5_named_character_references;
+
+/**
+ * Set of named character references in the HTML5 specification.
+ *
+ * This list will never change, according to the spec. Each named
+ * character reference is case-sensitive and the presence or absence
+ * of the semicolon is significant. Without the semicolon, the rules
+ * for an ambiguous ampersand govern whether the following text is
+ * to be interpreted as a character reference or not.
+ *
+ * The list of entities is sourced directly from the WHATWG server
+ * and cached in the test directory to avoid needing to download it
+ * every time this file is updated.
+ *
+ * @link https://html.spec.whatwg.org/entities.json.
+ */
+$html5_named_character_references = WP_Token_Map::from_precomputed_table(
+ array(
+ "storage_version" => "6.6.0-trunk",
+ "key_length" => 2,
+ "groups" => "AE\x00AM\x00Aa\x00Ab\x00Ac\x00Af\x00Ag\x00Al\x00Am\x00An\x00Ao\x00Ap\x00Ar\x00As\x00At\x00Au\x00Ba\x00Bc\x00Be\x00Bf\x00Bo\x00Br\x00Bs\x00Bu\x00CH\x00CO\x00Ca\x00Cc\x00Cd\x00Ce\x00Cf\x00Ch\x00Ci\x00Cl\x00Co\x00Cr\x00Cs\x00Cu\x00DD\x00DJ\x00DS\x00DZ\x00Da\x00Dc\x00De\x00Df\x00Di\x00Do\x00Ds\x00EN\x00ET\x00Ea\x00Ec\x00Ed\x00Ef\x00Eg\x00El\x00Em\x00Eo\x00Ep\x00Eq\x00Es\x00Et\x00Eu\x00Ex\x00Fc\x00Ff\x00Fi\x00Fo\x00Fs\x00GJ\x00GT\x00Ga\x00Gb\x00Gc\x00Gd\x00Gf\x00Gg\x00Go\x00Gr\x00Gs\x00Gt\x00HA\x00Ha\x00Hc\x00Hf\x00Hi\x00Ho\x00Hs\x00Hu\x00IE\x00IJ\x00IO\x00Ia\x00Ic\x00Id\x00If\x00Ig\x00Im\x00In\x00Io\x00Is\x00It\x00Iu\x00Jc\x00Jf\x00Jo\x00Js\x00Ju\x00KH\x00KJ\x00Ka\x00Kc\x00Kf\x00Ko\x00Ks\x00LJ\x00LT\x00La\x00Lc\x00Le\x00Lf\x00Ll\x00Lm\x00Lo\x00Ls\x00Lt\x00Ma\x00Mc\x00Me\x00Mf\x00Mi\x00Mo\x00Ms\x00Mu\x00NJ\x00Na\x00Nc\x00Ne\x00Nf\x00No\x00Ns\x00Nt\x00Nu\x00OE\x00Oa\x00Oc\x00Od\x00Of\x00Og\x00Om\x00Oo\x00Op\x00Or\x00Os\x00Ot\x00Ou\x00Ov\x00Pa\x00Pc\x00Pf\x00Ph\x00Pi\x00Pl\x00Po\x00Pr\x00Ps\x00QU\x00Qf\x00Qo\x00Qs\x00RB\x00RE\x00Ra\x00Rc\x00Re\x00Rf\x00Rh\x00Ri\x00Ro\x00Rr\x00Rs\x00Ru\x00SH\x00SO\x00Sa\x00Sc\x00Sf\x00Sh\x00Si\x00Sm\x00So\x00Sq\x00Ss\x00St\x00Su\x00TH\x00TR\x00TS\x00Ta\x00Tc\x00Tf\x00Th\x00Ti\x00To\x00Tr\x00Ts\x00Ua\x00Ub\x00Uc\x00Ud\x00Uf\x00Ug\x00Um\x00Un\x00Uo\x00Up\x00Ur\x00Us\x00Ut\x00Uu\x00VD\x00Vb\x00Vc\x00Vd\x00Ve\x00Vf\x00Vo\x00Vs\x00Vv\x00Wc\x00We\x00Wf\x00Wo\x00Ws\x00Xf\x00Xi\x00Xo\x00Xs\x00YA\x00YI\x00YU\x00Ya\x00Yc\x00Yf\x00Yo\x00Ys\x00Yu\x00ZH\x00Za\x00Zc\x00Zd\x00Ze\x00Zf\x00Zo\x00Zs\x00aa\x00ab\x00ac\x00ae\x00af\x00ag\x00al\x00am\x00an\x00ao\x00ap\x00ar\x00as\x00at\x00au\x00aw\x00bN\x00ba\x00bb\x00bc\x00bd\x00be\x00bf\x00bi\x00bk\x00bl\x00bn\x00bo\x00bp\x00br\x00bs\x00bu\x00ca\x00cc\x00cd\x00ce\x00cf\x00ch\x00ci\x00cl\x00co\x00cr\x00cs\x00ct\x00cu\x00cw\x00cy\x00dA\x00dH\x00da\x00db\x00dc\x00dd\x00de\x00df\x00dh\x00di\x00dj\x00dl\x00do\x00dr\x00ds\x00dt\x00du\x00dw\x00dz\x00eD\x00ea\x00ec\x00ed\x00ee\x00ef\x00eg\x00el\x00em\x00en\x00eo\x00ep\x00eq\x00er\x00es\x00et\x00eu\x00ex\x00fa\x00fc\x00fe\x00ff\x00fi\x00fj\x00fl\x00fn\x00fo\x00fp\x00fr\x00fs\x00gE\x00ga\x00gb\x00gc\x00gd\x00ge\x00gf\x00gg\x00gi\x00gj\x00gl\x00gn\x00go\x00gr\x00gs\x00gt\x00gv\x00hA\x00ha\x00hb\x00hc\x00he\x00hf\x00hk\x00ho\x00hs\x00hy\x00ia\x00ic\x00ie\x00if\x00ig\x00ii\x00ij\x00im\x00in\x00io\x00ip\x00iq\x00is\x00it\x00iu\x00jc\x00jf\x00jm\x00jo\x00js\x00ju\x00ka\x00kc\x00kf\x00kg\x00kh\x00kj\x00ko\x00ks\x00lA\x00lB\x00lE\x00lH\x00la\x00lb\x00lc\x00ld\x00le\x00lf\x00lg\x00lh\x00lj\x00ll\x00lm\x00ln\x00lo\x00lp\x00lr\x00ls\x00lt\x00lu\x00lv\x00mD\x00ma\x00mc\x00md\x00me\x00mf\x00mh\x00mi\x00ml\x00mn\x00mo\x00mp\x00ms\x00mu\x00nG\x00nL\x00nR\x00nV\x00na\x00nb\x00nc\x00nd\x00ne\x00nf\x00ng\x00nh\x00ni\x00nj\x00nl\x00nm\x00no\x00np\x00nr\x00ns\x00nt\x00nu\x00nv\x00nw\x00oS\x00oa\x00oc\x00od\x00oe\x00of\x00og\x00oh\x00oi\x00ol\x00om\x00oo\x00op\x00or\x00os\x00ot\x00ou\x00ov\x00pa\x00pc\x00pe\x00pf\x00ph\x00pi\x00pl\x00pm\x00po\x00pr\x00ps\x00pu\x00qf\x00qi\x00qo\x00qp\x00qs\x00qu\x00rA\x00rB\x00rH\x00ra\x00rb\x00rc\x00rd\x00re\x00rf\x00rh\x00ri\x00rl\x00rm\x00rn\x00ro\x00rp\x00rr\x00rs\x00rt\x00ru\x00rx\x00sa\x00sb\x00sc\x00sd\x00se\x00sf\x00sh\x00si\x00sl\x00sm\x00so\x00sp\x00sq\x00sr\x00ss\x00st\x00su\x00sw\x00sz\x00ta\x00tb\x00tc\x00td\x00te\x00tf\x00th\x00ti\x00to\x00tp\x00tr\x00ts\x00tw\x00uA\x00uH\x00ua\x00ub\x00uc\x00ud\x00uf\x00ug\x00uh\x00ul\x00um\x00uo\x00up\x00ur\x00us\x00ut\x00uu\x00uw\x00vA\x00vB\x00vD\x00va\x00vc\x00vd\x00ve\x00vf\x00vl\x00vn\x00vo\x00vp\x00vr\x00vs\x00vz\x00wc\x00we\x00wf\x00wo\x00wp\x00wr\x00ws\x00xc\x00xd\x00xf\x00xh\x00xi\x00xl\x00xm\x00xn\x00xo\x00xr\x00xs\x00xu\x00xv\x00xw\x00ya\x00yc\x00ye\x00yf\x00yi\x00yo\x00ys\x00yu\x00za\x00zc\x00zd\x00ze\x00zf\x00zh\x00zi\x00zo\x00zs\x00zw\x00",
+ "large_words" => array(
+ // AElig;[Æ] AElig[Æ].
+ "\x04lig;\x02Æ\x03lig\x02Æ",
+ // AMP;[&] AMP[&].
+ "\x02P;\x01&\x01P\x01&",
+ // Aacute;[Á] Aacute[Á].
+ "\x05cute;\x02Á\x04cute\x02Á",
+ // Abreve;[Ă].
+ "\x05reve;\x02Ă",
+ // Acirc;[Â] Acirc[Â] Acy;[А].
+ "\x04irc;\x02Â\x03irc\x02Â\x02y;\x02А",
+ // Afr;[𝔄].
+ "\x02r;\x04𝔄",
+ // Agrave;[À] Agrave[À].
+ "\x05rave;\x02À\x04rave\x02À",
+ // Alpha;[Α].
+ "\x04pha;\x02Α",
+ // Amacr;[Ā].
+ "\x04acr;\x02Ā",
+ // And;[⩓].
+ "\x02d;\x03⩓",
+ // Aogon;[Ą] Aopf;[𝔸].
+ "\x04gon;\x02Ą\x03pf;\x04𝔸",
+ // ApplyFunction;[⁡].
+ "\x0cplyFunction;\x03⁡",
+ // Aring;[Å] Aring[Å].
+ "\x04ing;\x02Å\x03ing\x02Å",
+ // Assign;[≔] Ascr;[𝒜].
+ "\x05sign;\x03≔\x03cr;\x04𝒜",
+ // Atilde;[Ã] Atilde[Ã].
+ "\x05ilde;\x02Ã\x04ilde\x02Ã",
+ // Auml;[Ä] Auml[Ä].
+ "\x03ml;\x02Ä\x02ml\x02Ä",
+ // Backslash;[∖] Barwed;[⌆] Barv;[⫧].
+ "\x08ckslash;\x03∖\x05rwed;\x03⌆\x03rv;\x03⫧",
+ // Bcy;[Б].
+ "\x02y;\x02Б",
+ // Bernoullis;[ℬ] Because;[∵] Beta;[Β].
+ "\x09rnoullis;\x03ℬ\x06cause;\x03∵\x03ta;\x02Β",
+ // Bfr;[𝔅].
+ "\x02r;\x04𝔅",
+ // Bopf;[𝔹].
+ "\x03pf;\x04𝔹",
+ // Breve;[˘].
+ "\x04eve;\x02˘",
+ // Bscr;[ℬ].
+ "\x03cr;\x03ℬ",
+ // Bumpeq;[≎].
+ "\x05mpeq;\x03≎",
+ // CHcy;[Ч].
+ "\x03cy;\x02Ч",
+ // COPY;[©] COPY[©].
+ "\x03PY;\x02©\x02PY\x02©",
+ // CapitalDifferentialD;[ⅅ] Cayleys;[ℭ] Cacute;[Ć] Cap;[⋒].
+ "\x13pitalDifferentialD;\x03ⅅ\x06yleys;\x03ℭ\x05cute;\x02Ć\x02p;\x03⋒",
+ // Cconint;[∰] Ccaron;[Č] Ccedil;[Ç] Ccedil[Ç] Ccirc;[Ĉ].
+ "\x06onint;\x03∰\x05aron;\x02Č\x05edil;\x02Ç\x04edil\x02Ç\x04irc;\x02Ĉ",
+ // Cdot;[Ċ].
+ "\x03ot;\x02Ċ",
+ // CenterDot;[·] Cedilla;[¸].
+ "\x08nterDot;\x02·\x06dilla;\x02¸",
+ // Cfr;[ℭ].
+ "\x02r;\x03ℭ",
+ // Chi;[Χ].
+ "\x02i;\x02Χ",
+ // CircleMinus;[⊖] CircleTimes;[⊗] CirclePlus;[⊕] CircleDot;[⊙].
+ "\x0arcleMinus;\x03⊖\x0arcleTimes;\x03⊗\x09rclePlus;\x03⊕\x08rcleDot;\x03⊙",
+ // ClockwiseContourIntegral;[∲] CloseCurlyDoubleQuote;[”] CloseCurlyQuote;[’].
+ "\x17ockwiseContourIntegral;\x03∲\x14oseCurlyDoubleQuote;\x03”\x0eoseCurlyQuote;\x03’",
+ // CounterClockwiseContourIntegral;[∳] ContourIntegral;[∮] Congruent;[≡] Coproduct;[∐] Colone;[⩴] Conint;[∯] Colon;[∷] Copf;[ℂ].
+ "\x1eunterClockwiseContourIntegral;\x03∳\x0entourIntegral;\x03∮\x08ngruent;\x03≡\x08product;\x03∐\x05lone;\x03⩴\x05nint;\x03∯\x04lon;\x03∷\x03pf;\x03ℂ",
+ // Cross;[⨯].
+ "\x04oss;\x03⨯",
+ // Cscr;[𝒞].
+ "\x03cr;\x04𝒞",
+ // CupCap;[≍] Cup;[⋓].
+ "\x05pCap;\x03≍\x02p;\x03⋓",
+ // DDotrahd;[⤑] DD;[ⅅ].
+ "\x07otrahd;\x03⤑\x01;\x03ⅅ",
+ // DJcy;[Ђ].
+ "\x03cy;\x02Ђ",
+ // DScy;[Ѕ].
+ "\x03cy;\x02Ѕ",
+ // DZcy;[Џ].
+ "\x03cy;\x02Џ",
+ // Dagger;[‡] Dashv;[⫤] Darr;[↡].
+ "\x05gger;\x03‡\x04shv;\x03⫤\x03rr;\x03↡",
+ // Dcaron;[Ď] Dcy;[Д].
+ "\x05aron;\x02Ď\x02y;\x02Д",
+ // Delta;[Δ] Del;[∇].
+ "\x04lta;\x02Δ\x02l;\x03∇",
+ // Dfr;[𝔇].
+ "\x02r;\x04𝔇",
+ // DiacriticalDoubleAcute;[˝] DiacriticalAcute;[´] DiacriticalGrave;[`] DiacriticalTilde;[˜] DiacriticalDot;[˙] DifferentialD;[ⅆ] Diamond;[⋄].
+ "\x15acriticalDoubleAcute;\x02˝\x0facriticalAcute;\x02´\x0facriticalGrave;\x01`\x0facriticalTilde;\x02˜\x0dacriticalDot;\x02˙\x0cfferentialD;\x03ⅆ\x06amond;\x03⋄",
+ // DoubleLongLeftRightArrow;[⟺] DoubleContourIntegral;[∯] DoubleLeftRightArrow;[⇔] DoubleLongRightArrow;[⟹] DoubleLongLeftArrow;[⟸] DownLeftRightVector;[⥐] DownRightTeeVector;[⥟] DownRightVectorBar;[⥗] DoubleUpDownArrow;[⇕] DoubleVerticalBar;[∥] DownLeftTeeVector;[⥞] DownLeftVectorBar;[⥖] DoubleRightArrow;[⇒] DownArrowUpArrow;[⇵] DoubleDownArrow;[⇓] DoubleLeftArrow;[⇐] DownRightVector;[⇁] DoubleRightTee;[⊨] DownLeftVector;[↽] DoubleLeftTee;[⫤] DoubleUpArrow;[⇑] DownArrowBar;[⤓] DownTeeArrow;[↧] DoubleDot;[¨] DownArrow;[↓] DownBreve;[̑] Downarrow;[⇓] DotEqual;[≐] DownTee;[⊤] DotDot;[⃜] Dopf;[𝔻] Dot;[¨].
+ "\x17ubleLongLeftRightArrow;\x03⟺\x14ubleContourIntegral;\x03∯\x13ubleLeftRightArrow;\x03⇔\x13ubleLongRightArrow;\x03⟹\x12ubleLongLeftArrow;\x03⟸\x12wnLeftRightVector;\x03⥐\x11wnRightTeeVector;\x03⥟\x11wnRightVectorBar;\x03⥗\x10ubleUpDownArrow;\x03⇕\x10ubleVerticalBar;\x03∥\x10wnLeftTeeVector;\x03⥞\x10wnLeftVectorBar;\x03⥖\x0fubleRightArrow;\x03⇒\x0fwnArrowUpArrow;\x03⇵\x0eubleDownArrow;\x03⇓\x0eubleLeftArrow;\x03⇐\x0ewnRightVector;\x03⇁\x0dubleRightTee;\x03⊨\x0dwnLeftVector;\x03↽\x0cubleLeftTee;\x03⫤\x0cubleUpArrow;\x03⇑\x0bwnArrowBar;\x03⤓\x0bwnTeeArrow;\x03↧\x08ubleDot;\x02¨\x08wnArrow;\x03↓\x08wnBreve;\x02̑\x08wnarrow;\x03⇓\x07tEqual;\x03≐\x06wnTee;\x03⊤\x05tDot;\x03⃜\x03pf;\x04𝔻\x02t;\x02¨",
+ // Dstrok;[Đ] Dscr;[𝒟].
+ "\x05trok;\x02Đ\x03cr;\x04𝒟",
+ // ENG;[Ŋ].
+ "\x02G;\x02Ŋ",
+ // ETH;[Ð] ETH[Ð].
+ "\x02H;\x02Ð\x01H\x02Ð",
+ // Eacute;[É] Eacute[É].
+ "\x05cute;\x02É\x04cute\x02É",
+ // Ecaron;[Ě] Ecirc;[Ê] Ecirc[Ê] Ecy;[Э].
+ "\x05aron;\x02Ě\x04irc;\x02Ê\x03irc\x02Ê\x02y;\x02Э",
+ // Edot;[Ė].
+ "\x03ot;\x02Ė",
+ // Efr;[𝔈].
+ "\x02r;\x04𝔈",
+ // Egrave;[È] Egrave[È].
+ "\x05rave;\x02È\x04rave\x02È",
+ // Element;[∈].
+ "\x06ement;\x03∈",
+ // EmptyVerySmallSquare;[▫] EmptySmallSquare;[◻] Emacr;[Ē].
+ "\x13ptyVerySmallSquare;\x03▫\x0fptySmallSquare;\x03◻\x04acr;\x02Ē",
+ // Eogon;[Ę] Eopf;[𝔼].
+ "\x04gon;\x02Ę\x03pf;\x04𝔼",
+ // Epsilon;[Ε].
+ "\x06silon;\x02Ε",
+ // Equilibrium;[⇌] EqualTilde;[≂] Equal;[⩵].
+ "\x0auilibrium;\x03⇌\x09ualTilde;\x03≂\x04ual;\x03⩵",
+ // Escr;[ℰ] Esim;[⩳].
+ "\x03cr;\x03ℰ\x03im;\x03⩳",
+ // Eta;[Η].
+ "\x02a;\x02Η",
+ // Euml;[Ë] Euml[Ë].
+ "\x03ml;\x02Ë\x02ml\x02Ë",
+ // ExponentialE;[ⅇ] Exists;[∃].
+ "\x0bponentialE;\x03ⅇ\x05ists;\x03∃",
+ // Fcy;[Ф].
+ "\x02y;\x02Ф",
+ // Ffr;[𝔉].
+ "\x02r;\x04𝔉",
+ // FilledVerySmallSquare;[▪] FilledSmallSquare;[◼].
+ "\x14lledVerySmallSquare;\x03▪\x10lledSmallSquare;\x03◼",
+ // Fouriertrf;[ℱ] ForAll;[∀] Fopf;[𝔽].
+ "\x09uriertrf;\x03ℱ\x05rAll;\x03∀\x03pf;\x04𝔽",
+ // Fscr;[ℱ].
+ "\x03cr;\x03ℱ",
+ // GJcy;[Ѓ].
+ "\x03cy;\x02Ѓ",
+ // GT;[>].
+ "\x01;\x01>",
+ // Gammad;[Ϝ] Gamma;[Γ].
+ "\x05mmad;\x02Ϝ\x04mma;\x02Γ",
+ // Gbreve;[Ğ].
+ "\x05reve;\x02Ğ",
+ // Gcedil;[Ģ] Gcirc;[Ĝ] Gcy;[Г].
+ "\x05edil;\x02Ģ\x04irc;\x02Ĝ\x02y;\x02Г",
+ // Gdot;[Ġ].
+ "\x03ot;\x02Ġ",
+ // Gfr;[𝔊].
+ "\x02r;\x04𝔊",
+ // Gg;[⋙].
+ "\x01;\x03⋙",
+ // Gopf;[𝔾].
+ "\x03pf;\x04𝔾",
+ // GreaterSlantEqual;[⩾] GreaterEqualLess;[⋛] GreaterFullEqual;[≧] GreaterGreater;[⪢] GreaterEqual;[≥] GreaterTilde;[≳] GreaterLess;[≷].
+ "\x10eaterSlantEqual;\x03⩾\x0featerEqualLess;\x03⋛\x0featerFullEqual;\x03≧\x0deaterGreater;\x03⪢\x0beaterEqual;\x03≥\x0beaterTilde;\x03≳\x0aeaterLess;\x03≷",
+ // Gscr;[𝒢].
+ "\x03cr;\x04𝒢",
+ // Gt;[≫].
+ "\x01;\x03≫",
+ // HARDcy;[Ъ].
+ "\x05RDcy;\x02Ъ",
+ // Hacek;[ˇ] Hat;[^].
+ "\x04cek;\x02ˇ\x02t;\x01^",
+ // Hcirc;[Ĥ].
+ "\x04irc;\x02Ĥ",
+ // Hfr;[ℌ].
+ "\x02r;\x03ℌ",
+ // HilbertSpace;[ℋ].
+ "\x0blbertSpace;\x03ℋ",
+ // HorizontalLine;[─] Hopf;[ℍ].
+ "\x0drizontalLine;\x03─\x03pf;\x03ℍ",
+ // Hstrok;[Ħ] Hscr;[ℋ].
+ "\x05trok;\x02Ħ\x03cr;\x03ℋ",
+ // HumpDownHump;[≎] HumpEqual;[≏].
+ "\x0bmpDownHump;\x03≎\x08mpEqual;\x03≏",
+ // IEcy;[Е].
+ "\x03cy;\x02Е",
+ // IJlig;[IJ].
+ "\x04lig;\x02IJ",
+ // IOcy;[Ё].
+ "\x03cy;\x02Ё",
+ // Iacute;[Í] Iacute[Í].
+ "\x05cute;\x02Í\x04cute\x02Í",
+ // Icirc;[Î] Icirc[Î] Icy;[И].
+ "\x04irc;\x02Î\x03irc\x02Î\x02y;\x02И",
+ // Idot;[İ].
+ "\x03ot;\x02İ",
+ // Ifr;[ℑ].
+ "\x02r;\x03ℑ",
+ // Igrave;[Ì] Igrave[Ì].
+ "\x05rave;\x02Ì\x04rave\x02Ì",
+ // ImaginaryI;[ⅈ] Implies;[⇒] Imacr;[Ī] Im;[ℑ].
+ "\x09aginaryI;\x03ⅈ\x06plies;\x03⇒\x04acr;\x02Ī\x01;\x03ℑ",
+ // InvisibleComma;[⁣] InvisibleTimes;[⁢] Intersection;[⋂] Integral;[∫] Int;[∬].
+ "\x0dvisibleComma;\x03⁣\x0dvisibleTimes;\x03⁢\x0btersection;\x03⋂\x07tegral;\x03∫\x02t;\x03∬",
+ // Iogon;[Į] Iopf;[𝕀] Iota;[Ι].
+ "\x04gon;\x02Į\x03pf;\x04𝕀\x03ta;\x02Ι",
+ // Iscr;[ℐ].
+ "\x03cr;\x03ℐ",
+ // Itilde;[Ĩ].
+ "\x05ilde;\x02Ĩ",
+ // Iukcy;[І] Iuml;[Ï] Iuml[Ï].
+ "\x04kcy;\x02І\x03ml;\x02Ï\x02ml\x02Ï",
+ // Jcirc;[Ĵ] Jcy;[Й].
+ "\x04irc;\x02Ĵ\x02y;\x02Й",
+ // Jfr;[𝔍].
+ "\x02r;\x04𝔍",
+ // Jopf;[𝕁].
+ "\x03pf;\x04𝕁",
+ // Jsercy;[Ј] Jscr;[𝒥].
+ "\x05ercy;\x02Ј\x03cr;\x04𝒥",
+ // Jukcy;[Є].
+ "\x04kcy;\x02Є",
+ // KHcy;[Х].
+ "\x03cy;\x02Х",
+ // KJcy;[Ќ].
+ "\x03cy;\x02Ќ",
+ // Kappa;[Κ].
+ "\x04ppa;\x02Κ",
+ // Kcedil;[Ķ] Kcy;[К].
+ "\x05edil;\x02Ķ\x02y;\x02К",
+ // Kfr;[𝔎].
+ "\x02r;\x04𝔎",
+ // Kopf;[𝕂].
+ "\x03pf;\x04𝕂",
+ // Kscr;[𝒦].
+ "\x03cr;\x04𝒦",
+ // LJcy;[Љ].
+ "\x03cy;\x02Љ",
+ // LT;[<].
+ "\x01;\x01<",
+ // Laplacetrf;[ℒ] Lacute;[Ĺ] Lambda;[Λ] Lang;[⟪] Larr;[↞].
+ "\x09placetrf;\x03ℒ\x05cute;\x02Ĺ\x05mbda;\x02Λ\x03ng;\x03⟪\x03rr;\x03↞",
+ // Lcaron;[Ľ] Lcedil;[Ļ] Lcy;[Л].
+ "\x05aron;\x02Ľ\x05edil;\x02Ļ\x02y;\x02Л",
+ // LeftArrowRightArrow;[⇆] LeftDoubleBracket;[⟦] LeftDownTeeVector;[⥡] LeftDownVectorBar;[⥙] LeftTriangleEqual;[⊴] LeftAngleBracket;[⟨] LeftUpDownVector;[⥑] LessEqualGreater;[⋚] LeftRightVector;[⥎] LeftTriangleBar;[⧏] LeftUpTeeVector;[⥠] LeftUpVectorBar;[⥘] LeftDownVector;[⇃] LeftRightArrow;[↔] Leftrightarrow;[⇔] LessSlantEqual;[⩽] LeftTeeVector;[⥚] LeftVectorBar;[⥒] LessFullEqual;[≦] LeftArrowBar;[⇤] LeftTeeArrow;[↤] LeftTriangle;[⊲] LeftUpVector;[↿] LeftCeiling;[⌈] LessGreater;[≶] LeftVector;[↼] LeftArrow;[←] LeftFloor;[⌊] Leftarrow;[⇐] LessTilde;[≲] LessLess;[⪡] LeftTee;[⊣].
+ "\x12ftArrowRightArrow;\x03⇆\x10ftDoubleBracket;\x03⟦\x10ftDownTeeVector;\x03⥡\x10ftDownVectorBar;\x03⥙\x10ftTriangleEqual;\x03⊴\x0fftAngleBracket;\x03⟨\x0fftUpDownVector;\x03⥑\x0fssEqualGreater;\x03⋚\x0eftRightVector;\x03⥎\x0eftTriangleBar;\x03⧏\x0eftUpTeeVector;\x03⥠\x0eftUpVectorBar;\x03⥘\x0dftDownVector;\x03⇃\x0dftRightArrow;\x03↔\x0dftrightarrow;\x03⇔\x0dssSlantEqual;\x03⩽\x0cftTeeVector;\x03⥚\x0cftVectorBar;\x03⥒\x0cssFullEqual;\x03≦\x0bftArrowBar;\x03⇤\x0bftTeeArrow;\x03↤\x0bftTriangle;\x03⊲\x0bftUpVector;\x03↿\x0aftCeiling;\x03⌈\x0assGreater;\x03≶\x09ftVector;\x03↼\x08ftArrow;\x03←\x08ftFloor;\x03⌊\x08ftarrow;\x03⇐\x08ssTilde;\x03≲\x07ssLess;\x03⪡\x06ftTee;\x03⊣",
+ // Lfr;[𝔏].
+ "\x02r;\x04𝔏",
+ // Lleftarrow;[⇚] Ll;[⋘].
+ "\x09eftarrow;\x03⇚\x01;\x03⋘",
+ // Lmidot;[Ŀ].
+ "\x05idot;\x02Ŀ",
+ // LongLeftRightArrow;[⟷] Longleftrightarrow;[⟺] LowerRightArrow;[↘] LongRightArrow;[⟶] Longrightarrow;[⟹] LowerLeftArrow;[↙] LongLeftArrow;[⟵] Longleftarrow;[⟸] Lopf;[𝕃].
+ "\x11ngLeftRightArrow;\x03⟷\x11ngleftrightarrow;\x03⟺\x0ewerRightArrow;\x03↘\x0dngRightArrow;\x03⟶\x0dngrightarrow;\x03⟹\x0dwerLeftArrow;\x03↙\x0cngLeftArrow;\x03⟵\x0cngleftarrow;\x03⟸\x03pf;\x04𝕃",
+ // Lstrok;[Ł] Lscr;[ℒ] Lsh;[↰].
+ "\x05trok;\x02Ł\x03cr;\x03ℒ\x02h;\x03↰",
+ // Lt;[≪].
+ "\x01;\x03≪",
+ // Map;[⤅].
+ "\x02p;\x03⤅",
+ // Mcy;[М].
+ "\x02y;\x02М",
+ // MediumSpace;[ ] Mellintrf;[ℳ].
+ "\x0adiumSpace;\x03 \x08llintrf;\x03ℳ",
+ // Mfr;[𝔐].
+ "\x02r;\x04𝔐",
+ // MinusPlus;[∓].
+ "\x08nusPlus;\x03∓",
+ // Mopf;[𝕄].
+ "\x03pf;\x04𝕄",
+ // Mscr;[ℳ].
+ "\x03cr;\x03ℳ",
+ // Mu;[Μ].
+ "\x01;\x02Μ",
+ // NJcy;[Њ].
+ "\x03cy;\x02Њ",
+ // Nacute;[Ń].
+ "\x05cute;\x02Ń",
+ // Ncaron;[Ň] Ncedil;[Ņ] Ncy;[Н].
+ "\x05aron;\x02Ň\x05edil;\x02Ņ\x02y;\x02Н",
+ // NegativeVeryThinSpace;[​] NestedGreaterGreater;[≫] NegativeMediumSpace;[​] NegativeThickSpace;[​] NegativeThinSpace;[​] NestedLessLess;[≪] NewLine;[\xa].
+ "\x14gativeVeryThinSpace;\x03​\x13stedGreaterGreater;\x03≫\x12gativeMediumSpace;\x03​\x11gativeThickSpace;\x03​\x10gativeThinSpace;\x03​\x0dstedLessLess;\x03≪\x06wLine;\x01\xa",
+ // Nfr;[𝔑].
+ "\x02r;\x04𝔑",
+ // NotNestedGreaterGreater;[⪢̸] NotSquareSupersetEqual;[⋣] NotPrecedesSlantEqual;[⋠] NotRightTriangleEqual;[⋭] NotSucceedsSlantEqual;[⋡] NotDoubleVerticalBar;[∦] NotGreaterSlantEqual;[⩾̸] NotLeftTriangleEqual;[⋬] NotSquareSubsetEqual;[⋢] NotGreaterFullEqual;[≧̸] NotRightTriangleBar;[⧐̸] NotLeftTriangleBar;[⧏̸] NotGreaterGreater;[≫̸] NotLessSlantEqual;[⩽̸] NotNestedLessLess;[⪡̸] NotReverseElement;[∌] NotSquareSuperset;[⊐̸] NotTildeFullEqual;[≇] NonBreakingSpace;[ ] NotPrecedesEqual;[⪯̸] NotRightTriangle;[⋫] NotSucceedsEqual;[⪰̸] NotSucceedsTilde;[≿̸] NotSupersetEqual;[⊉] NotGreaterEqual;[≱] NotGreaterTilde;[≵] NotHumpDownHump;[≎̸] NotLeftTriangle;[⋪] NotSquareSubset;[⊏̸] NotGreaterLess;[≹] NotLessGreater;[≸] NotSubsetEqual;[⊈] NotVerticalBar;[∤] NotEqualTilde;[≂̸] NotTildeEqual;[≄] NotTildeTilde;[≉] NotCongruent;[≢] NotHumpEqual;[≏̸] NotLessEqual;[≰] NotLessTilde;[≴] NotLessLess;[≪̸] NotPrecedes;[⊀] NotSucceeds;[⊁] NotSuperset;[⊃⃒] NotElement;[∉] NotGreater;[≯] NotCupCap;[≭] NotExists;[∄] NotSubset;[⊂⃒] NotEqual;[≠] NotTilde;[≁] NoBreak;[⁠] NotLess;[≮] Nopf;[ℕ] Not;[⫬].
+ "\x16tNestedGreaterGreater;\x05⪢̸\x15tSquareSupersetEqual;\x03⋣\x14tPrecedesSlantEqual;\x03⋠\x14tRightTriangleEqual;\x03⋭\x14tSucceedsSlantEqual;\x03⋡\x13tDoubleVerticalBar;\x03∦\x13tGreaterSlantEqual;\x05⩾̸\x13tLeftTriangleEqual;\x03⋬\x13tSquareSubsetEqual;\x03⋢\x12tGreaterFullEqual;\x05≧̸\x12tRightTriangleBar;\x05⧐̸\x11tLeftTriangleBar;\x05⧏̸\x10tGreaterGreater;\x05≫̸\x10tLessSlantEqual;\x05⩽̸\x10tNestedLessLess;\x05⪡̸\x10tReverseElement;\x03∌\x10tSquareSuperset;\x05⊐̸\x10tTildeFullEqual;\x03≇\x0fnBreakingSpace;\x02 \x0ftPrecedesEqual;\x05⪯̸\x0ftRightTriangle;\x03⋫\x0ftSucceedsEqual;\x05⪰̸\x0ftSucceedsTilde;\x05≿̸\x0ftSupersetEqual;\x03⊉\x0etGreaterEqual;\x03≱\x0etGreaterTilde;\x03≵\x0etHumpDownHump;\x05≎̸\x0etLeftTriangle;\x03⋪\x0etSquareSubset;\x05⊏̸\x0dtGreaterLess;\x03≹\x0dtLessGreater;\x03≸\x0dtSubsetEqual;\x03⊈\x0dtVerticalBar;\x03∤\x0ctEqualTilde;\x05≂̸\x0ctTildeEqual;\x03≄\x0ctTildeTilde;\x03≉\x0btCongruent;\x03≢\x0btHumpEqual;\x05≏̸\x0btLessEqual;\x03≰\x0btLessTilde;\x03≴\x0atLessLess;\x05≪̸\x0atPrecedes;\x03⊀\x0atSucceeds;\x03⊁\x0atSuperset;\x06⊃⃒\x09tElement;\x03∉\x09tGreater;\x03≯\x08tCupCap;\x03≭\x08tExists;\x03∄\x08tSubset;\x06⊂⃒\x07tEqual;\x03≠\x07tTilde;\x03≁\x06Break;\x03⁠\x06tLess;\x03≮\x03pf;\x03ℕ\x02t;\x03⫬",
+ // Nscr;[𝒩].
+ "\x03cr;\x04𝒩",
+ // Ntilde;[Ñ] Ntilde[Ñ].
+ "\x05ilde;\x02Ñ\x04ilde\x02Ñ",
+ // Nu;[Ν].
+ "\x01;\x02Ν",
+ // OElig;[Œ].
+ "\x04lig;\x02Œ",
+ // Oacute;[Ó] Oacute[Ó].
+ "\x05cute;\x02Ó\x04cute\x02Ó",
+ // Ocirc;[Ô] Ocirc[Ô] Ocy;[О].
+ "\x04irc;\x02Ô\x03irc\x02Ô\x02y;\x02О",
+ // Odblac;[Ő].
+ "\x05blac;\x02Ő",
+ // Ofr;[𝔒].
+ "\x02r;\x04𝔒",
+ // Ograve;[Ò] Ograve[Ò].
+ "\x05rave;\x02Ò\x04rave\x02Ò",
+ // Omicron;[Ο] Omacr;[Ō] Omega;[Ω].
+ "\x06icron;\x02Ο\x04acr;\x02Ō\x04ega;\x02Ω",
+ // Oopf;[𝕆].
+ "\x03pf;\x04𝕆",
+ // OpenCurlyDoubleQuote;[“] OpenCurlyQuote;[‘].
+ "\x13enCurlyDoubleQuote;\x03“\x0denCurlyQuote;\x03‘",
+ // Or;[⩔].
+ "\x01;\x03⩔",
+ // Oslash;[Ø] Oslash[Ø] Oscr;[𝒪].
+ "\x05lash;\x02Ø\x04lash\x02Ø\x03cr;\x04𝒪",
+ // Otilde;[Õ] Otimes;[⨷] Otilde[Õ].
+ "\x05ilde;\x02Õ\x05imes;\x03⨷\x04ilde\x02Õ",
+ // Ouml;[Ö] Ouml[Ö].
+ "\x03ml;\x02Ö\x02ml\x02Ö",
+ // OverParenthesis;[⏜] OverBracket;[⎴] OverBrace;[⏞] OverBar;[‾].
+ "\x0eerParenthesis;\x03⏜\x0aerBracket;\x03⎴\x08erBrace;\x03⏞\x06erBar;\x03‾",
+ // PartialD;[∂].
+ "\x07rtialD;\x03∂",
+ // Pcy;[П].
+ "\x02y;\x02П",
+ // Pfr;[𝔓].
+ "\x02r;\x04𝔓",
+ // Phi;[Φ].
+ "\x02i;\x02Φ",
+ // Pi;[Π].
+ "\x01;\x02Π",
+ // PlusMinus;[±].
+ "\x08usMinus;\x02±",
+ // Poincareplane;[ℌ] Popf;[ℙ].
+ "\x0cincareplane;\x03ℌ\x03pf;\x03ℙ",
+ // PrecedesSlantEqual;[≼] PrecedesEqual;[⪯] PrecedesTilde;[≾] Proportional;[∝] Proportion;[∷] Precedes;[≺] Product;[∏] Prime;[″] Pr;[⪻].
+ "\x11ecedesSlantEqual;\x03≼\x0cecedesEqual;\x03⪯\x0cecedesTilde;\x03≾\x0boportional;\x03∝\x09oportion;\x03∷\x07ecedes;\x03≺\x06oduct;\x03∏\x04ime;\x03″\x01;\x03⪻",
+ // Pscr;[𝒫] Psi;[Ψ].
+ "\x03cr;\x04𝒫\x02i;\x02Ψ",
+ // QUOT;[\"] QUOT[\"].
+ "\x03OT;\x01\"\x02OT\x01\"",
+ // Qfr;[𝔔].
+ "\x02r;\x04𝔔",
+ // Qopf;[ℚ].
+ "\x03pf;\x03ℚ",
+ // Qscr;[𝒬].
+ "\x03cr;\x04𝒬",
+ // RBarr;[⤐].
+ "\x04arr;\x03⤐",
+ // REG;[®] REG[®].
+ "\x02G;\x02®\x01G\x02®",
+ // Racute;[Ŕ] Rarrtl;[⤖] Rang;[⟫] Rarr;[↠].
+ "\x05cute;\x02Ŕ\x05rrtl;\x03⤖\x03ng;\x03⟫\x03rr;\x03↠",
+ // Rcaron;[Ř] Rcedil;[Ŗ] Rcy;[Р].
+ "\x05aron;\x02Ř\x05edil;\x02Ŗ\x02y;\x02Р",
+ // ReverseUpEquilibrium;[⥯] ReverseEquilibrium;[⇋] ReverseElement;[∋] Re;[ℜ].
+ "\x13verseUpEquilibrium;\x03⥯\x11verseEquilibrium;\x03⇋\x0dverseElement;\x03∋\x01;\x03ℜ",
+ // Rfr;[ℜ].
+ "\x02r;\x03ℜ",
+ // Rho;[Ρ].
+ "\x02o;\x02Ρ",
+ // RightArrowLeftArrow;[⇄] RightDoubleBracket;[⟧] RightDownTeeVector;[⥝] RightDownVectorBar;[⥕] RightTriangleEqual;[⊵] RightAngleBracket;[⟩] RightUpDownVector;[⥏] RightTriangleBar;[⧐] RightUpTeeVector;[⥜] RightUpVectorBar;[⥔] RightDownVector;[⇂] RightTeeVector;[⥛] RightVectorBar;[⥓] RightArrowBar;[⇥] RightTeeArrow;[↦] RightTriangle;[⊳] RightUpVector;[↾] RightCeiling;[⌉] RightVector;[⇀] RightArrow;[→] RightFloor;[⌋] Rightarrow;[⇒] RightTee;[⊢].
+ "\x12ghtArrowLeftArrow;\x03⇄\x11ghtDoubleBracket;\x03⟧\x11ghtDownTeeVector;\x03⥝\x11ghtDownVectorBar;\x03⥕\x11ghtTriangleEqual;\x03⊵\x10ghtAngleBracket;\x03⟩\x10ghtUpDownVector;\x03⥏\x0fghtTriangleBar;\x03⧐\x0fghtUpTeeVector;\x03⥜\x0fghtUpVectorBar;\x03⥔\x0eghtDownVector;\x03⇂\x0dghtTeeVector;\x03⥛\x0dghtVectorBar;\x03⥓\x0cghtArrowBar;\x03⇥\x0cghtTeeArrow;\x03↦\x0cghtTriangle;\x03⊳\x0cghtUpVector;\x03↾\x0bghtCeiling;\x03⌉\x0aghtVector;\x03⇀\x09ghtArrow;\x03→\x09ghtFloor;\x03⌋\x09ghtarrow;\x03⇒\x07ghtTee;\x03⊢",
+ // RoundImplies;[⥰] Ropf;[ℝ].
+ "\x0bundImplies;\x03⥰\x03pf;\x03ℝ",
+ // Rrightarrow;[⇛].
+ "\x0aightarrow;\x03⇛",
+ // Rscr;[ℛ] Rsh;[↱].
+ "\x03cr;\x03ℛ\x02h;\x03↱",
+ // RuleDelayed;[⧴].
+ "\x0aleDelayed;\x03⧴",
+ // SHCHcy;[Щ] SHcy;[Ш].
+ "\x05CHcy;\x02Щ\x03cy;\x02Ш",
+ // SOFTcy;[Ь].
+ "\x05FTcy;\x02Ь",
+ // Sacute;[Ś].
+ "\x05cute;\x02Ś",
+ // Scaron;[Š] Scedil;[Ş] Scirc;[Ŝ] Scy;[С] Sc;[⪼].
+ "\x05aron;\x02Š\x05edil;\x02Ş\x04irc;\x02Ŝ\x02y;\x02С\x01;\x03⪼",
+ // Sfr;[𝔖].
+ "\x02r;\x04𝔖",
+ // ShortRightArrow;[→] ShortDownArrow;[↓] ShortLeftArrow;[←] ShortUpArrow;[↑].
+ "\x0eortRightArrow;\x03→\x0dortDownArrow;\x03↓\x0dortLeftArrow;\x03←\x0bortUpArrow;\x03↑",
+ // Sigma;[Σ].
+ "\x04gma;\x02Σ",
+ // SmallCircle;[∘].
+ "\x0aallCircle;\x03∘",
+ // Sopf;[𝕊].
+ "\x03pf;\x04𝕊",
+ // SquareSupersetEqual;[⊒] SquareIntersection;[⊓] SquareSubsetEqual;[⊑] SquareSuperset;[⊐] SquareSubset;[⊏] SquareUnion;[⊔] Square;[□] Sqrt;[√].
+ "\x12uareSupersetEqual;\x03⊒\x11uareIntersection;\x03⊓\x10uareSubsetEqual;\x03⊑\x0duareSuperset;\x03⊐\x0buareSubset;\x03⊏\x0auareUnion;\x03⊔\x05uare;\x03□\x03rt;\x03√",
+ // Sscr;[𝒮].
+ "\x03cr;\x04𝒮",
+ // Star;[⋆].
+ "\x03ar;\x03⋆",
+ // SucceedsSlantEqual;[≽] SucceedsEqual;[⪰] SucceedsTilde;[≿] SupersetEqual;[⊇] SubsetEqual;[⊆] Succeeds;[≻] SuchThat;[∋] Superset;[⊃] Subset;[⋐] Supset;[⋑] Sub;[⋐] Sum;[∑] Sup;[⋑].
+ "\x11cceedsSlantEqual;\x03≽\x0ccceedsEqual;\x03⪰\x0ccceedsTilde;\x03≿\x0cpersetEqual;\x03⊇\x0absetEqual;\x03⊆\x07cceeds;\x03≻\x07chThat;\x03∋\x07perset;\x03⊃\x05bset;\x03⋐\x05pset;\x03⋑\x02b;\x03⋐\x02m;\x03∑\x02p;\x03⋑",
+ // THORN;[Þ] THORN[Þ].
+ "\x04ORN;\x02Þ\x03ORN\x02Þ",
+ // TRADE;[™].
+ "\x04ADE;\x03™",
+ // TSHcy;[Ћ] TScy;[Ц].
+ "\x04Hcy;\x02Ћ\x03cy;\x02Ц",
+ // Tab;[\x9] Tau;[Τ].
+ "\x02b;\x01\x9\x02u;\x02Τ",
+ // Tcaron;[Ť] Tcedil;[Ţ] Tcy;[Т].
+ "\x05aron;\x02Ť\x05edil;\x02Ţ\x02y;\x02Т",
+ // Tfr;[𝔗].
+ "\x02r;\x04𝔗",
+ // ThickSpace;[  ] Therefore;[∴] ThinSpace;[ ] Theta;[Θ].
+ "\x09ickSpace;\x06  \x08erefore;\x03∴\x08inSpace;\x03 \x04eta;\x02Θ",
+ // TildeFullEqual;[≅] TildeEqual;[≃] TildeTilde;[≈] Tilde;[∼].
+ "\x0dldeFullEqual;\x03≅\x09ldeEqual;\x03≃\x09ldeTilde;\x03≈\x04lde;\x03∼",
+ // Topf;[𝕋].
+ "\x03pf;\x04𝕋",
+ // TripleDot;[⃛].
+ "\x08ipleDot;\x03⃛",
+ // Tstrok;[Ŧ] Tscr;[𝒯].
+ "\x05trok;\x02Ŧ\x03cr;\x04𝒯",
+ // Uarrocir;[⥉] Uacute;[Ú] Uacute[Ú] Uarr;[↟].
+ "\x07rrocir;\x03⥉\x05cute;\x02Ú\x04cute\x02Ú\x03rr;\x03↟",
+ // Ubreve;[Ŭ] Ubrcy;[Ў].
+ "\x05reve;\x02Ŭ\x04rcy;\x02Ў",
+ // Ucirc;[Û] Ucirc[Û] Ucy;[У].
+ "\x04irc;\x02Û\x03irc\x02Û\x02y;\x02У",
+ // Udblac;[Ű].
+ "\x05blac;\x02Ű",
+ // Ufr;[𝔘].
+ "\x02r;\x04𝔘",
+ // Ugrave;[Ù] Ugrave[Ù].
+ "\x05rave;\x02Ù\x04rave\x02Ù",
+ // Umacr;[Ū].
+ "\x04acr;\x02Ū",
+ // UnderParenthesis;[⏝] UnderBracket;[⎵] UnderBrace;[⏟] UnionPlus;[⊎] UnderBar;[_] Union;[⋃].
+ "\x0fderParenthesis;\x03⏝\x0bderBracket;\x03⎵\x09derBrace;\x03⏟\x08ionPlus;\x03⊎\x07derBar;\x01_\x04ion;\x03⋃",
+ // Uogon;[Ų] Uopf;[𝕌].
+ "\x04gon;\x02Ų\x03pf;\x04𝕌",
+ // UpArrowDownArrow;[⇅] UpperRightArrow;[↗] UpperLeftArrow;[↖] UpEquilibrium;[⥮] UpDownArrow;[↕] Updownarrow;[⇕] UpArrowBar;[⤒] UpTeeArrow;[↥] UpArrow;[↑] Uparrow;[⇑] Upsilon;[Υ] UpTee;[⊥] Upsi;[ϒ].
+ "\x0fArrowDownArrow;\x03⇅\x0eperRightArrow;\x03↗\x0dperLeftArrow;\x03↖\x0cEquilibrium;\x03⥮\x0aDownArrow;\x03↕\x0adownarrow;\x03⇕\x09ArrowBar;\x03⤒\x09TeeArrow;\x03↥\x06Arrow;\x03↑\x06arrow;\x03⇑\x06silon;\x02Υ\x04Tee;\x03⊥\x03si;\x02ϒ",
+ // Uring;[Ů].
+ "\x04ing;\x02Ů",
+ // Uscr;[𝒰].
+ "\x03cr;\x04𝒰",
+ // Utilde;[Ũ].
+ "\x05ilde;\x02Ũ",
+ // Uuml;[Ü] Uuml[Ü].
+ "\x03ml;\x02Ü\x02ml\x02Ü",
+ // VDash;[⊫].
+ "\x04ash;\x03⊫",
+ // Vbar;[⫫].
+ "\x03ar;\x03⫫",
+ // Vcy;[В].
+ "\x02y;\x02В",
+ // Vdashl;[⫦] Vdash;[⊩].
+ "\x05ashl;\x03⫦\x04ash;\x03⊩",
+ // VerticalSeparator;[❘] VerticalTilde;[≀] VeryThinSpace;[ ] VerticalLine;[|] VerticalBar;[∣] Verbar;[‖] Vert;[‖] Vee;[⋁].
+ "\x10rticalSeparator;\x03❘\x0crticalTilde;\x03≀\x0cryThinSpace;\x03 \x0brticalLine;\x01|\x0articalBar;\x03∣\x05rbar;\x03‖\x03rt;\x03‖\x02e;\x03⋁",
+ // Vfr;[𝔙].
+ "\x02r;\x04𝔙",
+ // Vopf;[𝕍].
+ "\x03pf;\x04𝕍",
+ // Vscr;[𝒱].
+ "\x03cr;\x04𝒱",
+ // Vvdash;[⊪].
+ "\x05dash;\x03⊪",
+ // Wcirc;[Ŵ].
+ "\x04irc;\x02Ŵ",
+ // Wedge;[⋀].
+ "\x04dge;\x03⋀",
+ // Wfr;[𝔚].
+ "\x02r;\x04𝔚",
+ // Wopf;[𝕎].
+ "\x03pf;\x04𝕎",
+ // Wscr;[𝒲].
+ "\x03cr;\x04𝒲",
+ // Xfr;[𝔛].
+ "\x02r;\x04𝔛",
+ // Xi;[Ξ].
+ "\x01;\x02Ξ",
+ // Xopf;[𝕏].
+ "\x03pf;\x04𝕏",
+ // Xscr;[𝒳].
+ "\x03cr;\x04𝒳",
+ // YAcy;[Я].
+ "\x03cy;\x02Я",
+ // YIcy;[Ї].
+ "\x03cy;\x02Ї",
+ // YUcy;[Ю].
+ "\x03cy;\x02Ю",
+ // Yacute;[Ý] Yacute[Ý].
+ "\x05cute;\x02Ý\x04cute\x02Ý",
+ // Ycirc;[Ŷ] Ycy;[Ы].
+ "\x04irc;\x02Ŷ\x02y;\x02Ы",
+ // Yfr;[𝔜].
+ "\x02r;\x04𝔜",
+ // Yopf;[𝕐].
+ "\x03pf;\x04𝕐",
+ // Yscr;[𝒴].
+ "\x03cr;\x04𝒴",
+ // Yuml;[Ÿ].
+ "\x03ml;\x02Ÿ",
+ // ZHcy;[Ж].
+ "\x03cy;\x02Ж",
+ // Zacute;[Ź].
+ "\x05cute;\x02Ź",
+ // Zcaron;[Ž] Zcy;[З].
+ "\x05aron;\x02Ž\x02y;\x02З",
+ // Zdot;[Ż].
+ "\x03ot;\x02Ż",
+ // ZeroWidthSpace;[​] Zeta;[Ζ].
+ "\x0droWidthSpace;\x03​\x03ta;\x02Ζ",
+ // Zfr;[ℨ].
+ "\x02r;\x03ℨ",
+ // Zopf;[ℤ].
+ "\x03pf;\x03ℤ",
+ // Zscr;[𝒵].
+ "\x03cr;\x04𝒵",
+ // aacute;[á] aacute[á].
+ "\x05cute;\x02á\x04cute\x02á",
+ // abreve;[ă].
+ "\x05reve;\x02ă",
+ // acirc;[â] acute;[´] acirc[â] acute[´] acE;[∾̳] acd;[∿] acy;[а] ac;[∾].
+ "\x04irc;\x02â\x04ute;\x02´\x03irc\x02â\x03ute\x02´\x02E;\x05∾̳\x02d;\x03∿\x02y;\x02а\x01;\x03∾",
+ // aelig;[æ] aelig[æ].
+ "\x04lig;\x02æ\x03lig\x02æ",
+ // afr;[𝔞] af;[⁡].
+ "\x02r;\x04𝔞\x01;\x03⁡",
+ // agrave;[à] agrave[à].
+ "\x05rave;\x02à\x04rave\x02à",
+ // alefsym;[ℵ] aleph;[ℵ] alpha;[α].
+ "\x06efsym;\x03ℵ\x04eph;\x03ℵ\x04pha;\x02α",
+ // amacr;[ā] amalg;[⨿] amp;[&] amp[&].
+ "\x04acr;\x02ā\x04alg;\x03⨿\x02p;\x01&\x01p\x01&",
+ // andslope;[⩘] angmsdaa;[⦨] angmsdab;[⦩] angmsdac;[⦪] angmsdad;[⦫] angmsdae;[⦬] angmsdaf;[⦭] angmsdag;[⦮] angmsdah;[⦯] angrtvbd;[⦝] angrtvb;[⊾] angzarr;[⍼] andand;[⩕] angmsd;[∡] angsph;[∢] angle;[∠] angrt;[∟] angst;[Å] andd;[⩜] andv;[⩚] ange;[⦤] and;[∧] ang;[∠].
+ "\x07dslope;\x03⩘\x07gmsdaa;\x03⦨\x07gmsdab;\x03⦩\x07gmsdac;\x03⦪\x07gmsdad;\x03⦫\x07gmsdae;\x03⦬\x07gmsdaf;\x03⦭\x07gmsdag;\x03⦮\x07gmsdah;\x03⦯\x07grtvbd;\x03⦝\x06grtvb;\x03⊾\x06gzarr;\x03⍼\x05dand;\x03⩕\x05gmsd;\x03∡\x05gsph;\x03∢\x04gle;\x03∠\x04grt;\x03∟\x04gst;\x02Å\x03dd;\x03⩜\x03dv;\x03⩚\x03ge;\x03⦤\x02d;\x03∧\x02g;\x03∠",
+ // aogon;[ą] aopf;[𝕒].
+ "\x04gon;\x02ą\x03pf;\x04𝕒",
+ // approxeq;[≊] apacir;[⩯] approx;[≈] apid;[≋] apos;['] apE;[⩰] ape;[≊] ap;[≈].
+ "\x07proxeq;\x03≊\x05acir;\x03⩯\x05prox;\x03≈\x03id;\x03≋\x03os;\x01'\x02E;\x03⩰\x02e;\x03≊\x01;\x03≈",
+ // aring;[å] aring[å].
+ "\x04ing;\x02å\x03ing\x02å",
+ // asympeq;[≍] asymp;[≈] ascr;[𝒶] ast;[*].
+ "\x06ympeq;\x03≍\x04ymp;\x03≈\x03cr;\x04𝒶\x02t;\x01*",
+ // atilde;[ã] atilde[ã].
+ "\x05ilde;\x02ã\x04ilde\x02ã",
+ // auml;[ä] auml[ä].
+ "\x03ml;\x02ä\x02ml\x02ä",
+ // awconint;[∳] awint;[⨑].
+ "\x07conint;\x03∳\x04int;\x03⨑",
+ // bNot;[⫭].
+ "\x03ot;\x03⫭",
+ // backepsilon;[϶] backprime;[‵] backsimeq;[⋍] backcong;[≌] barwedge;[⌅] backsim;[∽] barvee;[⊽] barwed;[⌅].
+ "\x0ackepsilon;\x02϶\x08ckprime;\x03‵\x08cksimeq;\x03⋍\x07ckcong;\x03≌\x07rwedge;\x03⌅\x06cksim;\x03∽\x05rvee;\x03⊽\x05rwed;\x03⌅",
+ // bbrktbrk;[⎶] bbrk;[⎵].
+ "\x07rktbrk;\x03⎶\x03rk;\x03⎵",
+ // bcong;[≌] bcy;[б].
+ "\x04ong;\x03≌\x02y;\x02б",
+ // bdquo;[„].
+ "\x04quo;\x03„",
+ // because;[∵] bemptyv;[⦰] between;[≬] becaus;[∵] bernou;[ℬ] bepsi;[϶] beta;[β] beth;[ℶ].
+ "\x06cause;\x03∵\x06mptyv;\x03⦰\x06tween;\x03≬\x05caus;\x03∵\x05rnou;\x03ℬ\x04psi;\x02϶\x03ta;\x02β\x03th;\x03ℶ",
+ // bfr;[𝔟].
+ "\x02r;\x04𝔟",
+ // bigtriangledown;[▽] bigtriangleup;[△] bigotimes;[⨂] bigoplus;[⨁] bigsqcup;[⨆] biguplus;[⨄] bigwedge;[⋀] bigcirc;[◯] bigodot;[⨀] bigstar;[★] bigcap;[⋂] bigcup;[⋃] bigvee;[⋁].
+ "\x0egtriangledown;\x03▽\x0cgtriangleup;\x03△\x08gotimes;\x03⨂\x07goplus;\x03⨁\x07gsqcup;\x03⨆\x07guplus;\x03⨄\x07gwedge;\x03⋀\x06gcirc;\x03◯\x06godot;\x03⨀\x06gstar;\x03★\x05gcap;\x03⋂\x05gcup;\x03⋃\x05gvee;\x03⋁",
+ // bkarow;[⤍].
+ "\x05arow;\x03⤍",
+ // blacktriangleright;[▸] blacktriangledown;[▾] blacktriangleleft;[◂] blacktriangle;[▴] blacklozenge;[⧫] blacksquare;[▪] blank;[␣] blk12;[▒] blk14;[░] blk34;[▓] block;[█].
+ "\x11acktriangleright;\x03▸\x10acktriangledown;\x03▾\x10acktriangleleft;\x03◂\x0cacktriangle;\x03▴\x0backlozenge;\x03⧫\x0aacksquare;\x03▪\x04ank;\x03␣\x04k12;\x03▒\x04k14;\x03░\x04k34;\x03▓\x04ock;\x03█",
+ // bnequiv;[≡⃥] bnot;[⌐] bne;[=⃥].
+ "\x06equiv;\x06≡⃥\x03ot;\x03⌐\x02e;\x04=⃥",
+ // boxminus;[⊟] boxtimes;[⊠] boxplus;[⊞] bottom;[⊥] bowtie;[⋈] boxbox;[⧉] boxDL;[╗] boxDR;[╔] boxDl;[╖] boxDr;[╓] boxHD;[╦] boxHU;[╩] boxHd;[╤] boxHu;[╧] boxUL;[╝] boxUR;[╚] boxUl;[╜] boxUr;[╙] boxVH;[╬] boxVL;[╣] boxVR;[╠] boxVh;[╫] boxVl;[╢] boxVr;[╟] boxdL;[╕] boxdR;[╒] boxdl;[┐] boxdr;[┌] boxhD;[╥] boxhU;[╨] boxhd;[┬] boxhu;[┴] boxuL;[╛] boxuR;[╘] boxul;[┘] boxur;[└] boxvH;[╪] boxvL;[╡] boxvR;[╞] boxvh;[┼] boxvl;[┤] boxvr;[├] bopf;[𝕓] boxH;[═] boxV;[║] boxh;[─] boxv;[│] bot;[⊥].
+ "\x07xminus;\x03⊟\x07xtimes;\x03⊠\x06xplus;\x03⊞\x05ttom;\x03⊥\x05wtie;\x03⋈\x05xbox;\x03⧉\x04xDL;\x03╗\x04xDR;\x03╔\x04xDl;\x03╖\x04xDr;\x03╓\x04xHD;\x03╦\x04xHU;\x03╩\x04xHd;\x03╤\x04xHu;\x03╧\x04xUL;\x03╝\x04xUR;\x03╚\x04xUl;\x03╜\x04xUr;\x03╙\x04xVH;\x03╬\x04xVL;\x03╣\x04xVR;\x03╠\x04xVh;\x03╫\x04xVl;\x03╢\x04xVr;\x03╟\x04xdL;\x03╕\x04xdR;\x03╒\x04xdl;\x03┐\x04xdr;\x03┌\x04xhD;\x03╥\x04xhU;\x03╨\x04xhd;\x03┬\x04xhu;\x03┴\x04xuL;\x03╛\x04xuR;\x03╘\x04xul;\x03┘\x04xur;\x03└\x04xvH;\x03╪\x04xvL;\x03╡\x04xvR;\x03╞\x04xvh;\x03┼\x04xvl;\x03┤\x04xvr;\x03├\x03pf;\x04𝕓\x03xH;\x03═\x03xV;\x03║\x03xh;\x03─\x03xv;\x03│\x02t;\x03⊥",
+ // bprime;[‵].
+ "\x05rime;\x03‵",
+ // brvbar;[¦] breve;[˘] brvbar[¦].
+ "\x05vbar;\x02¦\x04eve;\x02˘\x04vbar\x02¦",
+ // bsolhsub;[⟈] bsemi;[⁏] bsime;[⋍] bsolb;[⧅] bscr;[𝒷] bsim;[∽] bsol;[\\].
+ "\x07olhsub;\x03⟈\x04emi;\x03⁏\x04ime;\x03⋍\x04olb;\x03⧅\x03cr;\x04𝒷\x03im;\x03∽\x03ol;\x01\\",
+ // bullet;[•] bumpeq;[≏] bumpE;[⪮] bumpe;[≏] bull;[•] bump;[≎].
+ "\x05llet;\x03•\x05mpeq;\x03≏\x04mpE;\x03⪮\x04mpe;\x03≏\x03ll;\x03•\x03mp;\x03≎",
+ // capbrcup;[⩉] cacute;[ć] capand;[⩄] capcap;[⩋] capcup;[⩇] capdot;[⩀] caret;[⁁] caron;[ˇ] caps;[∩︀] cap;[∩].
+ "\x07pbrcup;\x03⩉\x05cute;\x02ć\x05pand;\x03⩄\x05pcap;\x03⩋\x05pcup;\x03⩇\x05pdot;\x03⩀\x04ret;\x03⁁\x04ron;\x02ˇ\x03ps;\x06∩︀\x02p;\x03∩",
+ // ccupssm;[⩐] ccaron;[č] ccedil;[ç] ccaps;[⩍] ccedil[ç] ccirc;[ĉ] ccups;[⩌].
+ "\x06upssm;\x03⩐\x05aron;\x02č\x05edil;\x02ç\x04aps;\x03⩍\x04edil\x02ç\x04irc;\x02ĉ\x04ups;\x03⩌",
+ // cdot;[ċ].
+ "\x03ot;\x02ċ",
+ // centerdot;[·] cemptyv;[⦲] cedil;[¸] cedil[¸] cent;[¢] cent[¢].
+ "\x08nterdot;\x02·\x06mptyv;\x03⦲\x04dil;\x02¸\x03dil\x02¸\x03nt;\x02¢\x02nt\x02¢",
+ // cfr;[𝔠].
+ "\x02r;\x04𝔠",
+ // checkmark;[✓] check;[✓] chcy;[ч] chi;[χ].
+ "\x08eckmark;\x03✓\x04eck;\x03✓\x03cy;\x02ч\x02i;\x02χ",
+ // circlearrowright;[↻] circlearrowleft;[↺] circledcirc;[⊚] circleddash;[⊝] circledast;[⊛] circledR;[®] circledS;[Ⓢ] cirfnint;[⨐] cirscir;[⧂] circeq;[≗] cirmid;[⫯] cirE;[⧃] circ;[ˆ] cire;[≗] cir;[○].
+ "\x0frclearrowright;\x03↻\x0erclearrowleft;\x03↺\x0arcledcirc;\x03⊚\x0arcleddash;\x03⊝\x09rcledast;\x03⊛\x07rcledR;\x02®\x07rcledS;\x03Ⓢ\x07rfnint;\x03⨐\x06rscir;\x03⧂\x05rceq;\x03≗\x05rmid;\x03⫯\x03rE;\x03⧃\x03rc;\x02ˆ\x03re;\x03≗\x02r;\x03○",
+ // clubsuit;[♣] clubs;[♣].
+ "\x07ubsuit;\x03♣\x04ubs;\x03♣",
+ // complement;[∁] complexes;[ℂ] coloneq;[≔] congdot;[⩭] colone;[≔] commat;[@] compfn;[∘] conint;[∮] coprod;[∐] copysr;[℗] colon;[:] comma;[,] comp;[∁] cong;[≅] copf;[𝕔] copy;[©] copy[©].
+ "\x09mplement;\x03∁\x08mplexes;\x03ℂ\x06loneq;\x03≔\x06ngdot;\x03⩭\x05lone;\x03≔\x05mmat;\x01@\x05mpfn;\x03∘\x05nint;\x03∮\x05prod;\x03∐\x05pysr;\x03℗\x04lon;\x01:\x04mma;\x01,\x03mp;\x03∁\x03ng;\x03≅\x03pf;\x04𝕔\x03py;\x02©\x02py\x02©",
+ // crarr;[↵] cross;[✗].
+ "\x04arr;\x03↵\x04oss;\x03✗",
+ // csube;[⫑] csupe;[⫒] cscr;[𝒸] csub;[⫏] csup;[⫐].
+ "\x04ube;\x03⫑\x04upe;\x03⫒\x03cr;\x04𝒸\x03ub;\x03⫏\x03up;\x03⫐",
+ // ctdot;[⋯].
+ "\x04dot;\x03⋯",
+ // curvearrowright;[↷] curvearrowleft;[↶] curlyeqprec;[⋞] curlyeqsucc;[⋟] curlywedge;[⋏] cupbrcap;[⩈] curlyvee;[⋎] cudarrl;[⤸] cudarrr;[⤵] cularrp;[⤽] curarrm;[⤼] cularr;[↶] cupcap;[⩆] cupcup;[⩊] cupdot;[⊍] curarr;[↷] curren;[¤] cuepr;[⋞] cuesc;[⋟] cupor;[⩅] curren[¤] cuvee;[⋎] cuwed;[⋏] cups;[∪︀] cup;[∪].
+ "\x0ervearrowright;\x03↷\x0drvearrowleft;\x03↶\x0arlyeqprec;\x03⋞\x0arlyeqsucc;\x03⋟\x09rlywedge;\x03⋏\x07pbrcap;\x03⩈\x07rlyvee;\x03⋎\x06darrl;\x03⤸\x06darrr;\x03⤵\x06larrp;\x03⤽\x06rarrm;\x03⤼\x05larr;\x03↶\x05pcap;\x03⩆\x05pcup;\x03⩊\x05pdot;\x03⊍\x05rarr;\x03↷\x05rren;\x02¤\x04epr;\x03⋞\x04esc;\x03⋟\x04por;\x03⩅\x04rren\x02¤\x04vee;\x03⋎\x04wed;\x03⋏\x03ps;\x06∪︀\x02p;\x03∪",
+ // cwconint;[∲] cwint;[∱].
+ "\x07conint;\x03∲\x04int;\x03∱",
+ // cylcty;[⌭].
+ "\x05lcty;\x03⌭",
+ // dArr;[⇓].
+ "\x03rr;\x03⇓",
+ // dHar;[⥥].
+ "\x03ar;\x03⥥",
+ // dagger;[†] daleth;[ℸ] dashv;[⊣] darr;[↓] dash;[‐].
+ "\x05gger;\x03†\x05leth;\x03ℸ\x04shv;\x03⊣\x03rr;\x03↓\x03sh;\x03‐",
+ // dbkarow;[⤏] dblac;[˝].
+ "\x06karow;\x03⤏\x04lac;\x02˝",
+ // dcaron;[ď] dcy;[д].
+ "\x05aron;\x02ď\x02y;\x02д",
+ // ddagger;[‡] ddotseq;[⩷] ddarr;[⇊] dd;[ⅆ].
+ "\x06agger;\x03‡\x06otseq;\x03⩷\x04arr;\x03⇊\x01;\x03ⅆ",
+ // demptyv;[⦱] delta;[δ] deg;[°] deg[°].
+ "\x06mptyv;\x03⦱\x04lta;\x02δ\x02g;\x02°\x01g\x02°",
+ // dfisht;[⥿] dfr;[𝔡].
+ "\x05isht;\x03⥿\x02r;\x04𝔡",
+ // dharl;[⇃] dharr;[⇂].
+ "\x04arl;\x03⇃\x04arr;\x03⇂",
+ // divideontimes;[⋇] diamondsuit;[♦] diamond;[⋄] digamma;[ϝ] divide;[÷] divonx;[⋇] diams;[♦] disin;[⋲] divide[÷] diam;[⋄] die;[¨] div;[÷].
+ "\x0cvideontimes;\x03⋇\x0aamondsuit;\x03♦\x06amond;\x03⋄\x06gamma;\x02ϝ\x05vide;\x02÷\x05vonx;\x03⋇\x04ams;\x03♦\x04sin;\x03⋲\x04vide\x02÷\x03am;\x03⋄\x02e;\x02¨\x02v;\x02÷",
+ // djcy;[ђ].
+ "\x03cy;\x02ђ",
+ // dlcorn;[⌞] dlcrop;[⌍].
+ "\x05corn;\x03⌞\x05crop;\x03⌍",
+ // downharpoonright;[⇂] downharpoonleft;[⇃] doublebarwedge;[⌆] downdownarrows;[⇊] dotsquare;[⊡] downarrow;[↓] doteqdot;[≑] dotminus;[∸] dotplus;[∔] dollar;[$] doteq;[≐] dopf;[𝕕] dot;[˙].
+ "\x0fwnharpoonright;\x03⇂\x0ewnharpoonleft;\x03⇃\x0dublebarwedge;\x03⌆\x0dwndownarrows;\x03⇊\x08tsquare;\x03⊡\x08wnarrow;\x03↓\x07teqdot;\x03≑\x07tminus;\x03∸\x06tplus;\x03∔\x05llar;\x01$\x04teq;\x03≐\x03pf;\x04𝕕\x02t;\x02˙",
+ // drbkarow;[⤐] drcorn;[⌟] drcrop;[⌌].
+ "\x07bkarow;\x03⤐\x05corn;\x03⌟\x05crop;\x03⌌",
+ // dstrok;[đ] dscr;[𝒹] dscy;[ѕ] dsol;[⧶].
+ "\x05trok;\x02đ\x03cr;\x04𝒹\x03cy;\x02ѕ\x03ol;\x03⧶",
+ // dtdot;[⋱] dtrif;[▾] dtri;[▿].
+ "\x04dot;\x03⋱\x04rif;\x03▾\x03ri;\x03▿",
+ // duarr;[⇵] duhar;[⥯].
+ "\x04arr;\x03⇵\x04har;\x03⥯",
+ // dwangle;[⦦].
+ "\x06angle;\x03⦦",
+ // dzigrarr;[⟿] dzcy;[џ].
+ "\x07igrarr;\x03⟿\x03cy;\x02џ",
+ // eDDot;[⩷] eDot;[≑].
+ "\x04Dot;\x03⩷\x03ot;\x03≑",
+ // eacute;[é] easter;[⩮] eacute[é].
+ "\x05cute;\x02é\x05ster;\x03⩮\x04cute\x02é",
+ // ecaron;[ě] ecolon;[≕] ecirc;[ê] ecir;[≖] ecirc[ê] ecy;[э].
+ "\x05aron;\x02ě\x05olon;\x03≕\x04irc;\x02ê\x03ir;\x03≖\x03irc\x02ê\x02y;\x02э",
+ // edot;[ė].
+ "\x03ot;\x02ė",
+ // ee;[ⅇ].
+ "\x01;\x03ⅇ",
+ // efDot;[≒] efr;[𝔢].
+ "\x04Dot;\x03≒\x02r;\x04𝔢",
+ // egrave;[è] egsdot;[⪘] egrave[è] egs;[⪖] eg;[⪚].
+ "\x05rave;\x02è\x05sdot;\x03⪘\x04rave\x02è\x02s;\x03⪖\x01;\x03⪚",
+ // elinters;[⏧] elsdot;[⪗] ell;[ℓ] els;[⪕] el;[⪙].
+ "\x07inters;\x03⏧\x05sdot;\x03⪗\x02l;\x03ℓ\x02s;\x03⪕\x01;\x03⪙",
+ // emptyset;[∅] emptyv;[∅] emsp13;[ ] emsp14;[ ] emacr;[ē] empty;[∅] emsp;[ ].
+ "\x07ptyset;\x03∅\x05ptyv;\x03∅\x05sp13;\x03 \x05sp14;\x03 \x04acr;\x02ē\x04pty;\x03∅\x03sp;\x03 ",
+ // ensp;[ ] eng;[ŋ].
+ "\x03sp;\x03 \x02g;\x02ŋ",
+ // eogon;[ę] eopf;[𝕖].
+ "\x04gon;\x02ę\x03pf;\x04𝕖",
+ // epsilon;[ε] eparsl;[⧣] eplus;[⩱] epsiv;[ϵ] epar;[⋕] epsi;[ε].
+ "\x06silon;\x02ε\x05arsl;\x03⧣\x04lus;\x03⩱\x04siv;\x02ϵ\x03ar;\x03⋕\x03si;\x02ε",
+ // eqslantless;[⪕] eqslantgtr;[⪖] eqvparsl;[⧥] eqcolon;[≕] equivDD;[⩸] eqcirc;[≖] equals;[=] equest;[≟] eqsim;[≂] equiv;[≡].
+ "\x0aslantless;\x03⪕\x09slantgtr;\x03⪖\x07vparsl;\x03⧥\x06colon;\x03≕\x06uivDD;\x03⩸\x05circ;\x03≖\x05uals;\x01=\x05uest;\x03≟\x04sim;\x03≂\x04uiv;\x03≡",
+ // erDot;[≓] erarr;[⥱].
+ "\x04Dot;\x03≓\x04arr;\x03⥱",
+ // esdot;[≐] escr;[ℯ] esim;[≂].
+ "\x04dot;\x03≐\x03cr;\x03ℯ\x03im;\x03≂",
+ // eta;[η] eth;[ð] eth[ð].
+ "\x02a;\x02η\x02h;\x02ð\x01h\x02ð",
+ // euml;[ë] euro;[€] euml[ë].
+ "\x03ml;\x02ë\x03ro;\x03€\x02ml\x02ë",
+ // exponentiale;[ⅇ] expectation;[ℰ] exist;[∃] excl;[!].
+ "\x0bponentiale;\x03ⅇ\x0apectation;\x03ℰ\x04ist;\x03∃\x03cl;\x01!",
+ // fallingdotseq;[≒].
+ "\x0cllingdotseq;\x03≒",
+ // fcy;[ф].
+ "\x02y;\x02ф",
+ // female;[♀].
+ "\x05male;\x03♀",
+ // ffilig;[ffi] ffllig;[ffl] fflig;[ff] ffr;[𝔣].
+ "\x05ilig;\x03ffi\x05llig;\x03ffl\x04lig;\x03ff\x02r;\x04𝔣",
+ // filig;[fi].
+ "\x04lig;\x03fi",
+ // fjlig;[fj].
+ "\x04lig;\x02fj",
+ // fllig;[fl] fltns;[▱] flat;[♭].
+ "\x04lig;\x03fl\x04tns;\x03▱\x03at;\x03♭",
+ // fnof;[ƒ].
+ "\x03of;\x02ƒ",
+ // forall;[∀] forkv;[⫙] fopf;[𝕗] fork;[⋔].
+ "\x05rall;\x03∀\x04rkv;\x03⫙\x03pf;\x04𝕗\x03rk;\x03⋔",
+ // fpartint;[⨍].
+ "\x07artint;\x03⨍",
+ // frac12;[½] frac13;[⅓] frac14;[¼] frac15;[⅕] frac16;[⅙] frac18;[⅛] frac23;[⅔] frac25;[⅖] frac34;[¾] frac35;[⅗] frac38;[⅜] frac45;[⅘] frac56;[⅚] frac58;[⅝] frac78;[⅞] frac12[½] frac14[¼] frac34[¾] frasl;[⁄] frown;[⌢].
+ "\x05ac12;\x02½\x05ac13;\x03⅓\x05ac14;\x02¼\x05ac15;\x03⅕\x05ac16;\x03⅙\x05ac18;\x03⅛\x05ac23;\x03⅔\x05ac25;\x03⅖\x05ac34;\x02¾\x05ac35;\x03⅗\x05ac38;\x03⅜\x05ac45;\x03⅘\x05ac56;\x03⅚\x05ac58;\x03⅝\x05ac78;\x03⅞\x04ac12\x02½\x04ac14\x02¼\x04ac34\x02¾\x04asl;\x03⁄\x04own;\x03⌢",
+ // fscr;[𝒻].
+ "\x03cr;\x04𝒻",
+ // gEl;[⪌] gE;[≧].
+ "\x02l;\x03⪌\x01;\x03≧",
+ // gacute;[ǵ] gammad;[ϝ] gamma;[γ] gap;[⪆].
+ "\x05cute;\x02ǵ\x05mmad;\x02ϝ\x04mma;\x02γ\x02p;\x03⪆",
+ // gbreve;[ğ].
+ "\x05reve;\x02ğ",
+ // gcirc;[ĝ] gcy;[г].
+ "\x04irc;\x02ĝ\x02y;\x02г",
+ // gdot;[ġ].
+ "\x03ot;\x02ġ",
+ // geqslant;[⩾] gesdotol;[⪄] gesdoto;[⪂] gesdot;[⪀] gesles;[⪔] gescc;[⪩] geqq;[≧] gesl;[⋛︀] gel;[⋛] geq;[≥] ges;[⩾] ge;[≥].
+ "\x07qslant;\x03⩾\x07sdotol;\x03⪄\x06sdoto;\x03⪂\x05sdot;\x03⪀\x05sles;\x03⪔\x04scc;\x03⪩\x03qq;\x03≧\x03sl;\x06⋛︀\x02l;\x03⋛\x02q;\x03≥\x02s;\x03⩾\x01;\x03≥",
+ // gfr;[𝔤].
+ "\x02r;\x04𝔤",
+ // ggg;[⋙] gg;[≫].
+ "\x02g;\x03⋙\x01;\x03≫",
+ // gimel;[ℷ].
+ "\x04mel;\x03ℷ",
+ // gjcy;[ѓ].
+ "\x03cy;\x02ѓ",
+ // glE;[⪒] gla;[⪥] glj;[⪤] gl;[≷].
+ "\x02E;\x03⪒\x02a;\x03⪥\x02j;\x03⪤\x01;\x03≷",
+ // gnapprox;[⪊] gneqq;[≩] gnsim;[⋧] gnap;[⪊] gneq;[⪈] gnE;[≩] gne;[⪈].
+ "\x07approx;\x03⪊\x04eqq;\x03≩\x04sim;\x03⋧\x03ap;\x03⪊\x03eq;\x03⪈\x02E;\x03≩\x02e;\x03⪈",
+ // gopf;[𝕘].
+ "\x03pf;\x04𝕘",
+ // grave;[`].
+ "\x04ave;\x01`",
+ // gsime;[⪎] gsiml;[⪐] gscr;[ℊ] gsim;[≳].
+ "\x04ime;\x03⪎\x04iml;\x03⪐\x03cr;\x03ℊ\x03im;\x03≳",
+ // gtreqqless;[⪌] gtrapprox;[⪆] gtreqless;[⋛] gtquest;[⩼] gtrless;[≷] gtlPar;[⦕] gtrarr;[⥸] gtrdot;[⋗] gtrsim;[≳] gtcir;[⩺] gtdot;[⋗] gtcc;[⪧] gt;[>].
+ "\x09reqqless;\x03⪌\x08rapprox;\x03⪆\x08reqless;\x03⋛\x06quest;\x03⩼\x06rless;\x03≷\x05lPar;\x03⦕\x05rarr;\x03⥸\x05rdot;\x03⋗\x05rsim;\x03≳\x04cir;\x03⩺\x04dot;\x03⋗\x03cc;\x03⪧\x01;\x01>",
+ // gvertneqq;[≩︀] gvnE;[≩︀].
+ "\x08ertneqq;\x06≩︀\x03nE;\x06≩︀",
+ // hArr;[⇔].
+ "\x03rr;\x03⇔",
+ // harrcir;[⥈] hairsp;[ ] hamilt;[ℋ] hardcy;[ъ] harrw;[↭] half;[½] harr;[↔].
+ "\x06rrcir;\x03⥈\x05irsp;\x03 \x05milt;\x03ℋ\x05rdcy;\x02ъ\x04rrw;\x03↭\x03lf;\x02½\x03rr;\x03↔",
+ // hbar;[ℏ].
+ "\x03ar;\x03ℏ",
+ // hcirc;[ĥ].
+ "\x04irc;\x02ĥ",
+ // heartsuit;[♥] hearts;[♥] hellip;[…] hercon;[⊹].
+ "\x08artsuit;\x03♥\x05arts;\x03♥\x05llip;\x03…\x05rcon;\x03⊹",
+ // hfr;[𝔥].
+ "\x02r;\x04𝔥",
+ // hksearow;[⤥] hkswarow;[⤦].
+ "\x07searow;\x03⤥\x07swarow;\x03⤦",
+ // hookrightarrow;[↪] hookleftarrow;[↩] homtht;[∻] horbar;[―] hoarr;[⇿] hopf;[𝕙].
+ "\x0dokrightarrow;\x03↪\x0cokleftarrow;\x03↩\x05mtht;\x03∻\x05rbar;\x03―\x04arr;\x03⇿\x03pf;\x04𝕙",
+ // hslash;[ℏ] hstrok;[ħ] hscr;[𝒽].
+ "\x05lash;\x03ℏ\x05trok;\x02ħ\x03cr;\x04𝒽",
+ // hybull;[⁃] hyphen;[‐].
+ "\x05bull;\x03⁃\x05phen;\x03‐",
+ // iacute;[í] iacute[í].
+ "\x05cute;\x02í\x04cute\x02í",
+ // icirc;[î] icirc[î] icy;[и] ic;[⁣].
+ "\x04irc;\x02î\x03irc\x02î\x02y;\x02и\x01;\x03⁣",
+ // iexcl;[¡] iecy;[е] iexcl[¡].
+ "\x04xcl;\x02¡\x03cy;\x02е\x03xcl\x02¡",
+ // iff;[⇔] ifr;[𝔦].
+ "\x02f;\x03⇔\x02r;\x04𝔦",
+ // igrave;[ì] igrave[ì].
+ "\x05rave;\x02ì\x04rave\x02ì",
+ // iiiint;[⨌] iinfin;[⧜] iiint;[∭] iiota;[℩] ii;[ⅈ].
+ "\x05iint;\x03⨌\x05nfin;\x03⧜\x04int;\x03∭\x04ota;\x03℩\x01;\x03ⅈ",
+ // ijlig;[ij].
+ "\x04lig;\x02ij",
+ // imagline;[ℐ] imagpart;[ℑ] imacr;[ī] image;[ℑ] imath;[ı] imped;[Ƶ] imof;[⊷].
+ "\x07agline;\x03ℐ\x07agpart;\x03ℑ\x04acr;\x02ī\x04age;\x03ℑ\x04ath;\x02ı\x04ped;\x02Ƶ\x03of;\x03⊷",
+ // infintie;[⧝] integers;[ℤ] intercal;[⊺] intlarhk;[⨗] intprod;[⨼] incare;[℅] inodot;[ı] intcal;[⊺] infin;[∞] int;[∫] in;[∈].
+ "\x07fintie;\x03⧝\x07tegers;\x03ℤ\x07tercal;\x03⊺\x07tlarhk;\x03⨗\x06tprod;\x03⨼\x05care;\x03℅\x05odot;\x02ı\x05tcal;\x03⊺\x04fin;\x03∞\x02t;\x03∫\x01;\x03∈",
+ // iogon;[į] iocy;[ё] iopf;[𝕚] iota;[ι].
+ "\x04gon;\x02į\x03cy;\x02ё\x03pf;\x04𝕚\x03ta;\x02ι",
+ // iprod;[⨼].
+ "\x04rod;\x03⨼",
+ // iquest;[¿] iquest[¿].
+ "\x05uest;\x02¿\x04uest\x02¿",
+ // isindot;[⋵] isinsv;[⋳] isinE;[⋹] isins;[⋴] isinv;[∈] iscr;[𝒾] isin;[∈].
+ "\x06indot;\x03⋵\x05insv;\x03⋳\x04inE;\x03⋹\x04ins;\x03⋴\x04inv;\x03∈\x03cr;\x04𝒾\x03in;\x03∈",
+ // itilde;[ĩ] it;[⁢].
+ "\x05ilde;\x02ĩ\x01;\x03⁢",
+ // iukcy;[і] iuml;[ï] iuml[ï].
+ "\x04kcy;\x02і\x03ml;\x02ï\x02ml\x02ï",
+ // jcirc;[ĵ] jcy;[й].
+ "\x04irc;\x02ĵ\x02y;\x02й",
+ // jfr;[𝔧].
+ "\x02r;\x04𝔧",
+ // jmath;[ȷ].
+ "\x04ath;\x02ȷ",
+ // jopf;[𝕛].
+ "\x03pf;\x04𝕛",
+ // jsercy;[ј] jscr;[𝒿].
+ "\x05ercy;\x02ј\x03cr;\x04𝒿",
+ // jukcy;[є].
+ "\x04kcy;\x02є",
+ // kappav;[ϰ] kappa;[κ].
+ "\x05ppav;\x02ϰ\x04ppa;\x02κ",
+ // kcedil;[ķ] kcy;[к].
+ "\x05edil;\x02ķ\x02y;\x02к",
+ // kfr;[𝔨].
+ "\x02r;\x04𝔨",
+ // kgreen;[ĸ].
+ "\x05reen;\x02ĸ",
+ // khcy;[х].
+ "\x03cy;\x02х",
+ // kjcy;[ќ].
+ "\x03cy;\x02ќ",
+ // kopf;[𝕜].
+ "\x03pf;\x04𝕜",
+ // kscr;[𝓀].
+ "\x03cr;\x04𝓀",
+ // lAtail;[⤛] lAarr;[⇚] lArr;[⇐].
+ "\x05tail;\x03⤛\x04arr;\x03⇚\x03rr;\x03⇐",
+ // lBarr;[⤎].
+ "\x04arr;\x03⤎",
+ // lEg;[⪋] lE;[≦].
+ "\x02g;\x03⪋\x01;\x03≦",
+ // lHar;[⥢].
+ "\x03ar;\x03⥢",
+ // laemptyv;[⦴] larrbfs;[⤟] larrsim;[⥳] lacute;[ĺ] lagran;[ℒ] lambda;[λ] langle;[⟨] larrfs;[⤝] larrhk;[↩] larrlp;[↫] larrpl;[⤹] larrtl;[↢] latail;[⤙] langd;[⦑] laquo;[«] larrb;[⇤] lates;[⪭︀] lang;[⟨] laquo[«] larr;[←] late;[⪭] lap;[⪅] lat;[⪫].
+ "\x07emptyv;\x03⦴\x06rrbfs;\x03⤟\x06rrsim;\x03⥳\x05cute;\x02ĺ\x05gran;\x03ℒ\x05mbda;\x02λ\x05ngle;\x03⟨\x05rrfs;\x03⤝\x05rrhk;\x03↩\x05rrlp;\x03↫\x05rrpl;\x03⤹\x05rrtl;\x03↢\x05tail;\x03⤙\x04ngd;\x03⦑\x04quo;\x02«\x04rrb;\x03⇤\x04tes;\x06⪭︀\x03ng;\x03⟨\x03quo\x02«\x03rr;\x03←\x03te;\x03⪭\x02p;\x03⪅\x02t;\x03⪫",
+ // lbrksld;[⦏] lbrkslu;[⦍] lbrace;[{] lbrack;[[] lbarr;[⤌] lbbrk;[❲] lbrke;[⦋].
+ "\x06rksld;\x03⦏\x06rkslu;\x03⦍\x05race;\x01{\x05rack;\x01[\x04arr;\x03⤌\x04brk;\x03❲\x04rke;\x03⦋",
+ // lcaron;[ľ] lcedil;[ļ] lceil;[⌈] lcub;[{] lcy;[л].
+ "\x05aron;\x02ľ\x05edil;\x02ļ\x04eil;\x03⌈\x03ub;\x01{\x02y;\x02л",
+ // ldrushar;[⥋] ldrdhar;[⥧] ldquor;[„] ldquo;[“] ldca;[⤶] ldsh;[↲].
+ "\x07rushar;\x03⥋\x06rdhar;\x03⥧\x05quor;\x03„\x04quo;\x03“\x03ca;\x03⤶\x03sh;\x03↲",
+ // leftrightsquigarrow;[↭] leftrightharpoons;[⇋] leftharpoondown;[↽] leftrightarrows;[⇆] leftleftarrows;[⇇] leftrightarrow;[↔] leftthreetimes;[⋋] leftarrowtail;[↢] leftharpoonup;[↼] lessapprox;[⪅] lesseqqgtr;[⪋] leftarrow;[←] lesseqgtr;[⋚] leqslant;[⩽] lesdotor;[⪃] lesdoto;[⪁] lessdot;[⋖] lessgtr;[≶] lesssim;[≲] lesdot;[⩿] lesges;[⪓] lescc;[⪨] leqq;[≦] lesg;[⋚︀] leg;[⋚] leq;[≤] les;[⩽] le;[≤].
+ "\x12ftrightsquigarrow;\x03↭\x10ftrightharpoons;\x03⇋\x0eftharpoondown;\x03↽\x0eftrightarrows;\x03⇆\x0dftleftarrows;\x03⇇\x0dftrightarrow;\x03↔\x0dftthreetimes;\x03⋋\x0cftarrowtail;\x03↢\x0cftharpoonup;\x03↼\x09ssapprox;\x03⪅\x09sseqqgtr;\x03⪋\x08ftarrow;\x03←\x08sseqgtr;\x03⋚\x07qslant;\x03⩽\x07sdotor;\x03⪃\x06sdoto;\x03⪁\x06ssdot;\x03⋖\x06ssgtr;\x03≶\x06sssim;\x03≲\x05sdot;\x03⩿\x05sges;\x03⪓\x04scc;\x03⪨\x03qq;\x03≦\x03sg;\x06⋚︀\x02g;\x03⋚\x02q;\x03≤\x02s;\x03⩽\x01;\x03≤",
+ // lfisht;[⥼] lfloor;[⌊] lfr;[𝔩].
+ "\x05isht;\x03⥼\x05loor;\x03⌊\x02r;\x04𝔩",
+ // lgE;[⪑] lg;[≶].
+ "\x02E;\x03⪑\x01;\x03≶",
+ // lharul;[⥪] lhard;[↽] lharu;[↼] lhblk;[▄].
+ "\x05arul;\x03⥪\x04ard;\x03↽\x04aru;\x03↼\x04blk;\x03▄",
+ // ljcy;[љ].
+ "\x03cy;\x02љ",
+ // llcorner;[⌞] llhard;[⥫] llarr;[⇇] lltri;[◺] ll;[≪].
+ "\x07corner;\x03⌞\x05hard;\x03⥫\x04arr;\x03⇇\x04tri;\x03◺\x01;\x03≪",
+ // lmoustache;[⎰] lmidot;[ŀ] lmoust;[⎰].
+ "\x09oustache;\x03⎰\x05idot;\x02ŀ\x05oust;\x03⎰",
+ // lnapprox;[⪉] lneqq;[≨] lnsim;[⋦] lnap;[⪉] lneq;[⪇] lnE;[≨] lne;[⪇].
+ "\x07approx;\x03⪉\x04eqq;\x03≨\x04sim;\x03⋦\x03ap;\x03⪉\x03eq;\x03⪇\x02E;\x03≨\x02e;\x03⪇",
+ // longleftrightarrow;[⟷] longrightarrow;[⟶] looparrowright;[↬] longleftarrow;[⟵] looparrowleft;[↫] longmapsto;[⟼] lotimes;[⨴] lozenge;[◊] loplus;[⨭] lowast;[∗] lowbar;[_] loang;[⟬] loarr;[⇽] lobrk;[⟦] lopar;[⦅] lopf;[𝕝] lozf;[⧫] loz;[◊].
+ "\x11ngleftrightarrow;\x03⟷\x0dngrightarrow;\x03⟶\x0doparrowright;\x03↬\x0cngleftarrow;\x03⟵\x0coparrowleft;\x03↫\x09ngmapsto;\x03⟼\x06times;\x03⨴\x06zenge;\x03◊\x05plus;\x03⨭\x05wast;\x03∗\x05wbar;\x01_\x04ang;\x03⟬\x04arr;\x03⇽\x04brk;\x03⟦\x04par;\x03⦅\x03pf;\x04𝕝\x03zf;\x03⧫\x02z;\x03◊",
+ // lparlt;[⦓] lpar;[(].
+ "\x05arlt;\x03⦓\x03ar;\x01(",
+ // lrcorner;[⌟] lrhard;[⥭] lrarr;[⇆] lrhar;[⇋] lrtri;[⊿] lrm;[‎].
+ "\x07corner;\x03⌟\x05hard;\x03⥭\x04arr;\x03⇆\x04har;\x03⇋\x04tri;\x03⊿\x02m;\x03‎",
+ // lsaquo;[‹] lsquor;[‚] lstrok;[ł] lsime;[⪍] lsimg;[⪏] lsquo;[‘] lscr;[𝓁] lsim;[≲] lsqb;[[] lsh;[↰].
+ "\x05aquo;\x03‹\x05quor;\x03‚\x05trok;\x02ł\x04ime;\x03⪍\x04img;\x03⪏\x04quo;\x03‘\x03cr;\x04𝓁\x03im;\x03≲\x03qb;\x01[\x02h;\x03↰",
+ // ltquest;[⩻] lthree;[⋋] ltimes;[⋉] ltlarr;[⥶] ltrPar;[⦖] ltcir;[⩹] ltdot;[⋖] ltrie;[⊴] ltrif;[◂] ltcc;[⪦] ltri;[◃] lt;[<].
+ "\x06quest;\x03⩻\x05hree;\x03⋋\x05imes;\x03⋉\x05larr;\x03⥶\x05rPar;\x03⦖\x04cir;\x03⩹\x04dot;\x03⋖\x04rie;\x03⊴\x04rif;\x03◂\x03cc;\x03⪦\x03ri;\x03◃\x01;\x01<",
+ // lurdshar;[⥊] luruhar;[⥦].
+ "\x07rdshar;\x03⥊\x06ruhar;\x03⥦",
+ // lvertneqq;[≨︀] lvnE;[≨︀].
+ "\x08ertneqq;\x06≨︀\x03nE;\x06≨︀",
+ // mDDot;[∺].
+ "\x04Dot;\x03∺",
+ // mapstodown;[↧] mapstoleft;[↤] mapstoup;[↥] maltese;[✠] mapsto;[↦] marker;[▮] macr;[¯] male;[♂] malt;[✠] macr[¯] map;[↦].
+ "\x09pstodown;\x03↧\x09pstoleft;\x03↤\x07pstoup;\x03↥\x06ltese;\x03✠\x05psto;\x03↦\x05rker;\x03▮\x03cr;\x02¯\x03le;\x03♂\x03lt;\x03✠\x02cr\x02¯\x02p;\x03↦",
+ // mcomma;[⨩] mcy;[м].
+ "\x05omma;\x03⨩\x02y;\x02м",
+ // mdash;[—].
+ "\x04ash;\x03—",
+ // measuredangle;[∡].
+ "\x0casuredangle;\x03∡",
+ // mfr;[𝔪].
+ "\x02r;\x04𝔪",
+ // mho;[℧].
+ "\x02o;\x03℧",
+ // minusdu;[⨪] midast;[*] midcir;[⫰] middot;[·] minusb;[⊟] minusd;[∸] micro;[µ] middot[·] minus;[−] micro[µ] mid;[∣].
+ "\x06nusdu;\x03⨪\x05dast;\x01*\x05dcir;\x03⫰\x05ddot;\x02·\x05nusb;\x03⊟\x05nusd;\x03∸\x04cro;\x02µ\x04ddot\x02·\x04nus;\x03−\x03cro\x02µ\x02d;\x03∣",
+ // mlcp;[⫛] mldr;[…].
+ "\x03cp;\x03⫛\x03dr;\x03…",
+ // mnplus;[∓].
+ "\x05plus;\x03∓",
+ // models;[⊧] mopf;[𝕞].
+ "\x05dels;\x03⊧\x03pf;\x04𝕞",
+ // mp;[∓].
+ "\x01;\x03∓",
+ // mstpos;[∾] mscr;[𝓂].
+ "\x05tpos;\x03∾\x03cr;\x04𝓂",
+ // multimap;[⊸] mumap;[⊸] mu;[μ].
+ "\x07ltimap;\x03⊸\x04map;\x03⊸\x01;\x02μ",
+ // nGtv;[≫̸] nGg;[⋙̸] nGt;[≫⃒].
+ "\x03tv;\x05≫̸\x02g;\x05⋙̸\x02t;\x06≫⃒",
+ // nLeftrightarrow;[⇎] nLeftarrow;[⇍] nLtv;[≪̸] nLl;[⋘̸] nLt;[≪⃒].
+ "\x0eeftrightarrow;\x03⇎\x09eftarrow;\x03⇍\x03tv;\x05≪̸\x02l;\x05⋘̸\x02t;\x06≪⃒",
+ // nRightarrow;[⇏].
+ "\x0aightarrow;\x03⇏",
+ // nVDash;[⊯] nVdash;[⊮].
+ "\x05Dash;\x03⊯\x05dash;\x03⊮",
+ // naturals;[ℕ] napprox;[≉] natural;[♮] nacute;[ń] nabla;[∇] napid;[≋̸] napos;[ʼn] natur;[♮] nang;[∠⃒] napE;[⩰̸] nap;[≉].
+ "\x07turals;\x03ℕ\x06pprox;\x03≉\x06tural;\x03♮\x05cute;\x02ń\x04bla;\x03∇\x04pid;\x05≋̸\x04pos;\x02ʼn\x04tur;\x03♮\x03ng;\x06∠⃒\x03pE;\x05⩰̸\x02p;\x03≉",
+ // nbumpe;[≏̸] nbump;[≎̸] nbsp;[ ] nbsp[ ].
+ "\x05umpe;\x05≏̸\x04ump;\x05≎̸\x03sp;\x02 \x02sp\x02 ",
+ // ncongdot;[⩭̸] ncaron;[ň] ncedil;[ņ] ncong;[≇] ncap;[⩃] ncup;[⩂] ncy;[н].
+ "\x07ongdot;\x05⩭̸\x05aron;\x02ň\x05edil;\x02ņ\x04ong;\x03≇\x03ap;\x03⩃\x03up;\x03⩂\x02y;\x02н",
+ // ndash;[–].
+ "\x04ash;\x03–",
+ // nearrow;[↗] nexists;[∄] nearhk;[⤤] nequiv;[≢] nesear;[⤨] nexist;[∄] neArr;[⇗] nearr;[↗] nedot;[≐̸] nesim;[≂̸] ne;[≠].
+ "\x06arrow;\x03↗\x06xists;\x03∄\x05arhk;\x03⤤\x05quiv;\x03≢\x05sear;\x03⤨\x05xist;\x03∄\x04Arr;\x03⇗\x04arr;\x03↗\x04dot;\x05≐̸\x04sim;\x05≂̸\x01;\x03≠",
+ // nfr;[𝔫].
+ "\x02r;\x04𝔫",
+ // ngeqslant;[⩾̸] ngeqq;[≧̸] ngsim;[≵] ngeq;[≱] nges;[⩾̸] ngtr;[≯] ngE;[≧̸] nge;[≱] ngt;[≯].
+ "\x08eqslant;\x05⩾̸\x04eqq;\x05≧̸\x04sim;\x03≵\x03eq;\x03≱\x03es;\x05⩾̸\x03tr;\x03≯\x02E;\x05≧̸\x02e;\x03≱\x02t;\x03≯",
+ // nhArr;[⇎] nharr;[↮] nhpar;[⫲].
+ "\x04Arr;\x03⇎\x04arr;\x03↮\x04par;\x03⫲",
+ // nisd;[⋺] nis;[⋼] niv;[∋] ni;[∋].
+ "\x03sd;\x03⋺\x02s;\x03⋼\x02v;\x03∋\x01;\x03∋",
+ // njcy;[њ].
+ "\x03cy;\x02њ",
+ // nleftrightarrow;[↮] nleftarrow;[↚] nleqslant;[⩽̸] nltrie;[⋬] nlArr;[⇍] nlarr;[↚] nleqq;[≦̸] nless;[≮] nlsim;[≴] nltri;[⋪] nldr;[‥] nleq;[≰] nles;[⩽̸] nlE;[≦̸] nle;[≰] nlt;[≮].
+ "\x0eeftrightarrow;\x03↮\x09eftarrow;\x03↚\x08eqslant;\x05⩽̸\x05trie;\x03⋬\x04Arr;\x03⇍\x04arr;\x03↚\x04eqq;\x05≦̸\x04ess;\x03≮\x04sim;\x03≴\x04tri;\x03⋪\x03dr;\x03‥\x03eq;\x03≰\x03es;\x05⩽̸\x02E;\x05≦̸\x02e;\x03≰\x02t;\x03≮",
+ // nmid;[∤].
+ "\x03id;\x03∤",
+ // notindot;[⋵̸] notinva;[∉] notinvb;[⋷] notinvc;[⋶] notniva;[∌] notnivb;[⋾] notnivc;[⋽] notinE;[⋹̸] notin;[∉] notni;[∌] nopf;[𝕟] not;[¬] not[¬].
+ "\x07tindot;\x05⋵̸\x06tinva;\x03∉\x06tinvb;\x03⋷\x06tinvc;\x03⋶\x06tniva;\x03∌\x06tnivb;\x03⋾\x06tnivc;\x03⋽\x05tinE;\x05⋹̸\x04tin;\x03∉\x04tni;\x03∌\x03pf;\x04𝕟\x02t;\x02¬\x01t\x02¬",
+ // nparallel;[∦] npolint;[⨔] npreceq;[⪯̸] nparsl;[⫽⃥] nprcue;[⋠] npart;[∂̸] nprec;[⊀] npar;[∦] npre;[⪯̸] npr;[⊀].
+ "\x08arallel;\x03∦\x06olint;\x03⨔\x06receq;\x05⪯̸\x05arsl;\x06⫽⃥\x05rcue;\x03⋠\x04art;\x05∂̸\x04rec;\x03⊀\x03ar;\x03∦\x03re;\x05⪯̸\x02r;\x03⊀",
+ // nrightarrow;[↛] nrarrc;[⤳̸] nrarrw;[↝̸] nrtrie;[⋭] nrArr;[⇏] nrarr;[↛] nrtri;[⋫].
+ "\x0aightarrow;\x03↛\x05arrc;\x05⤳̸\x05arrw;\x05↝̸\x05trie;\x03⋭\x04Arr;\x03⇏\x04arr;\x03↛\x04tri;\x03⋫",
+ // nshortparallel;[∦] nsubseteqq;[⫅̸] nsupseteqq;[⫆̸] nshortmid;[∤] nsubseteq;[⊈] nsupseteq;[⊉] nsqsube;[⋢] nsqsupe;[⋣] nsubset;[⊂⃒] nsucceq;[⪰̸] nsupset;[⊃⃒] nsccue;[⋡] nsimeq;[≄] nsime;[≄] nsmid;[∤] nspar;[∦] nsubE;[⫅̸] nsube;[⊈] nsucc;[⊁] nsupE;[⫆̸] nsupe;[⊉] nsce;[⪰̸] nscr;[𝓃] nsim;[≁] nsub;[⊄] nsup;[⊅] nsc;[⊁].
+ "\x0dhortparallel;\x03∦\x09ubseteqq;\x05⫅̸\x09upseteqq;\x05⫆̸\x08hortmid;\x03∤\x08ubseteq;\x03⊈\x08upseteq;\x03⊉\x06qsube;\x03⋢\x06qsupe;\x03⋣\x06ubset;\x06⊂⃒\x06ucceq;\x05⪰̸\x06upset;\x06⊃⃒\x05ccue;\x03⋡\x05imeq;\x03≄\x04ime;\x03≄\x04mid;\x03∤\x04par;\x03∦\x04ubE;\x05⫅̸\x04ube;\x03⊈\x04ucc;\x03⊁\x04upE;\x05⫆̸\x04upe;\x03⊉\x03ce;\x05⪰̸\x03cr;\x04𝓃\x03im;\x03≁\x03ub;\x03⊄\x03up;\x03⊅\x02c;\x03⊁",
+ // ntrianglerighteq;[⋭] ntrianglelefteq;[⋬] ntriangleright;[⋫] ntriangleleft;[⋪] ntilde;[ñ] ntilde[ñ] ntgl;[≹] ntlg;[≸].
+ "\x0frianglerighteq;\x03⋭\x0erianglelefteq;\x03⋬\x0driangleright;\x03⋫\x0criangleleft;\x03⋪\x05ilde;\x02ñ\x04ilde\x02ñ\x03gl;\x03≹\x03lg;\x03≸",
+ // numero;[№] numsp;[ ] num;[#] nu;[ν].
+ "\x05mero;\x03№\x04msp;\x03 \x02m;\x01#\x01;\x02ν",
+ // nvinfin;[⧞] nvltrie;[⊴⃒] nvrtrie;[⊵⃒] nvDash;[⊭] nvHarr;[⤄] nvdash;[⊬] nvlArr;[⤂] nvrArr;[⤃] nvsim;[∼⃒] nvap;[≍⃒] nvge;[≥⃒] nvgt;[>⃒] nvle;[≤⃒] nvlt;[<⃒].
+ "\x06infin;\x03⧞\x06ltrie;\x06⊴⃒\x06rtrie;\x06⊵⃒\x05Dash;\x03⊭\x05Harr;\x03⤄\x05dash;\x03⊬\x05lArr;\x03⤂\x05rArr;\x03⤃\x04sim;\x06∼⃒\x03ap;\x06≍⃒\x03ge;\x06≥⃒\x03gt;\x04>⃒\x03le;\x06≤⃒\x03lt;\x04<⃒",
+ // nwarrow;[↖] nwarhk;[⤣] nwnear;[⤧] nwArr;[⇖] nwarr;[↖].
+ "\x06arrow;\x03↖\x05arhk;\x03⤣\x05near;\x03⤧\x04Arr;\x03⇖\x04arr;\x03↖",
+ // oS;[Ⓢ].
+ "\x01;\x03Ⓢ",
+ // oacute;[ó] oacute[ó] oast;[⊛].
+ "\x05cute;\x02ó\x04cute\x02ó\x03st;\x03⊛",
+ // ocirc;[ô] ocir;[⊚] ocirc[ô] ocy;[о].
+ "\x04irc;\x02ô\x03ir;\x03⊚\x03irc\x02ô\x02y;\x02о",
+ // odblac;[ő] odsold;[⦼] odash;[⊝] odiv;[⨸] odot;[⊙].
+ "\x05blac;\x02ő\x05sold;\x03⦼\x04ash;\x03⊝\x03iv;\x03⨸\x03ot;\x03⊙",
+ // oelig;[œ].
+ "\x04lig;\x02œ",
+ // ofcir;[⦿] ofr;[𝔬].
+ "\x04cir;\x03⦿\x02r;\x04𝔬",
+ // ograve;[ò] ograve[ò] ogon;[˛] ogt;[⧁].
+ "\x05rave;\x02ò\x04rave\x02ò\x03on;\x02˛\x02t;\x03⧁",
+ // ohbar;[⦵] ohm;[Ω].
+ "\x04bar;\x03⦵\x02m;\x02Ω",
+ // oint;[∮].
+ "\x03nt;\x03∮",
+ // olcross;[⦻] olarr;[↺] olcir;[⦾] oline;[‾] olt;[⧀].
+ "\x06cross;\x03⦻\x04arr;\x03↺\x04cir;\x03⦾\x04ine;\x03‾\x02t;\x03⧀",
+ // omicron;[ο] ominus;[⊖] omacr;[ō] omega;[ω] omid;[⦶].
+ "\x06icron;\x02ο\x05inus;\x03⊖\x04acr;\x02ō\x04ega;\x02ω\x03id;\x03⦶",
+ // oopf;[𝕠].
+ "\x03pf;\x04𝕠",
+ // operp;[⦹] oplus;[⊕] opar;[⦷].
+ "\x04erp;\x03⦹\x04lus;\x03⊕\x03ar;\x03⦷",
+ // orderof;[ℴ] orslope;[⩗] origof;[⊶] orarr;[↻] order;[ℴ] ordf;[ª] ordm;[º] oror;[⩖] ord;[⩝] ordf[ª] ordm[º] orv;[⩛] or;[∨].
+ "\x06derof;\x03ℴ\x06slope;\x03⩗\x05igof;\x03⊶\x04arr;\x03↻\x04der;\x03ℴ\x03df;\x02ª\x03dm;\x02º\x03or;\x03⩖\x02d;\x03⩝\x02df\x02ª\x02dm\x02º\x02v;\x03⩛\x01;\x03∨",
+ // oslash;[ø] oslash[ø] oscr;[ℴ] osol;[⊘].
+ "\x05lash;\x02ø\x04lash\x02ø\x03cr;\x03ℴ\x03ol;\x03⊘",
+ // otimesas;[⨶] otilde;[õ] otimes;[⊗] otilde[õ].
+ "\x07imesas;\x03⨶\x05ilde;\x02õ\x05imes;\x03⊗\x04ilde\x02õ",
+ // ouml;[ö] ouml[ö].
+ "\x03ml;\x02ö\x02ml\x02ö",
+ // ovbar;[⌽].
+ "\x04bar;\x03⌽",
+ // parallel;[∥] parsim;[⫳] parsl;[⫽] para;[¶] part;[∂] par;[∥] para[¶].
+ "\x07rallel;\x03∥\x05rsim;\x03⫳\x04rsl;\x03⫽\x03ra;\x02¶\x03rt;\x03∂\x02r;\x03∥\x02ra\x02¶",
+ // pcy;[п].
+ "\x02y;\x02п",
+ // pertenk;[‱] percnt;[%] period;[.] permil;[‰] perp;[⊥].
+ "\x06rtenk;\x03‱\x05rcnt;\x01%\x05riod;\x01.\x05rmil;\x03‰\x03rp;\x03⊥",
+ // pfr;[𝔭].
+ "\x02r;\x04𝔭",
+ // phmmat;[ℳ] phone;[☎] phiv;[ϕ] phi;[φ].
+ "\x05mmat;\x03ℳ\x04one;\x03☎\x03iv;\x02ϕ\x02i;\x02φ",
+ // pitchfork;[⋔] piv;[ϖ] pi;[π].
+ "\x08tchfork;\x03⋔\x02v;\x02ϖ\x01;\x02π",
+ // plusacir;[⨣] planckh;[ℎ] pluscir;[⨢] plussim;[⨦] plustwo;[⨧] planck;[ℏ] plankv;[ℏ] plusdo;[∔] plusdu;[⨥] plusmn;[±] plusb;[⊞] pluse;[⩲] plusmn[±] plus;[+].
+ "\x07usacir;\x03⨣\x06anckh;\x03ℎ\x06uscir;\x03⨢\x06ussim;\x03⨦\x06ustwo;\x03⨧\x05anck;\x03ℏ\x05ankv;\x03ℏ\x05usdo;\x03∔\x05usdu;\x03⨥\x05usmn;\x02±\x04usb;\x03⊞\x04use;\x03⩲\x04usmn\x02±\x03us;\x01+",
+ // pm;[±].
+ "\x01;\x02±",
+ // pointint;[⨕] pound;[£] popf;[𝕡] pound[£].
+ "\x07intint;\x03⨕\x04und;\x02£\x03pf;\x04𝕡\x03und\x02£",
+ // preccurlyeq;[≼] precnapprox;[⪹] precapprox;[⪷] precneqq;[⪵] precnsim;[⋨] profalar;[⌮] profline;[⌒] profsurf;[⌓] precsim;[≾] preceq;[⪯] primes;[ℙ] prnsim;[⋨] propto;[∝] prurel;[⊰] prcue;[≼] prime;[′] prnap;[⪹] prsim;[≾] prap;[⪷] prec;[≺] prnE;[⪵] prod;[∏] prop;[∝] prE;[⪳] pre;[⪯] pr;[≺].
+ "\x0aeccurlyeq;\x03≼\x0aecnapprox;\x03⪹\x09ecapprox;\x03⪷\x07ecneqq;\x03⪵\x07ecnsim;\x03⋨\x07ofalar;\x03⌮\x07ofline;\x03⌒\x07ofsurf;\x03⌓\x06ecsim;\x03≾\x05eceq;\x03⪯\x05imes;\x03ℙ\x05nsim;\x03⋨\x05opto;\x03∝\x05urel;\x03⊰\x04cue;\x03≼\x04ime;\x03′\x04nap;\x03⪹\x04sim;\x03≾\x03ap;\x03⪷\x03ec;\x03≺\x03nE;\x03⪵\x03od;\x03∏\x03op;\x03∝\x02E;\x03⪳\x02e;\x03⪯\x01;\x03≺",
+ // pscr;[𝓅] psi;[ψ].
+ "\x03cr;\x04𝓅\x02i;\x02ψ",
+ // puncsp;[ ].
+ "\x05ncsp;\x03 ",
+ // qfr;[𝔮].
+ "\x02r;\x04𝔮",
+ // qint;[⨌].
+ "\x03nt;\x03⨌",
+ // qopf;[𝕢].
+ "\x03pf;\x04𝕢",
+ // qprime;[⁗].
+ "\x05rime;\x03⁗",
+ // qscr;[𝓆].
+ "\x03cr;\x04𝓆",
+ // quaternions;[ℍ] quatint;[⨖] questeq;[≟] quest;[?] quot;[\"] quot[\"].
+ "\x0aaternions;\x03ℍ\x06atint;\x03⨖\x06esteq;\x03≟\x04est;\x01?\x03ot;\x01\"\x02ot\x01\"",
+ // rAtail;[⤜] rAarr;[⇛] rArr;[⇒].
+ "\x05tail;\x03⤜\x04arr;\x03⇛\x03rr;\x03⇒",
+ // rBarr;[⤏].
+ "\x04arr;\x03⤏",
+ // rHar;[⥤].
+ "\x03ar;\x03⥤",
+ // rationals;[ℚ] raemptyv;[⦳] rarrbfs;[⤠] rarrsim;[⥴] racute;[ŕ] rangle;[⟩] rarrap;[⥵] rarrfs;[⤞] rarrhk;[↪] rarrlp;[↬] rarrpl;[⥅] rarrtl;[↣] ratail;[⤚] radic;[√] rangd;[⦒] range;[⦥] raquo;[»] rarrb;[⇥] rarrc;[⤳] rarrw;[↝] ratio;[∶] race;[∽̱] rang;[⟩] raquo[»] rarr;[→].
+ "\x08tionals;\x03ℚ\x07emptyv;\x03⦳\x06rrbfs;\x03⤠\x06rrsim;\x03⥴\x05cute;\x02ŕ\x05ngle;\x03⟩\x05rrap;\x03⥵\x05rrfs;\x03⤞\x05rrhk;\x03↪\x05rrlp;\x03↬\x05rrpl;\x03⥅\x05rrtl;\x03↣\x05tail;\x03⤚\x04dic;\x03√\x04ngd;\x03⦒\x04nge;\x03⦥\x04quo;\x02»\x04rrb;\x03⇥\x04rrc;\x03⤳\x04rrw;\x03↝\x04tio;\x03∶\x03ce;\x05∽̱\x03ng;\x03⟩\x03quo\x02»\x03rr;\x03→",
+ // rbrksld;[⦎] rbrkslu;[⦐] rbrace;[}] rbrack;[]] rbarr;[⤍] rbbrk;[❳] rbrke;[⦌].
+ "\x06rksld;\x03⦎\x06rkslu;\x03⦐\x05race;\x01}\x05rack;\x01]\x04arr;\x03⤍\x04brk;\x03❳\x04rke;\x03⦌",
+ // rcaron;[ř] rcedil;[ŗ] rceil;[⌉] rcub;[}] rcy;[р].
+ "\x05aron;\x02ř\x05edil;\x02ŗ\x04eil;\x03⌉\x03ub;\x01}\x02y;\x02р",
+ // rdldhar;[⥩] rdquor;[”] rdquo;[”] rdca;[⤷] rdsh;[↳].
+ "\x06ldhar;\x03⥩\x05quor;\x03”\x04quo;\x03”\x03ca;\x03⤷\x03sh;\x03↳",
+ // realpart;[ℜ] realine;[ℛ] reals;[ℝ] real;[ℜ] rect;[▭] reg;[®] reg[®].
+ "\x07alpart;\x03ℜ\x06aline;\x03ℛ\x04als;\x03ℝ\x03al;\x03ℜ\x03ct;\x03▭\x02g;\x02®\x01g\x02®",
+ // rfisht;[⥽] rfloor;[⌋] rfr;[𝔯].
+ "\x05isht;\x03⥽\x05loor;\x03⌋\x02r;\x04𝔯",
+ // rharul;[⥬] rhard;[⇁] rharu;[⇀] rhov;[ϱ] rho;[ρ].
+ "\x05arul;\x03⥬\x04ard;\x03⇁\x04aru;\x03⇀\x03ov;\x02ϱ\x02o;\x02ρ",
+ // rightleftharpoons;[⇌] rightharpoondown;[⇁] rightrightarrows;[⇉] rightleftarrows;[⇄] rightsquigarrow;[↝] rightthreetimes;[⋌] rightarrowtail;[↣] rightharpoonup;[⇀] risingdotseq;[≓] rightarrow;[→] ring;[˚].
+ "\x10ghtleftharpoons;\x03⇌\x0fghtharpoondown;\x03⇁\x0fghtrightarrows;\x03⇉\x0eghtleftarrows;\x03⇄\x0eghtsquigarrow;\x03↝\x0eghtthreetimes;\x03⋌\x0dghtarrowtail;\x03↣\x0dghtharpoonup;\x03⇀\x0bsingdotseq;\x03≓\x09ghtarrow;\x03→\x03ng;\x02˚",
+ // rlarr;[⇄] rlhar;[⇌] rlm;[‏].
+ "\x04arr;\x03⇄\x04har;\x03⇌\x02m;\x03‏",
+ // rmoustache;[⎱] rmoust;[⎱].
+ "\x09oustache;\x03⎱\x05oust;\x03⎱",
+ // rnmid;[⫮].
+ "\x04mid;\x03⫮",
+ // rotimes;[⨵] roplus;[⨮] roang;[⟭] roarr;[⇾] robrk;[⟧] ropar;[⦆] ropf;[𝕣].
+ "\x06times;\x03⨵\x05plus;\x03⨮\x04ang;\x03⟭\x04arr;\x03⇾\x04brk;\x03⟧\x04par;\x03⦆\x03pf;\x04𝕣",
+ // rppolint;[⨒] rpargt;[⦔] rpar;[)].
+ "\x07polint;\x03⨒\x05argt;\x03⦔\x03ar;\x01)",
+ // rrarr;[⇉].
+ "\x04arr;\x03⇉",
+ // rsaquo;[›] rsquor;[’] rsquo;[’] rscr;[𝓇] rsqb;[]] rsh;[↱].
+ "\x05aquo;\x03›\x05quor;\x03’\x04quo;\x03’\x03cr;\x04𝓇\x03qb;\x01]\x02h;\x03↱",
+ // rtriltri;[⧎] rthree;[⋌] rtimes;[⋊] rtrie;[⊵] rtrif;[▸] rtri;[▹].
+ "\x07riltri;\x03⧎\x05hree;\x03⋌\x05imes;\x03⋊\x04rie;\x03⊵\x04rif;\x03▸\x03ri;\x03▹",
+ // ruluhar;[⥨].
+ "\x06luhar;\x03⥨",
+ // rx;[℞].
+ "\x01;\x03℞",
+ // sacute;[ś].
+ "\x05cute;\x02ś",
+ // sbquo;[‚].
+ "\x04quo;\x03‚",
+ // scpolint;[⨓] scaron;[š] scedil;[ş] scnsim;[⋩] sccue;[≽] scirc;[ŝ] scnap;[⪺] scsim;[≿] scap;[⪸] scnE;[⪶] scE;[⪴] sce;[⪰] scy;[с] sc;[≻].
+ "\x07polint;\x03⨓\x05aron;\x02š\x05edil;\x02ş\x05nsim;\x03⋩\x04cue;\x03≽\x04irc;\x02ŝ\x04nap;\x03⪺\x04sim;\x03≿\x03ap;\x03⪸\x03nE;\x03⪶\x02E;\x03⪴\x02e;\x03⪰\x02y;\x02с\x01;\x03≻",
+ // sdotb;[⊡] sdote;[⩦] sdot;[⋅].
+ "\x04otb;\x03⊡\x04ote;\x03⩦\x03ot;\x03⋅",
+ // setminus;[∖] searrow;[↘] searhk;[⤥] seswar;[⤩] seArr;[⇘] searr;[↘] setmn;[∖] sect;[§] semi;[;] sext;[✶] sect[§].
+ "\x07tminus;\x03∖\x06arrow;\x03↘\x05arhk;\x03⤥\x05swar;\x03⤩\x04Arr;\x03⇘\x04arr;\x03↘\x04tmn;\x03∖\x03ct;\x02§\x03mi;\x01;\x03xt;\x03✶\x02ct\x02§",
+ // sfrown;[⌢] sfr;[𝔰].
+ "\x05rown;\x03⌢\x02r;\x04𝔰",
+ // shortparallel;[∥] shortmid;[∣] shchcy;[щ] sharp;[♯] shcy;[ш] shy;[­] shy[­].
+ "\x0cortparallel;\x03∥\x07ortmid;\x03∣\x05chcy;\x02щ\x04arp;\x03♯\x03cy;\x02ш\x02y;\x02­\x01y\x02­",
+ // simplus;[⨤] simrarr;[⥲] sigmaf;[ς] sigmav;[ς] simdot;[⩪] sigma;[σ] simeq;[≃] simgE;[⪠] simlE;[⪟] simne;[≆] sime;[≃] simg;[⪞] siml;[⪝] sim;[∼].
+ "\x06mplus;\x03⨤\x06mrarr;\x03⥲\x05gmaf;\x02ς\x05gmav;\x02ς\x05mdot;\x03⩪\x04gma;\x02σ\x04meq;\x03≃\x04mgE;\x03⪠\x04mlE;\x03⪟\x04mne;\x03≆\x03me;\x03≃\x03mg;\x03⪞\x03ml;\x03⪝\x02m;\x03∼",
+ // slarr;[←].
+ "\x04arr;\x03←",
+ // smallsetminus;[∖] smeparsl;[⧤] smashp;[⨳] smile;[⌣] smtes;[⪬︀] smid;[∣] smte;[⪬] smt;[⪪].
+ "\x0callsetminus;\x03∖\x07eparsl;\x03⧤\x05ashp;\x03⨳\x04ile;\x03⌣\x04tes;\x06⪬︀\x03id;\x03∣\x03te;\x03⪬\x02t;\x03⪪",
+ // softcy;[ь] solbar;[⌿] solb;[⧄] sopf;[𝕤] sol;[/].
+ "\x05ftcy;\x02ь\x05lbar;\x03⌿\x03lb;\x03⧄\x03pf;\x04𝕤\x02l;\x01/",
+ // spadesuit;[♠] spades;[♠] spar;[∥].
+ "\x08adesuit;\x03♠\x05ades;\x03♠\x03ar;\x03∥",
+ // sqsubseteq;[⊑] sqsupseteq;[⊒] sqsubset;[⊏] sqsupset;[⊐] sqcaps;[⊓︀] sqcups;[⊔︀] sqsube;[⊑] sqsupe;[⊒] square;[□] squarf;[▪] sqcap;[⊓] sqcup;[⊔] sqsub;[⊏] sqsup;[⊐] squf;[▪] squ;[□].
+ "\x09subseteq;\x03⊑\x09supseteq;\x03⊒\x07subset;\x03⊏\x07supset;\x03⊐\x05caps;\x06⊓︀\x05cups;\x06⊔︀\x05sube;\x03⊑\x05supe;\x03⊒\x05uare;\x03□\x05uarf;\x03▪\x04cap;\x03⊓\x04cup;\x03⊔\x04sub;\x03⊏\x04sup;\x03⊐\x03uf;\x03▪\x02u;\x03□",
+ // srarr;[→].
+ "\x04arr;\x03→",
+ // ssetmn;[∖] ssmile;[⌣] sstarf;[⋆] sscr;[𝓈].
+ "\x05etmn;\x03∖\x05mile;\x03⌣\x05tarf;\x03⋆\x03cr;\x04𝓈",
+ // straightepsilon;[ϵ] straightphi;[ϕ] starf;[★] strns;[¯] star;[☆].
+ "\x0eraightepsilon;\x02ϵ\x0araightphi;\x02ϕ\x04arf;\x03★\x04rns;\x02¯\x03ar;\x03☆",
+ // succcurlyeq;[≽] succnapprox;[⪺] subsetneqq;[⫋] succapprox;[⪸] supsetneqq;[⫌] subseteqq;[⫅] subsetneq;[⊊] supseteqq;[⫆] supsetneq;[⊋] subseteq;[⊆] succneqq;[⪶] succnsim;[⋩] supseteq;[⊇] subedot;[⫃] submult;[⫁] subplus;[⪿] subrarr;[⥹] succsim;[≿] supdsub;[⫘] supedot;[⫄] suphsol;[⟉] suphsub;[⫗] suplarr;[⥻] supmult;[⫂] supplus;[⫀] subdot;[⪽] subset;[⊂] subsim;[⫇] subsub;[⫕] subsup;[⫓] succeq;[⪰] supdot;[⪾] supset;[⊃] supsim;[⫈] supsub;[⫔] supsup;[⫖] subnE;[⫋] subne;[⊊] supnE;[⫌] supne;[⊋] subE;[⫅] sube;[⊆] succ;[≻] sung;[♪] sup1;[¹] sup2;[²] sup3;[³] supE;[⫆] supe;[⊇] sub;[⊂] sum;[∑] sup1[¹] sup2[²] sup3[³] sup;[⊃].
+ "\x0acccurlyeq;\x03≽\x0accnapprox;\x03⪺\x09bsetneqq;\x03⫋\x09ccapprox;\x03⪸\x09psetneqq;\x03⫌\x08bseteqq;\x03⫅\x08bsetneq;\x03⊊\x08pseteqq;\x03⫆\x08psetneq;\x03⊋\x07bseteq;\x03⊆\x07ccneqq;\x03⪶\x07ccnsim;\x03⋩\x07pseteq;\x03⊇\x06bedot;\x03⫃\x06bmult;\x03⫁\x06bplus;\x03⪿\x06brarr;\x03⥹\x06ccsim;\x03≿\x06pdsub;\x03⫘\x06pedot;\x03⫄\x06phsol;\x03⟉\x06phsub;\x03⫗\x06plarr;\x03⥻\x06pmult;\x03⫂\x06pplus;\x03⫀\x05bdot;\x03⪽\x05bset;\x03⊂\x05bsim;\x03⫇\x05bsub;\x03⫕\x05bsup;\x03⫓\x05cceq;\x03⪰\x05pdot;\x03⪾\x05pset;\x03⊃\x05psim;\x03⫈\x05psub;\x03⫔\x05psup;\x03⫖\x04bnE;\x03⫋\x04bne;\x03⊊\x04pnE;\x03⫌\x04pne;\x03⊋\x03bE;\x03⫅\x03be;\x03⊆\x03cc;\x03≻\x03ng;\x03♪\x03p1;\x02¹\x03p2;\x02²\x03p3;\x02³\x03pE;\x03⫆\x03pe;\x03⊇\x02b;\x03⊂\x02m;\x03∑\x02p1\x02¹\x02p2\x02²\x02p3\x02³\x02p;\x03⊃",
+ // swarrow;[↙] swarhk;[⤦] swnwar;[⤪] swArr;[⇙] swarr;[↙].
+ "\x06arrow;\x03↙\x05arhk;\x03⤦\x05nwar;\x03⤪\x04Arr;\x03⇙\x04arr;\x03↙",
+ // szlig;[ß] szlig[ß].
+ "\x04lig;\x02ß\x03lig\x02ß",
+ // target;[⌖] tau;[τ].
+ "\x05rget;\x03⌖\x02u;\x02τ",
+ // tbrk;[⎴].
+ "\x03rk;\x03⎴",
+ // tcaron;[ť] tcedil;[ţ] tcy;[т].
+ "\x05aron;\x02ť\x05edil;\x02ţ\x02y;\x02т",
+ // tdot;[⃛].
+ "\x03ot;\x03⃛",
+ // telrec;[⌕].
+ "\x05lrec;\x03⌕",
+ // tfr;[𝔱].
+ "\x02r;\x04𝔱",
+ // thickapprox;[≈] therefore;[∴] thetasym;[ϑ] thicksim;[∼] there4;[∴] thetav;[ϑ] thinsp;[ ] thksim;[∼] theta;[θ] thkap;[≈] thorn;[þ] thorn[þ].
+ "\x0aickapprox;\x03≈\x08erefore;\x03∴\x07etasym;\x02ϑ\x07icksim;\x03∼\x05ere4;\x03∴\x05etav;\x02ϑ\x05insp;\x03 \x05ksim;\x03∼\x04eta;\x02θ\x04kap;\x03≈\x04orn;\x02þ\x03orn\x02þ",
+ // timesbar;[⨱] timesb;[⊠] timesd;[⨰] tilde;[˜] times;[×] times[×] tint;[∭].
+ "\x07mesbar;\x03⨱\x05mesb;\x03⊠\x05mesd;\x03⨰\x04lde;\x02˜\x04mes;\x02×\x03mes\x02×\x03nt;\x03∭",
+ // topfork;[⫚] topbot;[⌶] topcir;[⫱] toea;[⤨] topf;[𝕥] tosa;[⤩] top;[⊤].
+ "\x06pfork;\x03⫚\x05pbot;\x03⌶\x05pcir;\x03⫱\x03ea;\x03⤨\x03pf;\x04𝕥\x03sa;\x03⤩\x02p;\x03⊤",
+ // tprime;[‴].
+ "\x05rime;\x03‴",
+ // trianglerighteq;[⊵] trianglelefteq;[⊴] triangleright;[▹] triangledown;[▿] triangleleft;[◃] triangleq;[≜] triangle;[▵] triminus;[⨺] trpezium;[⏢] triplus;[⨹] tritime;[⨻] tridot;[◬] trade;[™] trisb;[⧍] trie;[≜].
+ "\x0eianglerighteq;\x03⊵\x0dianglelefteq;\x03⊴\x0ciangleright;\x03▹\x0biangledown;\x03▿\x0biangleleft;\x03◃\x08iangleq;\x03≜\x07iangle;\x03▵\x07iminus;\x03⨺\x07pezium;\x03⏢\x06iplus;\x03⨹\x06itime;\x03⨻\x05idot;\x03◬\x04ade;\x03™\x04isb;\x03⧍\x03ie;\x03≜",
+ // tstrok;[ŧ] tshcy;[ћ] tscr;[𝓉] tscy;[ц].
+ "\x05trok;\x02ŧ\x04hcy;\x02ћ\x03cr;\x04𝓉\x03cy;\x02ц",
+ // twoheadrightarrow;[↠] twoheadleftarrow;[↞] twixt;[≬].
+ "\x10oheadrightarrow;\x03↠\x0foheadleftarrow;\x03↞\x04ixt;\x03≬",
+ // uArr;[⇑].
+ "\x03rr;\x03⇑",
+ // uHar;[⥣].
+ "\x03ar;\x03⥣",
+ // uacute;[ú] uacute[ú] uarr;[↑].
+ "\x05cute;\x02ú\x04cute\x02ú\x03rr;\x03↑",
+ // ubreve;[ŭ] ubrcy;[ў].
+ "\x05reve;\x02ŭ\x04rcy;\x02ў",
+ // ucirc;[û] ucirc[û] ucy;[у].
+ "\x04irc;\x02û\x03irc\x02û\x02y;\x02у",
+ // udblac;[ű] udarr;[⇅] udhar;[⥮].
+ "\x05blac;\x02ű\x04arr;\x03⇅\x04har;\x03⥮",
+ // ufisht;[⥾] ufr;[𝔲].
+ "\x05isht;\x03⥾\x02r;\x04𝔲",
+ // ugrave;[ù] ugrave[ù].
+ "\x05rave;\x02ù\x04rave\x02ù",
+ // uharl;[↿] uharr;[↾] uhblk;[▀].
+ "\x04arl;\x03↿\x04arr;\x03↾\x04blk;\x03▀",
+ // ulcorner;[⌜] ulcorn;[⌜] ulcrop;[⌏] ultri;[◸].
+ "\x07corner;\x03⌜\x05corn;\x03⌜\x05crop;\x03⌏\x04tri;\x03◸",
+ // umacr;[ū] uml;[¨] uml[¨].
+ "\x04acr;\x02ū\x02l;\x02¨\x01l\x02¨",
+ // uogon;[ų] uopf;[𝕦].
+ "\x04gon;\x02ų\x03pf;\x04𝕦",
+ // upharpoonright;[↾] upharpoonleft;[↿] updownarrow;[↕] upuparrows;[⇈] uparrow;[↑] upsilon;[υ] uplus;[⊎] upsih;[ϒ] upsi;[υ].
+ "\x0dharpoonright;\x03↾\x0charpoonleft;\x03↿\x0adownarrow;\x03↕\x09uparrows;\x03⇈\x06arrow;\x03↑\x06silon;\x02υ\x04lus;\x03⊎\x04sih;\x02ϒ\x03si;\x02υ",
+ // urcorner;[⌝] urcorn;[⌝] urcrop;[⌎] uring;[ů] urtri;[◹].
+ "\x07corner;\x03⌝\x05corn;\x03⌝\x05crop;\x03⌎\x04ing;\x02ů\x04tri;\x03◹",
+ // uscr;[𝓊].
+ "\x03cr;\x04𝓊",
+ // utilde;[ũ] utdot;[⋰] utrif;[▴] utri;[▵].
+ "\x05ilde;\x02ũ\x04dot;\x03⋰\x04rif;\x03▴\x03ri;\x03▵",
+ // uuarr;[⇈] uuml;[ü] uuml[ü].
+ "\x04arr;\x03⇈\x03ml;\x02ü\x02ml\x02ü",
+ // uwangle;[⦧].
+ "\x06angle;\x03⦧",
+ // vArr;[⇕].
+ "\x03rr;\x03⇕",
+ // vBarv;[⫩] vBar;[⫨].
+ "\x04arv;\x03⫩\x03ar;\x03⫨",
+ // vDash;[⊨].
+ "\x04ash;\x03⊨",
+ // vartriangleright;[⊳] vartriangleleft;[⊲] varsubsetneqq;[⫋︀] varsupsetneqq;[⫌︀] varsubsetneq;[⊊︀] varsupsetneq;[⊋︀] varepsilon;[ϵ] varnothing;[∅] varpropto;[∝] varkappa;[ϰ] varsigma;[ς] vartheta;[ϑ] vangrt;[⦜] varphi;[ϕ] varrho;[ϱ] varpi;[ϖ] varr;[↕].
+ "\x0frtriangleright;\x03⊳\x0ertriangleleft;\x03⊲\x0crsubsetneqq;\x06⫋︀\x0crsupsetneqq;\x06⫌︀\x0brsubsetneq;\x06⊊︀\x0brsupsetneq;\x06⊋︀\x09repsilon;\x02ϵ\x09rnothing;\x03∅\x08rpropto;\x03∝\x07rkappa;\x02ϰ\x07rsigma;\x02ς\x07rtheta;\x02ϑ\x05ngrt;\x03⦜\x05rphi;\x02ϕ\x05rrho;\x02ϱ\x04rpi;\x02ϖ\x03rr;\x03↕",
+ // vcy;[в].
+ "\x02y;\x02в",
+ // vdash;[⊢].
+ "\x04ash;\x03⊢",
+ // veebar;[⊻] vellip;[⋮] verbar;[|] veeeq;[≚] vert;[|] vee;[∨].
+ "\x05ebar;\x03⊻\x05llip;\x03⋮\x05rbar;\x01|\x04eeq;\x03≚\x03rt;\x01|\x02e;\x03∨",
+ // vfr;[𝔳].
+ "\x02r;\x04𝔳",
+ // vltri;[⊲].
+ "\x04tri;\x03⊲",
+ // vnsub;[⊂⃒] vnsup;[⊃⃒].
+ "\x04sub;\x06⊂⃒\x04sup;\x06⊃⃒",
+ // vopf;[𝕧].
+ "\x03pf;\x04𝕧",
+ // vprop;[∝].
+ "\x04rop;\x03∝",
+ // vrtri;[⊳].
+ "\x04tri;\x03⊳",
+ // vsubnE;[⫋︀] vsubne;[⊊︀] vsupnE;[⫌︀] vsupne;[⊋︀] vscr;[𝓋].
+ "\x05ubnE;\x06⫋︀\x05ubne;\x06⊊︀\x05upnE;\x06⫌︀\x05upne;\x06⊋︀\x03cr;\x04𝓋",
+ // vzigzag;[⦚].
+ "\x06igzag;\x03⦚",
+ // wcirc;[ŵ].
+ "\x04irc;\x02ŵ",
+ // wedbar;[⩟] wedgeq;[≙] weierp;[℘] wedge;[∧].
+ "\x05dbar;\x03⩟\x05dgeq;\x03≙\x05ierp;\x03℘\x04dge;\x03∧",
+ // wfr;[𝔴].
+ "\x02r;\x04𝔴",
+ // wopf;[𝕨].
+ "\x03pf;\x04𝕨",
+ // wp;[℘].
+ "\x01;\x03℘",
+ // wreath;[≀] wr;[≀].
+ "\x05eath;\x03≀\x01;\x03≀",
+ // wscr;[𝓌].
+ "\x03cr;\x04𝓌",
+ // xcirc;[◯] xcap;[⋂] xcup;[⋃].
+ "\x04irc;\x03◯\x03ap;\x03⋂\x03up;\x03⋃",
+ // xdtri;[▽].
+ "\x04tri;\x03▽",
+ // xfr;[𝔵].
+ "\x02r;\x04𝔵",
+ // xhArr;[⟺] xharr;[⟷].
+ "\x04Arr;\x03⟺\x04arr;\x03⟷",
+ // xi;[ξ].
+ "\x01;\x02ξ",
+ // xlArr;[⟸] xlarr;[⟵].
+ "\x04Arr;\x03⟸\x04arr;\x03⟵",
+ // xmap;[⟼].
+ "\x03ap;\x03⟼",
+ // xnis;[⋻].
+ "\x03is;\x03⋻",
+ // xoplus;[⨁] xotime;[⨂] xodot;[⨀] xopf;[𝕩].
+ "\x05plus;\x03⨁\x05time;\x03⨂\x04dot;\x03⨀\x03pf;\x04𝕩",
+ // xrArr;[⟹] xrarr;[⟶].
+ "\x04Arr;\x03⟹\x04arr;\x03⟶",
+ // xsqcup;[⨆] xscr;[𝓍].
+ "\x05qcup;\x03⨆\x03cr;\x04𝓍",
+ // xuplus;[⨄] xutri;[△].
+ "\x05plus;\x03⨄\x04tri;\x03△",
+ // xvee;[⋁].
+ "\x03ee;\x03⋁",
+ // xwedge;[⋀].
+ "\x05edge;\x03⋀",
+ // yacute;[ý] yacute[ý] yacy;[я].
+ "\x05cute;\x02ý\x04cute\x02ý\x03cy;\x02я",
+ // ycirc;[ŷ] ycy;[ы].
+ "\x04irc;\x02ŷ\x02y;\x02ы",
+ // yen;[¥] yen[¥].
+ "\x02n;\x02¥\x01n\x02¥",
+ // yfr;[𝔶].
+ "\x02r;\x04𝔶",
+ // yicy;[ї].
+ "\x03cy;\x02ї",
+ // yopf;[𝕪].
+ "\x03pf;\x04𝕪",
+ // yscr;[𝓎].
+ "\x03cr;\x04𝓎",
+ // yucy;[ю] yuml;[ÿ] yuml[ÿ].
+ "\x03cy;\x02ю\x03ml;\x02ÿ\x02ml\x02ÿ",
+ // zacute;[ź].
+ "\x05cute;\x02ź",
+ // zcaron;[ž] zcy;[з].
+ "\x05aron;\x02ž\x02y;\x02з",
+ // zdot;[ż].
+ "\x03ot;\x02ż",
+ // zeetrf;[ℨ] zeta;[ζ].
+ "\x05etrf;\x03ℨ\x03ta;\x02ζ",
+ // zfr;[𝔷].
+ "\x02r;\x04𝔷",
+ // zhcy;[ж].
+ "\x03cy;\x02ж",
+ // zigrarr;[⇝].
+ "\x06grarr;\x03⇝",
+ // zopf;[𝕫].
+ "\x03pf;\x04𝕫",
+ // zscr;[𝓏].
+ "\x03cr;\x04𝓏",
+ // zwnj;[‌] zwj;[‍].
+ "\x03nj;\x03‌\x02j;\x03‍",
+ ),
+ "small_words" => "GT\x00LT\x00gt\x00lt\x00",
+ "small_mappings" => array(
+ ">",
+ "<",
+ ">",
+ "<",
+ )
+ )
+);