You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by je...@apache.org on 2018/10/25 16:40:12 UTC

[sling-whiteboard] branch master updated: initial commit

This is an automated email from the ASF dual-hosted git repository.

jeb pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-whiteboard.git


The following commit(s) were added to refs/heads/master by this push:
     new 87bcf1b  initial commit
87bcf1b is described below

commit 87bcf1b9d002cb26e1bf377f58697a07373c4278
Author: JE Bailey <ja...@sas.com>
AuthorDate: Wed Oct 24 12:39:51 2018 -0400

    initial commit
---
 tag-modifier/LICENSE                               |  201 ++
 tag-modifier/README.md                             |   45 +
 tag-modifier/pom.xml                               |  105 +
 .../org/apache/sling/tagmodifier/AttrValue.java    |   96 +
 .../java/org/apache/sling/tagmodifier/Element.java |   87 +
 .../org/apache/sling/tagmodifier/ElementType.java  |   21 +
 .../java/org/apache/sling/tagmodifier/Tag.java     |   52 +
 .../org/apache/sling/tagmodifier/TagIterator.java  |   74 +
 .../org/apache/sling/tagmodifier/TagMapping.java   |   64 +
 .../java/org/apache/sling/tagmodifier/Visitor.java |   21 +
 .../sling/tagmodifier/consumer/HtmlSAXSupport.java |   90 +
 .../sling/tagmodifier/impl/ParseException.java     |  187 ++
 .../sling/tagmodifier/impl/SimpleCharStream.java   |  471 ++++
 .../apache/sling/tagmodifier/impl/TagParser.java   |  532 +++++
 .../sling/tagmodifier/impl/TagParserConstants.java |  113 +
 .../tagmodifier/impl/TagParserTokenManager.java    | 1138 ++++++++++
 .../org/apache/sling/tagmodifier/impl/Token.java   |  131 ++
 .../sling/tagmodifier/impl/TokenMgrError.java      |  147 ++
 .../impl/components/HtmlGeneratorFactory.java      |  110 +
 .../tagmodifier/impl/components/TagHtmlParser.java |   62 +
 .../apache/sling/tagmodifier/impl/tag/Comment.java |   51 +
 .../apache/sling/tagmodifier/impl/tag/DocType.java |   52 +
 .../sling/tagmodifier/impl/tag/EndOfFile.java      |   45 +
 .../apache/sling/tagmodifier/impl/tag/EndTag.java  |   49 +
 .../sling/tagmodifier/impl/tag/StartTag.java       |   52 +
 .../sling/tagmodifier/impl/tag/TextData.java       |   66 +
 .../sling/tagmodifier/map/HtmlTextEncoder.java     |   75 +
 .../org/apache/sling/tagmodifier/package-info.java |   15 +
 .../apache/sling/tagmodifier/util/DOMBuilder.java  |  171 ++
 .../sling/tagmodifier/util/Html5Entities.java      | 2273 ++++++++++++++++++++
 .../tagmodifier/util/HtmlEntityTranslator.java     |   37 +
 .../apache/sling/tagmodifier/util/HtmlStreams.java |   72 +
 tag-modifier/src/main/javacc/htmlParser.jj         |  231 ++
 tag-modifier/src/main/resources/entities.json      | 2233 +++++++++++++++++++
 tag-modifier/src/main/resources/structure.json     |   87 +
 .../java/com/github/htmlparser/HtmlParseTest.java  |  117 +
 .../com/github/htmlparser/UnusualHtmlTest.java     |   65 +
 tag-modifier/src/test/resources/demo.html          |  864 ++++++++
 tag-modifier/src/test/resources/fail.html          |   23 +
 39 files changed, 10325 insertions(+)

diff --git a/tag-modifier/LICENSE b/tag-modifier/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/tag-modifier/LICENSE
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/tag-modifier/README.md b/tag-modifier/README.md
new file mode 100644
index 0000000..8f1d0d5
--- /dev/null
+++ b/tag-modifier/README.md
@@ -0,0 +1,45 @@
+[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)
+
+# TagStream
+Module to provide a fast, HTML5/XML tokenzier. TagStream takes an InputStream and tokenizes into a Tag or Text element which can be used for inspection or transformation by leveraging Java's Stream API.
+
+This provides:
+* Reduced memory footprint by eliminating the virtual dom
+* Event based/pull processing of the source
+* Enables stream processing from an input to an output stream
+
+
+## Using TagStream 
+There are multiple ways which provides access to the processing of an HTML/XML source. 
+
+### Iteration
+The ``TagIterator`` allows you to iterate the HTML/XML document utilizing a pull methodology. Whenever you request the next element, the element is tokenized from the InputStream
+
+### Stream
+The ``Tag`` class wraps the ``TagIterator`` to provide a ``Stream<Element>`` provider.
+
+
+Examples:
+
+```java
+//count the number of start tags
+Tag.stream(inputStream).filter(elem -> elem.getType() == ElementType.START_TAG ).count();
+```
+
+```java
+// find any elements that has an href attribute that doesn't point anywhere
+// print out the bad links as an html list of anchors 
+stream.filter(elem -> elem.getType() == ElementType.START_TAG && elem.hasAttribute("href") )
+    .filter(elem -> isLinkBad(elem.getAttribute("href")))
+    .map(HtmlStreams.TO_HTML)
+    .forEach(System.out::println);
+```
+
+```java
+//count the number of tags
+HtmlSAXSupport saxEventGenerator = new HtmlSAXSupport(customHandler);
+Tag.stream(inputStream).forEach(saxEventGenerator);
+```
+TagStream works by using the W3C's HTML5 *parsing* rules to properly identify a Tag. This is a separate set of guidelines from what defines valid HTML. The TagStream parser responds with a Tag or Text element and then proceeds to the next section. It does not attempt to create a DOM tree, it doesn't perform validation of tag it found. It assumes that you know what you are doing and won't judge you.
+
+
diff --git a/tag-modifier/pom.xml b/tag-modifier/pom.xml
new file mode 100644
index 0000000..b9effb1
--- /dev/null
+++ b/tag-modifier/pom.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor 
+    license agreements. See the NOTICE file distributed with this work for additional 
+    information regarding copyright ownership. The ASF licenses this file to 
+    you under the Apache License, Version 2.0 (the "License"); you may not use 
+    this file except in compliance with the License. You may obtain a copy of 
+    the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required 
+    by applicable law or agreed to in writing, software distributed under the 
+    License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 
+    OF ANY KIND, either express or implied. See the License for the specific 
+    language governing permissions and limitations under the License. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>sling</artifactId>
+        <version>34</version>
+    </parent>
+
+    <artifactId>org.apache.sling.tag-modifier</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+
+    <name>Apache Sling Tag Modifier</name>
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.resources.sourceEncoding>UTF-8</project.resources.sourceEncoding>
+    </properties>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.sling</groupId>
+                <artifactId>maven-sling-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>javacc-maven-plugin</artifactId>
+                <version>2.6</version>
+                <executions>
+                    <execution>
+                        <id>javacc</id>
+                        <goals>
+                            <goal>javacc</goal>
+                        </goals>
+                        <configuration>
+                            <jdkVersion>1.8</jdkVersion>
+                            <javadocFriendlyComments>true</javadocFriendlyComments>
+                            <outputDirectory>${basedir}/src/main/java</outputDirectory>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.testing.sling-mock</artifactId>
+            <version>2.2.10</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.johnzon</artifactId>
+            <version>1.0.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-text</artifactId>
+            <version>1.4</version>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.annotation.versioning</artifactId>
+            <version>1.1.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.api</artifactId>
+            <version>2.18.4</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.html</artifactId>
+            <version>1.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.rewriter</artifactId>
+            <version>1.2.2</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+    <packaging>bundle</packaging>
+</project>
\ No newline at end of file
diff --git a/tag-modifier/src/main/java/org/apache/sling/tagmodifier/AttrValue.java b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/AttrValue.java
new file mode 100644
index 0000000..23bc487
--- /dev/null
+++ b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/AttrValue.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.tagmodifier;
+
+import java.util.function.Predicate;
+import java.util.regex.Pattern;
+
+import org.osgi.annotation.versioning.ProviderType;
+
+@ProviderType
+public class AttrValue implements CharSequence {
+
+    Predicate<String> nonQuotable = Pattern.compile("^[a-zA-Z][-_a-zA-Z0-9\\u00A0-\\u10FFFF]*$").asPredicate();
+
+    private String value;
+
+    public AttrValue() {
+    }
+    
+    public AttrValue(String value) {
+        this.value = value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+    
+    public String getValue() {
+        return value;
+    }
+
+    public String quoteIfNeeded() {
+        if (shouldBeQuoted()) {
+            return getQuoted('"');
+        }
+        return value;
+    }
+    
+    public String getQuoted(char paren) {
+        if (isEmpty()) {
+            return null;
+        }
+        return paren + value + paren;
+    }
+
+    public boolean shouldBeQuoted() {
+        if (isEmpty()) {
+            return false;
+        }
+        return nonQuotable.negate().test(value);
+    }
+    
+    public boolean isEmpty() {
+        return value == null;
+    }
+
+    @Override
+    public int length() {
+        if (isEmpty()) {
+            return 0;
+        }
+        return value.length();
+    }
+
+    @Override
+    public char charAt(int index) {
+        if (isEmpty()) {
+            throw new IndexOutOfBoundsException();
+        }
+        return value.charAt(index);
+    }
+
+    @Override
+    public CharSequence subSequence(int start, int end) {
+        if (isEmpty()) {
+            throw new IndexOutOfBoundsException();
+        }
+        return value.subSequence(start, end);
+    }
+    @Override
+    public String toString() {
+        return value;
+    }
+    
+}
diff --git a/tag-modifier/src/main/java/org/apache/sling/tagmodifier/Element.java b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/Element.java
new file mode 100644
index 0000000..64639ac
--- /dev/null
+++ b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/Element.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.tagmodifier;
+
+import java.util.Map;
+
+import org.osgi.annotation.versioning.ProviderType;
+
+@ProviderType
+public interface Element {
+    /**
+     * Retrieve the associated ElementType
+     * 
+     * @return the type of element
+     */
+    ElementType getType();
+
+    /**
+     * Must be defined as true to allow default methods to work correctly, this
+     * method and the getAttributes method are used together to implement attribute
+     * support in an element.
+     * 
+     * @return true if Element supports attributes
+     */
+    boolean supportsAttributes();
+
+    Map<String, AttrValue> getAttributes();
+
+    /**
+     * The String value that best represents what this element is.
+     * 
+     * @return
+     */
+    String getValue();
+
+    /**
+     * Accepts a Visitor to visit
+     * 
+     * @param visitor
+     * @return
+     */
+    default <T> T accept(Visitor<T> visitor) {
+        return visitor.visit(this);
+    }
+
+    /**
+     * Whether this element contains Attributes
+     * 
+     * @return
+     */
+    default boolean hasAttributes() {
+        if (supportsAttributes()) {
+            return !getAttributes().isEmpty();
+        }
+        return false;
+    }
+
+    default boolean containsAttribute(String attrName) {
+        return getAttributes().containsKey(attrName);
+    }
+
+    default String getAttributeValue(String name) {
+        if (supportsAttributes()) {
+            return getAttributes().get(name).toString();
+        }
+        return null;
+    }
+
+    default void setAttribute(String name, String value) {
+        if (supportsAttributes()) {
+            getAttributes().put(name, new AttrValue(value));
+            return;
+        }
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/tag-modifier/src/main/java/org/apache/sling/tagmodifier/ElementType.java b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/ElementType.java
new file mode 100644
index 0000000..7e09d9e
--- /dev/null
+++ b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/ElementType.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.tagmodifier;
+
+import org.osgi.annotation.versioning.ProviderType;
+
+@ProviderType
+public enum ElementType {
+    EOF, START_TAG, COMMENT, END_TAG, TEXT, DOCTYPE;
+}
diff --git a/tag-modifier/src/main/java/org/apache/sling/tagmodifier/Tag.java b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/Tag.java
new file mode 100644
index 0000000..facaad3
--- /dev/null
+++ b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/Tag.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.tagmodifier;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+import org.osgi.annotation.versioning.ProviderType;
+
+/**
+ * Provides access to a stream of elements from a XML/HTML source
+ * 
+ */
+@ProviderType
+public class Tag {
+
+    private Tag() {
+    }
+    
+    public static Stream<Element> stream(String input) {
+        return stream(new ByteArrayInputStream(input.getBytes()));
+    }
+
+    public static Stream<Element> stream(InputStream is) {
+        return  stream(new TagIterator(is));
+    }
+
+    public static Stream<Element> stream(InputStream is, String encoding) {
+        return stream(new TagIterator(is, encoding));
+    }
+
+    private static Stream<Element> stream(TagIterator iterator) {
+        return StreamSupport.stream(
+                Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED | Spliterator.IMMUTABLE), false);
+    }
+
+}
diff --git a/tag-modifier/src/main/java/org/apache/sling/tagmodifier/TagIterator.java b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/TagIterator.java
new file mode 100644
index 0000000..7f450ba
--- /dev/null
+++ b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/TagIterator.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.tagmodifier;
+
+import java.io.InputStream;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.apache.sling.tagmodifier.impl.ParseException;
+import org.apache.sling.tagmodifier.impl.TagParser;
+import org.osgi.annotation.versioning.ProviderType;
+
+@ProviderType
+public class TagIterator implements Iterator<Element> {
+
+    private Element current;
+
+    boolean eof = false;
+    private TagParser parser;
+
+    public TagIterator(InputStream is) {
+        parser = new TagParser(is);
+    }
+
+    public TagIterator(InputStream is, String encoding) {
+        parser = new TagParser(is, encoding);
+    }
+
+    @Override
+    public boolean hasNext() {
+        if (current == null && !eof) {
+            return seek();
+        }
+        return !eof;
+    }
+
+    @Override
+    public Element next() {
+        if (current == null && !eof) {
+            seek();
+        }
+        if (current == null || eof) {
+            throw new NoSuchElementException();
+        }
+        Element response = current;
+        current = null;
+        return response;
+    }
+
+    private boolean seek() {
+        if (eof) {
+            return false;
+        }
+        try {
+            current = parser.element();
+            eof =  (current.getType() == ElementType.EOF);
+            return !eof;
+        } catch (ParseException e) {
+        }
+        return false;
+    }
+
+}
\ No newline at end of file
diff --git a/tag-modifier/src/main/java/org/apache/sling/tagmodifier/TagMapping.java b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/TagMapping.java
new file mode 100644
index 0000000..369b754
--- /dev/null
+++ b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/TagMapping.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.tagmodifier;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+import org.osgi.annotation.versioning.ProviderType;
+
+/**
+ * Utility class that allows you to define a flatMap process in the form of a
+ * BiConsumer<Element,TagMapping> lambda.
+ * 
+ * This allows you to use the next() method to collect the elements that will be
+ * passed on to the stream method. This can modify the eventual output and assists in use cases where
+ * there is a need to add or remove elements
+ *
+ */
+@ProviderType
+public class TagMapping {
+
+    private List<Element> list = new ArrayList<>();
+
+    private TagMapping() {
+    }
+
+    /**
+     * Collects all the elements that are either being passed through or created in
+     * the accept method of the consumer so that they may be passed on to the next
+     * process.
+     */
+    public void next(Element... elements) {
+        Collections.addAll(list, elements);
+    }
+
+    Function<Element, Stream<Element>> createFlatMap(BiConsumer<Element, TagMapping> consumer, TagMapping mapper) {
+        return element -> {
+            list.clear();
+            consumer.accept(element, mapper);
+            return list.stream();
+        };
+    }
+
+    public static Function<Element, Stream<Element>> map(BiConsumer<Element, TagMapping> consumer) {
+        TagMapping mapper = new TagMapping();
+        return mapper.createFlatMap(consumer, mapper);
+    }
+
+}
diff --git a/tag-modifier/src/main/java/org/apache/sling/tagmodifier/Visitor.java b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/Visitor.java
new file mode 100644
index 0000000..ac9a609
--- /dev/null
+++ b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/Visitor.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.sling.tagmodifier;
+
+public interface Visitor<T> {
+
+    T visit(Element element);
+
+}
diff --git a/tag-modifier/src/main/java/org/apache/sling/tagmodifier/consumer/HtmlSAXSupport.java b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/consumer/HtmlSAXSupport.java
new file mode 100644
index 0000000..3c4aa87
--- /dev/null
+++ b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/consumer/HtmlSAXSupport.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.tagmodifier.consumer;
+
+import java.util.Map;
+import java.util.function.Consumer;
+
+import org.apache.sling.tagmodifier.AttrValue;
+import org.apache.sling.tagmodifier.Element;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.Attributes2Impl;
+import org.xml.sax.ext.DefaultHandler2;
+import org.xml.sax.ext.LexicalHandler;
+
+public class HtmlSAXSupport implements Consumer<Element> {
+    
+    private static final DefaultHandler2 handler = new DefaultHandler2();
+    
+    private ContentHandler contentHandler = handler;
+    private LexicalHandler lexicalHandler = handler;
+    private boolean initialized;
+
+    public HtmlSAXSupport(ContentHandler ch, final LexicalHandler lh) {
+        if (ch != null) {
+            contentHandler = ch;
+        }
+        if (lh != null ) {
+            lexicalHandler = lh;
+        }
+    }
+
+    @Override
+    public void accept(Element element) {
+        try {
+            if (!initialized) {
+                contentHandler.startDocument();
+                initialized = true;
+            }
+            String value = element.getValue();
+            switch (element.getType()) {
+            case COMMENT:
+                lexicalHandler.comment(value.toCharArray(), 0, value.length());
+                break;
+            case DOCTYPE:
+                break;
+            case END_TAG:
+                lexicalHandler.endEntity(value);
+                contentHandler.endElement("", value, value);
+                break;
+            case EOF:
+                contentHandler.endDocument();
+                break;
+            case START_TAG:
+                lexicalHandler.startEntity(value);
+                contentHandler.startElement("", value, value, HtmlSAXSupport.convert(element.getAttributes()));
+                break;
+            case TEXT:
+                contentHandler.characters(value.toCharArray(), 0, value.toCharArray().length);
+                break;
+            default:
+                break;
+            }
+        } catch (SAXException se) {
+            //log message
+        }
+
+    }
+    
+    public static Attributes convert(Map<String,AttrValue> attributes) {
+        Attributes2Impl response = new Attributes2Impl();
+        attributes.entrySet().forEach(attr ->
+            response.addAttribute("",attr.getKey(), attr.getKey(), "xsi:String", attr.getValue().toString())
+        );
+        return response;
+    }
+
+}
diff --git a/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/ParseException.java b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/ParseException.java
new file mode 100644
index 0000000..bb13d80
--- /dev/null
+++ b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/ParseException.java
@@ -0,0 +1,187 @@
+/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 5.0 */
+/* JavaCCOptions:KEEP_LINE_COL=null */
+package org.apache.sling.tagmodifier.impl;
+
+/**
+ * This exception is thrown when parse errors are encountered.
+ * You can explicitly create objects of this exception type by
+ * calling the method generateParseException in the generated
+ * parser.
+ *
+ * You can modify this class to customize your error reporting
+ * mechanisms so long as you retain the public fields.
+ */
+public class ParseException extends Exception {
+
+  /**
+   * The version identifier for this Serializable class.
+   * Increment only if the <i>serialized</i> form of the
+   * class changes.
+   */
+  private static final long serialVersionUID = 1L;
+
+  /**
+   * This constructor is used by the method "generateParseException"
+   * in the generated parser.  Calling this constructor generates
+   * a new object of this type with the fields "currentToken",
+   * "expectedTokenSequences", and "tokenImage" set.
+   */
+  public ParseException(Token currentTokenVal,
+                        int[][] expectedTokenSequencesVal,
+                        String[] tokenImageVal
+                       )
+  {
+    super(initialise(currentTokenVal, expectedTokenSequencesVal, tokenImageVal));
+    currentToken = currentTokenVal;
+    expectedTokenSequences = expectedTokenSequencesVal;
+    tokenImage = tokenImageVal;
+  }
+
+  /**
+   * The following constructors are for use by you for whatever
+   * purpose you can think of.  Constructing the exception in this
+   * manner makes the exception behave in the normal way - i.e., as
+   * documented in the class "Throwable".  The fields "errorToken",
+   * "expectedTokenSequences", and "tokenImage" do not contain
+   * relevant information.  The JavaCC generated code does not use
+   * these constructors.
+   */
+
+  public ParseException() {
+    super();
+  }
+
+  /** Constructor with message. */
+  public ParseException(String message) {
+    super(message);
+  }
+
+
+  /**
+   * This is the last token that has been consumed successfully.  If
+   * this object has been created due to a parse error, the token
+   * followng this token will (therefore) be the first error token.
+   */
+  public Token currentToken;
+
+  /**
+   * Each entry in this array is an array of integers.  Each array
+   * of integers represents a sequence of tokens (by their ordinal
+   * values) that is expected at this point of the parse.
+   */
+  public int[][] expectedTokenSequences;
+
+  /**
+   * This is a reference to the "tokenImage" array of the generated
+   * parser within which the parse error occurred.  This array is
+   * defined in the generated ...Constants interface.
+   */
+  public String[] tokenImage;
+
+  /**
+   * It uses "currentToken" and "expectedTokenSequences" to generate a parse
+   * error message and returns it.  If this object has been created
+   * due to a parse error, and you do not catch it (it gets thrown
+   * from the parser) the correct error message
+   * gets displayed.
+   */
+  private static String initialise(Token currentToken,
+                           int[][] expectedTokenSequences,
+                           String[] tokenImage) {
+    String eol = System.getProperty("line.separator", "\n");
+    StringBuffer expected = new StringBuffer();
+    int maxSize = 0;
+    for (int i = 0; i < expectedTokenSequences.length; i++) {
+      if (maxSize < expectedTokenSequences[i].length) {
+        maxSize = expectedTokenSequences[i].length;
+      }
+      for (int j = 0; j < expectedTokenSequences[i].length; j++) {
+        expected.append(tokenImage[expectedTokenSequences[i][j]]).append(' ');
+      }
+      if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
+        expected.append("...");
+      }
+      expected.append(eol).append("    ");
+    }
+    String retval = "Encountered \"";
+    Token tok = currentToken.next;
+    for (int i = 0; i < maxSize; i++) {
+      if (i != 0) retval += " ";
+      if (tok.kind == 0) {
+        retval += tokenImage[0];
+        break;
+      }
+      retval += " " + tokenImage[tok.kind];
+      retval += " \"";
+      retval += add_escapes(tok.image);
+      retval += " \"";
+      tok = tok.next;
+    }
+    retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
+    retval += "." + eol;
+    if (expectedTokenSequences.length == 1) {
+      retval += "Was expecting:" + eol + "    ";
+    } else {
+      retval += "Was expecting one of:" + eol + "    ";
+    }
+    retval += expected.toString();
+    return retval;
+  }
+
+  /**
+   * The end of line string for this machine.
+   */
+  protected String eol = System.getProperty("line.separator", "\n");
+
+  /**
+   * Used to convert raw characters to their escaped version
+   * when these raw version cannot be used as part of an ASCII
+   * string literal.
+   */
+  static String add_escapes(String str) {
+      StringBuffer retval = new StringBuffer();
+      char ch;
+      for (int i = 0; i < str.length(); i++) {
+        switch (str.charAt(i))
+        {
+           case 0 :
+              continue;
+           case '\b':
+              retval.append("\\b");
+              continue;
+           case '\t':
+              retval.append("\\t");
+              continue;
+           case '\n':
+              retval.append("\\n");
+              continue;
+           case '\f':
+              retval.append("\\f");
+              continue;
+           case '\r':
+              retval.append("\\r");
+              continue;
+           case '\"':
+              retval.append("\\\"");
+              continue;
+           case '\'':
+              retval.append("\\\'");
+              continue;
+           case '\\':
+              retval.append("\\\\");
+              continue;
+           default:
+              if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
+                 String s = "0000" + Integer.toString(ch, 16);
+                 retval.append("\\u" + s.substring(s.length() - 4, s.length()));
+              } else {
+                 retval.append(ch);
+              }
+              continue;
+        }
+      }
+      return retval.toString();
+   }
+
+}
+/* JavaCC - OriginalChecksum=ba1d20fcfc9de1875bf962a12af6f93e (do not edit this line) */
diff --git a/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/SimpleCharStream.java b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/SimpleCharStream.java
new file mode 100644
index 0000000..da12233
--- /dev/null
+++ b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/SimpleCharStream.java
@@ -0,0 +1,471 @@
+/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 5.0 */
+/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
+package org.apache.sling.tagmodifier.impl;
+
+/**
+ * An implementation of interface CharStream, where the stream is assumed to
+ * contain only ASCII characters (without unicode processing).
+ */
+
+public class SimpleCharStream
+{
+/** Whether parser is static. */
+  public static final boolean staticFlag = false;
+  int bufsize;
+  int available;
+  int tokenBegin;
+/** Position in buffer. */
+  public int bufpos = -1;
+  protected int bufline[];
+  protected int bufcolumn[];
+
+  protected int column = 0;
+  protected int line = 1;
+
+  protected boolean prevCharIsCR = false;
+  protected boolean prevCharIsLF = false;
+
+  protected java.io.Reader inputStream;
+
+  protected char[] buffer;
+  protected int maxNextCharInd = 0;
+  protected int inBuf = 0;
+  protected int tabSize = 8;
+
+  protected void setTabSize(int i) { tabSize = i; }
+  protected int getTabSize(int i) { return tabSize; }
+
+
+  protected void ExpandBuff(boolean wrapAround)
+  {
+    char[] newbuffer = new char[bufsize + 2048];
+    int newbufline[] = new int[bufsize + 2048];
+    int newbufcolumn[] = new int[bufsize + 2048];
+
+    try
+    {
+      if (wrapAround)
+      {
+        System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
+        System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos);
+        buffer = newbuffer;
+
+        System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
+        System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
+        bufline = newbufline;
+
+        System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
+        System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
+        bufcolumn = newbufcolumn;
+
+        maxNextCharInd = (bufpos += (bufsize - tokenBegin));
+      }
+      else
+      {
+        System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
+        buffer = newbuffer;
+
+        System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
+        bufline = newbufline;
+
+        System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
+        bufcolumn = newbufcolumn;
+
+        maxNextCharInd = (bufpos -= tokenBegin);
+      }
+    }
+    catch (Throwable t)
+    {
+      throw new Error(t.getMessage());
+    }
+
+
+    bufsize += 2048;
+    available = bufsize;
+    tokenBegin = 0;
+  }
+
+  protected void FillBuff() throws java.io.IOException
+  {
+    if (maxNextCharInd == available)
+    {
+      if (available == bufsize)
+      {
+        if (tokenBegin > 2048)
+        {
+          bufpos = maxNextCharInd = 0;
+          available = tokenBegin;
+        }
+        else if (tokenBegin < 0)
+          bufpos = maxNextCharInd = 0;
+        else
+          ExpandBuff(false);
+      }
+      else if (available > tokenBegin)
+        available = bufsize;
+      else if ((tokenBegin - available) < 2048)
+        ExpandBuff(true);
+      else
+        available = tokenBegin;
+    }
+
+    int i;
+    try {
+      if ((i = inputStream.read(buffer, maxNextCharInd, available - maxNextCharInd)) == -1)
+      {
+        inputStream.close();
+        throw new java.io.IOException();
+      }
+      else
+        maxNextCharInd += i;
+      return;
+    }
+    catch(java.io.IOException e) {
+      --bufpos;
+      backup(0);
+      if (tokenBegin == -1)
+        tokenBegin = bufpos;
+      throw e;
+    }
+  }
+
+/** Start. */
+  public char BeginToken() throws java.io.IOException
+  {
+    tokenBegin = -1;
+    char c = readChar();
+    tokenBegin = bufpos;
+
+    return c;
+  }
+
+  protected void UpdateLineColumn(char c)
+  {
+    column++;
+
+    if (prevCharIsLF)
+    {
+      prevCharIsLF = false;
+      line += (column = 1);
+    }
+    else if (prevCharIsCR)
+    {
+      prevCharIsCR = false;
+      if (c == '\n')
+      {
+        prevCharIsLF = true;
+      }
+      else
+        line += (column = 1);
+    }
+
+    switch (c)
+    {
+      case '\r' :
+        prevCharIsCR = true;
+        break;
+      case '\n' :
+        prevCharIsLF = true;
+        break;
+      case '\t' :
+        column--;
+        column += (tabSize - (column % tabSize));
+        break;
+      default :
+        break;
+    }
+
+    bufline[bufpos] = line;
+    bufcolumn[bufpos] = column;
+  }
+
+/** Read a character. */
+  public char readChar() throws java.io.IOException
+  {
+    if (inBuf > 0)
+    {
+      --inBuf;
+
+      if (++bufpos == bufsize)
+        bufpos = 0;
+
+      return buffer[bufpos];
+    }
+
+    if (++bufpos >= maxNextCharInd)
+      FillBuff();
+
+    char c = buffer[bufpos];
+
+    UpdateLineColumn(c);
+    return c;
+  }
+
+  @Deprecated
+  /**
+   * @deprecated
+   * @see #getEndColumn
+   */
+
+  public int getColumn() {
+    return bufcolumn[bufpos];
+  }
+
+  @Deprecated
+  /**
+   * @deprecated
+   * @see #getEndLine
+   */
+
+  public int getLine() {
+    return bufline[bufpos];
+  }
+
+  /** Get token end column number. */
+  public int getEndColumn() {
+    return bufcolumn[bufpos];
+  }
+
+  /** Get token end line number. */
+  public int getEndLine() {
+     return bufline[bufpos];
+  }
+
+  /** Get token beginning column number. */
+  public int getBeginColumn() {
+    return bufcolumn[tokenBegin];
+  }
+
+  /** Get token beginning line number. */
+  public int getBeginLine() {
+    return bufline[tokenBegin];
+  }
+
+/** Backup a number of characters. */
+  public void backup(int amount) {
+
+    inBuf += amount;
+    if ((bufpos -= amount) < 0)
+      bufpos += bufsize;
+  }
+
+  /** Constructor. */
+  public SimpleCharStream(java.io.Reader dstream, int startline,
+  int startcolumn, int buffersize)
+  {
+    inputStream = dstream;
+    line = startline;
+    column = startcolumn - 1;
+
+    available = bufsize = buffersize;
+    buffer = new char[buffersize];
+    bufline = new int[buffersize];
+    bufcolumn = new int[buffersize];
+  }
+
+  /** Constructor. */
+  public SimpleCharStream(java.io.Reader dstream, int startline,
+                          int startcolumn)
+  {
+    this(dstream, startline, startcolumn, 4096);
+  }
+
+  /** Constructor. */
+  public SimpleCharStream(java.io.Reader dstream)
+  {
+    this(dstream, 1, 1, 4096);
+  }
+
+  /** Reinitialise. */
+  public void ReInit(java.io.Reader dstream, int startline,
+  int startcolumn, int buffersize)
+  {
+    inputStream = dstream;
+    line = startline;
+    column = startcolumn - 1;
+
+    if (buffer == null || buffersize != buffer.length)
+    {
+      available = bufsize = buffersize;
+      buffer = new char[buffersize];
+      bufline = new int[buffersize];
+      bufcolumn = new int[buffersize];
+    }
+    prevCharIsLF = prevCharIsCR = false;
+    tokenBegin = inBuf = maxNextCharInd = 0;
+    bufpos = -1;
+  }
+
+  /** Reinitialise. */
+  public void ReInit(java.io.Reader dstream, int startline,
+                     int startcolumn)
+  {
+    ReInit(dstream, startline, startcolumn, 4096);
+  }
+
+  /** Reinitialise. */
+  public void ReInit(java.io.Reader dstream)
+  {
+    ReInit(dstream, 1, 1, 4096);
+  }
+  /** Constructor. */
+  public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
+  int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
+  {
+    this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
+  }
+
+  /** Constructor. */
+  public SimpleCharStream(java.io.InputStream dstream, int startline,
+  int startcolumn, int buffersize)
+  {
+    this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
+  }
+
+  /** Constructor. */
+  public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
+                          int startcolumn) throws java.io.UnsupportedEncodingException
+  {
+    this(dstream, encoding, startline, startcolumn, 4096);
+  }
+
+  /** Constructor. */
+  public SimpleCharStream(java.io.InputStream dstream, int startline,
+                          int startcolumn)
+  {
+    this(dstream, startline, startcolumn, 4096);
+  }
+
+  /** Constructor. */
+  public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
+  {
+    this(dstream, encoding, 1, 1, 4096);
+  }
+
+  /** Constructor. */
+  public SimpleCharStream(java.io.InputStream dstream)
+  {
+    this(dstream, 1, 1, 4096);
+  }
+
+  /** Reinitialise. */
+  public void ReInit(java.io.InputStream dstream, String encoding, int startline,
+                          int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
+  {
+    ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
+  }
+
+  /** Reinitialise. */
+  public void ReInit(java.io.InputStream dstream, int startline,
+                          int startcolumn, int buffersize)
+  {
+    ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
+  }
+
+  /** Reinitialise. */
+  public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
+  {
+    ReInit(dstream, encoding, 1, 1, 4096);
+  }
+
+  /** Reinitialise. */
+  public void ReInit(java.io.InputStream dstream)
+  {
+    ReInit(dstream, 1, 1, 4096);
+  }
+  /** Reinitialise. */
+  public void ReInit(java.io.InputStream dstream, String encoding, int startline,
+                     int startcolumn) throws java.io.UnsupportedEncodingException
+  {
+    ReInit(dstream, encoding, startline, startcolumn, 4096);
+  }
+  /** Reinitialise. */
+  public void ReInit(java.io.InputStream dstream, int startline,
+                     int startcolumn)
+  {
+    ReInit(dstream, startline, startcolumn, 4096);
+  }
+  /** Get token literal value. */
+  public String GetImage()
+  {
+    if (bufpos >= tokenBegin)
+      return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
+    else
+      return new String(buffer, tokenBegin, bufsize - tokenBegin) +
+                            new String(buffer, 0, bufpos + 1);
+  }
+
+  /** Get the suffix. */
+  public char[] GetSuffix(int len)
+  {
+    char[] ret = new char[len];
+
+    if ((bufpos + 1) >= len)
+      System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
+    else
+    {
+      System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
+                                                        len - bufpos - 1);
+      System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
+    }
+
+    return ret;
+  }
+
+  /** Reset buffer when finished. */
+  public void Done()
+  {
+    buffer = null;
+    bufline = null;
+    bufcolumn = null;
+  }
+
+  /**
+   * Method to adjust line and column numbers for the start of a token.
+   */
+  public void adjustBeginLineColumn(int newLine, int newCol)
+  {
+    int start = tokenBegin;
+    int len;
+
+    if (bufpos >= tokenBegin)
+    {
+      len = bufpos - tokenBegin + inBuf + 1;
+    }
+    else
+    {
+      len = bufsize - tokenBegin + bufpos + 1 + inBuf;
+    }
+
+    int i = 0, j = 0, k = 0;
+    int nextColDiff = 0, columnDiff = 0;
+
+    while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
+    {
+      bufline[j] = newLine;
+      nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
+      bufcolumn[j] = newCol + columnDiff;
+      columnDiff = nextColDiff;
+      i++;
+    }
+
+    if (i < len)
+    {
+      bufline[j] = newLine++;
+      bufcolumn[j] = newCol + columnDiff;
+
+      while (i++ < len)
+      {
+        if (bufline[j = start % bufsize] != bufline[++start % bufsize])
+          bufline[j] = newLine++;
+        else
+          bufline[j] = newLine;
+      }
+    }
+
+    line = bufline[j];
+    column = bufcolumn[j];
+  }
+
+}
+/* JavaCC - OriginalChecksum=4df3cbf20a871d13662e770c6d3acff3 (do not edit this line) */
diff --git a/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/TagParser.java b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/TagParser.java
new file mode 100644
index 0000000..85c8ca9
--- /dev/null
+++ b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/TagParser.java
@@ -0,0 +1,532 @@
+/* Generated By:JavaCC: Do not edit this line. TagParser.java */
+package org.apache.sling.tagmodifier.impl;
+
+import java.util.*;
+
+import org.apache.sling.tagmodifier.*;
+import org.apache.sling.tagmodifier.impl.tag.*;
+
+public class TagParser implements TagParserConstants {
+
+  private static String getTokenHtmlText(Token first, Token cur) {
+    Token t;
+    StringBuilder sb = new StringBuilder();
+
+    for (t=first; t != cur.next; t = t.next) {
+      if (t.specialToken != null) {
+        Token tt=t.specialToken;
+        while (tt.specialToken != null)
+          tt = tt.specialToken;
+        for (; tt != null; tt = tt.next)
+          sb.append(tt.image);
+      };
+      sb.append(t.image);
+    };
+    return sb.toString();
+  }
+
+  final public Element element() throws ParseException {
+  Element e;
+  Token text;
+    if (jj_2_1(2)) {
+      e = tag();
+                            {if (true) return e;}
+    } else {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case ENDTAG_START:
+        e = endHtmlElement();
+                                    {if (true) return e;}
+        break;
+      case COMMENT_START:
+        e = commentHtmlElement();
+                                    {if (true) return e;}
+        break;
+      case DECL_START:
+        e = decltag();
+                            {if (true) return e;}
+        break;
+      default:
+        jj_la1[0] = jj_gen;
+        if (jj_2_2(2)) {
+          jj_consume_token(TAG_START);
+          text = jj_consume_token(LST_ERROR);
+              {if (true) return new TextData("<" + text.image);}
+        } else {
+          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+          case RAWTEXT:
+            text = jj_consume_token(RAWTEXT);
+                             {if (true) return new TextData(text.image);}
+            break;
+          case 0:
+            jj_consume_token(0);
+              {if (true) return new EndOfFile();}
+            break;
+          default:
+            jj_la1[1] = jj_gen;
+            jj_consume_token(-1);
+            throw new ParseException();
+          }
+        }
+      }
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/** @return an attribute */
+  final public void attribute(Map<String,AttrValue > alist) throws ParseException {
+  Token t1, t2=null;
+    t1 = jj_consume_token(ATTR_NAME);
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case ATTR_EQ:
+    case ATTR_VAL:
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case ATTR_EQ:
+        jj_consume_token(ATTR_EQ);
+        t2 = jj_consume_token(QUOTED_STRING);
+        break;
+      case ATTR_VAL:
+        t2 = jj_consume_token(ATTR_VAL);
+        break;
+      default:
+        jj_la1[2] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      break;
+    default:
+      jj_la1[3] = jj_gen;
+      ;
+    }
+     if (t2 == null) {
+        alist.put(t1.image,new AttrValue());
+      } else {
+        alist.put(t1.image,new AttrValue(t2.image));
+     }
+  }
+
+  final public Map<String,AttrValue> attributeList() throws ParseException {
+  Map<String,AttrValue> alist = new HashMap<String,AttrValue>();
+    label_1:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case ATTR_NAME:
+        ;
+        break;
+      default:
+        jj_la1[4] = jj_gen;
+        break label_1;
+      }
+      attribute(alist);
+    }
+     {if (true) return alist;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Element tag() throws ParseException {
+  Token t, et;
+  Map<String,AttrValue> alist;
+  Token firstToken = getToken(1);
+    try {
+      jj_consume_token(TAG_START);
+      t = jj_consume_token(TAG_NAME);
+      alist = attributeList();
+      et = jj_consume_token(END_OF_TAG);
+      {if (true) return new StartTag(t.image, alist);}
+    } catch (ParseException ex) {
+    token_source.SwitchTo(DEFAULT);
+    String s = getTokenHtmlText(firstToken, getNextToken());
+    {if (true) return new TextData(s);}
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+/** @return the end of a tag */
+  final public Element endHtmlElement() throws ParseException {
+  Token t;
+  Token firstToken = getToken(1);
+    try {
+      jj_consume_token(ENDTAG_START);
+      t = jj_consume_token(TAG_NAME);
+      jj_consume_token(END_OF_TAG);
+      {if (true) return new EndTag(t.image);}
+    } catch (ParseException ex) {
+    token_source.SwitchTo(DEFAULT);
+    String s = getTokenHtmlText(firstToken, getNextToken());
+    {if (true) return new TextData(s);}
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Comment commentHtmlElement() throws ParseException {
+  StringBuilder sb = new StringBuilder();
+    jj_consume_token(COMMENT_START);
+    label_2:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case COMMENT_WORD:
+        ;
+        break;
+      default:
+        jj_la1[5] = jj_gen;
+        break label_2;
+      }
+      jj_consume_token(COMMENT_WORD);
+                                     sb.append(token.image);
+    }
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case 0:
+      jj_consume_token(0);
+      break;
+    case COMMENT_END:
+      jj_consume_token(COMMENT_END);
+      break;
+    default:
+      jj_la1[6] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    {if (true) return new Comment(sb.toString());}
+    throw new Error("Missing return statement in function");
+  }
+
+/** @return the start of a DECLARATION */
+  final public Element decltag() throws ParseException {
+  Token tok = null;
+  Map<String,AttrValue > alist = new HashMap<String,AttrValue>();
+  Token firstToken = getToken(1);
+    try {
+      jj_consume_token(DECL_START);
+      tok = jj_consume_token(DECL_TAG);
+      label_3:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case DECL_ATTR:
+          ;
+          break;
+        default:
+          jj_la1[7] = jj_gen;
+          break label_3;
+        }
+        jj_consume_token(DECL_ATTR);
+                                                 alist.put(token.image,new AttrValue());
+      }
+      jj_consume_token(DECL_END);
+      {if (true) return new StartTag(tok.image, alist);}
+    } catch (ParseException ex) {
+    token_source.SwitchTo(DEFAULT);
+    String s = getTokenHtmlText(firstToken, getNextToken());
+    {if (true) return new TextData(s);}
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  private boolean jj_2_1(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_1(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(0, xla); }
+  }
+
+  private boolean jj_2_2(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_2(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(1, xla); }
+  }
+
+  private boolean jj_3_1() {
+    if (jj_3R_4()) return true;
+    return false;
+  }
+
+  private boolean jj_3_2() {
+    if (jj_scan_token(TAG_START)) return true;
+    if (jj_scan_token(LST_ERROR)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_4() {
+    if (jj_scan_token(TAG_START)) return true;
+    if (jj_scan_token(TAG_NAME)) return true;
+    return false;
+  }
+
+  /** Generated Token Manager. */
+  public TagParserTokenManager token_source;
+  SimpleCharStream jj_input_stream;
+  /** Current token. */
+  public Token token;
+  /** Next token. */
+  public Token jj_nt;
+  private int jj_ntk;
+  private Token jj_scanpos, jj_lastpos;
+  private int jj_la;
+  private int jj_gen;
+  final private int[] jj_la1 = new int[8];
+  static private int[] jj_la1_0;
+  static {
+      jj_la1_init_0();
+   }
+   private static void jj_la1_init_0() {
+      jj_la1_0 = new int[] {0xe00,0x1001,0x240000,0x240000,0x10000,0x1000000,0x800001,0x4000000,};
+   }
+  final private JJCalls[] jj_2_rtns = new JJCalls[2];
+  private boolean jj_rescan = false;
+  private int jj_gc = 0;
+
+  /** Constructor with InputStream. */
+  public TagParser(java.io.InputStream stream) {
+     this(stream, null);
+  }
+  /** Constructor with InputStream and supplied encoding */
+  public TagParser(java.io.InputStream stream, String encoding) {
+    try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
+    token_source = new TagParserTokenManager(jj_input_stream);
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 8; i++) jj_la1[i] = -1;
+    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+  }
+
+  /** Reinitialise. */
+  public void ReInit(java.io.InputStream stream) {
+     ReInit(stream, null);
+  }
+  /** Reinitialise. */
+  public void ReInit(java.io.InputStream stream, String encoding) {
+    try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
+    token_source.ReInit(jj_input_stream);
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 8; i++) jj_la1[i] = -1;
+    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+  }
+
+  /** Constructor. */
+  public TagParser(java.io.Reader stream) {
+    jj_input_stream = new SimpleCharStream(stream, 1, 1);
+    token_source = new TagParserTokenManager(jj_input_stream);
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 8; i++) jj_la1[i] = -1;
+    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+  }
+
+  /** Reinitialise. */
+  public void ReInit(java.io.Reader stream) {
+    jj_input_stream.ReInit(stream, 1, 1);
+    token_source.ReInit(jj_input_stream);
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 8; i++) jj_la1[i] = -1;
+    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+  }
+
+  /** Constructor with generated Token Manager. */
+  public TagParser(TagParserTokenManager tm) {
+    token_source = tm;
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 8; i++) jj_la1[i] = -1;
+    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+  }
+
+  /** Reinitialise. */
+  public void ReInit(TagParserTokenManager tm) {
+    token_source = tm;
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 8; i++) jj_la1[i] = -1;
+    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+  }
+
+  private Token jj_consume_token(int kind) throws ParseException {
+    Token oldToken;
+    if ((oldToken = token).next != null) token = token.next;
+    else token = token.next = token_source.getNextToken();
+    jj_ntk = -1;
+    if (token.kind == kind) {
+      jj_gen++;
+      if (++jj_gc > 100) {
+        jj_gc = 0;
+        for (int i = 0; i < jj_2_rtns.length; i++) {
+          JJCalls c = jj_2_rtns[i];
+          while (c != null) {
+            if (c.gen < jj_gen) c.first = null;
+            c = c.next;
+          }
+        }
+      }
+      return token;
+    }
+    token = oldToken;
+    jj_kind = kind;
+    throw generateParseException();
+  }
+
+  static private final class LookaheadSuccess extends java.lang.Error { }
+  final private LookaheadSuccess jj_ls = new LookaheadSuccess();
+  private boolean jj_scan_token(int kind) {
+    if (jj_scanpos == jj_lastpos) {
+      jj_la--;
+      if (jj_scanpos.next == null) {
+        jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
+      } else {
+        jj_lastpos = jj_scanpos = jj_scanpos.next;
+      }
+    } else {
+      jj_scanpos = jj_scanpos.next;
+    }
+    if (jj_rescan) {
+      int i = 0; Token tok = token;
+      while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
+      if (tok != null) jj_add_error_token(kind, i);
+    }
+    if (jj_scanpos.kind != kind) return true;
+    if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls;
+    return false;
+  }
+
+
+/** Get the next Token. */
+  final public Token getNextToken() {
+    if (token.next != null) token = token.next;
+    else token = token.next = token_source.getNextToken();
+    jj_ntk = -1;
+    jj_gen++;
+    return token;
+  }
+
+/** Get the specific Token. */
+  final public Token getToken(int index) {
+    Token t = token;
+    for (int i = 0; i < index; i++) {
+      if (t.next != null) t = t.next;
+      else t = t.next = token_source.getNextToken();
+    }
+    return t;
+  }
+
+  private int jj_ntk() {
+    if ((jj_nt=token.next) == null)
+      return (jj_ntk = (token.next=token_source.getNextToken()).kind);
+    else
+      return (jj_ntk = jj_nt.kind);
+  }
+
+  private java.util.List<int[]> jj_expentries = new java.util.ArrayList<int[]>();
+  private int[] jj_expentry;
+  private int jj_kind = -1;
+  private int[] jj_lasttokens = new int[100];
+  private int jj_endpos;
+
+  private void jj_add_error_token(int kind, int pos) {
+    if (pos >= 100) return;
+    if (pos == jj_endpos + 1) {
+      jj_lasttokens[jj_endpos++] = kind;
+    } else if (jj_endpos != 0) {
+      jj_expentry = new int[jj_endpos];
+      for (int i = 0; i < jj_endpos; i++) {
+        jj_expentry[i] = jj_lasttokens[i];
+      }
+      jj_entries_loop: for (java.util.Iterator<?> it = jj_expentries.iterator(); it.hasNext();) {
+        int[] oldentry = (int[])(it.next());
+        if (oldentry.length == jj_expentry.length) {
+          for (int i = 0; i < jj_expentry.length; i++) {
+            if (oldentry[i] != jj_expentry[i]) {
+              continue jj_entries_loop;
+            }
+          }
+          jj_expentries.add(jj_expentry);
+          break jj_entries_loop;
+        }
+      }
+      if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind;
+    }
+  }
+
+  /** Generate ParseException. */
+  public ParseException generateParseException() {
+    jj_expentries.clear();
+    boolean[] la1tokens = new boolean[28];
+    if (jj_kind >= 0) {
+      la1tokens[jj_kind] = true;
+      jj_kind = -1;
+    }
+    for (int i = 0; i < 8; i++) {
+      if (jj_la1[i] == jj_gen) {
+        for (int j = 0; j < 32; j++) {
+          if ((jj_la1_0[i] & (1<<j)) != 0) {
+            la1tokens[j] = true;
+          }
+        }
+      }
+    }
+    for (int i = 0; i < 28; i++) {
+      if (la1tokens[i]) {
+        jj_expentry = new int[1];
+        jj_expentry[0] = i;
+        jj_expentries.add(jj_expentry);
+      }
+    }
+    jj_endpos = 0;
+    jj_rescan_token();
+    jj_add_error_token(0, 0);
+    int[][] exptokseq = new int[jj_expentries.size()][];
+    for (int i = 0; i < jj_expentries.size(); i++) {
+      exptokseq[i] = jj_expentries.get(i);
+    }
+    return new ParseException(token, exptokseq, tokenImage);
+  }
+
+  /** Enable tracing. */
+  final public void enable_tracing() {
+  }
+
+  /** Disable tracing. */
+  final public void disable_tracing() {
+  }
+
+  private void jj_rescan_token() {
+    jj_rescan = true;
+    for (int i = 0; i < 2; i++) {
+    try {
+      JJCalls p = jj_2_rtns[i];
+      do {
+        if (p.gen > jj_gen) {
+          jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
+          switch (i) {
+            case 0: jj_3_1(); break;
+            case 1: jj_3_2(); break;
+          }
+        }
+        p = p.next;
+      } while (p != null);
+      } catch(LookaheadSuccess ls) { }
+    }
+    jj_rescan = false;
+  }
+
+  private void jj_save(int index, int xla) {
+    JJCalls p = jj_2_rtns[index];
+    while (p.gen > jj_gen) {
+      if (p.next == null) { p = p.next = new JJCalls(); break; }
+      p = p.next;
+    }
+    p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla;
+  }
+
+  static final class JJCalls {
+    int gen;
+    Token first;
+    int arg;
+    JJCalls next;
+  }
+
+}
diff --git a/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/TagParserConstants.java b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/TagParserConstants.java
new file mode 100644
index 0000000..035c5e8
--- /dev/null
+++ b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/TagParserConstants.java
@@ -0,0 +1,113 @@
+/* Generated By:JavaCC: Do not edit this line. TagParserConstants.java */
+package org.apache.sling.tagmodifier.impl;
+
+
+/**
+ * Token literal values and constants.
+ * Generated by org.javacc.parser.OtherFilesGen#start()
+ */
+public interface TagParserConstants {
+
+  /** End of File. */
+  int EOF = 0;
+  /** RegularExpression Id. */
+  int SPACE = 1;
+  /** RegularExpression Id. */
+  int ATTR_IDENTIFIER = 2;
+  /** RegularExpression Id. */
+  int NAME_IDENTIFIER = 3;
+  /** RegularExpression Id. */
+  int SQUOTE = 4;
+  /** RegularExpression Id. */
+  int DQUOTE = 5;
+  /** RegularExpression Id. */
+  int TAG_END = 6;
+  /** RegularExpression Id. */
+  int TAG_SLASHEND = 7;
+  /** RegularExpression Id. */
+  int TAG_START = 8;
+  /** RegularExpression Id. */
+  int ENDTAG_START = 9;
+  /** RegularExpression Id. */
+  int COMMENT_START = 10;
+  /** RegularExpression Id. */
+  int DECL_START = 11;
+  /** RegularExpression Id. */
+  int RAWTEXT = 12;
+  /** RegularExpression Id. */
+  int TAG_NAME = 13;
+  /** RegularExpression Id. */
+  int LST_ERROR = 14;
+  /** RegularExpression Id. */
+  int ATTR_NAME = 16;
+  /** RegularExpression Id. */
+  int END_OF_TAG = 17;
+  /** RegularExpression Id. */
+  int ATTR_EQ = 18;
+  /** RegularExpression Id. */
+  int LIT_ERROR = 19;
+  /** RegularExpression Id. */
+  int QUOTED_STRING = 20;
+  /** RegularExpression Id. */
+  int ATTR_VAL = 21;
+  /** RegularExpression Id. */
+  int ERROR = 22;
+  /** RegularExpression Id. */
+  int COMMENT_END = 23;
+  /** RegularExpression Id. */
+  int COMMENT_WORD = 24;
+  /** RegularExpression Id. */
+  int DECL_TAG = 25;
+  /** RegularExpression Id. */
+  int DECL_ATTR = 26;
+  /** RegularExpression Id. */
+  int DECL_END = 27;
+
+  /** Lexical state. */
+  int DECLARATION = 0;
+  /** Lexical state. */
+  int COMMENT = 1;
+  /** Lexical state. */
+  int IN_DECLARATION = 2;
+  /** Lexical state. */
+  int ATTR_VALUE = 3;
+  /** Lexical state. */
+  int IN_TAG = 4;
+  /** Lexical state. */
+  int START_TAG = 5;
+  /** Lexical state. */
+  int DEFAULT = 6;
+
+  /** Literal token values. */
+  String[] tokenImage = {
+    "<EOF>",
+    "<SPACE>",
+    "<ATTR_IDENTIFIER>",
+    "<NAME_IDENTIFIER>",
+    "<SQUOTE>",
+    "<DQUOTE>",
+    "\">\"",
+    "\"/>\"",
+    "\"<\"",
+    "\"</\"",
+    "\"<!--\"",
+    "\"<!\"",
+    "<RAWTEXT>",
+    "<TAG_NAME>",
+    "<LST_ERROR>",
+    "<token of kind 15>",
+    "<ATTR_NAME>",
+    "<END_OF_TAG>",
+    "\"=\"",
+    "<LIT_ERROR>",
+    "<QUOTED_STRING>",
+    "<ATTR_VAL>",
+    "<ERROR>",
+    "\"-->\"",
+    "<COMMENT_WORD>",
+    "<DECL_TAG>",
+    "<DECL_ATTR>",
+    "<DECL_END>",
+  };
+
+}
diff --git a/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/TagParserTokenManager.java b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/TagParserTokenManager.java
new file mode 100644
index 0000000..15c0f72
--- /dev/null
+++ b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/TagParserTokenManager.java
@@ -0,0 +1,1138 @@
+/* Generated By:JavaCC: Do not edit this line. TagParserTokenManager.java */
+package org.apache.sling.tagmodifier.impl;
+import java.util.*;
+
+import org.apache.sling.tagmodifier.*;
+import org.apache.sling.tagmodifier.impl.tag.*;
+
+/** Token Manager. */
+public class TagParserTokenManager implements TagParserConstants
+{
+
+  /** Debug output. */
+  public  java.io.PrintStream debugStream = System.out;
+  /** Set debug output. */
+  public  void setDebugStream(java.io.PrintStream ds) { debugStream = ds; }
+private final int jjStopStringLiteralDfa_6(int pos, long active0)
+{
+   switch (pos)
+   {
+      default :
+         return -1;
+   }
+}
+private final int jjStartNfa_6(int pos, long active0)
+{
+   return jjMoveNfa_6(jjStopStringLiteralDfa_6(pos, active0), pos + 1);
+}
+private int jjStopAtPos(int pos, int kind)
+{
+   jjmatchedKind = kind;
+   jjmatchedPos = pos;
+   return pos + 1;
+}
+private int jjMoveStringLiteralDfa0_6()
+{
+   switch(curChar)
+   {
+      case 60:
+         jjmatchedKind = 8;
+         return jjMoveStringLiteralDfa1_6(0xe00L);
+      default :
+         return jjMoveNfa_6(0, 0);
+   }
+}
+private int jjMoveStringLiteralDfa1_6(long active0)
+{
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_6(0, active0);
+      return 1;
+   }
+   switch(curChar)
+   {
+      case 33:
+         if ((active0 & 0x800L) != 0L)
+         {
+            jjmatchedKind = 11;
+            jjmatchedPos = 1;
+         }
+         return jjMoveStringLiteralDfa2_6(active0, 0x400L);
+      case 47:
+         if ((active0 & 0x200L) != 0L)
+            return jjStopAtPos(1, 9);
+         break;
+      default :
+         break;
+   }
+   return jjStartNfa_6(0, active0);
+}
+private int jjMoveStringLiteralDfa2_6(long old0, long active0)
+{
+   if (((active0 &= old0)) == 0L)
+      return jjStartNfa_6(0, old0);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_6(1, active0);
+      return 2;
+   }
+   switch(curChar)
+   {
+      case 45:
+         return jjMoveStringLiteralDfa3_6(active0, 0x400L);
+      default :
+         break;
+   }
+   return jjStartNfa_6(1, active0);
+}
+private int jjMoveStringLiteralDfa3_6(long old0, long active0)
+{
+   if (((active0 &= old0)) == 0L)
+      return jjStartNfa_6(1, old0);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_6(2, active0);
+      return 3;
+   }
+   switch(curChar)
+   {
+      case 45:
+         if ((active0 & 0x400L) != 0L)
+            return jjStopAtPos(3, 10);
+         break;
+      default :
+         break;
+   }
+   return jjStartNfa_6(2, active0);
+}
+static final long[] jjbitVec0 = {
+   0xfffffffffffffffeL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL
+};
+static final long[] jjbitVec2 = {
+   0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL
+};
+private int jjMoveNfa_6(int startState, int curPos)
+{
+   int startsAt = 0;
+   jjnewStateCnt = 1;
+   int i = 1;
+   jjstateSet[0] = startState;
+   int kind = 0x7fffffff;
+   for (;;)
+   {
+      if (++jjround == 0x7fffffff)
+         ReInitRounds();
+      if (curChar < 64)
+      {
+         long l = 1L << curChar;
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 0:
+                  if ((0xefffffffffffffffL & l) == 0L)
+                     break;
+                  kind = 12;
+                  jjstateSet[jjnewStateCnt++] = 0;
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else if (curChar < 128)
+      {
+         long l = 1L << (curChar & 077);
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 0:
+                  kind = 12;
+                  jjstateSet[jjnewStateCnt++] = 0;
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else
+      {
+         int hiByte = (int)(curChar >> 8);
+         int i1 = hiByte >> 6;
+         long l1 = 1L << (hiByte & 077);
+         int i2 = (curChar & 0xff) >> 6;
+         long l2 = 1L << (curChar & 077);
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 0:
+                  if (!jjCanMove_0(hiByte, i1, i2, l1, l2))
+                     break;
+                  if (kind > 12)
+                     kind = 12;
+                  jjstateSet[jjnewStateCnt++] = 0;
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      if (kind != 0x7fffffff)
+      {
+         jjmatchedKind = kind;
+         jjmatchedPos = curPos;
+         kind = 0x7fffffff;
+      }
+      ++curPos;
+      if ((i = jjnewStateCnt) == (startsAt = 1 - (jjnewStateCnt = startsAt)))
+         return curPos;
+      try { curChar = input_stream.readChar(); }
+      catch(java.io.IOException e) { return curPos; }
+   }
+}
+private int jjMoveStringLiteralDfa0_5()
+{
+   return jjMoveNfa_5(0, 0);
+}
+private int jjMoveNfa_5(int startState, int curPos)
+{
+   int startsAt = 0;
+   jjnewStateCnt = 1;
+   int i = 1;
+   jjstateSet[0] = startState;
+   int kind = 0x7fffffff;
+   for (;;)
+   {
+      if (++jjround == 0x7fffffff)
+         ReInitRounds();
+      if (curChar < 64)
+      {
+         long l = 1L << curChar;
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 0:
+                  if ((0xbfff7ffeffffc9ffL & l) == 0L)
+                     break;
+                  kind = 13;
+                  jjstateSet[jjnewStateCnt++] = 0;
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else if (curChar < 128)
+      {
+         long l = 1L << (curChar & 077);
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 0:
+                  kind = 13;
+                  jjstateSet[jjnewStateCnt++] = 0;
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else
+      {
+         int hiByte = (int)(curChar >> 8);
+         int i1 = hiByte >> 6;
+         long l1 = 1L << (hiByte & 077);
+         int i2 = (curChar & 0xff) >> 6;
+         long l2 = 1L << (curChar & 077);
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 0:
+                  if (!jjCanMove_0(hiByte, i1, i2, l1, l2))
+                     break;
+                  if (kind > 13)
+                     kind = 13;
+                  jjstateSet[jjnewStateCnt++] = 0;
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      if (kind != 0x7fffffff)
+      {
+         jjmatchedKind = kind;
+         jjmatchedPos = curPos;
+         kind = 0x7fffffff;
+      }
+      ++curPos;
+      if ((i = jjnewStateCnt) == (startsAt = 1 - (jjnewStateCnt = startsAt)))
+         return curPos;
+      try { curChar = input_stream.readChar(); }
+      catch(java.io.IOException e) { return curPos; }
+   }
+}
+private int jjMoveStringLiteralDfa0_1()
+{
+   switch(curChar)
+   {
+      case 45:
+         return jjMoveStringLiteralDfa1_1(0x800000L);
+      default :
+         return 1;
+   }
+}
+private int jjMoveStringLiteralDfa1_1(long active0)
+{
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      return 1;
+   }
+   switch(curChar)
+   {
+      case 45:
+         return jjMoveStringLiteralDfa2_1(active0, 0x800000L);
+      default :
+         return 2;
+   }
+}
+private int jjMoveStringLiteralDfa2_1(long old0, long active0)
+{
+   if (((active0 &= old0)) == 0L)
+      return 2;
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      return 2;
+   }
+   switch(curChar)
+   {
+      case 62:
+         if ((active0 & 0x800000L) != 0L)
+            return jjStopAtPos(2, 23);
+         break;
+      default :
+         return 3;
+   }
+   return 3;
+}
+private int jjMoveStringLiteralDfa0_2()
+{
+   return jjMoveNfa_2(2, 0);
+}
+private int jjMoveNfa_2(int startState, int curPos)
+{
+   int startsAt = 0;
+   jjnewStateCnt = 11;
+   int i = 1;
+   jjstateSet[0] = startState;
+   int kind = 0x7fffffff;
+   for (;;)
+   {
+      if (++jjround == 0x7fffffff)
+         ReInitRounds();
+      if (curChar < 64)
+      {
+         long l = 1L << curChar;
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 2:
+                  if ((0xbfffff7affffd9ffL & l) != 0L)
+                  {
+                     if (kind > 26)
+                        kind = 26;
+                     jjCheckNAdd(1);
+                  }
+                  else if (curChar == 62)
+                  {
+                     if (kind > 27)
+                        kind = 27;
+                  }
+                  else if (curChar == 39)
+                     jjCheckNAddTwoStates(6, 7);
+                  else if (curChar == 34)
+                     jjCheckNAddTwoStates(3, 4);
+                  if ((0x100003600L & l) != 0L)
+                  {
+                     if (kind > 15)
+                        kind = 15;
+                     jjCheckNAdd(0);
+                  }
+                  else if (curChar == 47)
+                     jjstateSet[jjnewStateCnt++] = 9;
+                  break;
+               case 0:
+                  if ((0x100003600L & l) == 0L)
+                     break;
+                  if (kind > 15)
+                     kind = 15;
+                  jjCheckNAdd(0);
+                  break;
+               case 1:
+                  if ((0xbfffff7affffd9ffL & l) == 0L)
+                     break;
+                  if (kind > 26)
+                     kind = 26;
+                  jjCheckNAdd(1);
+                  break;
+               case 3:
+                  if ((0xfffffffbffffffffL & l) != 0L)
+                     jjCheckNAddTwoStates(3, 4);
+                  break;
+               case 4:
+                  if (curChar == 34 && kind > 26)
+                     kind = 26;
+                  break;
+               case 5:
+                  if (curChar == 39)
+                     jjCheckNAddTwoStates(6, 7);
+                  break;
+               case 6:
+                  if ((0xffffff7fffffffffL & l) != 0L)
+                     jjCheckNAddTwoStates(6, 7);
+                  break;
+               case 7:
+                  if (curChar == 39 && kind > 26)
+                     kind = 26;
+                  break;
+               case 8:
+               case 9:
+                  if (curChar == 62 && kind > 27)
+                     kind = 27;
+                  break;
+               case 10:
+                  if (curChar == 47)
+                     jjstateSet[jjnewStateCnt++] = 9;
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else if (curChar < 128)
+      {
+         long l = 1L << (curChar & 077);
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 2:
+               case 1:
+                  if (kind > 26)
+                     kind = 26;
+                  jjCheckNAdd(1);
+                  break;
+               case 3:
+                  jjAddStates(0, 1);
+                  break;
+               case 6:
+                  jjAddStates(2, 3);
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else
+      {
+         int hiByte = (int)(curChar >> 8);
+         int i1 = hiByte >> 6;
+         long l1 = 1L << (hiByte & 077);
+         int i2 = (curChar & 0xff) >> 6;
+         long l2 = 1L << (curChar & 077);
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 2:
+               case 1:
+                  if (!jjCanMove_0(hiByte, i1, i2, l1, l2))
+                     break;
+                  if (kind > 26)
+                     kind = 26;
+                  jjCheckNAdd(1);
+                  break;
+               case 3:
+                  if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+                     jjAddStates(0, 1);
+                  break;
+               case 6:
+                  if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+                     jjAddStates(2, 3);
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      if (kind != 0x7fffffff)
+      {
+         jjmatchedKind = kind;
+         jjmatchedPos = curPos;
+         kind = 0x7fffffff;
+      }
+      ++curPos;
+      if ((i = jjnewStateCnt) == (startsAt = 11 - (jjnewStateCnt = startsAt)))
+         return curPos;
+      try { curChar = input_stream.readChar(); }
+      catch(java.io.IOException e) { return curPos; }
+   }
+}
+private int jjMoveStringLiteralDfa0_0()
+{
+   return jjMoveNfa_0(0, 0);
+}
+private int jjMoveNfa_0(int startState, int curPos)
+{
+   int startsAt = 0;
+   jjnewStateCnt = 1;
+   int i = 1;
+   jjstateSet[0] = startState;
+   int kind = 0x7fffffff;
+   for (;;)
+   {
+      if (++jjround == 0x7fffffff)
+         ReInitRounds();
+      if (curChar < 64)
+      {
+         long l = 1L << curChar;
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 0:
+                  if ((0xbfff7ffeffffc9ffL & l) == 0L)
+                     break;
+                  kind = 25;
+                  jjstateSet[jjnewStateCnt++] = 0;
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else if (curChar < 128)
+      {
+         long l = 1L << (curChar & 077);
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 0:
+                  kind = 25;
+                  jjstateSet[jjnewStateCnt++] = 0;
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else
+      {
+         int hiByte = (int)(curChar >> 8);
+         int i1 = hiByte >> 6;
+         long l1 = 1L << (hiByte & 077);
+         int i2 = (curChar & 0xff) >> 6;
+         long l2 = 1L << (curChar & 077);
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 0:
+                  if (!jjCanMove_0(hiByte, i1, i2, l1, l2))
+                     break;
+                  if (kind > 25)
+                     kind = 25;
+                  jjstateSet[jjnewStateCnt++] = 0;
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      if (kind != 0x7fffffff)
+      {
+         jjmatchedKind = kind;
+         jjmatchedPos = curPos;
+         kind = 0x7fffffff;
+      }
+      ++curPos;
+      if ((i = jjnewStateCnt) == (startsAt = 1 - (jjnewStateCnt = startsAt)))
+         return curPos;
+      try { curChar = input_stream.readChar(); }
+      catch(java.io.IOException e) { return curPos; }
+   }
+}
+private final int jjStopStringLiteralDfa_4(int pos, long active0)
+{
+   switch (pos)
+   {
+      default :
+         return -1;
+   }
+}
+private final int jjStartNfa_4(int pos, long active0)
+{
+   return jjMoveNfa_4(jjStopStringLiteralDfa_4(pos, active0), pos + 1);
+}
+private int jjMoveStringLiteralDfa0_4()
+{
+   switch(curChar)
+   {
+      case 61:
+         return jjStopAtPos(0, 18);
+      default :
+         return jjMoveNfa_4(2, 0);
+   }
+}
+private int jjMoveNfa_4(int startState, int curPos)
+{
+   int startsAt = 0;
+   jjnewStateCnt = 5;
+   int i = 1;
+   jjstateSet[0] = startState;
+   int kind = 0x7fffffff;
+   for (;;)
+   {
+      if (++jjround == 0x7fffffff)
+         ReInitRounds();
+      if (curChar < 64)
+      {
+         long l = 1L << curChar;
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 2:
+                  if ((0x9fff7ffeffffc9ffL & l) != 0L)
+                  {
+                     if (kind > 16)
+                        kind = 16;
+                     jjCheckNAdd(1);
+                  }
+                  else if ((0x100003600L & l) != 0L)
+                  {
+                     if (kind > 15)
+                        kind = 15;
+                     jjCheckNAdd(0);
+                  }
+                  else if (curChar == 47)
+                     jjstateSet[jjnewStateCnt++] = 3;
+                  else if (curChar == 62)
+                  {
+                     if (kind > 17)
+                        kind = 17;
+                  }
+                  break;
+               case 0:
+                  if ((0x100003600L & l) == 0L)
+                     break;
+                  kind = 15;
+                  jjCheckNAdd(0);
+                  break;
+               case 1:
+                  if ((0x9fff7ffeffffc9ffL & l) == 0L)
+                     break;
+                  kind = 16;
+                  jjCheckNAdd(1);
+                  break;
+               case 3:
+                  if (curChar == 62 && kind > 17)
+                     kind = 17;
+                  break;
+               case 4:
+                  if (curChar == 47)
+                     jjstateSet[jjnewStateCnt++] = 3;
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else if (curChar < 128)
+      {
+         long l = 1L << (curChar & 077);
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 2:
+               case 1:
+                  kind = 16;
+                  jjCheckNAdd(1);
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else
+      {
+         int hiByte = (int)(curChar >> 8);
+         int i1 = hiByte >> 6;
+         long l1 = 1L << (hiByte & 077);
+         int i2 = (curChar & 0xff) >> 6;
+         long l2 = 1L << (curChar & 077);
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 2:
+               case 1:
+                  if (!jjCanMove_0(hiByte, i1, i2, l1, l2))
+                     break;
+                  if (kind > 16)
+                     kind = 16;
+                  jjCheckNAdd(1);
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      if (kind != 0x7fffffff)
+      {
+         jjmatchedKind = kind;
+         jjmatchedPos = curPos;
+         kind = 0x7fffffff;
+      }
+      ++curPos;
+      if ((i = jjnewStateCnt) == (startsAt = 5 - (jjnewStateCnt = startsAt)))
+         return curPos;
+      try { curChar = input_stream.readChar(); }
+      catch(java.io.IOException e) { return curPos; }
+   }
+}
+private int jjMoveStringLiteralDfa0_3()
+{
+   return jjMoveNfa_3(1, 0);
+}
+private int jjMoveNfa_3(int startState, int curPos)
+{
+   int startsAt = 0;
+   jjnewStateCnt = 8;
+   int i = 1;
+   jjstateSet[0] = startState;
+   int kind = 0x7fffffff;
+   for (;;)
+   {
+      if (++jjround == 0x7fffffff)
+         ReInitRounds();
+      if (curChar < 64)
+      {
+         long l = 1L << curChar;
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 1:
+                  if ((0xbfffff7affffd9ffL & l) != 0L)
+                  {
+                     if (kind > 21)
+                        kind = 21;
+                     jjCheckNAdd(7);
+                  }
+                  else if (curChar == 34)
+                     jjCheckNAddTwoStates(5, 6);
+                  else if (curChar == 39)
+                     jjCheckNAddTwoStates(2, 3);
+                  if ((0x100003600L & l) != 0L)
+                  {
+                     if (kind > 15)
+                        kind = 15;
+                     jjCheckNAdd(0);
+                  }
+                  break;
+               case 0:
+                  if ((0x100003600L & l) == 0L)
+                     break;
+                  if (kind > 15)
+                     kind = 15;
+                  jjCheckNAdd(0);
+                  break;
+               case 2:
+                  if ((0xffffff7fffffffffL & l) != 0L)
+                     jjCheckNAddTwoStates(2, 3);
+                  break;
+               case 3:
+                  if (curChar == 39 && kind > 20)
+                     kind = 20;
+                  break;
+               case 4:
+                  if (curChar == 34)
+                     jjCheckNAddTwoStates(5, 6);
+                  break;
+               case 5:
+                  if ((0xfffffffbffffffffL & l) != 0L)
+                     jjCheckNAddTwoStates(5, 6);
+                  break;
+               case 6:
+                  if (curChar == 34 && kind > 20)
+                     kind = 20;
+                  break;
+               case 7:
+                  if ((0xbfffff7affffd9ffL & l) == 0L)
+                     break;
+                  if (kind > 21)
+                     kind = 21;
+                  jjCheckNAdd(7);
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else if (curChar < 128)
+      {
+         long l = 1L << (curChar & 077);
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 1:
+               case 7:
+                  if (kind > 21)
+                     kind = 21;
+                  jjCheckNAdd(7);
+                  break;
+               case 2:
+                  jjAddStates(4, 5);
+                  break;
+               case 5:
+                  jjAddStates(6, 7);
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else
+      {
+         int hiByte = (int)(curChar >> 8);
+         int i1 = hiByte >> 6;
+         long l1 = 1L << (hiByte & 077);
+         int i2 = (curChar & 0xff) >> 6;
+         long l2 = 1L << (curChar & 077);
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 1:
+               case 7:
+                  if (!jjCanMove_0(hiByte, i1, i2, l1, l2))
+                     break;
+                  if (kind > 21)
+                     kind = 21;
+                  jjCheckNAdd(7);
+                  break;
+               case 2:
+                  if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+                     jjAddStates(4, 5);
+                  break;
+               case 5:
+                  if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+                     jjAddStates(6, 7);
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      if (kind != 0x7fffffff)
+      {
+         jjmatchedKind = kind;
+         jjmatchedPos = curPos;
+         kind = 0x7fffffff;
+      }
+      ++curPos;
+      if ((i = jjnewStateCnt) == (startsAt = 8 - (jjnewStateCnt = startsAt)))
+         return curPos;
+      try { curChar = input_stream.readChar(); }
+      catch(java.io.IOException e) { return curPos; }
+   }
+}
+static final int[] jjnextStates = {
+   3, 4, 6, 7, 2, 3, 5, 6, 
+};
+private static final boolean jjCanMove_0(int hiByte, int i1, int i2, long l1, long l2)
+{
+   switch(hiByte)
+   {
+      case 0:
+         return ((jjbitVec2[i2] & l2) != 0L);
+      default :
+         if ((jjbitVec0[i1] & l1) != 0L)
+            return true;
+         return false;
+   }
+}
+
+/** Token literal values. */
+public static final String[] jjstrLiteralImages = {
+"", null, null, null, null, null, null, null, "\74", "\74\57", "\74\41\55\55", 
+"\74\41", null, null, null, null, null, null, "\75", null, null, null, null, 
+"\55\55\76", null, null, null, null, };
+
+/** Lexer state names. */
+public static final String[] lexStateNames = {
+   "DECLARATION",
+   "COMMENT",
+   "IN_DECLARATION",
+   "ATTR_VALUE",
+   "IN_TAG",
+   "START_TAG",
+   "DEFAULT",
+};
+
+/** Lex State array. */
+public static final int[] jjnewLexState = {
+   -1, -1, -1, -1, -1, -1, -1, -1, 5, 5, 1, 0, -1, 4, 6, -1, -1, 6, 3, -1, 4, 4, -1, 6, -1, 
+   2, -1, 6, 
+};
+static final long[] jjtoToken = {
+   0xfff7f01L, 
+};
+static final long[] jjtoSkip = {
+   0x8000L, 
+};
+static final long[] jjtoSpecial = {
+   0x8000L, 
+};
+protected SimpleCharStream input_stream;
+private final int[] jjrounds = new int[11];
+private final int[] jjstateSet = new int[22];
+private final StringBuilder jjimage = new StringBuilder();
+private StringBuilder image = jjimage;
+private int jjimageLen;
+private int lengthOfMatch;
+protected char curChar;
+/** Constructor. */
+public TagParserTokenManager(SimpleCharStream stream){
+   if (SimpleCharStream.staticFlag)
+      throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer.");
+   input_stream = stream;
+}
+
+/** Constructor. */
+public TagParserTokenManager(SimpleCharStream stream, int lexState){
+   this(stream);
+   SwitchTo(lexState);
+}
+
+/** Reinitialise parser. */
+public void ReInit(SimpleCharStream stream)
+{
+   jjmatchedPos = jjnewStateCnt = 0;
+   curLexState = defaultLexState;
+   input_stream = stream;
+   ReInitRounds();
+}
+private void ReInitRounds()
+{
+   int i;
+   jjround = 0x80000001;
+   for (i = 11; i-- > 0;)
+      jjrounds[i] = 0x80000000;
+}
+
+/** Reinitialise parser. */
+public void ReInit(SimpleCharStream stream, int lexState)
+{
+   ReInit(stream);
+   SwitchTo(lexState);
+}
+
+/** Switch to specified lex state. */
+public void SwitchTo(int lexState)
+{
+   if (lexState >= 7 || lexState < 0)
+      throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
+   else
+      curLexState = lexState;
+}
+
+protected Token jjFillToken()
+{
+   final Token t;
+   final String curTokenImage;
+   final int beginLine;
+   final int endLine;
+   final int beginColumn;
+   final int endColumn;
+   String im = jjstrLiteralImages[jjmatchedKind];
+   curTokenImage = (im == null) ? input_stream.GetImage() : im;
+   beginLine = input_stream.getBeginLine();
+   beginColumn = input_stream.getBeginColumn();
+   endLine = input_stream.getEndLine();
+   endColumn = input_stream.getEndColumn();
+   t = Token.newToken(jjmatchedKind, curTokenImage);
+
+   t.beginLine = beginLine;
+   t.endLine = endLine;
+   t.beginColumn = beginColumn;
+   t.endColumn = endColumn;
+
+   return t;
+}
+
+int curLexState = 6;
+int defaultLexState = 6;
+int jjnewStateCnt;
+int jjround;
+int jjmatchedPos;
+int jjmatchedKind;
+
+/** Get the next Token. */
+public Token getNextToken() 
+{
+  Token specialToken = null;
+  Token matchedToken;
+  int curPos = 0;
+
+  EOFLoop :
+  for (;;)
+  {
+   try
+   {
+      curChar = input_stream.BeginToken();
+   }
+   catch(java.io.IOException e)
+   {
+      jjmatchedKind = 0;
+      matchedToken = jjFillToken();
+      matchedToken.specialToken = specialToken;
+      return matchedToken;
+   }
+   image = jjimage;
+   image.setLength(0);
+   jjimageLen = 0;
+
+   switch(curLexState)
+   {
+     case 0:
+       jjmatchedKind = 0x7fffffff;
+       jjmatchedPos = 0;
+       curPos = jjMoveStringLiteralDfa0_0();
+       break;
+     case 1:
+       jjmatchedKind = 0x7fffffff;
+       jjmatchedPos = 0;
+       curPos = jjMoveStringLiteralDfa0_1();
+       if (jjmatchedPos == 0 && jjmatchedKind > 24)
+       {
+          jjmatchedKind = 24;
+       }
+       break;
+     case 2:
+       jjmatchedKind = 0x7fffffff;
+       jjmatchedPos = 0;
+       curPos = jjMoveStringLiteralDfa0_2();
+       break;
+     case 3:
+       jjmatchedKind = 0x7fffffff;
+       jjmatchedPos = 0;
+       curPos = jjMoveStringLiteralDfa0_3();
+       if (jjmatchedPos == 0 && jjmatchedKind > 22)
+       {
+          jjmatchedKind = 22;
+       }
+       break;
+     case 4:
+       jjmatchedKind = 0x7fffffff;
+       jjmatchedPos = 0;
+       curPos = jjMoveStringLiteralDfa0_4();
+       if (jjmatchedPos == 0 && jjmatchedKind > 19)
+       {
+          jjmatchedKind = 19;
+       }
+       break;
+     case 5:
+       jjmatchedKind = 0x7fffffff;
+       jjmatchedPos = 0;
+       curPos = jjMoveStringLiteralDfa0_5();
+       if (jjmatchedPos == 0 && jjmatchedKind > 14)
+       {
+          jjmatchedKind = 14;
+       }
+       break;
+     case 6:
+       jjmatchedKind = 0x7fffffff;
+       jjmatchedPos = 0;
+       curPos = jjMoveStringLiteralDfa0_6();
+       break;
+   }
+     if (jjmatchedKind != 0x7fffffff)
+     {
+        if (jjmatchedPos + 1 < curPos)
+           input_stream.backup(curPos - jjmatchedPos - 1);
+        if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
+        {
+           matchedToken = jjFillToken();
+           matchedToken.specialToken = specialToken;
+           TokenLexicalActions(matchedToken);
+       if (jjnewLexState[jjmatchedKind] != -1)
+         curLexState = jjnewLexState[jjmatchedKind];
+           return matchedToken;
+        }
+        else
+        {
+           if ((jjtoSpecial[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
+           {
+              matchedToken = jjFillToken();
+              if (specialToken == null)
+                 specialToken = matchedToken;
+              else
+              {
+                 matchedToken.specialToken = specialToken;
+                 specialToken = (specialToken.next = matchedToken);
+              }
+           }
+         if (jjnewLexState[jjmatchedKind] != -1)
+           curLexState = jjnewLexState[jjmatchedKind];
+           continue EOFLoop;
+        }
+     }
+     int error_line = input_stream.getEndLine();
+     int error_column = input_stream.getEndColumn();
+     String error_after = null;
+     boolean EOFSeen = false;
+     try { input_stream.readChar(); input_stream.backup(1); }
+     catch (java.io.IOException e1) {
+        EOFSeen = true;
+        error_after = curPos <= 1 ? "" : input_stream.GetImage();
+        if (curChar == '\n' || curChar == '\r') {
+           error_line++;
+           error_column = 0;
+        }
+        else
+           error_column++;
+     }
+     if (!EOFSeen) {
+        input_stream.backup(1);
+        error_after = curPos <= 1 ? "" : input_stream.GetImage();
+     }
+     throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR);
+  }
+}
+
+void TokenLexicalActions(Token matchedToken)
+{
+   switch(jjmatchedKind)
+   {
+      case 20 :
+        image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
+                                             matchedToken.image = image.substring(1, lengthOfMatch - 1);
+         break;
+      default :
+         break;
+   }
+}
+private void jjCheckNAdd(int state)
+{
+   if (jjrounds[state] != jjround)
+   {
+      jjstateSet[jjnewStateCnt++] = state;
+      jjrounds[state] = jjround;
+   }
+}
+private void jjAddStates(int start, int end)
+{
+   do {
+      jjstateSet[jjnewStateCnt++] = jjnextStates[start];
+   } while (start++ != end);
+}
+private void jjCheckNAddTwoStates(int state1, int state2)
+{
+   jjCheckNAdd(state1);
+   jjCheckNAdd(state2);
+}
+
+}
diff --git a/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/Token.java b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/Token.java
new file mode 100644
index 0000000..d9bc9bd
--- /dev/null
+++ b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/Token.java
@@ -0,0 +1,131 @@
+/* Generated By:JavaCC: Do not edit this line. Token.java Version 5.0 */
+/* JavaCCOptions:TOKEN_EXTENDS=,KEEP_LINE_COL=null,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
+package org.apache.sling.tagmodifier.impl;
+
+/**
+ * Describes the input token stream.
+ */
+
+public class Token implements java.io.Serializable {
+
+  /**
+   * The version identifier for this Serializable class.
+   * Increment only if the <i>serialized</i> form of the
+   * class changes.
+   */
+  private static final long serialVersionUID = 1L;
+
+  /**
+   * An integer that describes the kind of this token.  This numbering
+   * system is determined by JavaCCParser, and a table of these numbers is
+   * stored in the file ...Constants.java.
+   */
+  public int kind;
+
+  /** The line number of the first character of this Token. */
+  public int beginLine;
+  /** The column number of the first character of this Token. */
+  public int beginColumn;
+  /** The line number of the last character of this Token. */
+  public int endLine;
+  /** The column number of the last character of this Token. */
+  public int endColumn;
+
+  /**
+   * The string image of the token.
+   */
+  public String image;
+
+  /**
+   * A reference to the next regular (non-special) token from the input
+   * stream.  If this is the last token from the input stream, or if the
+   * token manager has not read tokens beyond this one, this field is
+   * set to null.  This is true only if this token is also a regular
+   * token.  Otherwise, see below for a description of the contents of
+   * this field.
+   */
+  public Token next;
+
+  /**
+   * This field is used to access special tokens that occur prior to this
+   * token, but after the immediately preceding regular (non-special) token.
+   * If there are no such special tokens, this field is set to null.
+   * When there are more than one such special token, this field refers
+   * to the last of these special tokens, which in turn refers to the next
+   * previous special token through its specialToken field, and so on
+   * until the first special token (whose specialToken field is null).
+   * The next fields of special tokens refer to other special tokens that
+   * immediately follow it (without an intervening regular token).  If there
+   * is no such token, this field is null.
+   */
+  public Token specialToken;
+
+  /**
+   * An optional attribute value of the Token.
+   * Tokens which are not used as syntactic sugar will often contain
+   * meaningful values that will be used later on by the compiler or
+   * interpreter. This attribute value is often different from the image.
+   * Any subclass of Token that actually wants to return a non-null value can
+   * override this method as appropriate.
+   */
+  public Object getValue() {
+    return null;
+  }
+
+  /**
+   * No-argument constructor
+   */
+  public Token() {}
+
+  /**
+   * Constructs a new token for the specified Image.
+   */
+  public Token(int kind)
+  {
+    this(kind, null);
+  }
+
+  /**
+   * Constructs a new token for the specified Image and Kind.
+   */
+  public Token(int kind, String image)
+  {
+    this.kind = kind;
+    this.image = image;
+  }
+
+  /**
+   * Returns the image.
+   */
+  public String toString()
+  {
+    return image;
+  }
+
+  /**
+   * Returns a new Token object, by default. However, if you want, you
+   * can create and return subclass objects based on the value of ofKind.
+   * Simply add the cases to the switch for all those special cases.
+   * For example, if you have a subclass of Token called IDToken that
+   * you want to create if ofKind is ID, simply add something like :
+   *
+   *    case MyParserConstants.ID : return new IDToken(ofKind, image);
+   *
+   * to the following switch statement. Then you can cast matchedToken
+   * variable to the appropriate type and use sit in your lexical actions.
+   */
+  public static Token newToken(int ofKind, String image)
+  {
+    switch(ofKind)
+    {
+      default : return new Token(ofKind, image);
+    }
+  }
+
+  public static Token newToken(int ofKind)
+  {
+    return newToken(ofKind, null);
+  }
+
+}
+/* JavaCC - OriginalChecksum=81ad7854912711be917c774d4f150610 (do not edit this line) */
diff --git a/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/TokenMgrError.java b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/TokenMgrError.java
new file mode 100644
index 0000000..411e939
--- /dev/null
+++ b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/TokenMgrError.java
@@ -0,0 +1,147 @@
+/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 5.0 */
+/* JavaCCOptions: */
+package org.apache.sling.tagmodifier.impl;
+
+/** Token Manager Error. */
+public class TokenMgrError extends Error
+{
+
+  /**
+   * The version identifier for this Serializable class.
+   * Increment only if the <i>serialized</i> form of the
+   * class changes.
+   */
+  private static final long serialVersionUID = 1L;
+
+  /*
+   * Ordinals for various reasons why an Error of this type can be thrown.
+   */
+
+  /**
+   * Lexical error occurred.
+   */
+  static final int LEXICAL_ERROR = 0;
+
+  /**
+   * An attempt was made to create a second instance of a static token manager.
+   */
+  static final int STATIC_LEXER_ERROR = 1;
+
+  /**
+   * Tried to change to an invalid lexical state.
+   */
+  static final int INVALID_LEXICAL_STATE = 2;
+
+  /**
+   * Detected (and bailed out of) an infinite loop in the token manager.
+   */
+  static final int LOOP_DETECTED = 3;
+
+  /**
+   * Indicates the reason why the exception is thrown. It will have
+   * one of the above 4 values.
+   */
+  int errorCode;
+
+  /**
+   * Replaces unprintable characters by their escaped (or unicode escaped)
+   * equivalents in the given string
+   */
+  protected static final String addEscapes(String str) {
+    StringBuffer retval = new StringBuffer();
+    char ch;
+    for (int i = 0; i < str.length(); i++) {
+      switch (str.charAt(i))
+      {
+        case 0 :
+          continue;
+        case '\b':
+          retval.append("\\b");
+          continue;
+        case '\t':
+          retval.append("\\t");
+          continue;
+        case '\n':
+          retval.append("\\n");
+          continue;
+        case '\f':
+          retval.append("\\f");
+          continue;
+        case '\r':
+          retval.append("\\r");
+          continue;
+        case '\"':
+          retval.append("\\\"");
+          continue;
+        case '\'':
+          retval.append("\\\'");
+          continue;
+        case '\\':
+          retval.append("\\\\");
+          continue;
+        default:
+          if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
+            String s = "0000" + Integer.toString(ch, 16);
+            retval.append("\\u" + s.substring(s.length() - 4, s.length()));
+          } else {
+            retval.append(ch);
+          }
+          continue;
+      }
+    }
+    return retval.toString();
+  }
+
+  /**
+   * Returns a detailed message for the Error when it is thrown by the
+   * token manager to indicate a lexical error.
+   * Parameters :
+   *    EOFSeen     : indicates if EOF caused the lexical error
+   *    curLexState : lexical state in which this error occurred
+   *    errorLine   : line number when the error occurred
+   *    errorColumn : column number when the error occurred
+   *    errorAfter  : prefix that was seen before this error occurred
+   *    curchar     : the offending character
+   * Note: You can customize the lexical error message by modifying this method.
+   */
+  protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) {
+    return("Lexical error at line " +
+          errorLine + ", column " +
+          errorColumn + ".  Encountered: " +
+          (EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") +
+          "after : \"" + addEscapes(errorAfter) + "\"");
+  }
+
+  /**
+   * You can also modify the body of this method to customize your error messages.
+   * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
+   * of end-users concern, so you can return something like :
+   *
+   *     "Internal Error : Please file a bug report .... "
+   *
+   * from this method for such cases in the release version of your parser.
+   */
+  public String getMessage() {
+    return super.getMessage();
+  }
+
+  /*
+   * Constructors of various flavors follow.
+   */
+
+  /** No arg constructor. */
+  public TokenMgrError() {
+  }
+
+  /** Constructor with message and reason. */
+  public TokenMgrError(String message, int reason) {
+    super(message);
+    errorCode = reason;
+  }
+
+  /** Full Constructor. */
+  public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) {
+    this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
+  }
+}
+/* JavaCC - OriginalChecksum=f7fa2506e61d308a4e64469fb4552a86 (do not edit this line) */
diff --git a/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/components/HtmlGeneratorFactory.java b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/components/HtmlGeneratorFactory.java
new file mode 100644
index 0000000..758c7ea
--- /dev/null
+++ b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/components/HtmlGeneratorFactory.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.tagmodifier.impl.components;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import org.apache.sling.commons.html.HtmlParser;
+import org.apache.sling.rewriter.Generator;
+import org.apache.sling.rewriter.GeneratorFactory;
+import org.apache.sling.rewriter.ProcessingComponentConfiguration;
+import org.apache.sling.rewriter.ProcessingContext;
+import org.osgi.framework.Constants;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * On the fly HTML parser which can be used as the
+ * starting point for html pipelines.
+ *
+ */
+@Component(service = GeneratorFactory.class,
+    property = {
+            Constants.SERVICE_VENDOR + "=The Apache Software Foundation",
+            "pipeline.type=html5-generator"
+    })
+public class HtmlGeneratorFactory implements GeneratorFactory {
+
+    @Reference(target="(version=html5)")
+    private HtmlParser htmlParser;
+
+    /**
+     * @see org.apache.sling.rewriter.GeneratorFactory#createGenerator()
+     */
+    @Override
+    public Generator createGenerator() {
+        return new HtmlGenerator(htmlParser);
+    }
+
+    public static final class HtmlGenerator implements Generator {
+
+        private final StringWriter writer;
+
+        private final HtmlParser htmlParser;
+
+        private ContentHandler contentHandler;
+
+        public HtmlGenerator(final HtmlParser parser) {
+            this.htmlParser = parser;
+            this.writer = new StringWriter();
+        }
+
+        /**
+         * @see org.apache.sling.rewriter.Generator#finished()
+         */
+        @Override
+        public void finished() throws IOException, SAXException {
+            this.htmlParser.parse(new ByteArrayInputStream(this.writer.toString().getBytes("UTF-8")), "UTF-8", this.contentHandler);
+        }
+
+        /**
+         * @see org.apache.sling.rewriter.Generator#getWriter()
+         */
+        @Override
+        public PrintWriter getWriter() {
+            return new PrintWriter(writer);
+        }
+
+        @Override
+        public void init(ProcessingContext context,
+                         ProcessingComponentConfiguration config)
+        throws IOException {
+            // nothing to do
+        }
+
+        /**
+         * @see org.apache.sling.rewriter.Generator#setContentHandler(org.xml.sax.ContentHandler)
+         */
+        @Override
+        public void setContentHandler(ContentHandler handler) {
+            this.contentHandler = handler;
+        }
+
+        /**
+         * @see org.apache.sling.rewriter.Generator#dispose()
+         */
+        @Override
+        public void dispose() {
+            // nothing to do
+        }
+    }
+}
\ No newline at end of file
diff --git a/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/components/TagHtmlParser.java b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/components/TagHtmlParser.java
new file mode 100644
index 0000000..74c9646
--- /dev/null
+++ b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/components/TagHtmlParser.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.tagmodifier.impl.components;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.sling.commons.html.HtmlParser;
+import org.apache.sling.tagmodifier.Tag;
+import org.apache.sling.tagmodifier.consumer.HtmlSAXSupport;
+import org.apache.sling.tagmodifier.util.DOMBuilder;
+import org.osgi.service.component.annotations.Component;
+import org.w3c.dom.Document;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+@Component(
+    property = {
+        "dom=tagmodifier",
+        "sax=tagmodifier",
+        "version=html5"
+    }
+)
+public class TagHtmlParser implements HtmlParser {
+
+
+
+    /**
+     * @see org.apache.sling.commons.html.HtmlParser#parse(java.io.InputStream, java.lang.String, org.xml.sax.ContentHandler)
+     */
+    @Override
+    public void parse(final InputStream stream, final String encoding, final ContentHandler contentHandler) throws SAXException {
+        Tag.stream(stream,encoding).forEach(new HtmlSAXSupport(contentHandler, null));
+    }
+
+    /**
+     * @see org.apache.sling.commons.html.HtmlParser#parse(java.lang.String, java.io.InputStream, java.lang.String)
+     */
+    @Override
+    public Document parse(String systemId, InputStream stream, String encoding) throws IOException {
+        final DOMBuilder builder = new DOMBuilder();
+        Tag.stream(stream, encoding).forEach(new HtmlSAXSupport(builder, builder));
+        return builder.getDocument();
+    }
+
+}
diff --git a/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/tag/Comment.java b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/tag/Comment.java
new file mode 100644
index 0000000..1bd23d1
--- /dev/null
+++ b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/tag/Comment.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.tagmodifier.impl.tag;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.sling.tagmodifier.AttrValue;
+import org.apache.sling.tagmodifier.Element;
+import org.apache.sling.tagmodifier.ElementType;
+
+public class Comment implements Element {
+
+    private String value;
+
+    public Comment(String text) {
+        this.value = text;
+    }
+
+    @Override
+    public ElementType getType() {
+        return ElementType.COMMENT;
+    }
+    
+    public String getValue() {
+        return value;
+    }
+
+    @Override
+    public boolean supportsAttributes() {
+        return false;
+    }
+
+    @Override
+    public Map<String, AttrValue> getAttributes() {
+        return Collections.emptyMap();
+    }
+
+
+}
\ No newline at end of file
diff --git a/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/tag/DocType.java b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/tag/DocType.java
new file mode 100644
index 0000000..71e844e
--- /dev/null
+++ b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/tag/DocType.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.tagmodifier.impl.tag; 
+
+import java.util.Map;
+
+import org.apache.sling.tagmodifier.AttrValue;
+import org.apache.sling.tagmodifier.Element;
+import org.apache.sling.tagmodifier.ElementType;
+
+public class DocType implements Element {
+    
+    private String value;
+    private Map<String,AttrValue> attributes;
+
+    public DocType(String tag, Map<String,AttrValue> attrList) {
+        this.value = tag;
+        this.attributes = attrList;
+    }
+    
+    @Override
+    public ElementType getType() {
+        return ElementType.DOCTYPE;
+    }
+
+    @Override
+    public boolean supportsAttributes() {
+        return true;
+    }
+
+    @Override
+    public Map<String, AttrValue> getAttributes() {
+        return attributes;
+    }
+
+    @Override
+    public String getValue() {
+        return value;
+    }
+
+}
diff --git a/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/tag/EndOfFile.java b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/tag/EndOfFile.java
new file mode 100644
index 0000000..23fa85b
--- /dev/null
+++ b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/tag/EndOfFile.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.tagmodifier.impl.tag;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.sling.tagmodifier.AttrValue;
+import org.apache.sling.tagmodifier.Element;
+import org.apache.sling.tagmodifier.ElementType;
+
+public class EndOfFile implements Element {
+
+    @Override
+    public ElementType getType() {
+        return ElementType.EOF;
+    }
+
+    @Override
+    public boolean supportsAttributes() {
+        return false;
+    }
+
+    @Override
+    public Map<String, AttrValue> getAttributes() {
+        return Collections.emptyMap();
+    }
+
+    @Override
+    public String getValue() {
+        return "EOF";
+    }
+
+}
diff --git a/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/tag/EndTag.java b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/tag/EndTag.java
new file mode 100644
index 0000000..481d2d9
--- /dev/null
+++ b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/tag/EndTag.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.tagmodifier.impl.tag;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.sling.tagmodifier.AttrValue;
+import org.apache.sling.tagmodifier.Element;
+import org.apache.sling.tagmodifier.ElementType;
+
+public class EndTag implements Element {
+
+    private String value;
+
+    public EndTag(String value) {
+        this.value = value;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    @Override
+    public ElementType getType() {
+        return ElementType.END_TAG;
+    }
+
+    @Override
+    public boolean supportsAttributes() {
+        return false;
+    }
+
+    @Override
+    public Map<String, AttrValue> getAttributes() {
+        return Collections.emptyMap();
+    }
+}
\ No newline at end of file
diff --git a/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/tag/StartTag.java b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/tag/StartTag.java
new file mode 100644
index 0000000..690849a
--- /dev/null
+++ b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/tag/StartTag.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.tagmodifier.impl.tag;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.sling.tagmodifier.AttrValue;
+import org.apache.sling.tagmodifier.Element;
+import org.apache.sling.tagmodifier.ElementType;
+
+public class StartTag implements Element {
+
+    private String value;
+    private Map<String, AttrValue> attributes = Collections.emptyMap();
+
+    public StartTag(String value, Map<String, AttrValue> attrList) {
+        this.value = value;
+        attributes = attrList;
+    }
+
+    @Override
+    public ElementType getType() {
+        return ElementType.START_TAG;
+    }
+
+    @Override
+    public String getValue() {
+        return value;
+    }
+
+    @Override
+    public boolean supportsAttributes() {
+        return true;
+    }
+
+    @Override
+    public Map<String, AttrValue> getAttributes() {
+        return attributes;
+    }
+}
\ No newline at end of file
diff --git a/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/tag/TextData.java b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/tag/TextData.java
new file mode 100644
index 0000000..5b903de
--- /dev/null
+++ b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/impl/tag/TextData.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.tagmodifier.impl.tag;
+/**
+ * Plain text
+ */
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.sling.tagmodifier.AttrValue;
+import org.apache.sling.tagmodifier.Element;
+import org.apache.sling.tagmodifier.ElementType;
+
+/**
+ * Represents the data that is found between tags.
+ * 
+ *
+ */
+public class TextData implements Element {
+
+    private String value;
+
+    public TextData(String t) {
+        value = t;
+    }
+
+    public String toString() {
+        return value;
+    }
+
+    @Override
+    public ElementType getType() {
+        return ElementType.TEXT;
+    }
+   
+    public String getValue() {
+        return value;
+    }
+    
+    public void setText(String text) {
+        this.value = text;
+    }
+
+    @Override
+    public boolean supportsAttributes() {
+        return false;
+    }
+
+    @Override
+    public Map<String, AttrValue> getAttributes() {
+        return Collections.emptyMap();
+    }
+    
+}
\ No newline at end of file
diff --git a/tag-modifier/src/main/java/org/apache/sling/tagmodifier/map/HtmlTextEncoder.java b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/map/HtmlTextEncoder.java
new file mode 100644
index 0000000..9473443
--- /dev/null
+++ b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/map/HtmlTextEncoder.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.tagmodifier.map;
+
+import java.util.LinkedList;
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+import org.apache.sling.tagmodifier.Element;
+import org.apache.sling.tagmodifier.impl.tag.TextData;
+import org.apache.sling.tagmodifier.util.HtmlEntityTranslator;
+
+public class HtmlTextEncoder implements Function<Element, Stream<Element>> {
+
+    LinkedList<String> insideOf = new LinkedList<>();
+
+    @Override
+    public Stream<Element> apply(Element element) {
+        switch (element.getType()) {
+
+        case START_TAG:
+            String name = element.getValue();
+            switch (name) {
+            case "noframes":
+            case "noscript":
+            case "style":
+            case "script":
+                insideOf.push(name);
+                break;
+            default:
+                break;
+            }
+            break;
+        case END_TAG:
+            String endName = element.getValue();
+            switch (endName) {
+            case "noframes":
+            case "noscript":
+            case "style":
+            case "script":
+                while (!insideOf.isEmpty()) {
+                    String tagName = insideOf.pop();
+                    if (tagName.equals(endName)) {
+                        break;
+                    }
+                }
+                break;
+            default:
+                break;
+            }
+            break;
+        case TEXT:
+            if (!insideOf.isEmpty()) {
+                TextData text = (TextData)element;
+                text.setText(HtmlEntityTranslator.encodeHTML(text.getValue()));
+            }
+            break;
+        default:
+            break;
+        }
+        return Stream.of(element);
+    }
+
+}
diff --git a/tag-modifier/src/main/java/org/apache/sling/tagmodifier/package-info.java b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/package-info.java
new file mode 100644
index 0000000..55de967
--- /dev/null
+++ b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/package-info.java
@@ -0,0 +1,15 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+@org.osgi.annotation.versioning.Version("0.0.1")
+package org.apache.sling.tagmodifier;
\ No newline at end of file
diff --git a/tag-modifier/src/main/java/org/apache/sling/tagmodifier/util/DOMBuilder.java b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/util/DOMBuilder.java
new file mode 100644
index 0000000..cd170ce
--- /dev/null
+++ b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/util/DOMBuilder.java
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.tagmodifier.util;
+
+import java.io.IOException;
+
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TransformerHandler;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
+
+/**
+ * The <code>DOMBuilder</code> is a utility class that will generate a W3C
+ * DOM Document from SAX events.
+ */
+public class DOMBuilder implements ContentHandler, LexicalHandler {
+
+    /**
+     * The default transformer factory shared by all instances
+     */
+    private static final SAXTransformerFactory FACTORY = (SAXTransformerFactory) TransformerFactory.newInstance();
+
+    private final DOMResult result;
+
+    private final ContentHandler contentHandler;
+    private final LexicalHandler lexicalHandler;
+
+    /**
+     * Construct a new instance of this DOMBuilder.
+     *
+     * @throws IOException If for some reason the <code>TransformerHandler</code> cannot be created.
+     */
+    public DOMBuilder() throws IOException {
+        try {
+            final TransformerHandler handler = FACTORY.newTransformerHandler();
+            this.contentHandler = handler;
+            this.lexicalHandler = handler;
+            this.result = new DOMResult();
+            handler.setResult(this.result);
+        } catch (TransformerException te) {
+            throw new IOException("Unable to get transformer handler", te);
+        }
+    }
+
+    /**
+     * @return The newly built <code>Document</code> or <code>null</code>.
+     */
+    public Document getDocument() {
+        if (this.result.getNode() == null) {
+            return null;
+        } else if (this.result.getNode().getNodeType() == Node.DOCUMENT_NODE) {
+            return (Document) this.result.getNode();
+        } else {
+            return this.result.getNode().getOwnerDocument();
+        }
+    }
+
+    @Override
+    public void setDocumentLocator(Locator locator) {
+        contentHandler.setDocumentLocator(locator);
+    }
+
+    @Override
+    public void startDocument() throws SAXException {
+        contentHandler.startDocument();
+    }
+
+    @Override
+    public void endDocument() throws SAXException {
+        contentHandler.endDocument();
+    }
+
+    @Override
+    public void startPrefixMapping(String prefix, String uri) throws SAXException {
+        contentHandler.startPrefixMapping(prefix, uri);
+    }
+
+    @Override
+    public void endPrefixMapping(String prefix) throws SAXException {
+        contentHandler.endPrefixMapping(prefix);
+    }
+
+    @Override
+    public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
+        contentHandler.startElement(uri, localName, qName, atts);
+    }
+
+    @Override
+    public void endElement(String uri, String localName, String qName) throws SAXException {
+        contentHandler.endElement(uri, localName, qName);
+    }
+
+    @Override
+    public void characters(char[] ch, int start, int length) throws SAXException {
+        contentHandler.characters(ch, start, length);
+    }
+
+    @Override
+    public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
+        contentHandler.ignorableWhitespace(ch, start, length);
+    }
+
+    @Override
+    public void processingInstruction(String target, String data) throws SAXException {
+        contentHandler.processingInstruction(target, data);
+    }
+
+    @Override
+    public void skippedEntity(String name) throws SAXException {
+        contentHandler.skippedEntity(name);
+    }
+
+    @Override
+    public void startDTD(String name, String publicId, String systemId) throws SAXException {
+        lexicalHandler.startDTD(name, publicId, systemId);
+    }
+
+    @Override
+    public void endDTD() throws SAXException {
+        lexicalHandler.endDTD();
+    }
+
+    @Override
+    public void startEntity(String name) throws SAXException {
+        lexicalHandler.startEntity(name);
+    }
+
+    @Override
+    public void endEntity(String name) throws SAXException {
+        lexicalHandler.endEntity(name);
+    }
+
+    @Override
+    public void startCDATA() throws SAXException {
+        lexicalHandler.startCDATA();
+    }
+
+    @Override
+    public void endCDATA() throws SAXException {
+        lexicalHandler.endCDATA();
+    }
+
+    @Override
+    public void comment(char[] ch, int start, int length) throws SAXException {
+        lexicalHandler.comment(ch, start, length);
+    }
+
+}
diff --git a/tag-modifier/src/main/java/org/apache/sling/tagmodifier/util/Html5Entities.java b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/util/Html5Entities.java
new file mode 100644
index 0000000..64572c1
--- /dev/null
+++ b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/util/Html5Entities.java
@@ -0,0 +1,2273 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.tagmodifier.util;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.text.translate.EntityArrays;
+
+public class Html5Entities {
+    
+    private Html5Entities() {
+    }
+    
+    /**
+     * HTML 5.0 character entities.
+     */
+    public static final Map<CharSequence, CharSequence> HTML50_EXTENDED_ESCAPE;
+    static {
+        final Map<CharSequence, CharSequence> initialMap = new HashMap<>();
+        initialMap.put("\u200C", "&zwnj;");
+        initialMap.put("\u200D", "&zwj;");
+        initialMap.put("\uD835\uDCCF", "&zscr;");
+        initialMap.put("\uD835\uDCB5", "&Zscr;");
+        initialMap.put("\u2124", "&Zopf;");
+        initialMap.put("\uD835\uDD6B", "&zopf;");
+        initialMap.put("\u21DD", "&zigrarr;");
+        initialMap.put("\u0436", "&zhcy;");
+        initialMap.put("\u0416", "&ZHcy;");
+        initialMap.put("\u2128", "&Zfr;");
+        initialMap.put("\uD835\uDD37", "&zfr;");
+        initialMap.put("\u03B6", "&zeta;");
+        initialMap.put("\u0396", "&Zeta;");
+        initialMap.put("\u200B", "&ZeroWidthSpace;");
+        initialMap.put("\u2128", "&zeetrf;");
+        initialMap.put("\u017C", "&zdot;");
+        initialMap.put("\u017B", "&Zdot;");
+        initialMap.put("\u0437", "&zcy;");
+        initialMap.put("\u0417", "&Zcy;");
+        initialMap.put("\u017E", "&zcaron;");
+        initialMap.put("\u017D", "&Zcaron;");
+        initialMap.put("\u017A", "&zacute;");
+        initialMap.put("\u0179", "&Zacute;");
+        initialMap.put("\u0178", "&Yuml;");
+        initialMap.put("\u00FF", "&yuml");
+        initialMap.put("\u00FF", "&yuml;");
+        initialMap.put("\u044E", "&yucy;");
+        initialMap.put("\u042E", "&YUcy;");
+        initialMap.put("\uD835\uDCCE", "&yscr;");
+        initialMap.put("\uD835\uDCB4", "&Yscr;");
+        initialMap.put("\uD835\uDD6A", "&yopf;");
+        initialMap.put("\uD835\uDD50", "&Yopf;");
+        initialMap.put("\u0457", "&yicy;");
+        initialMap.put("\u0407", "&YIcy;");
+        initialMap.put("\uD835\uDD36", "&yfr;");
+        initialMap.put("\uD835\uDD1C", "&Yfr;");
+        initialMap.put("\u00A5", "&yen");
+        initialMap.put("\u00A5", "&yen;");
+        initialMap.put("\u044B", "&ycy;");
+        initialMap.put("\u042B", "&Ycy;");
+        initialMap.put("\u0177", "&ycirc;");
+        initialMap.put("\u0176", "&Ycirc;");
+        initialMap.put("\u044F", "&yacy;");
+        initialMap.put("\u042F", "&YAcy;");
+        initialMap.put("\u00FD", "&yacute");
+        initialMap.put("\u00FD", "&yacute;");
+        initialMap.put("\u00DD", "&Yacute");
+        initialMap.put("\u00DD", "&Yacute;");
+        initialMap.put("\u22C0", "&xwedge;");
+        initialMap.put("\u22C1", "&xvee;");
+        initialMap.put("\u25B3", "&xutri;");
+        initialMap.put("\u2A04", "&xuplus;");
+        initialMap.put("\u2A06", "&xsqcup;");
+        initialMap.put("\uD835\uDCCD", "&xscr;");
+        initialMap.put("\uD835\uDCB3", "&Xscr;");
+        initialMap.put("\u27F9", "&xrArr;");
+        initialMap.put("\u27F6", "&xrarr;");
+        initialMap.put("\u2A02", "&xotime;");
+        initialMap.put("\u2A01", "&xoplus;");
+        initialMap.put("\uD835\uDD69", "&xopf;");
+        initialMap.put("\uD835\uDD4F", "&Xopf;");
+        initialMap.put("\u2A00", "&xodot;");
+        initialMap.put("\u22FB", "&xnis;");
+        initialMap.put("\u27FC", "&xmap;");
+        initialMap.put("\u27F8", "&xlArr;");
+        initialMap.put("\u27F5", "&xlarr;");
+        initialMap.put("\u03BE", "&xi;");
+        initialMap.put("\u039E", "&Xi;");
+        initialMap.put("\u27FA", "&xhArr;");
+        initialMap.put("\u27F7", "&xharr;");
+        initialMap.put("\uD835\uDD35", "&xfr;");
+        initialMap.put("\uD835\uDD1B", "&Xfr;");
+        initialMap.put("\u25BD", "&xdtri;");
+        initialMap.put("\u22C3", "&xcup;");
+        initialMap.put("\u25EF", "&xcirc;");
+        initialMap.put("\u22C2", "&xcap;");
+        initialMap.put("\uD835\uDCCC", "&wscr;");
+        initialMap.put("\uD835\uDCB2", "&Wscr;");
+        initialMap.put("\u2240", "&wreath;");
+        initialMap.put("\u2240", "&wr;");
+        initialMap.put("\u2118", "&wp;");
+        initialMap.put("\uD835\uDD68", "&wopf;");
+        initialMap.put("\uD835\uDD4E", "&Wopf;");
+        initialMap.put("\uD835\uDD34", "&wfr;");
+        initialMap.put("\uD835\uDD1A", "&Wfr;");
+        initialMap.put("\u2118", "&weierp;");
+        initialMap.put("\u2259", "&wedgeq;");
+        initialMap.put("\u22C0", "&Wedge;");
+        initialMap.put("\u2227", "&wedge;");
+        initialMap.put("\u2A5F", "&wedbar;");
+        initialMap.put("\u0175", "&wcirc;");
+        initialMap.put("\u0174", "&Wcirc;");
+        initialMap.put("\u299A", "&vzigzag;");
+        initialMap.put("\u22AA", "&Vvdash;");
+        initialMap.put("\u228B\uFE00", "&vsupne;");
+        initialMap.put("\u2ACC\uFE00", "&vsupnE;");
+        initialMap.put("\u228A\uFE00", "&vsubne;");
+        initialMap.put("\u2ACB\uFE00", "&vsubnE;");
+        initialMap.put("\uD835\uDCCB", "&vscr;");
+        initialMap.put("\uD835\uDCB1", "&Vscr;");
+        initialMap.put("\u22B3", "&vrtri;");
+        initialMap.put("\u221D", "&vprop;");
+        initialMap.put("\uD835\uDD67", "&vopf;");
+        initialMap.put("\uD835\uDD4D", "&Vopf;");
+        initialMap.put("\u2283\u20D2", "&vnsup;");
+        initialMap.put("\u2282\u20D2", "&vnsub;");
+        initialMap.put("\u22B2", "&vltri;");
+        initialMap.put("\uD835\uDD33", "&vfr;");
+        initialMap.put("\uD835\uDD19", "&Vfr;");
+        initialMap.put("\u200A", "&VeryThinSpace;");
+        initialMap.put("\u2240", "&VerticalTilde;");
+        initialMap.put("\u2758", "&VerticalSeparator;");
+        initialMap.put("\u007C", "&VerticalLine;");
+        initialMap.put("\u2223", "&VerticalBar;");
+        initialMap.put("\u2016", "&Vert;");
+        initialMap.put("\u007C", "&vert;");
+        initialMap.put("\u2016", "&Verbar;");
+        initialMap.put("\u007C", "&verbar;");
+        initialMap.put("\u22EE", "&vellip;");
+        initialMap.put("\u225A", "&veeeq;");
+        initialMap.put("\u22C1", "&Vee;");
+        initialMap.put("\u2228", "&vee;");
+        initialMap.put("\u22BB", "&veebar;");
+        initialMap.put("\u2AE6", "&Vdashl;");
+        initialMap.put("\u22AB", "&VDash;");
+        initialMap.put("\u22A9", "&Vdash;");
+        initialMap.put("\u22A8", "&vDash;");
+        initialMap.put("\u22A2", "&vdash;");
+        initialMap.put("\u0432", "&vcy;");
+        initialMap.put("\u0412", "&Vcy;");
+        initialMap.put("\u2AE9", "&vBarv;");
+        initialMap.put("\u2AEB", "&Vbar;");
+        initialMap.put("\u2AE8", "&vBar;");
+        initialMap.put("\u22B3", "&vartriangleright;");
+        initialMap.put("\u22B2", "&vartriangleleft;");
+        initialMap.put("\u03D1", "&vartheta;");
+        initialMap.put("\u2ACC\uFE00", "&varsupsetneqq;");
+        initialMap.put("\u228B\uFE00", "&varsupsetneq;");
+        initialMap.put("\u2ACB\uFE00", "&varsubsetneqq;");
+        initialMap.put("\u228A\uFE00", "&varsubsetneq;");
+        initialMap.put("\u03C2", "&varsigma;");
+        initialMap.put("\u03F1", "&varrho;");
+        initialMap.put("\u21D5", "&vArr;");
+        initialMap.put("\u2195", "&varr;");
+        initialMap.put("\u221D", "&varpropto;");
+        initialMap.put("\u03D6", "&varpi;");
+        initialMap.put("\u03D5", "&varphi;");
+        initialMap.put("\u2205", "&varnothing;");
+        initialMap.put("\u03F0", "&varkappa;");
+        initialMap.put("\u03F5", "&varepsilon;");
+        initialMap.put("\u299C", "&vangrt;");
+        initialMap.put("\u29A7", "&uwangle;");
+        initialMap.put("\u00FC", "&uuml");
+        initialMap.put("\u00FC", "&uuml;");
+        initialMap.put("\u00DC", "&Uuml");
+        initialMap.put("\u00DC", "&Uuml;");
+        initialMap.put("\u21C8", "&uuarr;");
+        initialMap.put("\u25B4", "&utrif;");
+        initialMap.put("\u25B5", "&utri;");
+        initialMap.put("\u0169", "&utilde;");
+        initialMap.put("\u0168", "&Utilde;");
+        initialMap.put("\u22F0", "&utdot;");
+        initialMap.put("\uD835\uDCCA", "&uscr;");
+        initialMap.put("\uD835\uDCB0", "&Uscr;");
+        initialMap.put("\u25F9", "&urtri;");
+        initialMap.put("\u016F", "&uring;");
+        initialMap.put("\u016E", "&Uring;");
+        initialMap.put("\u230E", "&urcrop;");
+        initialMap.put("\u231D", "&urcorner;");
+        initialMap.put("\u231D", "&urcorn;");
+        initialMap.put("\u21C8", "&upuparrows;");
+        initialMap.put("\u22A5", "&UpTee;");
+        initialMap.put("\u21A5", "&UpTeeArrow;");
+        initialMap.put("\u03C5", "&upsilon;");
+        initialMap.put("\u03A5", "&Upsilon;");
+        initialMap.put("\u03D2", "&upsih;");
+        initialMap.put("\u03D2", "&Upsi;");
+        initialMap.put("\u03C5", "&upsi;");
+        initialMap.put("\u2197", "&UpperRightArrow;");
+        initialMap.put("\u2196", "&UpperLeftArrow;");
+        initialMap.put("\u228E", "&uplus;");
+        initialMap.put("\u21BE", "&upharpoonright;");
+        initialMap.put("\u21BF", "&upharpoonleft;");
+        initialMap.put("\u296E", "&UpEquilibrium;");
+        initialMap.put("\u21D5", "&Updownarrow;");
+        initialMap.put("\u2195", "&UpDownArrow;");
+        initialMap.put("\u2195", "&updownarrow;");
+        initialMap.put("\u21C5", "&UpArrowDownArrow;");
+        initialMap.put("\u21D1", "&Uparrow;");
+        initialMap.put("\u2191", "&UpArrow;");
+        initialMap.put("\u2191", "&uparrow;");
+        initialMap.put("\u2912", "&UpArrowBar;");
+        initialMap.put("\uD835\uDD66", "&uopf;");
+        initialMap.put("\uD835\uDD4C", "&Uopf;");
+        initialMap.put("\u0173", "&uogon;");
+        initialMap.put("\u0172", "&Uogon;");
+        initialMap.put("\u228E", "&UnionPlus;");
+        initialMap.put("\u22C3", "&Union;");
+        initialMap.put("\u23DD", "&UnderParenthesis;");
+        initialMap.put("\u23B5", "&UnderBracket;");
+        initialMap.put("\u23DF", "&UnderBrace;");
+        initialMap.put("\u005F", "&UnderBar;");
+        initialMap.put("\u00A8", "&uml");
+        initialMap.put("\u00A8", "&uml;");
+        initialMap.put("\u016B", "&umacr;");
+        initialMap.put("\u016A", "&Umacr;");
+        initialMap.put("\u25F8", "&ultri;");
+        initialMap.put("\u230F", "&ulcrop;");
+        initialMap.put("\u231C", "&ulcorner;");
+        initialMap.put("\u231C", "&ulcorn;");
+        initialMap.put("\u2580", "&uhblk;");
+        initialMap.put("\u21BE", "&uharr;");
+        initialMap.put("\u21BF", "&uharl;");
+        initialMap.put("\u2963", "&uHar;");
+        initialMap.put("\u00F9", "&ugrave");
+        initialMap.put("\u00F9", "&ugrave;");
+        initialMap.put("\u00D9", "&Ugrave");
+        initialMap.put("\u00D9", "&Ugrave;");
+        initialMap.put("\uD835\uDD32", "&ufr;");
+        initialMap.put("\uD835\uDD18", "&Ufr;");
+        initialMap.put("\u297E", "&ufisht;");
+        initialMap.put("\u296E", "&udhar;");
+        initialMap.put("\u0171", "&udblac;");
+        initialMap.put("\u0170", "&Udblac;");
+        initialMap.put("\u21C5", "&udarr;");
+        initialMap.put("\u0443", "&ucy;");
+        initialMap.put("\u0423", "&Ucy;");
+        initialMap.put("\u00FB", "&ucirc");
+        initialMap.put("\u00FB", "&ucirc;");
+        initialMap.put("\u00DB", "&Ucirc");
+        initialMap.put("\u00DB", "&Ucirc;");
+        initialMap.put("\u016D", "&ubreve;");
+        initialMap.put("\u016C", "&Ubreve;");
+        initialMap.put("\u045E", "&ubrcy;");
+        initialMap.put("\u040E", "&Ubrcy;");
+        initialMap.put("\u2949", "&Uarrocir;");
+        initialMap.put("\u21D1", "&uArr;");
+        initialMap.put("\u219F", "&Uarr;");
+        initialMap.put("\u2191", "&uarr;");
+        initialMap.put("\u00FA", "&uacute");
+        initialMap.put("\u00FA", "&uacute;");
+        initialMap.put("\u00DA", "&Uacute");
+        initialMap.put("\u00DA", "&Uacute;");
+        initialMap.put("\u21A0", "&twoheadrightarrow;");
+        initialMap.put("\u219E", "&twoheadleftarrow;");
+        initialMap.put("\u226C", "&twixt;");
+        initialMap.put("\u0167", "&tstrok;");
+        initialMap.put("\u0166", "&Tstrok;");
+        initialMap.put("\u045B", "&tshcy;");
+        initialMap.put("\u040B", "&TSHcy;");
+        initialMap.put("\u0446", "&tscy;");
+        initialMap.put("\u0426", "&TScy;");
+        initialMap.put("\uD835\uDCC9", "&tscr;");
+        initialMap.put("\uD835\uDCAF", "&Tscr;");
+        initialMap.put("\u23E2", "&trpezium;");
+        initialMap.put("\u2A3B", "&tritime;");
+        initialMap.put("\u29CD", "&trisb;");
+        initialMap.put("\u2A39", "&triplus;");
+        initialMap.put("\u20DB", "&TripleDot;");
+        initialMap.put("\u2A3A", "&triminus;");
+        initialMap.put("\u225C", "&trie;");
+        initialMap.put("\u25EC", "&tridot;");
+        initialMap.put("\u22B5", "&trianglerighteq;");
+        initialMap.put("\u25B9", "&triangleright;");
+        initialMap.put("\u225C", "&triangleq;");
+        initialMap.put("\u22B4", "&trianglelefteq;");
+        initialMap.put("\u25C3", "&triangleleft;");
+        initialMap.put("\u25BF", "&triangledown;");
+        initialMap.put("\u25B5", "&triangle;");
+        initialMap.put("\u2122", "&TRADE;");
+        initialMap.put("\u2122", "&trade;");
+        initialMap.put("\u2034", "&tprime;");
+        initialMap.put("\u2929", "&tosa;");
+        initialMap.put("\u2ADA", "&topfork;");
+        initialMap.put("\uD835\uDD65", "&topf;");
+        initialMap.put("\uD835\uDD4B", "&Topf;");
+        initialMap.put("\u22A4", "&top;");
+        initialMap.put("\u2AF1", "&topcir;");
+        initialMap.put("\u2336", "&topbot;");
+        initialMap.put("\u2928", "&toea;");
+        initialMap.put("\u222D", "&tint;");
+        initialMap.put("\u2A30", "&timesd;");
+        initialMap.put("\u00D7", "&times");
+        initialMap.put("\u00D7", "&times;");
+        initialMap.put("\u22A0", "&timesb;");
+        initialMap.put("\u2A31", "&timesbar;");
+        initialMap.put("\u2248", "&TildeTilde;");
+        initialMap.put("\u2245", "&TildeFullEqual;");
+        initialMap.put("\u2243", "&TildeEqual;");
+        initialMap.put("\u223C", "&Tilde;");
+        initialMap.put("\u02DC", "&tilde;");
+        initialMap.put("\u00FE", "&thorn");
+        initialMap.put("\u00FE", "&thorn;");
+        initialMap.put("\u00DE", "&THORN");
+        initialMap.put("\u00DE", "&THORN;");
+        initialMap.put("\u223C", "&thksim;");
+        initialMap.put("\u2248", "&thkap;");
+        initialMap.put("\u2009", "&thinsp;");
+        initialMap.put("\u2009", "&ThinSpace;");
+        initialMap.put("\u205F\u200A", "&ThickSpace;");
+        initialMap.put("\u223C", "&thicksim;");
+        initialMap.put("\u2248", "&thickapprox;");
+        initialMap.put("\u03D1", "&thetav;");
+        initialMap.put("\u03D1", "&thetasym;");
+        initialMap.put("\u03B8", "&theta;");
+        initialMap.put("\u0398", "&Theta;");
+        initialMap.put("\u2234", "&Therefore;");
+        initialMap.put("\u2234", "&therefore;");
+        initialMap.put("\u2234", "&there4;");
+        initialMap.put("\uD835\uDD31", "&tfr;");
+        initialMap.put("\uD835\uDD17", "&Tfr;");
+        initialMap.put("\u2315", "&telrec;");
+        initialMap.put("\u20DB", "&tdot;");
+        initialMap.put("\u0442", "&tcy;");
+        initialMap.put("\u0422", "&Tcy;");
+        initialMap.put("\u0163", "&tcedil;");
+        initialMap.put("\u0162", "&Tcedil;");
+        initialMap.put("\u0165", "&tcaron;");
+        initialMap.put("\u0164", "&Tcaron;");
+        initialMap.put("\u23B4", "&tbrk;");
+        initialMap.put("\u03C4", "&tau;");
+        initialMap.put("\u03A4", "&Tau;");
+        initialMap.put("\u2316", "&target;");
+        initialMap.put("\u0009", "&Tab;");
+        initialMap.put("\u00DF", "&szlig");
+        initialMap.put("\u00DF", "&szlig;");
+        initialMap.put("\u292A", "&swnwar;");
+        initialMap.put("\u2199", "&swarrow;");
+        initialMap.put("\u21D9", "&swArr;");
+        initialMap.put("\u2199", "&swarr;");
+        initialMap.put("\u2926", "&swarhk;");
+        initialMap.put("\u2AD6", "&supsup;");
+        initialMap.put("\u2AD4", "&supsub;");
+        initialMap.put("\u2AC8", "&supsim;");
+        initialMap.put("\u2ACC", "&supsetneqq;");
+        initialMap.put("\u228B", "&supsetneq;");
+        initialMap.put("\u2AC6", "&supseteqq;");
+        initialMap.put("\u2287", "&supseteq;");
+        initialMap.put("\u22D1", "&Supset;");
+        initialMap.put("\u2283", "&supset;");
+        initialMap.put("\u2AC0", "&supplus;");
+        initialMap.put("\u228B", "&supne;");
+        initialMap.put("\u2ACC", "&supnE;");
+        initialMap.put("\u2AC2", "&supmult;");
+        initialMap.put("\u297B", "&suplarr;");
+        initialMap.put("\u2AD7", "&suphsub;");
+        initialMap.put("\u27C9", "&suphsol;");
+        initialMap.put("\u2287", "&SupersetEqual;");
+        initialMap.put("\u2283", "&Superset;");
+        initialMap.put("\u2AC4", "&supedot;");
+        initialMap.put("\u2287", "&supe;");
+        initialMap.put("\u2AC6", "&supE;");
+        initialMap.put("\u2AD8", "&supdsub;");
+        initialMap.put("\u2ABE", "&supdot;");
+        initialMap.put("\u22D1", "&Sup;");
+        initialMap.put("\u2283", "&sup;");
+        initialMap.put("\u00B3", "&sup3");
+        initialMap.put("\u00B3", "&sup3;");
+        initialMap.put("\u00B2", "&sup2");
+        initialMap.put("\u00B2", "&sup2;");
+        initialMap.put("\u00B9", "&sup1");
+        initialMap.put("\u00B9", "&sup1;");
+        initialMap.put("\u266A", "&sung;");
+        initialMap.put("\u2211", "&Sum;");
+        initialMap.put("\u2211", "&sum;");
+        initialMap.put("\u220B", "&SuchThat;");
+        initialMap.put("\u227F", "&succsim;");
+        initialMap.put("\u22E9", "&succnsim;");
+        initialMap.put("\u2AB6", "&succneqq;");
+        initialMap.put("\u2ABA", "&succnapprox;");
+        initialMap.put("\u2AB0", "&succeq;");
+        initialMap.put("\u227F", "&SucceedsTilde;");
+        initialMap.put("\u227D", "&SucceedsSlantEqual;");
+        initialMap.put("\u2AB0", "&SucceedsEqual;");
+        initialMap.put("\u227B", "&Succeeds;");
+        initialMap.put("\u227D", "&succcurlyeq;");
+        initialMap.put("\u227B", "&succ;");
+        initialMap.put("\u2AB8", "&succapprox;");
+        initialMap.put("\u2AD3", "&subsup;");
+        initialMap.put("\u2AD5", "&subsub;");
+        initialMap.put("\u2AC7", "&subsim;");
+        initialMap.put("\u2ACB", "&subsetneqq;");
+        initialMap.put("\u228A", "&subsetneq;");
+        initialMap.put("\u2286", "&SubsetEqual;");
+        initialMap.put("\u2AC5", "&subseteqq;");
+        initialMap.put("\u2286", "&subseteq;");
+        initialMap.put("\u22D0", "&Subset;");
+        initialMap.put("\u2282", "&subset;");
+        initialMap.put("\u2979", "&subrarr;");
+        initialMap.put("\u2ABF", "&subplus;");
+        initialMap.put("\u228A", "&subne;");
+        initialMap.put("\u2ACB", "&subnE;");
+        initialMap.put("\u2AC1", "&submult;");
+        initialMap.put("\u2AC3", "&subedot;");
+        initialMap.put("\u2286", "&sube;");
+        initialMap.put("\u2AC5", "&subE;");
+        initialMap.put("\u2ABD", "&subdot;");
+        initialMap.put("\u22D0", "&Sub;");
+        initialMap.put("\u2282", "&sub;");
+        initialMap.put("\u00AF", "&strns;");
+        initialMap.put("\u03D5", "&straightphi;");
+        initialMap.put("\u03F5", "&straightepsilon;");
+        initialMap.put("\u2605", "&starf;");
+        initialMap.put("\u2606", "&star;");
+        initialMap.put("\u22C6", "&Star;");
+        initialMap.put("\u22C6", "&sstarf;");
+        initialMap.put("\u2323", "&ssmile;");
+        initialMap.put("\u2216", "&ssetmn;");
+        initialMap.put("\uD835\uDCC8", "&sscr;");
+        initialMap.put("\uD835\uDCAE", "&Sscr;");
+        initialMap.put("\u2192", "&srarr;");
+        initialMap.put("\u25AA", "&squf;");
+        initialMap.put("\u25A1", "&squ;");
+        initialMap.put("\u25AA", "&squarf;");
+        initialMap.put("\u2294", "&SquareUnion;");
+        initialMap.put("\u2292", "&SquareSupersetEqual;");
+        initialMap.put("\u2290", "&SquareSuperset;");
+        initialMap.put("\u2291", "&SquareSubsetEqual;");
+        initialMap.put("\u228F", "&SquareSubset;");
+        initialMap.put("\u2293", "&SquareIntersection;");
+        initialMap.put("\u25A1", "&Square;");
+        initialMap.put("\u25A1", "&square;");
+        initialMap.put("\u2292", "&sqsupseteq;");
+        initialMap.put("\u2290", "&sqsupset;");
+        initialMap.put("\u2292", "&sqsupe;");
+        initialMap.put("\u2290", "&sqsup;");
+        initialMap.put("\u2291", "&sqsubseteq;");
+        initialMap.put("\u228F", "&sqsubset;");
+        initialMap.put("\u2291", "&sqsube;");
+        initialMap.put("\u228F", "&sqsub;");
+        initialMap.put("\u221A", "&Sqrt;");
+        initialMap.put("\u2294\uFE00", "&sqcups;");
+        initialMap.put("\u2294", "&sqcup;");
+        initialMap.put("\u2293\uFE00", "&sqcaps;");
+        initialMap.put("\u2293", "&sqcap;");
+        initialMap.put("\u2225", "&spar;");
+        initialMap.put("\u2660", "&spadesuit;");
+        initialMap.put("\u2660", "&spades;");
+        initialMap.put("\uD835\uDD64", "&sopf;");
+        initialMap.put("\uD835\uDD4A", "&Sopf;");
+        initialMap.put("\u002F", "&sol;");
+        initialMap.put("\u29C4", "&solb;");
+        initialMap.put("\u233F", "&solbar;");
+        initialMap.put("\u044C", "&softcy;");
+        initialMap.put("\u042C", "&SOFTcy;");
+        initialMap.put("\u2AAC\uFE00", "&smtes;");
+        initialMap.put("\u2AAC", "&smte;");
+        initialMap.put("\u2AAA", "&smt;");
+        initialMap.put("\u2323", "&smile;");
+        initialMap.put("\u2223", "&smid;");
+        initialMap.put("\u29E4", "&smeparsl;");
+        initialMap.put("\u2A33", "&smashp;");
+        initialMap.put("\u2216", "&smallsetminus;");
+        initialMap.put("\u2218", "&SmallCircle;");
+        initialMap.put("\u2190", "&slarr;");
+        initialMap.put("\u2972", "&simrarr;");
+        initialMap.put("\u2A24", "&simplus;");
+        initialMap.put("\u2246", "&simne;");
+        initialMap.put("\u2A9F", "&simlE;");
+        initialMap.put("\u2A9D", "&siml;");
+        initialMap.put("\u2AA0", "&simgE;");
+        initialMap.put("\u2A9E", "&simg;");
+        initialMap.put("\u2243", "&simeq;");
+        initialMap.put("\u2243", "&sime;");
+        initialMap.put("\u2A6A", "&simdot;");
+        initialMap.put("\u223C", "&sim;");
+        initialMap.put("\u03C2", "&sigmav;");
+        initialMap.put("\u03C2", "&sigmaf;");
+        initialMap.put("\u03C3", "&sigma;");
+        initialMap.put("\u03A3", "&Sigma;");
+        initialMap.put("\u00AD", "&shy");
+        initialMap.put("\u00AD", "&shy;");
+        initialMap.put("\u2191", "&ShortUpArrow;");
+        initialMap.put("\u2192", "&ShortRightArrow;");
+        initialMap.put("\u2225", "&shortparallel;");
+        initialMap.put("\u2223", "&shortmid;");
+        initialMap.put("\u2190", "&ShortLeftArrow;");
+        initialMap.put("\u2193", "&ShortDownArrow;");
+        initialMap.put("\u0448", "&shcy;");
+        initialMap.put("\u0428", "&SHcy;");
+        initialMap.put("\u0449", "&shchcy;");
+        initialMap.put("\u0429", "&SHCHcy;");
+        initialMap.put("\u266F", "&sharp;");
+        initialMap.put("\u2322", "&sfrown;");
+        initialMap.put("\uD835\uDD30", "&sfr;");
+        initialMap.put("\uD835\uDD16", "&Sfr;");
+        initialMap.put("\u2736", "&sext;");
+        initialMap.put("\u2216", "&setmn;");
+        initialMap.put("\u2216", "&setminus;");
+        initialMap.put("\u2929", "&seswar;");
+        initialMap.put("\u003B", "&semi;");
+        initialMap.put("\u00A7", "&sect");
+        initialMap.put("\u00A7", "&sect;");
+        initialMap.put("\u2198", "&searrow;");
+        initialMap.put("\u21D8", "&seArr;");
+        initialMap.put("\u2198", "&searr;");
+        initialMap.put("\u2925", "&searhk;");
+        initialMap.put("\u2A66", "&sdote;");
+        initialMap.put("\u22C5", "&sdot;");
+        initialMap.put("\u22A1", "&sdotb;");
+        initialMap.put("\u0441", "&scy;");
+        initialMap.put("\u0421", "&Scy;");
+        initialMap.put("\u227F", "&scsim;");
+        initialMap.put("\u2A13", "&scpolint;");
+        initialMap.put("\u22E9", "&scnsim;");
+        initialMap.put("\u2AB6", "&scnE;");
+        initialMap.put("\u2ABA", "&scnap;");
+        initialMap.put("\u015D", "&scirc;");
+        initialMap.put("\u015C", "&Scirc;");
+        initialMap.put("\u015F", "&scedil;");
+        initialMap.put("\u015E", "&Scedil;");
+        initialMap.put("\u2AB4", "&scE;");
+        initialMap.put("\u2AB0", "&sce;");
+        initialMap.put("\u227D", "&sccue;");
+        initialMap.put("\u227B", "&sc;");
+        initialMap.put("\u2ABC", "&Sc;");
+        initialMap.put("\u0161", "&scaron;");
+        initialMap.put("\u0160", "&Scaron;");
+        initialMap.put("\u2AB8", "&scap;");
+        initialMap.put("\u201A", "&sbquo;");
+        initialMap.put("\u015B", "&sacute;");
+        initialMap.put("\u015A", "&Sacute;");
+        initialMap.put("\u211E", "&rx;");
+        initialMap.put("\u2968", "&ruluhar;");
+        initialMap.put("\u29F4", "&RuleDelayed;");
+        initialMap.put("\u29CE", "&rtriltri;");
+        initialMap.put("\u25B8", "&rtrif;");
+        initialMap.put("\u22B5", "&rtrie;");
+        initialMap.put("\u25B9", "&rtri;");
+        initialMap.put("\u22CA", "&rtimes;");
+        initialMap.put("\u22CC", "&rthree;");
+        initialMap.put("\u2019", "&rsquor;");
+        initialMap.put("\u2019", "&rsquo;");
+        initialMap.put("\u005D", "&rsqb;");
+        initialMap.put("\u21B1", "&Rsh;");
+        initialMap.put("\u21B1", "&rsh;");
+        initialMap.put("\u211B", "&Rscr;");
+        initialMap.put("\uD835\uDCC7", "&rscr;");
+        initialMap.put("\u203A", "&rsaquo;");
+        initialMap.put("\u21DB", "&Rrightarrow;");
+        initialMap.put("\u21C9", "&rrarr;");
+        initialMap.put("\u2A12", "&rppolint;");
+        initialMap.put("\u2994", "&rpargt;");
+        initialMap.put("\u0029", "&rpar;");
+        initialMap.put("\u2970", "&RoundImplies;");
+        initialMap.put("\u2A35", "&rotimes;");
+        initialMap.put("\u2A2E", "&roplus;");
+        initialMap.put("\u211D", "&Ropf;");
+        initialMap.put("\uD835\uDD63", "&ropf;");
+        initialMap.put("\u2986", "&ropar;");
+        initialMap.put("\u27E7", "&robrk;");
+        initialMap.put("\u21FE", "&roarr;");
+        initialMap.put("\u27ED", "&roang;");
+        initialMap.put("\u2AEE", "&rnmid;");
+        initialMap.put("\u23B1", "&rmoust;");
+        initialMap.put("\u23B1", "&rmoustache;");
+        initialMap.put("\u200F", "&rlm;");
+        initialMap.put("\u21CC", "&rlhar;");
+        initialMap.put("\u21C4", "&rlarr;");
+        initialMap.put("\u2253", "&risingdotseq;");
+        initialMap.put("\u02DA", "&ring;");
+        initialMap.put("\u21C0", "&RightVector;");
+        initialMap.put("\u2953", "&RightVectorBar;");
+        initialMap.put("\u21BE", "&RightUpVector;");
+        initialMap.put("\u2954", "&RightUpVectorBar;");
+        initialMap.put("\u295C", "&RightUpTeeVector;");
+        initialMap.put("\u294F", "&RightUpDownVector;");
+        initialMap.put("\u22B5", "&RightTriangleEqual;");
+        initialMap.put("\u22B3", "&RightTriangle;");
+        initialMap.put("\u29D0", "&RightTriangleBar;");
+        initialMap.put("\u22CC", "&rightthreetimes;");
+        initialMap.put("\u295B", "&RightTeeVector;");
+        initialMap.put("\u22A2", "&RightTee;");
+        initialMap.put("\u21A6", "&RightTeeArrow;");
+        initialMap.put("\u219D", "&rightsquigarrow;");
+        initialMap.put("\u21C9", "&rightrightarrows;");
+        initialMap.put("\u21CC", "&rightleftharpoons;");
+        initialMap.put("\u21C4", "&rightleftarrows;");
+        initialMap.put("\u21C0", "&rightharpoonup;");
+        initialMap.put("\u21C1", "&rightharpoondown;");
+        initialMap.put("\u230B", "&RightFloor;");
+        initialMap.put("\u21C2", "&RightDownVector;");
+        initialMap.put("\u2955", "&RightDownVectorBar;");
+        initialMap.put("\u295D", "&RightDownTeeVector;");
+        initialMap.put("\u27E7", "&RightDoubleBracket;");
+        initialMap.put("\u2309", "&RightCeiling;");
+        initialMap.put("\u21A3", "&rightarrowtail;");
+        initialMap.put("\u21C4", "&RightArrowLeftArrow;");
+        initialMap.put("\u21D2", "&Rightarrow;");
+        initialMap.put("\u2192", "&RightArrow;");
+        initialMap.put("\u2192", "&rightarrow;");
+        initialMap.put("\u21E5", "&RightArrowBar;");
+        initialMap.put("\u27E9", "&RightAngleBracket;");
+        initialMap.put("\u03F1", "&rhov;");
+        initialMap.put("\u03C1", "&rho;");
+        initialMap.put("\u03A1", "&Rho;");
+        initialMap.put("\u296C", "&rharul;");
+        initialMap.put("\u21C0", "&rharu;");
+        initialMap.put("\u21C1", "&rhard;");
+        initialMap.put("\u2964", "&rHar;");
+        initialMap.put("\u211C", "&Rfr;");
+        initialMap.put("\uD835\uDD2F", "&rfr;");
+        initialMap.put("\u230B", "&rfloor;");
+        initialMap.put("\u297D", "&rfisht;");
+        initialMap.put("\u296F", "&ReverseUpEquilibrium;");
+        initialMap.put("\u21CB", "&ReverseEquilibrium;");
+        initialMap.put("\u220B", "&ReverseElement;");
+        initialMap.put("\u00AE", "&REG");
+        initialMap.put("\u00AE", "&REG;");
+        initialMap.put("\u00AE", "&reg");
+        initialMap.put("\u00AE", "&reg;");
+        initialMap.put("\u25AD", "&rect;");
+        initialMap.put("\u211C", "&Re;");
+        initialMap.put("\u211D", "&reals;");
+        initialMap.put("\u211C", "&realpart;");
+        initialMap.put("\u211B", "&realine;");
+        initialMap.put("\u211C", "&real;");
+        initialMap.put("\u21B3", "&rdsh;");
+        initialMap.put("\u201D", "&rdquor;");
+        initialMap.put("\u201D", "&rdquo;");
+        initialMap.put("\u2969", "&rdldhar;");
+        initialMap.put("\u2937", "&rdca;");
+        initialMap.put("\u0440", "&rcy;");
+        initialMap.put("\u0420", "&Rcy;");
+        initialMap.put("\u007D", "&rcub;");
+        initialMap.put("\u2309", "&rceil;");
+        initialMap.put("\u0157", "&rcedil;");
+        initialMap.put("\u0156", "&Rcedil;");
+        initialMap.put("\u0159", "&rcaron;");
+        initialMap.put("\u0158", "&Rcaron;");
+        initialMap.put("\u2990", "&rbrkslu;");
+        initialMap.put("\u298E", "&rbrksld;");
+        initialMap.put("\u298C", "&rbrke;");
+        initialMap.put("\u005D", "&rbrack;");
+        initialMap.put("\u007D", "&rbrace;");
+        initialMap.put("\u2773", "&rbbrk;");
+        initialMap.put("\u2910", "&RBarr;");
+        initialMap.put("\u290F", "&rBarr;");
+        initialMap.put("\u290D", "&rbarr;");
+        initialMap.put("\u211A", "&rationals;");
+        initialMap.put("\u2236", "&ratio;");
+        initialMap.put("\u291C", "&rAtail;");
+        initialMap.put("\u291A", "&ratail;");
+        initialMap.put("\u219D", "&rarrw;");
+        initialMap.put("\u21A3", "&rarrtl;");
+        initialMap.put("\u2916", "&Rarrtl;");
+        initialMap.put("\u2974", "&rarrsim;");
+        initialMap.put("\u2945", "&rarrpl;");
+        initialMap.put("\u21AC", "&rarrlp;");
+        initialMap.put("\u21AA", "&rarrhk;");
+        initialMap.put("\u291E", "&rarrfs;");
+        initialMap.put("\u21D2", "&rArr;");
+        initialMap.put("\u21A0", "&Rarr;");
+        initialMap.put("\u2192", "&rarr;");
+        initialMap.put("\u2933", "&rarrc;");
+        initialMap.put("\u2920", "&rarrbfs;");
+        initialMap.put("\u21E5", "&rarrb;");
+        initialMap.put("\u2975", "&rarrap;");
+        initialMap.put("\u00BB", "&raquo");
+        initialMap.put("\u00BB", "&raquo;");
+        initialMap.put("\u27E9", "&rangle;");
+        initialMap.put("\u29A5", "&range;");
+        initialMap.put("\u2992", "&rangd;");
+        initialMap.put("\u27EB", "&Rang;");
+        initialMap.put("\u27E9", "&rang;");
+        initialMap.put("\u29B3", "&raemptyv;");
+        initialMap.put("\u221A", "&radic;");
+        initialMap.put("\u0155", "&racute;");
+        initialMap.put("\u0154", "&Racute;");
+        initialMap.put("\u223D\u0331", "&race;");
+        initialMap.put("\u21DB", "&rAarr;");
+        initialMap.put("\"", "&QUOT");
+        initialMap.put("\"", "&QUOT;");
+        initialMap.put("\"", "&quot");
+        initialMap.put("\"", "&quot;");
+        initialMap.put("\u225F", "&questeq;");
+        initialMap.put("\u003F", "&quest;");
+        initialMap.put("\u2A16", "&quatint;");
+        initialMap.put("\u210D", "&quaternions;");
+        initialMap.put("\uD835\uDCC6", "&qscr;");
+        initialMap.put("\uD835\uDCAC", "&Qscr;");
+        initialMap.put("\u2057", "&qprime;");
+        initialMap.put("\u211A", "&Qopf;");
+        initialMap.put("\uD835\uDD62", "&qopf;");
+        initialMap.put("\u2A0C", "&qint;");
+        initialMap.put("\uD835\uDD2E", "&qfr;");
+        initialMap.put("\uD835\uDD14", "&Qfr;");
+        initialMap.put("\u2008", "&puncsp;");
+        initialMap.put("\u03C8", "&psi;");
+        initialMap.put("\u03A8", "&Psi;");
+        initialMap.put("\uD835\uDCC5", "&pscr;");
+        initialMap.put("\uD835\uDCAB", "&Pscr;");
+        initialMap.put("\u22B0", "&prurel;");
+        initialMap.put("\u227E", "&prsim;");
+        initialMap.put("\u221D", "&propto;");
+        initialMap.put("\u2237", "&Proportion;");
+        initialMap.put("\u221D", "&Proportional;");
+        initialMap.put("\u221D", "&prop;");
+        initialMap.put("\u2313", "&profsurf;");
+        initialMap.put("\u2312", "&profline;");
+        initialMap.put("\u232E", "&profalar;");
+        initialMap.put("\u220F", "&Product;");
+        initialMap.put("\u220F", "&prod;");
+        initialMap.put("\u22E8", "&prnsim;");
+        initialMap.put("\u2AB5", "&prnE;");
+        initialMap.put("\u2AB9", "&prnap;");
+        initialMap.put("\u2119", "&primes;");
+        initialMap.put("\u2033", "&Prime;");
+        initialMap.put("\u2032", "&prime;");
+        initialMap.put("\u227E", "&precsim;");
+        initialMap.put("\u2AB3", "&prE;");
+        initialMap.put("\u2AAF", "&pre;");
+        initialMap.put("\u22E8", "&precnsim;");
+        initialMap.put("\u2AB5", "&precneqq;");
+        initialMap.put("\u2AB9", "&precnapprox;");
+        initialMap.put("\u2AAF", "&preceq;");
+        initialMap.put("\u227E", "&PrecedesTilde;");
+        initialMap.put("\u227C", "&PrecedesSlantEqual;");
+        initialMap.put("\u2AAF", "&PrecedesEqual;");
+        initialMap.put("\u227A", "&Precedes;");
+        initialMap.put("\u227C", "&preccurlyeq;");
+        initialMap.put("\u227A", "&prec;");
+        initialMap.put("\u2AB7", "&precapprox;");
+        initialMap.put("\u227C", "&prcue;");
+        initialMap.put("\u227A", "&pr;");
+        initialMap.put("\u2ABB", "&Pr;");
+        initialMap.put("\u2AB7", "&prap;");
+        initialMap.put("\u00A3", "&pound");
+        initialMap.put("\u00A3", "&pound;");
+        initialMap.put("\u2119", "&Popf;");
+        initialMap.put("\uD835\uDD61", "&popf;");
+        initialMap.put("\u2A15", "&pointint;");
+        initialMap.put("\u210C", "&Poincareplane;");
+        initialMap.put("\u00B1", "&pm;");
+        initialMap.put("\u2A27", "&plustwo;");
+        initialMap.put("\u2A26", "&plussim;");
+        initialMap.put("\u00B1", "&plusmn");
+        initialMap.put("\u00B1", "&plusmn;");
+        initialMap.put("\u00B1", "&PlusMinus;");
+        initialMap.put("\u2A72", "&pluse;");
+        initialMap.put("\u2A25", "&plusdu;");
+        initialMap.put("\u2214", "&plusdo;");
+        initialMap.put("\u002B", "&plus;");
+        initialMap.put("\u2A22", "&pluscir;");
+        initialMap.put("\u229E", "&plusb;");
+        initialMap.put("\u2A23", "&plusacir;");
+        initialMap.put("\u210F", "&plankv;");
+        initialMap.put("\u210E", "&planckh;");
+        initialMap.put("\u210F", "&planck;");
+        initialMap.put("\u03D6", "&piv;");
+        initialMap.put("\u22D4", "&pitchfork;");
+        initialMap.put("\u03C0", "&pi;");
+        initialMap.put("\u03A0", "&Pi;");
+        initialMap.put("\u260E", "&phone;");
+        initialMap.put("\u2133", "&phmmat;");
+        initialMap.put("\u03D5", "&phiv;");
+        initialMap.put("\u03C6", "&phi;");
+        initialMap.put("\u03A6", "&Phi;");
+        initialMap.put("\uD835\uDD2D", "&pfr;");
+        initialMap.put("\uD835\uDD13", "&Pfr;");
+        initialMap.put("\u2031", "&pertenk;");
+        initialMap.put("\u22A5", "&perp;");
+        initialMap.put("\u2030", "&permil;");
+        initialMap.put("\u002E", "&period;");
+        initialMap.put("\u0025", "&percnt;");
+        initialMap.put("\u043F", "&pcy;");
+        initialMap.put("\u041F", "&Pcy;");
+        initialMap.put("\u2202", "&PartialD;");
+        initialMap.put("\u2202", "&part;");
+        initialMap.put("\u2AFD", "&parsl;");
+        initialMap.put("\u2AF3", "&parsim;");
+        initialMap.put("\u2225", "&par;");
+        initialMap.put("\u2225", "&parallel;");
+        initialMap.put("\u00B6", "&para");
+        initialMap.put("\u00B6", "&para;");
+        initialMap.put("\u23DC", "&OverParenthesis;");
+        initialMap.put("\u23B4", "&OverBracket;");
+        initialMap.put("\u23DE", "&OverBrace;");
+        initialMap.put("\u203E", "&OverBar;");
+        initialMap.put("\u233D", "&ovbar;");
+        initialMap.put("\u00F6", "&ouml");
+        initialMap.put("\u00F6", "&ouml;");
+        initialMap.put("\u00D6", "&Ouml");
+        initialMap.put("\u00D6", "&Ouml;");
+        initialMap.put("\u2297", "&otimes;");
+        initialMap.put("\u2A37", "&Otimes;");
+        initialMap.put("\u2A36", "&otimesas;");
+        initialMap.put("\u00F5", "&otilde");
+        initialMap.put("\u00F5", "&otilde;");
+        initialMap.put("\u00D5", "&Otilde");
+        initialMap.put("\u00D5", "&Otilde;");
+        initialMap.put("\u2298", "&osol;");
+        initialMap.put("\u00F8", "&oslash");
+        initialMap.put("\u00F8", "&oslash;");
+        initialMap.put("\u00D8", "&Oslash");
+        initialMap.put("\u00D8", "&Oslash;");
+        initialMap.put("\u2134", "&oscr;");
+        initialMap.put("\uD835\uDCAA", "&Oscr;");
+        initialMap.put("\u24C8", "&oS;");
+        initialMap.put("\u2A5B", "&orv;");
+        initialMap.put("\u2A57", "&orslope;");
+        initialMap.put("\u2A56", "&oror;");
+        initialMap.put("\u22B6", "&origof;");
+        initialMap.put("\u00BA", "&ordm");
+        initialMap.put("\u00BA", "&ordm;");
+        initialMap.put("\u00AA", "&ordf");
+        initialMap.put("\u00AA", "&ordf;");
+        initialMap.put("\u2134", "&orderof;");
+        initialMap.put("\u2134", "&order;");
+        initialMap.put("\u2A5D", "&ord;");
+        initialMap.put("\u2228", "&or;");
+        initialMap.put("\u2A54", "&Or;");
+        initialMap.put("\u21BB", "&orarr;");
+        initialMap.put("\u2295", "&oplus;");
+        initialMap.put("\u29B9", "&operp;");
+        initialMap.put("\u2018", "&OpenCurlyQuote;");
+        initialMap.put("\u201C", "&OpenCurlyDoubleQuote;");
+        initialMap.put("\u29B7", "&opar;");
+        initialMap.put("\uD835\uDD60", "&oopf;");
+        initialMap.put("\uD835\uDD46", "&Oopf;");
+        initialMap.put("\u2296", "&ominus;");
+        initialMap.put("\u29B6", "&omid;");
+        initialMap.put("\u03BF", "&omicron;");
+        initialMap.put("\u039F", "&Omicron;");
+        initialMap.put("\u03C9", "&omega;");
+        initialMap.put("\u03A9", "&Omega;");
+        initialMap.put("\u014D", "&omacr;");
+        initialMap.put("\u014C", "&Omacr;");
+        initialMap.put("\u29C0", "&olt;");
+        initialMap.put("\u203E", "&oline;");
+        initialMap.put("\u29BB", "&olcross;");
+        initialMap.put("\u29BE", "&olcir;");
+        initialMap.put("\u21BA", "&olarr;");
+        initialMap.put("\u222E", "&oint;");
+        initialMap.put("\u03A9", "&ohm;");
+        initialMap.put("\u29B5", "&ohbar;");
+        initialMap.put("\u29C1", "&ogt;");
+        initialMap.put("\u00F2", "&ograve");
+        initialMap.put("\u00F2", "&ograve;");
+        initialMap.put("\u00D2", "&Ograve");
+        initialMap.put("\u00D2", "&Ograve;");
+        initialMap.put("\u02DB", "&ogon;");
+        initialMap.put("\uD835\uDD2C", "&ofr;");
+        initialMap.put("\uD835\uDD12", "&Ofr;");
+        initialMap.put("\u29BF", "&ofcir;");
+        initialMap.put("\u0153", "&oelig;");
+        initialMap.put("\u0152", "&OElig;");
+        initialMap.put("\u29BC", "&odsold;");
+        initialMap.put("\u2299", "&odot;");
+        initialMap.put("\u2A38", "&odiv;");
+        initialMap.put("\u0151", "&odblac;");
+        initialMap.put("\u0150", "&Odblac;");
+        initialMap.put("\u229D", "&odash;");
+        initialMap.put("\u043E", "&ocy;");
+        initialMap.put("\u041E", "&Ocy;");
+        initialMap.put("\u229A", "&ocir;");
+        initialMap.put("\u00F4", "&ocirc");
+        initialMap.put("\u00F4", "&ocirc;");
+        initialMap.put("\u00D4", "&Ocirc");
+        initialMap.put("\u00D4", "&Ocirc;");
+        initialMap.put("\u229B", "&oast;");
+        initialMap.put("\u00F3", "&oacute");
+        initialMap.put("\u00F3", "&oacute;");
+        initialMap.put("\u00D3", "&Oacute");
+        initialMap.put("\u00D3", "&Oacute;");
+        initialMap.put("\u2927", "&nwnear;");
+        initialMap.put("\u2196", "&nwarrow;");
+        initialMap.put("\u21D6", "&nwArr;");
+        initialMap.put("\u2196", "&nwarr;");
+        initialMap.put("\u2923", "&nwarhk;");
+        initialMap.put("\u223C\u20D2", "&nvsim;");
+        initialMap.put("\u22B5\u20D2", "&nvrtrie;");
+        initialMap.put("\u2903", "&nvrArr;");
+        initialMap.put("\u22B4\u20D2", "&nvltrie;");
+        initialMap.put("\u003C\u20D2", "&nvlt;");
+        initialMap.put("\u2264\u20D2", "&nvle;");
+        initialMap.put("\u2902", "&nvlArr;");
+        initialMap.put("\u29DE", "&nvinfin;");
+        initialMap.put("\u2904", "&nvHarr;");
+        initialMap.put("\u003E\u20D2", "&nvgt;");
+        initialMap.put("\u2265\u20D2", "&nvge;");
+        initialMap.put("\u22AF", "&nVDash;");
+        initialMap.put("\u22AE", "&nVdash;");
+        initialMap.put("\u22AD", "&nvDash;");
+        initialMap.put("\u22AC", "&nvdash;");
+        initialMap.put("\u224D\u20D2", "&nvap;");
+        initialMap.put("\u2007", "&numsp;");
+        initialMap.put("\u2116", "&numero;");
+        initialMap.put("\u0023", "&num;");
+        initialMap.put("\u03BD", "&nu;");
+        initialMap.put("\u039D", "&Nu;");
+        initialMap.put("\u22ED", "&ntrianglerighteq;");
+        initialMap.put("\u22EB", "&ntriangleright;");
+        initialMap.put("\u22EC", "&ntrianglelefteq;");
+        initialMap.put("\u22EA", "&ntriangleleft;");
+        initialMap.put("\u2278", "&ntlg;");
+        initialMap.put("\u00F1", "&ntilde");
+        initialMap.put("\u00F1", "&ntilde;");
+        initialMap.put("\u00D1", "&Ntilde");
+        initialMap.put("\u00D1", "&Ntilde;");
+        initialMap.put("\u2279", "&ntgl;");
+        initialMap.put("\u2AC6\u0338", "&nsupseteqq;");
+        initialMap.put("\u2289", "&nsupseteq;");
+        initialMap.put("\u2283\u20D2", "&nsupset;");
+        initialMap.put("\u2289", "&nsupe;");
+        initialMap.put("\u2AC6\u0338", "&nsupE;");
+        initialMap.put("\u2285", "&nsup;");
+        initialMap.put("\u2AB0\u0338", "&nsucceq;");
+        initialMap.put("\u2281", "&nsucc;");
+        initialMap.put("\u2AC5\u0338", "&nsubseteqq;");
+        initialMap.put("\u2288", "&nsubseteq;");
+        initialMap.put("\u2282\u20D2", "&nsubset;");
+        initialMap.put("\u2288", "&nsube;");
+        initialMap.put("\u2AC5\u0338", "&nsubE;");
+        initialMap.put("\u2284", "&nsub;");
+        initialMap.put("\u22E3", "&nsqsupe;");
+        initialMap.put("\u22E2", "&nsqsube;");
+        initialMap.put("\u2226", "&nspar;");
+        initialMap.put("\u2224", "&nsmid;");
+        initialMap.put("\u2244", "&nsimeq;");
+        initialMap.put("\u2244", "&nsime;");
+        initialMap.put("\u2241", "&nsim;");
+        initialMap.put("\u2226", "&nshortparallel;");
+        initialMap.put("\u2224", "&nshortmid;");
+        initialMap.put("\uD835\uDCC3", "&nscr;");
+        initialMap.put("\uD835\uDCA9", "&Nscr;");
+        initialMap.put("\u2AB0\u0338", "&nsce;");
+        initialMap.put("\u22E1", "&nsccue;");
+        initialMap.put("\u2281", "&nsc;");
+        initialMap.put("\u22ED", "&nrtrie;");
+        initialMap.put("\u22EB", "&nrtri;");
+        initialMap.put("\u21CF", "&nRightarrow;");
+        initialMap.put("\u219B", "&nrightarrow;");
+        initialMap.put("\u219D\u0338", "&nrarrw;");
+        initialMap.put("\u21CF", "&nrArr;");
+        initialMap.put("\u219B", "&nrarr;");
+        initialMap.put("\u2933\u0338", "&nrarrc;");
+        initialMap.put("\u2AAF\u0338", "&npre;");
+        initialMap.put("\u2AAF\u0338", "&npreceq;");
+        initialMap.put("\u2280", "&nprec;");
+        initialMap.put("\u22E0", "&nprcue;");
+        initialMap.put("\u2280", "&npr;");
+        initialMap.put("\u2A14", "&npolint;");
+        initialMap.put("\u2202\u0338", "&npart;");
+        initialMap.put("\u2AFD\u20E5", "&nparsl;");
+        initialMap.put("\u2226", "&npar;");
+        initialMap.put("\u2226", "&nparallel;");
+        initialMap.put("\u2224", "&NotVerticalBar;");
+        initialMap.put("\u2249", "&NotTildeTilde;");
+        initialMap.put("\u2247", "&NotTildeFullEqual;");
+        initialMap.put("\u2244", "&NotTildeEqual;");
+        initialMap.put("\u2241", "&NotTilde;");
+        initialMap.put("\u2289", "&NotSupersetEqual;");
+        initialMap.put("\u2283\u20D2", "&NotSuperset;");
+        initialMap.put("\u227F\u0338", "&NotSucceedsTilde;");
+        initialMap.put("\u22E1", "&NotSucceedsSlantEqual;");
+        initialMap.put("\u2AB0\u0338", "&NotSucceedsEqual;");
+        initialMap.put("\u2281", "&NotSucceeds;");
+        initialMap.put("\u2288", "&NotSubsetEqual;");
+        initialMap.put("\u2282\u20D2", "&NotSubset;");
+        initialMap.put("\u22E3", "&NotSquareSupersetEqual;");
+        initialMap.put("\u2290\u0338", "&NotSquareSuperset;");
+        initialMap.put("\u22E2", "&NotSquareSubsetEqual;");
+        initialMap.put("\u228F\u0338", "&NotSquareSubset;");
+        initialMap.put("\u22ED", "&NotRightTriangleEqual;");
+        initialMap.put("\u22EB", "&NotRightTriangle;");
+        initialMap.put("\u29D0\u0338", "&NotRightTriangleBar;");
+        initialMap.put("\u220C", "&NotReverseElement;");
+        initialMap.put("\u22E0", "&NotPrecedesSlantEqual;");
+        initialMap.put("\u2AAF\u0338", "&NotPrecedesEqual;");
+        initialMap.put("\u2280", "&NotPrecedes;");
+        initialMap.put("\u22FD", "&notnivc;");
+        initialMap.put("\u22FE", "&notnivb;");
+        initialMap.put("\u220C", "&notniva;");
+        initialMap.put("\u220C", "&notni;");
+        initialMap.put("\u2AA1\u0338", "&NotNestedLessLess;");
+        initialMap.put("\u2AA2\u0338", "&NotNestedGreaterGreater;");
+        initialMap.put("\u2274", "&NotLessTilde;");
+        initialMap.put("\u2A7D\u0338", "&NotLessSlantEqual;");
+        initialMap.put("\u226A\u0338", "&NotLessLess;");
+        initialMap.put("\u2278", "&NotLessGreater;");
+        initialMap.put("\u2270", "&NotLessEqual;");
+        initialMap.put("\u226E", "&NotLess;");
+        initialMap.put("\u22EC", "&NotLeftTriangleEqual;");
+        initialMap.put("\u22EA", "&NotLeftTriangle;");
+        initialMap.put("\u29CF\u0338", "&NotLeftTriangleBar;");
+        initialMap.put("\u22F6", "&notinvc;");
+        initialMap.put("\u22F7", "&notinvb;");
+        initialMap.put("\u2209", "&notinva;");
+        initialMap.put("\u22F9\u0338", "&notinE;");
+        initialMap.put("\u22F5\u0338", "&notindot;");
+        initialMap.put("\u2209", "&notin;");
+        initialMap.put("\u224F\u0338", "&NotHumpEqual;");
+        initialMap.put("\u224E\u0338", "&NotHumpDownHump;");
+        initialMap.put("\u2275", "&NotGreaterTilde;");
+        initialMap.put("\u2A7E\u0338", "&NotGreaterSlantEqual;");
+        initialMap.put("\u2279", "&NotGreaterLess;");
+        initialMap.put("\u226B\u0338", "&NotGreaterGreater;");
+        initialMap.put("\u2267\u0338", "&NotGreaterFullEqual;");
+        initialMap.put("\u2271", "&NotGreaterEqual;");
+        initialMap.put("\u226F", "&NotGreater;");
+        initialMap.put("\u2204", "&NotExists;");
+        initialMap.put("\u2242\u0338", "&NotEqualTilde;");
+        initialMap.put("\u2260", "&NotEqual;");
+        initialMap.put("\u2209", "&NotElement;");
+        initialMap.put("\u2226", "&NotDoubleVerticalBar;");
+        initialMap.put("\u226D", "&NotCupCap;");
+        initialMap.put("\u2262", "&NotCongruent;");
+        initialMap.put("\u00AC", "&not");
+        initialMap.put("\u00AC", "&not;");
+        initialMap.put("\u2AEC", "&Not;");
+        initialMap.put("\u2115", "&Nopf;");
+        initialMap.put("\uD835\uDD5F", "&nopf;");
+        initialMap.put("\u00A0", "&NonBreakingSpace;");
+        initialMap.put("\u2060", "&NoBreak;");
+        initialMap.put("\u2224", "&nmid;");
+        initialMap.put("\u226A\u0338", "&nLtv;");
+        initialMap.put("\u22EC", "&nltrie;");
+        initialMap.put("\u22EA", "&nltri;");
+        initialMap.put("\u226E", "&nlt;");
+        initialMap.put("\u226A\u20D2", "&nLt;");
+        initialMap.put("\u2274", "&nlsim;");
+        initialMap.put("\u22D8\u0338", "&nLl;");
+        initialMap.put("\u226E", "&nless;");
+        initialMap.put("\u2A7D\u0338", "&nles;");
+        initialMap.put("\u2A7D\u0338", "&nleqslant;");
+        initialMap.put("\u2266\u0338", "&nleqq;");
+        initialMap.put("\u2270", "&nleq;");
+        initialMap.put("\u21CE", "&nLeftrightarrow;");
+        initialMap.put("\u21AE", "&nleftrightarrow;");
+        initialMap.put("\u21CD", "&nLeftarrow;");
+        initialMap.put("\u219A", "&nleftarrow;");
+        initialMap.put("\u2270", "&nle;");
+        initialMap.put("\u2266\u0338", "&nlE;");
+        initialMap.put("\u2025", "&nldr;");
+        initialMap.put("\u21CD", "&nlArr;");
+        initialMap.put("\u219A", "&nlarr;");
+        initialMap.put("\u045A", "&njcy;");
+        initialMap.put("\u040A", "&NJcy;");
+        initialMap.put("\u220B", "&niv;");
+        initialMap.put("\u22FA", "&nisd;");
+        initialMap.put("\u22FC", "&nis;");
+        initialMap.put("\u220B", "&ni;");
+        initialMap.put("\u2AF2", "&nhpar;");
+        initialMap.put("\u21CE", "&nhArr;");
+        initialMap.put("\u21AE", "&nharr;");
+        initialMap.put("\u226B\u0338", "&nGtv;");
+        initialMap.put("\u226F", "&ngtr;");
+        initialMap.put("\u226F", "&ngt;");
+        initialMap.put("\u226B\u20D2", "&nGt;");
+        initialMap.put("\u2275", "&ngsim;");
+        initialMap.put("\u22D9\u0338", "&nGg;");
+        initialMap.put("\u2A7E\u0338", "&nges;");
+        initialMap.put("\u2A7E\u0338", "&ngeqslant;");
+        initialMap.put("\u2267\u0338", "&ngeqq;");
+        initialMap.put("\u2271", "&ngeq;");
+        initialMap.put("\u2271", "&nge;");
+        initialMap.put("\u2267\u0338", "&ngE;");
+        initialMap.put("\uD835\uDD2B", "&nfr;");
+        initialMap.put("\uD835\uDD11", "&Nfr;");
+        initialMap.put("\u2204", "&nexists;");
+        initialMap.put("\u2204", "&nexist;");
+        initialMap.put("\n", "&NewLine;");
+        initialMap.put("\u226A", "&NestedLessLess;");
+        initialMap.put("\u226B", "&NestedGreaterGreater;");
+        initialMap.put("\u2242\u0338", "&nesim;");
+        initialMap.put("\u2928", "&nesear;");
+        initialMap.put("\u2262", "&nequiv;");
+        initialMap.put("\u200B", "&NegativeVeryThinSpace;");
+        initialMap.put("\u200B", "&NegativeThinSpace;");
+        initialMap.put("\u200B", "&NegativeThickSpace;");
+        initialMap.put("\u200B", "&NegativeMediumSpace;");
+        initialMap.put("\u2250\u0338", "&nedot;");
+        initialMap.put("\u2260", "&ne;");
+        initialMap.put("\u2197", "&nearrow;");
+        initialMap.put("\u21D7", "&neArr;");
+        initialMap.put("\u2197", "&nearr;");
+        initialMap.put("\u2924", "&nearhk;");
+        initialMap.put("\u2013", "&ndash;");
+        initialMap.put("\u043D", "&ncy;");
+        initialMap.put("\u041D", "&Ncy;");
+        initialMap.put("\u2A42", "&ncup;");
+        initialMap.put("\u2A6D\u0338", "&ncongdot;");
+        initialMap.put("\u2247", "&ncong;");
+        initialMap.put("\u0146", "&ncedil;");
+        initialMap.put("\u0145", "&Ncedil;");
+        initialMap.put("\u0148", "&ncaron;");
+        initialMap.put("\u0147", "&Ncaron;");
+        initialMap.put("\u2A43", "&ncap;");
+        initialMap.put("\u224F\u0338", "&nbumpe;");
+        initialMap.put("\u224E\u0338", "&nbump;");
+        initialMap.put("\u00A0", "&nbsp");
+        initialMap.put("\u00A0", "&nbsp;");
+        initialMap.put("\u266E", "&natur;");
+        initialMap.put("\u2115", "&naturals;");
+        initialMap.put("\u266E", "&natural;");
+        initialMap.put("\u2249", "&napprox;");
+        initialMap.put("\u0149", "&napos;");
+        initialMap.put("\u224B\u0338", "&napid;");
+        initialMap.put("\u2A70\u0338", "&napE;");
+        initialMap.put("\u2249", "&nap;");
+        initialMap.put("\u2220\u20D2", "&nang;");
+        initialMap.put("\u0144", "&nacute;");
+        initialMap.put("\u0143", "&Nacute;");
+        initialMap.put("\u2207", "&nabla;");
+        initialMap.put("\u22B8", "&mumap;");
+        initialMap.put("\u22B8", "&multimap;");
+        initialMap.put("\u03BC", "&mu;");
+        initialMap.put("\u039C", "&Mu;");
+        initialMap.put("\u223E", "&mstpos;");
+        initialMap.put("\u2133", "&Mscr;");
+        initialMap.put("\uD835\uDCC2", "&mscr;");
+        initialMap.put("\u2213", "&mp;");
+        initialMap.put("\uD835\uDD5E", "&mopf;");
+        initialMap.put("\uD835\uDD44", "&Mopf;");
+        initialMap.put("\u22A7", "&models;");
+        initialMap.put("\u2213", "&mnplus;");
+        initialMap.put("\u2026", "&mldr;");
+        initialMap.put("\u2ADB", "&mlcp;");
+        initialMap.put("\u2213", "&MinusPlus;");
+        initialMap.put("\u2A2A", "&minusdu;");
+        initialMap.put("\u2238", "&minusd;");
+        initialMap.put("\u2212", "&minus;");
+        initialMap.put("\u229F", "&minusb;");
+        initialMap.put("\u00B7", "&middot");
+        initialMap.put("\u00B7", "&middot;");
+        initialMap.put("\u2223", "&mid;");
+        initialMap.put("\u2AF0", "&midcir;");
+        initialMap.put("\u002A", "&midast;");
+        initialMap.put("\u00B5", "&micro");
+        initialMap.put("\u00B5", "&micro;");
+        initialMap.put("\u2127", "&mho;");
+        initialMap.put("\uD835\uDD2A", "&mfr;");
+        initialMap.put("\uD835\uDD10", "&Mfr;");
+        initialMap.put("\u2133", "&Mellintrf;");
+        initialMap.put("\u205F", "&MediumSpace;");
+        initialMap.put("\u2221", "&measuredangle;");
+        initialMap.put("\u223A", "&mDDot;");
+        initialMap.put("\u2014", "&mdash;");
+        initialMap.put("\u043C", "&mcy;");
+        initialMap.put("\u041C", "&Mcy;");
+        initialMap.put("\u2A29", "&mcomma;");
+        initialMap.put("\u25AE", "&marker;");
+        initialMap.put("\u21A5", "&mapstoup;");
+        initialMap.put("\u21A4", "&mapstoleft;");
+        initialMap.put("\u21A7", "&mapstodown;");
+        initialMap.put("\u21A6", "&mapsto;");
+        initialMap.put("\u21A6", "&map;");
+        initialMap.put("\u2905", "&Map;");
+        initialMap.put("\u2720", "&maltese;");
+        initialMap.put("\u2720", "&malt;");
+        initialMap.put("\u2642", "&male;");
+        initialMap.put("\u00AF", "&macr");
+        initialMap.put("\u00AF", "&macr;");
+        initialMap.put("\u2268\uFE00", "&lvnE;");
+        initialMap.put("\u2268\uFE00", "&lvertneqq;");
+        initialMap.put("\u2966", "&luruhar;");
+        initialMap.put("\u294A", "&lurdshar;");
+        initialMap.put("\u2996", "&ltrPar;");
+        initialMap.put("\u25C2", "&ltrif;");
+        initialMap.put("\u22B4", "&ltrie;");
+        initialMap.put("\u25C3", "&ltri;");
+        initialMap.put("\u2A7B", "&ltquest;");
+        initialMap.put("\u2976", "&ltlarr;");
+        initialMap.put("\u22C9", "&ltimes;");
+        initialMap.put("\u22CB", "&lthree;");
+        initialMap.put("\u22D6", "&ltdot;");
+        initialMap.put("\u226A", "&Lt;");
+        initialMap.put("\u003C", "&LT");
+        initialMap.put("\u003C", "&LT;");
+        initialMap.put("\u003C", "&lt");
+        initialMap.put("\u003C", "&lt;");
+        initialMap.put("\u2A79", "&ltcir;");
+        initialMap.put("\u2AA6", "&ltcc;");
+        initialMap.put("\u0142", "&lstrok;");
+        initialMap.put("\u0141", "&Lstrok;");
+        initialMap.put("\u201A", "&lsquor;");
+        initialMap.put("\u2018", "&lsquo;");
+        initialMap.put("\u005B", "&lsqb;");
+        initialMap.put("\u2A8F", "&lsimg;");
+        initialMap.put("\u2A8D", "&lsime;");
+        initialMap.put("\u2272", "&lsim;");
+        initialMap.put("\u21B0", "&Lsh;");
+        initialMap.put("\u21B0", "&lsh;");
+        initialMap.put("\u2112", "&Lscr;");
+        initialMap.put("\uD835\uDCC1", "&lscr;");
+        initialMap.put("\u2039", "&lsaquo;");
+        initialMap.put("\u22BF", "&lrtri;");
+        initialMap.put("\u200E", "&lrm;");
+        initialMap.put("\u296D", "&lrhard;");
+        initialMap.put("\u21CB", "&lrhar;");
+        initialMap.put("\u231F", "&lrcorner;");
+        initialMap.put("\u21C6", "&lrarr;");
+        initialMap.put("\u2993", "&lparlt;");
+        initialMap.put("\u0028", "&lpar;");
+        initialMap.put("\u29EB", "&lozf;");
+        initialMap.put("\u25CA", "&lozenge;");
+        initialMap.put("\u25CA", "&loz;");
+        initialMap.put("\u2198", "&LowerRightArrow;");
+        initialMap.put("\u2199", "&LowerLeftArrow;");
+        initialMap.put("\u005F", "&lowbar;");
+        initialMap.put("\u2217", "&lowast;");
+        initialMap.put("\u2A34", "&lotimes;");
+        initialMap.put("\u2A2D", "&loplus;");
+        initialMap.put("\uD835\uDD5D", "&lopf;");
+        initialMap.put("\uD835\uDD43", "&Lopf;");
+        initialMap.put("\u2985", "&lopar;");
+        initialMap.put("\u21AC", "&looparrowright;");
+        initialMap.put("\u21AB", "&looparrowleft;");
+        initialMap.put("\u27F9", "&Longrightarrow;");
+        initialMap.put("\u27F6", "&LongRightArrow;");
+        initialMap.put("\u27F6", "&longrightarrow;");
+        initialMap.put("\u27FC", "&longmapsto;");
+        initialMap.put("\u27FA", "&Longleftrightarrow;");
+        initialMap.put("\u27F7", "&LongLeftRightArrow;");
+        initialMap.put("\u27F7", "&longleftrightarrow;");
+        initialMap.put("\u27F8", "&Longleftarrow;");
+        initialMap.put("\u27F5", "&LongLeftArrow;");
+        initialMap.put("\u27F5", "&longleftarrow;");
+        initialMap.put("\u27E6", "&lobrk;");
+        initialMap.put("\u21FD", "&loarr;");
+        initialMap.put("\u27EC", "&loang;");
+        initialMap.put("\u22E6", "&lnsim;");
+        initialMap.put("\u2268", "&lneqq;");
+        initialMap.put("\u2A87", "&lneq;");
+        initialMap.put("\u2268", "&lnE;");
+        initialMap.put("\u2A87", "&lne;");
+        initialMap.put("\u2A89", "&lnapprox;");
+        initialMap.put("\u2A89", "&lnap;");
+        initialMap.put("\u23B0", "&lmoust;");
+        initialMap.put("\u23B0", "&lmoustache;");
+        initialMap.put("\u0140", "&lmidot;");
+        initialMap.put("\u013F", "&Lmidot;");
+        initialMap.put("\u25FA", "&lltri;");
+        initialMap.put("\u296B", "&llhard;");
+        initialMap.put("\u21DA", "&Lleftarrow;");
+        initialMap.put("\u231E", "&llcorner;");
+        initialMap.put("\u22D8", "&Ll;");
+        initialMap.put("\u226A", "&ll;");
+        initialMap.put("\u21C7", "&llarr;");
+        initialMap.put("\u0459", "&ljcy;");
+        initialMap.put("\u0409", "&LJcy;");
+        initialMap.put("\u2584", "&lhblk;");
+        initialMap.put("\u296A", "&lharul;");
+        initialMap.put("\u21BC", "&lharu;");
+        initialMap.put("\u21BD", "&lhard;");
+        initialMap.put("\u2962", "&lHar;");
+        initialMap.put("\u2A91", "&lgE;");
+        initialMap.put("\u2276", "&lg;");
+        initialMap.put("\uD835\uDD29", "&lfr;");
+        initialMap.put("\uD835\uDD0F", "&Lfr;");
+        initialMap.put("\u230A", "&lfloor;");
+        initialMap.put("\u297C", "&lfisht;");
+        initialMap.put("\u2272", "&LessTilde;");
+        initialMap.put("\u2A7D", "&LessSlantEqual;");
+        initialMap.put("\u2272", "&lesssim;");
+        initialMap.put("\u2AA1", "&LessLess;");
+        initialMap.put("\u2276", "&lessgtr;");
+        initialMap.put("\u2276", "&LessGreater;");
+        initialMap.put("\u2266", "&LessFullEqual;");
+        initialMap.put("\u22DA", "&LessEqualGreater;");
+        initialMap.put("\u2A8B", "&lesseqqgtr;");
+        initialMap.put("\u22DA", "&lesseqgtr;");
+        initialMap.put("\u22D6", "&lessdot;");
+        initialMap.put("\u2A85", "&lessapprox;");
+        initialMap.put("\u2A93", "&lesges;");
+        initialMap.put("\u22DA\uFE00", "&lesg;");
+        initialMap.put("\u2A83", "&lesdotor;");
+        initialMap.put("\u2A81", "&lesdoto;");
+        initialMap.put("\u2A7F", "&lesdot;");
+        initialMap.put("\u2A7D", "&les;");
+        initialMap.put("\u2AA8", "&lescc;");
+        initialMap.put("\u2A7D", "&leqslant;");
+        initialMap.put("\u2266", "&leqq;");
+        initialMap.put("\u2264", "&leq;");
+        initialMap.put("\u22DA", "&leg;");
+        initialMap.put("\u2A8B", "&lEg;");
+        initialMap.put("\u21BC", "&LeftVector;");
+        initialMap.put("\u2952", "&LeftVectorBar;");
+        initialMap.put("\u21BF", "&LeftUpVector;");
+        initialMap.put("\u2958", "&LeftUpVectorBar;");
+        initialMap.put("\u2960", "&LeftUpTeeVector;");
+        initialMap.put("\u2951", "&LeftUpDownVector;");
+        initialMap.put("\u22B4", "&LeftTriangleEqual;");
+        initialMap.put("\u22B2", "&LeftTriangle;");
+        initialMap.put("\u29CF", "&LeftTriangleBar;");
+        initialMap.put("\u22CB", "&leftthreetimes;");
+        initialMap.put("\u295A", "&LeftTeeVector;");
+        initialMap.put("\u22A3", "&LeftTee;");
+        initialMap.put("\u21A4", "&LeftTeeArrow;");
+        initialMap.put("\u294E", "&LeftRightVector;");
+        initialMap.put("\u21AD", "&leftrightsquigarrow;");
+        initialMap.put("\u21CB", "&leftrightharpoons;");
+        initialMap.put("\u21C6", "&leftrightarrows;");
+        initialMap.put("\u21D4", "&Leftrightarrow;");
+        initialMap.put("\u2194", "&LeftRightArrow;");
+        initialMap.put("\u2194", "&leftrightarrow;");
+        initialMap.put("\u21C7", "&leftleftarrows;");
+        initialMap.put("\u21BC", "&leftharpoonup;");
+        initialMap.put("\u21BD", "&leftharpoondown;");
+        initialMap.put("\u230A", "&LeftFloor;");
+        initialMap.put("\u21C3", "&LeftDownVector;");
+        initialMap.put("\u2959", "&LeftDownVectorBar;");
+        initialMap.put("\u2961", "&LeftDownTeeVector;");
+        initialMap.put("\u27E6", "&LeftDoubleBracket;");
+        initialMap.put("\u2308", "&LeftCeiling;");
+        initialMap.put("\u21A2", "&leftarrowtail;");
+        initialMap.put("\u21C6", "&LeftArrowRightArrow;");
+        initialMap.put("\u21D0", "&Leftarrow;");
+        initialMap.put("\u2190", "&LeftArrow;");
+        initialMap.put("\u2190", "&leftarrow;");
+        initialMap.put("\u21E4", "&LeftArrowBar;");
+        initialMap.put("\u27E8", "&LeftAngleBracket;");
+        initialMap.put("\u2266", "&lE;");
+        initialMap.put("\u2264", "&le;");
+        initialMap.put("\u21B2", "&ldsh;");
+        initialMap.put("\u294B", "&ldrushar;");
+        initialMap.put("\u2967", "&ldrdhar;");
+        initialMap.put("\u201E", "&ldquor;");
+        initialMap.put("\u201C", "&ldquo;");
+        initialMap.put("\u2936", "&ldca;");
+        initialMap.put("\u043B", "&lcy;");
+        initialMap.put("\u041B", "&Lcy;");
+        initialMap.put("\u007B", "&lcub;");
+        initialMap.put("\u2308", "&lceil;");
+        initialMap.put("\u013C", "&lcedil;");
+        initialMap.put("\u013B", "&Lcedil;");
+        initialMap.put("\u013E", "&lcaron;");
+        initialMap.put("\u013D", "&Lcaron;");
+        initialMap.put("\u298D", "&lbrkslu;");
+        initialMap.put("\u298F", "&lbrksld;");
+        initialMap.put("\u298B", "&lbrke;");
+        initialMap.put("\u005B", "&lbrack;");
+        initialMap.put("\u007B", "&lbrace;");
+        initialMap.put("\u2772", "&lbbrk;");
+        initialMap.put("\u290E", "&lBarr;");
+        initialMap.put("\u290C", "&lbarr;");
+        initialMap.put("\u2AAD\uFE00", "&lates;");
+        initialMap.put("\u2AAD", "&late;");
+        initialMap.put("\u2AAB", "&lat;");
+        initialMap.put("\u291B", "&lAtail;");
+        initialMap.put("\u2919", "&latail;");
+        initialMap.put("\u21A2", "&larrtl;");
+        initialMap.put("\u2973", "&larrsim;");
+        initialMap.put("\u2939", "&larrpl;");
+        initialMap.put("\u21AB", "&larrlp;");
+        initialMap.put("\u21A9", "&larrhk;");
+        initialMap.put("\u291D", "&larrfs;");
+        initialMap.put("\u21D0", "&lArr;");
+        initialMap.put("\u219E", "&Larr;");
+        initialMap.put("\u2190", "&larr;");
+        initialMap.put("\u291F", "&larrbfs;");
+        initialMap.put("\u21E4", "&larrb;");
+        initialMap.put("\u00AB", "&laquo");
+        initialMap.put("\u00AB", "&laquo;");
+        initialMap.put("\u2112", "&Laplacetrf;");
+        initialMap.put("\u2A85", "&lap;");
+        initialMap.put("\u27E8", "&langle;");
+        initialMap.put("\u2991", "&langd;");
+        initialMap.put("\u27EA", "&Lang;");
+        initialMap.put("\u27E8", "&lang;");
+        initialMap.put("\u03BB", "&lambda;");
+        initialMap.put("\u039B", "&Lambda;");
+        initialMap.put("\u2112", "&lagran;");
+        initialMap.put("\u29B4", "&laemptyv;");
+        initialMap.put("\u013A", "&lacute;");
+        initialMap.put("\u0139", "&Lacute;");
+        initialMap.put("\u21DA", "&lAarr;");
+        initialMap.put("\uD835\uDCC0", "&kscr;");
+        initialMap.put("\uD835\uDCA6", "&Kscr;");
+        initialMap.put("\uD835\uDD5C", "&kopf;");
+        initialMap.put("\uD835\uDD42", "&Kopf;");
+        initialMap.put("\u045C", "&kjcy;");
+        initialMap.put("\u040C", "&KJcy;");
+        initialMap.put("\u0445", "&khcy;");
+        initialMap.put("\u0425", "&KHcy;");
+        initialMap.put("\u0138", "&kgreen;");
+        initialMap.put("\uD835\uDD28", "&kfr;");
+        initialMap.put("\uD835\uDD0E", "&Kfr;");
+        initialMap.put("\u043A", "&kcy;");
+        initialMap.put("\u041A", "&Kcy;");
+        initialMap.put("\u0137", "&kcedil;");
+        initialMap.put("\u0136", "&Kcedil;");
+        initialMap.put("\u03F0", "&kappav;");
+        initialMap.put("\u03BA", "&kappa;");
+        initialMap.put("\u039A", "&Kappa;");
+        initialMap.put("\u0454", "&jukcy;");
+        initialMap.put("\u0404", "&Jukcy;");
+        initialMap.put("\u0458", "&jsercy;");
+        initialMap.put("\u0408", "&Jsercy;");
+        initialMap.put("\uD835\uDCBF", "&jscr;");
+        initialMap.put("\uD835\uDCA5", "&Jscr;");
+        initialMap.put("\uD835\uDD5B", "&jopf;");
+        initialMap.put("\uD835\uDD41", "&Jopf;");
+        initialMap.put("\u0237", "&jmath;");
+        initialMap.put("\uD835\uDD27", "&jfr;");
+        initialMap.put("\uD835\uDD0D", "&Jfr;");
+        initialMap.put("\u0439", "&jcy;");
+        initialMap.put("\u0419", "&Jcy;");
+        initialMap.put("\u0135", "&jcirc;");
+        initialMap.put("\u0134", "&Jcirc;");
+        initialMap.put("\u00EF", "&iuml");
+        initialMap.put("\u00EF", "&iuml;");
+        initialMap.put("\u00CF", "&Iuml");
+        initialMap.put("\u00CF", "&Iuml;");
+        initialMap.put("\u0456", "&iukcy;");
+        initialMap.put("\u0406", "&Iukcy;");
+        initialMap.put("\u0129", "&itilde;");
+        initialMap.put("\u0128", "&Itilde;");
+        initialMap.put("\u2062", "&it;");
+        initialMap.put("\u2208", "&isinv;");
+        initialMap.put("\u22F3", "&isinsv;");
+        initialMap.put("\u22F4", "&isins;");
+        initialMap.put("\u22F9", "&isinE;");
+        initialMap.put("\u22F5", "&isindot;");
+        initialMap.put("\u2208", "&isin;");
+        initialMap.put("\u2110", "&Iscr;");
+        initialMap.put("\uD835\uDCBE", "&iscr;");
+        initialMap.put("\u00BF", "&iquest");
+        initialMap.put("\u00BF", "&iquest;");
+        initialMap.put("\u2A3C", "&iprod;");
+        initialMap.put("\u03B9", "&iota;");
+        initialMap.put("\u0399", "&Iota;");
+        initialMap.put("\uD835\uDD5A", "&iopf;");
+        initialMap.put("\uD835\uDD40", "&Iopf;");
+        initialMap.put("\u012F", "&iogon;");
+        initialMap.put("\u012E", "&Iogon;");
+        initialMap.put("\u0451", "&iocy;");
+        initialMap.put("\u0401", "&IOcy;");
+        initialMap.put("\u2062", "&InvisibleTimes;");
+        initialMap.put("\u2063", "&InvisibleComma;");
+        initialMap.put("\u2A3C", "&intprod;");
+        initialMap.put("\u2A17", "&intlarhk;");
+        initialMap.put("\u22C2", "&Intersection;");
+        initialMap.put("\u22BA", "&intercal;");
+        initialMap.put("\u222B", "&Integral;");
+        initialMap.put("\u2124", "&integers;");
+        initialMap.put("\u222C", "&Int;");
+        initialMap.put("\u222B", "&int;");
+        initialMap.put("\u22BA", "&intcal;");
+        initialMap.put("\u0131", "&inodot;");
+        initialMap.put("\u29DD", "&infintie;");
+        initialMap.put("\u221E", "&infin;");
+        initialMap.put("\u2208", "&in;");
+        initialMap.put("\u2105", "&incare;");
+        initialMap.put("\u21D2", "&Implies;");
+        initialMap.put("\u01B5", "&imped;");
+        initialMap.put("\u22B7", "&imof;");
+        initialMap.put("\u2111", "&Im;");
+        initialMap.put("\u0131", "&imath;");
+        initialMap.put("\u2111", "&imagpart;");
+        initialMap.put("\u2110", "&imagline;");
+        initialMap.put("\u2148", "&ImaginaryI;");
+        initialMap.put("\u2111", "&image;");
+        initialMap.put("\u012B", "&imacr;");
+        initialMap.put("\u012A", "&Imacr;");
+        initialMap.put("\u0133", "&ijlig;");
+        initialMap.put("\u0132", "&IJlig;");
+        initialMap.put("\u2129", "&iiota;");
+        initialMap.put("\u29DC", "&iinfin;");
+        initialMap.put("\u222D", "&iiint;");
+        initialMap.put("\u2A0C", "&iiiint;");
+        initialMap.put("\u2148", "&ii;");
+        initialMap.put("\u00EC", "&igrave");
+        initialMap.put("\u00EC", "&igrave;");
+        initialMap.put("\u00CC", "&Igrave");
+        initialMap.put("\u00CC", "&Igrave;");
+        initialMap.put("\u2111", "&Ifr;");
+        initialMap.put("\uD835\uDD26", "&ifr;");
+        initialMap.put("\u21D4", "&iff;");
+        initialMap.put("\u00A1", "&iexcl");
+        initialMap.put("\u00A1", "&iexcl;");
+        initialMap.put("\u0435", "&iecy;");
+        initialMap.put("\u0415", "&IEcy;");
+        initialMap.put("\u0130", "&Idot;");
+        initialMap.put("\u0438", "&icy;");
+        initialMap.put("\u0418", "&Icy;");
+        initialMap.put("\u00EE", "&icirc");
+        initialMap.put("\u00EE", "&icirc;");
+        initialMap.put("\u00CE", "&Icirc");
+        initialMap.put("\u00CE", "&Icirc;");
+        initialMap.put("\u2063", "&ic;");
+        initialMap.put("\u00ED", "&iacute");
+        initialMap.put("\u00ED", "&iacute;");
+        initialMap.put("\u00CD", "&Iacute");
+        initialMap.put("\u00CD", "&Iacute;");
+        initialMap.put("\u2010", "&hyphen;");
+        initialMap.put("\u2043", "&hybull;");
+        initialMap.put("\u224F", "&HumpEqual;");
+        initialMap.put("\u224E", "&HumpDownHump;");
+        initialMap.put("\u0127", "&hstrok;");
+        initialMap.put("\u0126", "&Hstrok;");
+        initialMap.put("\u210F", "&hslash;");
+        initialMap.put("\u210B", "&Hscr;");
+        initialMap.put("\uD835\uDCBD", "&hscr;");
+        initialMap.put("\u2500", "&HorizontalLine;");
+        initialMap.put("\u2015", "&horbar;");
+        initialMap.put("\u210D", "&Hopf;");
+        initialMap.put("\uD835\uDD59", "&hopf;");
+        initialMap.put("\u21AA", "&hookrightarrow;");
+        initialMap.put("\u21A9", "&hookleftarrow;");
+        initialMap.put("\u223B", "&homtht;");
+        initialMap.put("\u21FF", "&hoarr;");
+        initialMap.put("\u2926", "&hkswarow;");
+        initialMap.put("\u2925", "&hksearow;");
+        initialMap.put("\u210B", "&HilbertSpace;");
+        initialMap.put("\u210C", "&Hfr;");
+        initialMap.put("\uD835\uDD25", "&hfr;");
+        initialMap.put("\u22B9", "&hercon;");
+        initialMap.put("\u2026", "&hellip;");
+        initialMap.put("\u2665", "&heartsuit;");
+        initialMap.put("\u2665", "&hearts;");
+        initialMap.put("\u0125", "&hcirc;");
+        initialMap.put("\u0124", "&Hcirc;");
+        initialMap.put("\u210F", "&hbar;");
+        initialMap.put("\u005E", "&Hat;");
+        initialMap.put("\u21AD", "&harrw;");
+        initialMap.put("\u21D4", "&hArr;");
+        initialMap.put("\u2194", "&harr;");
+        initialMap.put("\u2948", "&harrcir;");
+        initialMap.put("\u044A", "&hardcy;");
+        initialMap.put("\u042A", "&HARDcy;");
+        initialMap.put("\u210B", "&hamilt;");
+        initialMap.put("\u00BD", "&half;");
+        initialMap.put("\u200A", "&hairsp;");
+        initialMap.put("\u02C7", "&Hacek;");
+        initialMap.put("\u2269\uFE00", "&gvnE;");
+        initialMap.put("\u2269\uFE00", "&gvertneqq;");
+        initialMap.put("\u2273", "&gtrsim;");
+        initialMap.put("\u2277", "&gtrless;");
+        initialMap.put("\u2A8C", "&gtreqqless;");
+        initialMap.put("\u22DB", "&gtreqless;");
+        initialMap.put("\u22D7", "&gtrdot;");
+        initialMap.put("\u2978", "&gtrarr;");
+        initialMap.put("\u2A86", "&gtrapprox;");
+        initialMap.put("\u2A7C", "&gtquest;");
+        initialMap.put("\u2995", "&gtlPar;");
+        initialMap.put("\u22D7", "&gtdot;");
+        initialMap.put("\u226B", "&Gt;");
+        initialMap.put("\u003E", "&GT");
+        initialMap.put("\u003E", "&GT;");
+        initialMap.put("\u003E", "&gt");
+        initialMap.put("\u003E", "&gt;");
+        initialMap.put("\u2A7A", "&gtcir;");
+        initialMap.put("\u2AA7", "&gtcc;");
+        initialMap.put("\u2A90", "&gsiml;");
+        initialMap.put("\u2A8E", "&gsime;");
+        initialMap.put("\u2273", "&gsim;");
+        initialMap.put("\u210A", "&gscr;");
+        initialMap.put("\uD835\uDCA2", "&Gscr;");
+        initialMap.put("\u2273", "&GreaterTilde;");
+        initialMap.put("\u2A7E", "&GreaterSlantEqual;");
+        initialMap.put("\u2277", "&GreaterLess;");
+        initialMap.put("\u2AA2", "&GreaterGreater;");
+        initialMap.put("\u2267", "&GreaterFullEqual;");
+        initialMap.put("\u22DB", "&GreaterEqualLess;");
+        initialMap.put("\u2265", "&GreaterEqual;");
+        initialMap.put("\u0060", "&grave;");
+        initialMap.put("\uD835\uDD58", "&gopf;");
+        initialMap.put("\uD835\uDD3E", "&Gopf;");
+        initialMap.put("\u22E7", "&gnsim;");
+        initialMap.put("\u2269", "&gneqq;");
+        initialMap.put("\u2A88", "&gneq;");
+        initialMap.put("\u2269", "&gnE;");
+        initialMap.put("\u2A88", "&gne;");
+        initialMap.put("\u2A8A", "&gnapprox;");
+        initialMap.put("\u2A8A", "&gnap;");
+        initialMap.put("\u2AA4", "&glj;");
+        initialMap.put("\u2A92", "&glE;");
+        initialMap.put("\u2277", "&gl;");
+        initialMap.put("\u2AA5", "&gla;");
+        initialMap.put("\u0453", "&gjcy;");
+        initialMap.put("\u0403", "&GJcy;");
+        initialMap.put("\u2137", "&gimel;");
+        initialMap.put("\u22D9", "&ggg;");
+        initialMap.put("\u22D9", "&Gg;");
+        initialMap.put("\u226B", "&gg;");
+        initialMap.put("\uD835\uDD24", "&gfr;");
+        initialMap.put("\uD835\uDD0A", "&Gfr;");
+        initialMap.put("\u2A94", "&gesles;");
+        initialMap.put("\u22DB\uFE00", "&gesl;");
+        initialMap.put("\u2A84", "&gesdotol;");
+        initialMap.put("\u2A82", "&gesdoto;");
+        initialMap.put("\u2A80", "&gesdot;");
+        initialMap.put("\u2A7E", "&ges;");
+        initialMap.put("\u2AA9", "&gescc;");
+        initialMap.put("\u2A7E", "&geqslant;");
+        initialMap.put("\u2267", "&geqq;");
+        initialMap.put("\u2265", "&geq;");
+        initialMap.put("\u22DB", "&gel;");
+        initialMap.put("\u2A8C", "&gEl;");
+        initialMap.put("\u2267", "&gE;");
+        initialMap.put("\u2265", "&ge;");
+        initialMap.put("\u0121", "&gdot;");
+        initialMap.put("\u0120", "&Gdot;");
+        initialMap.put("\u0433", "&gcy;");
+        initialMap.put("\u0413", "&Gcy;");
+        initialMap.put("\u011D", "&gcirc;");
+        initialMap.put("\u011C", "&Gcirc;");
+        initialMap.put("\u0122", "&Gcedil;");
+        initialMap.put("\u011F", "&gbreve;");
+        initialMap.put("\u011E", "&Gbreve;");
+        initialMap.put("\u2A86", "&gap;");
+        initialMap.put("\u03DD", "&gammad;");
+        initialMap.put("\u03DC", "&Gammad;");
+        initialMap.put("\u03B3", "&gamma;");
+        initialMap.put("\u0393", "&Gamma;");
+        initialMap.put("\u01F5", "&gacute;");
+        initialMap.put("\u2131", "&Fscr;");
+        initialMap.put("\uD835\uDCBB", "&fscr;");
+        initialMap.put("\u2322", "&frown;");
+        initialMap.put("\u2044", "&frasl;");
+        initialMap.put("\u215E", "&frac78;");
+        initialMap.put("\u215D", "&frac58;");
+        initialMap.put("\u215A", "&frac56;");
+        initialMap.put("\u2158", "&frac45;");
+        initialMap.put("\u215C", "&frac38;");
+        initialMap.put("\u2157", "&frac35;");
+        initialMap.put("\u00BE", "&frac34");
+        initialMap.put("\u00BE", "&frac34;");
+        initialMap.put("\u2156", "&frac25;");
+        initialMap.put("\u2154", "&frac23;");
+        initialMap.put("\u215B", "&frac18;");
+        initialMap.put("\u2159", "&frac16;");
+        initialMap.put("\u2155", "&frac15;");
+        initialMap.put("\u00BC", "&frac14");
+        initialMap.put("\u00BC", "&frac14;");
+        initialMap.put("\u2153", "&frac13;");
+        initialMap.put("\u00BD", "&frac12");
+        initialMap.put("\u00BD", "&frac12;");
+        initialMap.put("\u2A0D", "&fpartint;");
+        initialMap.put("\u2131", "&Fouriertrf;");
+        initialMap.put("\u2AD9", "&forkv;");
+        initialMap.put("\u22D4", "&fork;");
+        initialMap.put("\u2200", "&ForAll;");
+        initialMap.put("\u2200", "&forall;");
+        initialMap.put("\uD835\uDD57", "&fopf;");
+        initialMap.put("\uD835\uDD3D", "&Fopf;");
+        initialMap.put("\u0192", "&fnof;");
+        initialMap.put("\u25B1", "&fltns;");
+        initialMap.put("\uFB02", "&fllig;");
+        initialMap.put("\u266D", "&flat;");
+        initialMap.put("\u0066\u006A", "&fjlig;");
+        initialMap.put("\u25AA", "&FilledVerySmallSquare;");
+        initialMap.put("\u25FC", "&FilledSmallSquare;");
+        initialMap.put("\uFB01", "&filig;");
+        initialMap.put("\uD835\uDD23", "&ffr;");
+        initialMap.put("\uD835\uDD09", "&Ffr;");
+        initialMap.put("\uFB04", "&ffllig;");
+        initialMap.put("\uFB00", "&fflig;");
+        initialMap.put("\uFB03", "&ffilig;");
+        initialMap.put("\u2640", "&female;");
+        initialMap.put("\u0444", "&fcy;");
+        initialMap.put("\u0424", "&Fcy;");
+        initialMap.put("\u2252", "&fallingdotseq;");
+        initialMap.put("\u2147", "&ExponentialE;");
+        initialMap.put("\u2147", "&exponentiale;");
+        initialMap.put("\u2130", "&expectation;");
+        initialMap.put("\u2203", "&Exists;");
+        initialMap.put("\u2203", "&exist;");
+        initialMap.put("\u0021", "&excl;");
+        initialMap.put("\u20AC", "&euro;");
+        initialMap.put("\u00EB", "&euml");
+        initialMap.put("\u00EB", "&euml;");
+        initialMap.put("\u00CB", "&Euml");
+        initialMap.put("\u00CB", "&Euml;");
+        initialMap.put("\u00F0", "&eth");
+        initialMap.put("\u00F0", "&eth;");
+        initialMap.put("\u00D0", "&ETH");
+        initialMap.put("\u00D0", "&ETH;");
+        initialMap.put("\u03B7", "&eta;");
+        initialMap.put("\u0397", "&Eta;");
+        initialMap.put("\u2242", "&esim;");
+        initialMap.put("\u2A73", "&Esim;");
+        initialMap.put("\u2250", "&esdot;");
+        initialMap.put("\u2130", "&Escr;");
+        initialMap.put("\u212F", "&escr;");
+        initialMap.put("\u2253", "&erDot;");
+        initialMap.put("\u2971", "&erarr;");
+        initialMap.put("\u29E5", "&eqvparsl;");
+        initialMap.put("\u2A78", "&equivDD;");
+        initialMap.put("\u2261", "&equiv;");
+        initialMap.put("\u21CC", "&Equilibrium;");
+        initialMap.put("\u225F", "&equest;");
+        initialMap.put("\u2242", "&EqualTilde;");
+        initialMap.put("\u003D", "&equals;");
+        initialMap.put("\u2A75", "&Equal;");
+        initialMap.put("\u2A95", "&eqslantless;");
+        initialMap.put("\u2A96", "&eqslantgtr;");
+        initialMap.put("\u2242", "&eqsim;");
+        initialMap.put("\u2255", "&eqcolon;");
+        initialMap.put("\u2256", "&eqcirc;");
+        initialMap.put("\u03F5", "&epsiv;");
+        initialMap.put("\u03B5", "&epsilon;");
+        initialMap.put("\u0395", "&Epsilon;");
+        initialMap.put("\u03B5", "&epsi;");
+        initialMap.put("\u2A71", "&eplus;");
+        initialMap.put("\u29E3", "&eparsl;");
+        initialMap.put("\u22D5", "&epar;");
+        initialMap.put("\uD835\uDD56", "&eopf;");
+        initialMap.put("\uD835\uDD3C", "&Eopf;");
+        initialMap.put("\u0119", "&eogon;");
+        initialMap.put("\u0118", "&Eogon;");
+        initialMap.put("\u2002", "&ensp;");
+        initialMap.put("\u014B", "&eng;");
+        initialMap.put("\u014A", "&ENG;");
+        initialMap.put("\u2003", "&emsp;");
+        initialMap.put("\u2005", "&emsp14;");
+        initialMap.put("\u2004", "&emsp13;");
+        initialMap.put("\u25AB", "&EmptyVerySmallSquare;");
+        initialMap.put("\u2205", "&emptyv;");
+        initialMap.put("\u25FB", "&EmptySmallSquare;");
+        initialMap.put("\u2205", "&emptyset;");
+        initialMap.put("\u2205", "&empty;");
+        initialMap.put("\u0113", "&emacr;");
+        initialMap.put("\u0112", "&Emacr;");
+        initialMap.put("\u2A97", "&elsdot;");
+        initialMap.put("\u2A95", "&els;");
+        initialMap.put("\u2113", "&ell;");
+        initialMap.put("\u23E7", "&elinters;");
+        initialMap.put("\u2208", "&Element;");
+        initialMap.put("\u2A99", "&el;");
+        initialMap.put("\u2A98", "&egsdot;");
+        initialMap.put("\u2A96", "&egs;");
+        initialMap.put("\u00E8", "&egrave");
+        initialMap.put("\u00E8", "&egrave;");
+        initialMap.put("\u00C8", "&Egrave");
+        initialMap.put("\u00C8", "&Egrave;");
+        initialMap.put("\u2A9A", "&eg;");
+        initialMap.put("\uD835\uDD22", "&efr;");
+        initialMap.put("\uD835\uDD08", "&Efr;");
+        initialMap.put("\u2252", "&efDot;");
+        initialMap.put("\u2147", "&ee;");
+        initialMap.put("\u2251", "&eDot;");
+        initialMap.put("\u0117", "&edot;");
+        initialMap.put("\u0116", "&Edot;");
+        initialMap.put("\u2A77", "&eDDot;");
+        initialMap.put("\u044D", "&ecy;");
+        initialMap.put("\u042D", "&Ecy;");
+        initialMap.put("\u2255", "&ecolon;");
+        initialMap.put("\u2256", "&ecir;");
+        initialMap.put("\u00EA", "&ecirc");
+        initialMap.put("\u00EA", "&ecirc;");
+        initialMap.put("\u00CA", "&Ecirc");
+        initialMap.put("\u00CA", "&Ecirc;");
+        initialMap.put("\u011B", "&ecaron;");
+        initialMap.put("\u011A", "&Ecaron;");
+        initialMap.put("\u2A6E", "&easter;");
+        initialMap.put("\u00E9", "&eacute");
+        initialMap.put("\u00E9", "&eacute;");
+        initialMap.put("\u00C9", "&Eacute");
+        initialMap.put("\u00C9", "&Eacute;");
+        initialMap.put("\u27FF", "&dzigrarr;");
+        initialMap.put("\u045F", "&dzcy;");
+        initialMap.put("\u040F", "&DZcy;");
+        initialMap.put("\u29A6", "&dwangle;");
+        initialMap.put("\u296F", "&duhar;");
+        initialMap.put("\u21F5", "&duarr;");
+        initialMap.put("\u25BE", "&dtrif;");
+        initialMap.put("\u25BF", "&dtri;");
+        initialMap.put("\u22F1", "&dtdot;");
+        initialMap.put("\u0111", "&dstrok;");
+        initialMap.put("\u0110", "&Dstrok;");
+        initialMap.put("\u29F6", "&dsol;");
+        initialMap.put("\u0455", "&dscy;");
+        initialMap.put("\u0405", "&DScy;");
+        initialMap.put("\uD835\uDCB9", "&dscr;");
+        initialMap.put("\uD835\uDC9F", "&Dscr;");
+        initialMap.put("\u230C", "&drcrop;");
+        initialMap.put("\u231F", "&drcorn;");
+        initialMap.put("\u2910", "&drbkarow;");
+        initialMap.put("\u22A4", "&DownTee;");
+        initialMap.put("\u21A7", "&DownTeeArrow;");
+        initialMap.put("\u21C1", "&DownRightVector;");
+        initialMap.put("\u2957", "&DownRightVectorBar;");
+        initialMap.put("\u295F", "&DownRightTeeVector;");
+        initialMap.put("\u21BD", "&DownLeftVector;");
+        initialMap.put("\u2956", "&DownLeftVectorBar;");
+        initialMap.put("\u295E", "&DownLeftTeeVector;");
+        initialMap.put("\u2950", "&DownLeftRightVector;");
+        initialMap.put("\u21C2", "&downharpoonright;");
+        initialMap.put("\u21C3", "&downharpoonleft;");
+        initialMap.put("\u21CA", "&downdownarrows;");
+        initialMap.put("\u0311", "&DownBreve;");
+        initialMap.put("\u21F5", "&DownArrowUpArrow;");
+        initialMap.put("\u21D3", "&Downarrow;");
+        initialMap.put("\u2193", "&DownArrow;");
+        initialMap.put("\u2193", "&downarrow;");
+        initialMap.put("\u2913", "&DownArrowBar;");
+        initialMap.put("\u2225", "&DoubleVerticalBar;");
+        initialMap.put("\u21D5", "&DoubleUpDownArrow;");
+        initialMap.put("\u21D1", "&DoubleUpArrow;");
+        initialMap.put("\u22A8", "&DoubleRightTee;");
+        initialMap.put("\u21D2", "&DoubleRightArrow;");
+        initialMap.put("\u27F9", "&DoubleLongRightArrow;");
+        initialMap.put("\u27FA", "&DoubleLongLeftRightArrow;");
+        initialMap.put("\u27F8", "&DoubleLongLeftArrow;");
+        initialMap.put("\u2AE4", "&DoubleLeftTee;");
+        initialMap.put("\u21D4", "&DoubleLeftRightArrow;");
+        initialMap.put("\u21D0", "&DoubleLeftArrow;");
+        initialMap.put("\u21D3", "&DoubleDownArrow;");
+        initialMap.put("\u00A8", "&DoubleDot;");
+        initialMap.put("\u222F", "&DoubleContourIntegral;");
+        initialMap.put("\u2306", "&doublebarwedge;");
+        initialMap.put("\u22A1", "&dotsquare;");
+        initialMap.put("\u2214", "&dotplus;");
+        initialMap.put("\u2238", "&dotminus;");
+        initialMap.put("\u2250", "&DotEqual;");
+        initialMap.put("\u2251", "&doteqdot;");
+        initialMap.put("\u2250", "&doteq;");
+        initialMap.put("\u20DC", "&DotDot;");
+        initialMap.put("\u02D9", "&dot;");
+        initialMap.put("\u00A8", "&Dot;");
+        initialMap.put("\uD835\uDD55", "&dopf;");
+        initialMap.put("\uD835\uDD3B", "&Dopf;");
+        initialMap.put("\u0024", "&dollar;");
+        initialMap.put("\u230D", "&dlcrop;");
+        initialMap.put("\u231E", "&dlcorn;");
+        initialMap.put("\u0452", "&djcy;");
+        initialMap.put("\u0402", "&DJcy;");
+        initialMap.put("\u22C7", "&divonx;");
+        initialMap.put("\u22C7", "&divideontimes;");
+        initialMap.put("\u00F7", "&divide");
+        initialMap.put("\u00F7", "&divide;");
+        initialMap.put("\u00F7", "&div;");
+        initialMap.put("\u22F2", "&disin;");
+        initialMap.put("\u03DD", "&digamma;");
+        initialMap.put("\u2146", "&DifferentialD;");
+        initialMap.put("\u00A8", "&die;");
+        initialMap.put("\u2666", "&diams;");
+        initialMap.put("\u2666", "&diamondsuit;");
+        initialMap.put("\u22C4", "&Diamond;");
+        initialMap.put("\u22C4", "&diamond;");
+        initialMap.put("\u22C4", "&diam;");
+        initialMap.put("\u02DC", "&DiacriticalTilde;");
+        initialMap.put("\u0060", "&DiacriticalGrave;");
+        initialMap.put("\u02DD", "&DiacriticalDoubleAcute;");
+        initialMap.put("\u02D9", "&DiacriticalDot;");
+        initialMap.put("\u00B4", "&DiacriticalAcute;");
+        initialMap.put("\u21C2", "&dharr;");
+        initialMap.put("\u21C3", "&dharl;");
+        initialMap.put("\u2965", "&dHar;");
+        initialMap.put("\uD835\uDD21", "&dfr;");
+        initialMap.put("\uD835\uDD07", "&Dfr;");
+        initialMap.put("\u297F", "&dfisht;");
+        initialMap.put("\u29B1", "&demptyv;");
+        initialMap.put("\u03B4", "&delta;");
+        initialMap.put("\u0394", "&Delta;");
+        initialMap.put("\u2207", "&Del;");
+        initialMap.put("\u00B0", "&deg");
+        initialMap.put("\u00B0", "&deg;");
+        initialMap.put("\u2A77", "&ddotseq;");
+        initialMap.put("\u2911", "&DDotrahd;");
+        initialMap.put("\u2146", "&dd;");
+        initialMap.put("\u2145", "&DD;");
+        initialMap.put("\u21CA", "&ddarr;");
+        initialMap.put("\u2021", "&ddagger;");
+        initialMap.put("\u0434", "&dcy;");
+        initialMap.put("\u0414", "&Dcy;");
+        initialMap.put("\u010F", "&dcaron;");
+        initialMap.put("\u010E", "&Dcaron;");
+        initialMap.put("\u02DD", "&dblac;");
+        initialMap.put("\u290F", "&dbkarow;");
+        initialMap.put("\u22A3", "&dashv;");
+        initialMap.put("\u2AE4", "&Dashv;");
+        initialMap.put("\u2010", "&dash;");
+        initialMap.put("\u21D3", "&dArr;");
+        initialMap.put("\u21A1", "&Darr;");
+        initialMap.put("\u2193", "&darr;");
+        initialMap.put("\u2138", "&daleth;");
+        initialMap.put("\u2021", "&Dagger;");
+        initialMap.put("\u2020", "&dagger;");
+        initialMap.put("\u232D", "&cylcty;");
+        initialMap.put("\u2231", "&cwint;");
+        initialMap.put("\u2232", "&cwconint;");
+        initialMap.put("\u22CF", "&cuwed;");
+        initialMap.put("\u22CE", "&cuvee;");
+        initialMap.put("\u21B7", "&curvearrowright;");
+        initialMap.put("\u21B6", "&curvearrowleft;");
+        initialMap.put("\u00A4", "&curren");
+        initialMap.put("\u00A4", "&curren;");
+        initialMap.put("\u22CF", "&curlywedge;");
+        initialMap.put("\u22CE", "&curlyvee;");
+        initialMap.put("\u22DF", "&curlyeqsucc;");
+        initialMap.put("\u22DE", "&curlyeqprec;");
+        initialMap.put("\u293C", "&curarrm;");
+        initialMap.put("\u21B7", "&curarr;");
+        initialMap.put("\u222A\uFE00", "&cups;");
+        initialMap.put("\u2A45", "&cupor;");
+        initialMap.put("\u228D", "&cupdot;");
+        initialMap.put("\u2A4A", "&cupcup;");
+        initialMap.put("\u22D3", "&Cup;");
+        initialMap.put("\u222A", "&cup;");
+        initialMap.put("\u224D", "&CupCap;");
+        initialMap.put("\u2A46", "&cupcap;");
+        initialMap.put("\u2A48", "&cupbrcap;");
+        initialMap.put("\u293D", "&cularrp;");
+        initialMap.put("\u21B6", "&cularr;");
+        initialMap.put("\u22DF", "&cuesc;");
+        initialMap.put("\u22DE", "&cuepr;");
+        initialMap.put("\u2935", "&cudarrr;");
+        initialMap.put("\u2938", "&cudarrl;");
+        initialMap.put("\u22EF", "&ctdot;");
+        initialMap.put("\u2AD2", "&csupe;");
+        initialMap.put("\u2AD0", "&csup;");
+        initialMap.put("\u2AD1", "&csube;");
+        initialMap.put("\u2ACF", "&csub;");
+        initialMap.put("\uD835\uDCB8", "&cscr;");
+        initialMap.put("\uD835\uDC9E", "&Cscr;");
+        initialMap.put("\u2A2F", "&Cross;");
+        initialMap.put("\u2717", "&cross;");
+        initialMap.put("\u21B5", "&crarr;");
+        initialMap.put("\u2233", "&CounterClockwiseContourIntegral;");
+        initialMap.put("\u2117", "&copysr;");
+        initialMap.put("\u00A9", "&COPY");
+        initialMap.put("\u00A9", "&COPY;");
+        initialMap.put("\u00A9", "&copy");
+        initialMap.put("\u00A9", "&copy;");
+        initialMap.put("\u2210", "&Coproduct;");
+        initialMap.put("\u2210", "&coprod;");
+        initialMap.put("\u2102", "&Copf;");
+        initialMap.put("\uD835\uDD54", "&copf;");
+        initialMap.put("\u222E", "&ContourIntegral;");
+        initialMap.put("\u222F", "&Conint;");
+        initialMap.put("\u222E", "&conint;");
+        initialMap.put("\u2261", "&Congruent;");
+        initialMap.put("\u2A6D", "&congdot;");
+        initialMap.put("\u2245", "&cong;");
+        initialMap.put("\u2102", "&complexes;");
+        initialMap.put("\u2201", "&complement;");
+        initialMap.put("\u2218", "&compfn;");
+        initialMap.put("\u2201", "&comp;");
+        initialMap.put("\u0040", "&commat;");
+        initialMap.put("\u002C", "&comma;");
+        initialMap.put("\u2254", "&coloneq;");
+        initialMap.put("\u2254", "&colone;");
+        initialMap.put("\u2A74", "&Colone;");
+        initialMap.put("\u2237", "&Colon;");
+        initialMap.put("\u003A", "&colon;");
+        initialMap.put("\u2663", "&clubsuit;");
+        initialMap.put("\u2663", "&clubs;");
+        initialMap.put("\u2019", "&CloseCurlyQuote;");
+        initialMap.put("\u201D", "&CloseCurlyDoubleQuote;");
+        initialMap.put("\u2232", "&ClockwiseContourIntegral;");
+        initialMap.put("\u29C2", "&cirscir;");
+        initialMap.put("\u2AEF", "&cirmid;");
+        initialMap.put("\u2A10", "&cirfnint;");
+        initialMap.put("\u2257", "&cire;");
+        initialMap.put("\u29C3", "&cirE;");
+        initialMap.put("\u25CB", "&cir;");
+        initialMap.put("\u2297", "&CircleTimes;");
+        initialMap.put("\u2295", "&CirclePlus;");
+        initialMap.put("\u2296", "&CircleMinus;");
+        initialMap.put("\u24C8", "&circledS;");
+        initialMap.put("\u00AE", "&circledR;");
+        initialMap.put("\u2299", "&CircleDot;");
+        initialMap.put("\u229D", "&circleddash;");
+        initialMap.put("\u229A", "&circledcirc;");
+        initialMap.put("\u229B", "&circledast;");
+        initialMap.put("\u21BB", "&circlearrowright;");
+        initialMap.put("\u21BA", "&circlearrowleft;");
+        initialMap.put("\u2257", "&circeq;");
+        initialMap.put("\u02C6", "&circ;");
+        initialMap.put("\u03C7", "&chi;");
+        initialMap.put("\u03A7", "&Chi;");
+        initialMap.put("\u2713", "&checkmark;");
+        initialMap.put("\u2713", "&check;");
+        initialMap.put("\u0447", "&chcy;");
+        initialMap.put("\u0427", "&CHcy;");
+        initialMap.put("\u212D", "&Cfr;");
+        initialMap.put("\uD835\uDD20", "&cfr;");
+        initialMap.put("\u00B7", "&CenterDot;");
+        initialMap.put("\u00B7", "&centerdot;");
+        initialMap.put("\u00A2", "&cent");
+        initialMap.put("\u00A2", "&cent;");
+        initialMap.put("\u29B2", "&cemptyv;");
+        initialMap.put("\u00B8", "&Cedilla;");
+        initialMap.put("\u00B8", "&cedil");
+        initialMap.put("\u00B8", "&cedil;");
+        initialMap.put("\u010B", "&cdot;");
+        initialMap.put("\u010A", "&Cdot;");
+        initialMap.put("\u2A50", "&ccupssm;");
+        initialMap.put("\u2A4C", "&ccups;");
+        initialMap.put("\u2230", "&Cconint;");
+        initialMap.put("\u0109", "&ccirc;");
+        initialMap.put("\u0108", "&Ccirc;");
+        initialMap.put("\u00E7", "&ccedil");
+        initialMap.put("\u00E7", "&ccedil;");
+        initialMap.put("\u00C7", "&Ccedil");
+        initialMap.put("\u00C7", "&Ccedil;");
+        initialMap.put("\u010D", "&ccaron;");
+        initialMap.put("\u010C", "&Ccaron;");
+        initialMap.put("\u2A4D", "&ccaps;");
+        initialMap.put("\u212D", "&Cayleys;");
+        initialMap.put("\u02C7", "&caron;");
+        initialMap.put("\u2041", "&caret;");
+        initialMap.put("\u2229\uFE00", "&caps;");
+        initialMap.put("\u2145", "&CapitalDifferentialD;");
+        initialMap.put("\u2A40", "&capdot;");
+        initialMap.put("\u2A47", "&capcup;");
+        initialMap.put("\u22D2", "&Cap;");
+        initialMap.put("\u2229", "&cap;");
+        initialMap.put("\u2A4B", "&capcap;");
+        initialMap.put("\u2A49", "&capbrcup;");
+        initialMap.put("\u2A44", "&capand;");
+        initialMap.put("\u0107", "&cacute;");
+        initialMap.put("\u0106", "&Cacute;");
+        initialMap.put("\u224F", "&bumpeq;");
+        initialMap.put("\u224E", "&Bumpeq;");
+        initialMap.put("\u224F", "&bumpe;");
+        initialMap.put("\u2AAE", "&bumpE;");
+        initialMap.put("\u224E", "&bump;");
+        initialMap.put("\u2022", "&bullet;");
+        initialMap.put("\u2022", "&bull;");
+        initialMap.put("\u27C8", "&bsolhsub;");
+        initialMap.put("\\", "&bsol;");
+        initialMap.put("\u29C5", "&bsolb;");
+        initialMap.put("\u22CD", "&bsime;");
+        initialMap.put("\u223D", "&bsim;");
+        initialMap.put("\u204F", "&bsemi;");
+        initialMap.put("\u212C", "&Bscr;");
+        initialMap.put("\uD835\uDCB7", "&bscr;");
+        initialMap.put("\u00A6", "&brvbar");
+        initialMap.put("\u00A6", "&brvbar;");
+        initialMap.put("\u02D8", "&Breve;");
+        initialMap.put("\u02D8", "&breve;");
+        initialMap.put("\u2035", "&bprime;");
+        initialMap.put("\u2560", "&boxVR;");
+        initialMap.put("\u255F", "&boxVr;");
+        initialMap.put("\u255E", "&boxvR;");
+        initialMap.put("\u251C", "&boxvr;");
+        initialMap.put("\u2563", "&boxVL;");
+        initialMap.put("\u2562", "&boxVl;");
+        initialMap.put("\u2561", "&boxvL;");
+        initialMap.put("\u2524", "&boxvl;");
+        initialMap.put("\u256C", "&boxVH;");
+        initialMap.put("\u256B", "&boxVh;");
+        initialMap.put("\u256A", "&boxvH;");
+        initialMap.put("\u253C", "&boxvh;");
+        initialMap.put("\u2551", "&boxV;");
+        initialMap.put("\u2502", "&boxv;");
+        initialMap.put("\u255A", "&boxUR;");
+        initialMap.put("\u2559", "&boxUr;");
+        initialMap.put("\u2558", "&boxuR;");
+        initialMap.put("\u2514", "&boxur;");
+        initialMap.put("\u255D", "&boxUL;");
+        initialMap.put("\u255C", "&boxUl;");
+        initialMap.put("\u255B", "&boxuL;");
+        initialMap.put("\u2518", "&boxul;");
+        initialMap.put("\u22A0", "&boxtimes;");
+        initialMap.put("\u229E", "&boxplus;");
+        initialMap.put("\u229F", "&boxminus;");
+        initialMap.put("\u2569", "&boxHU;");
+        initialMap.put("\u2568", "&boxhU;");
+        initialMap.put("\u2567", "&boxHu;");
+        initialMap.put("\u2534", "&boxhu;");
+        initialMap.put("\u2566", "&boxHD;");
+        initialMap.put("\u2565", "&boxhD;");
+        initialMap.put("\u2564", "&boxHd;");
+        initialMap.put("\u252C", "&boxhd;");
+        initialMap.put("\u2550", "&boxH;");
+        initialMap.put("\u2500", "&boxh;");
+        initialMap.put("\u2554", "&boxDR;");
+        initialMap.put("\u2553", "&boxDr;");
+        initialMap.put("\u2552", "&boxdR;");
+        initialMap.put("\u250C", "&boxdr;");
+        initialMap.put("\u2557", "&boxDL;");
+        initialMap.put("\u2556", "&boxDl;");
+        initialMap.put("\u2555", "&boxdL;");
+        initialMap.put("\u2510", "&boxdl;");
+        initialMap.put("\u29C9", "&boxbox;");
+        initialMap.put("\u22C8", "&bowtie;");
+        initialMap.put("\u22A5", "&bottom;");
+        initialMap.put("\u22A5", "&bot;");
+        initialMap.put("\uD835\uDD53", "&bopf;");
+        initialMap.put("\uD835\uDD39", "&Bopf;");
+        initialMap.put("\u2310", "&bnot;");
+        initialMap.put("\u2AED", "&bNot;");
+        initialMap.put("\u2261\u20E5", "&bnequiv;");
+        initialMap.put("\u003D\u20E5", "&bne;");
+        initialMap.put("\u2588", "&block;");
+        initialMap.put("\u2593", "&blk34;");
+        initialMap.put("\u2591", "&blk14;");
+        initialMap.put("\u2592", "&blk12;");
+        initialMap.put("\u2423", "&blank;");
+        initialMap.put("\u25B8", "&blacktriangleright;");
+        initialMap.put("\u25C2", "&blacktriangleleft;");
+        initialMap.put("\u25BE", "&blacktriangledown;");
+        initialMap.put("\u25B4", "&blacktriangle;");
+        initialMap.put("\u25AA", "&blacksquare;");
+        initialMap.put("\u29EB", "&blacklozenge;");
+        initialMap.put("\u290D", "&bkarow;");
+        initialMap.put("\u22C0", "&bigwedge;");
+        initialMap.put("\u22C1", "&bigvee;");
+        initialMap.put("\u2A04", "&biguplus;");
+        initialMap.put("\u25B3", "&bigtriangleup;");
+        initialMap.put("\u25BD", "&bigtriangledown;");
+        initialMap.put("\u2605", "&bigstar;");
+        initialMap.put("\u2A06", "&bigsqcup;");
+        initialMap.put("\u2A02", "&bigotimes;");
+        initialMap.put("\u2A01", "&bigoplus;");
+        initialMap.put("\u2A00", "&bigodot;");
+        initialMap.put("\u22C3", "&bigcup;");
+        initialMap.put("\u25EF", "&bigcirc;");
+        initialMap.put("\u22C2", "&bigcap;");
+        initialMap.put("\uD835\uDD1F", "&bfr;");
+        initialMap.put("\uD835\uDD05", "&Bfr;");
+        initialMap.put("\u226C", "&between;");
+        initialMap.put("\u2136", "&beth;");
+        initialMap.put("\u03B2", "&beta;");
+        initialMap.put("\u0392", "&Beta;");
+        initialMap.put("\u212C", "&Bernoullis;");
+        initialMap.put("\u212C", "&bernou;");
+        initialMap.put("\u03F6", "&bepsi;");
+        initialMap.put("\u29B0", "&bemptyv;");
+        initialMap.put("\u2235", "&Because;");
+        initialMap.put("\u2235", "&because;");
+        initialMap.put("\u2235", "&becaus;");
+        initialMap.put("\u201E", "&bdquo;");
+        initialMap.put("\u0431", "&bcy;");
+        initialMap.put("\u0411", "&Bcy;");
+        initialMap.put("\u224C", "&bcong;");
+        initialMap.put("\u23B6", "&bbrktbrk;");
+        initialMap.put("\u23B5", "&bbrk;");
+        initialMap.put("\u2305", "&barwedge;");
+        initialMap.put("\u2306", "&Barwed;");
+        initialMap.put("\u2305", "&barwed;");
+        initialMap.put("\u22BD", "&barvee;");
+        initialMap.put("\u2AE7", "&Barv;");
+        initialMap.put("\u2216", "&Backslash;");
+        initialMap.put("\u22CD", "&backsimeq;");
+        initialMap.put("\u223D", "&backsim;");
+        initialMap.put("\u2035", "&backprime;");
+        initialMap.put("\u03F6", "&backepsilon;");
+        initialMap.put("\u224C", "&backcong;");
+        initialMap.put("\u2A11", "&awint;");
+        initialMap.put("\u2233", "&awconint;");
+        initialMap.put("\u00E4", "&auml");
+        initialMap.put("\u00E4", "&auml;");
+        initialMap.put("\u00C4", "&Auml");
+        initialMap.put("\u00C4", "&Auml;");
+        initialMap.put("\u00E3", "&atilde");
+        initialMap.put("\u00E3", "&atilde;");
+        initialMap.put("\u00C3", "&Atilde");
+        initialMap.put("\u00C3", "&Atilde;");
+        initialMap.put("\u224D", "&asympeq;");
+        initialMap.put("\u2248", "&asymp;");
+        initialMap.put("\u002A", "&ast;");
+        initialMap.put("\u2254", "&Assign;");
+        initialMap.put("\uD835\uDCB6", "&ascr;");
+        initialMap.put("\uD835\uDC9C", "&Ascr;");
+        initialMap.put("\u00E5", "&aring");
+        initialMap.put("\u00E5", "&aring;");
+        initialMap.put("\u00C5", "&Aring");
+        initialMap.put("\u00C5", "&Aring;");
+        initialMap.put("\u224A", "&approxeq;");
+        initialMap.put("\u2248", "&approx;");
+        initialMap.put("\u2061", "&ApplyFunction;");
+        initialMap.put("\u0027", "&apos;");
+        initialMap.put("\u224B", "&apid;");
+        initialMap.put("\u224A", "&ape;");
+        initialMap.put("\u2A70", "&apE;");
+        initialMap.put("\u2248", "&ap;");
+        initialMap.put("\u2A6F", "&apacir;");
+        initialMap.put("\uD835\uDD52", "&aopf;");
+        initialMap.put("\uD835\uDD38", "&Aopf;");
+        initialMap.put("\u0105", "&aogon;");
+        initialMap.put("\u0104", "&Aogon;");
+        initialMap.put("\u237C", "&angzarr;");
+        initialMap.put("\u00C5", "&angst;");
+        initialMap.put("\u2222", "&angsph;");
+        initialMap.put("\u299D", "&angrtvbd;");
+        initialMap.put("\u22BE", "&angrtvb;");
+        initialMap.put("\u221F", "&angrt;");
+        initialMap.put("\u2221", "&angmsd;");
+        initialMap.put("\u29AF", "&angmsdah;");
+        initialMap.put("\u29AE", "&angmsdag;");
+        initialMap.put("\u29AD", "&angmsdaf;");
+        initialMap.put("\u29AC", "&angmsdae;");
+        initialMap.put("\u29AB", "&angmsdad;");
+        initialMap.put("\u29AA", "&angmsdac;");
+        initialMap.put("\u29A9", "&angmsdab;");
+        initialMap.put("\u29A8", "&angmsdaa;");
+        initialMap.put("\u2220", "&angle;");
+        initialMap.put("\u29A4", "&ange;");
+        initialMap.put("\u2220", "&ang;");
+        initialMap.put("\u2A5A", "&andv;");
+        initialMap.put("\u2A58", "&andslope;");
+        initialMap.put("\u2A5C", "&andd;");
+        initialMap.put("\u2227", "&and;");
+        initialMap.put("\u2A53", "&And;");
+        initialMap.put("\u2A55", "&andand;");
+        initialMap.put("\u0026", "&AMP");
+        initialMap.put("\u0026", "&AMP;");
+        initialMap.put("\u0026", "&amp");
+        initialMap.put("\u0026", "&amp;");
+        initialMap.put("\u2A3F", "&amalg;");
+        initialMap.put("\u0101", "&amacr;");
+        initialMap.put("\u0100", "&Amacr;");
+        initialMap.put("\u03B1", "&alpha;");
+        initialMap.put("\u0391", "&Alpha;");
+        initialMap.put("\u2135", "&aleph;");
+        initialMap.put("\u2135", "&alefsym;");
+        initialMap.put("\u00E0", "&agrave");
+        initialMap.put("\u00E0", "&agrave;");
+        initialMap.put("\u00C0", "&Agrave");
+        initialMap.put("\u00C0", "&Agrave;");
+        initialMap.put("\uD835\uDD1E", "&afr;");
+        initialMap.put("\uD835\uDD04", "&Afr;");
+        initialMap.put("\u2061", "&af;");
+        initialMap.put("\u00E6", "&aelig");
+        initialMap.put("\u00E6", "&aelig;");
+        initialMap.put("\u00C6", "&AElig");
+        initialMap.put("\u00C6", "&AElig;");
+        initialMap.put("\u0430", "&acy;");
+        initialMap.put("\u0410", "&Acy;");
+        initialMap.put("\u00B4", "&acute");
+        initialMap.put("\u00B4", "&acute;");
+        initialMap.put("\u00E2", "&acirc");
+        initialMap.put("\u00E2", "&acirc;");
+        initialMap.put("\u00C2", "&Acirc");
+        initialMap.put("\u00C2", "&Acirc;");
+        initialMap.put("\u223E\u0333", "&acE;");
+        initialMap.put("\u223F", "&acd;");
+        initialMap.put("\u223E", "&ac;");
+        initialMap.put("\u0103", "&abreve;");
+        initialMap.put("\u0102", "&Abreve;");
+        initialMap.put("\u00E1", "&aacute");
+        initialMap.put("\u00E1", "&aacute;");
+        initialMap.put("\u00C1", "&Aacute");
+        initialMap.put("\u00C1", "&Aacute;");
+        HTML50_EXTENDED_ESCAPE = Collections.unmodifiableMap(initialMap);
+    }
+    
+    public static final Map<CharSequence, CharSequence> HTML50_EXTENDED_UNESCAPE;
+    static {
+        HTML50_EXTENDED_UNESCAPE = Collections.unmodifiableMap(EntityArrays.invert(HTML50_EXTENDED_ESCAPE));
+}
+
+
+}
diff --git a/tag-modifier/src/main/java/org/apache/sling/tagmodifier/util/HtmlEntityTranslator.java b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/util/HtmlEntityTranslator.java
new file mode 100644
index 0000000..a9d736d
--- /dev/null
+++ b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/util/HtmlEntityTranslator.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.tagmodifier.util;
+
+import javax.json.JsonObject;
+
+import org.apache.commons.text.translate.CharSequenceTranslator;
+import org.apache.commons.text.translate.LookupTranslator;
+
+public class HtmlEntityTranslator {
+
+    JsonObject jsonEntities;
+    JsonObject oldEntities;
+
+    public static final CharSequenceTranslator ESCAPE_HTML = new LookupTranslator(Html5Entities.HTML50_EXTENDED_ESCAPE);
+    public static final CharSequenceTranslator UNESCAPE_HTML = new LookupTranslator(Html5Entities.HTML50_EXTENDED_UNESCAPE);
+
+    public static String encodeHTML(String text) {
+        return ESCAPE_HTML.translate(text);
+    }
+    
+    public static String decodeHTML(String text) {
+        return UNESCAPE_HTML.translate(text);
+    }
+
+}
diff --git a/tag-modifier/src/main/java/org/apache/sling/tagmodifier/util/HtmlStreams.java b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/util/HtmlStreams.java
new file mode 100644
index 0000000..0bac268
--- /dev/null
+++ b/tag-modifier/src/main/java/org/apache/sling/tagmodifier/util/HtmlStreams.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.tagmodifier.util;
+
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import org.apache.sling.tagmodifier.AttrValue;
+import org.apache.sling.tagmodifier.Element;
+import org.apache.sling.tagmodifier.impl.tag.StartTag;
+
+public class HtmlStreams {
+    
+    private HtmlStreams() {
+    }
+
+    public static final  Function<Element, String> TO_HTML = element ->{
+        StringBuilder sb = new StringBuilder();
+        switch (element.getType()) {
+        case COMMENT:
+            sb.append("<!--");
+            sb.append(element.getValue());
+            sb.append("-->");
+            break;
+        case DOCTYPE:
+            sb.append("<!");
+            sb.append(element.getValue());
+            sb.append(">");
+            break;
+        case END_TAG:
+            sb.append("</");
+            sb.append(element.getValue());
+            sb.append('>');
+            break;
+        case EOF:
+            break;
+        case START_TAG:
+            sb.append('<');
+            sb.append(element.getValue());
+            StartTag tag = (StartTag) element;
+            if (tag.hasAttributes()) {
+                sb.append(' ');
+                sb.append(tag.getAttributes().entrySet().stream().map(entry -> {
+                    StringBuilder sb2 = new StringBuilder();
+                    sb2.append(entry.getKey());
+                    AttrValue value = entry.getValue();
+                    if (!value.isEmpty()) {
+                        sb2.append("=");
+                        sb2.append(value.quoteIfNeeded());
+                    } 
+                    return sb2.toString();
+                }).collect(Collectors.joining(" ")));
+            }
+            sb.append('>');
+            break;
+        case TEXT:
+            sb.append(element.toString());
+        }
+        return sb.toString();
+    };
+}
diff --git a/tag-modifier/src/main/javacc/htmlParser.jj b/tag-modifier/src/main/javacc/htmlParser.jj
new file mode 100644
index 0000000..9b41e05
--- /dev/null
+++ b/tag-modifier/src/main/javacc/htmlParser.jj
@@ -0,0 +1,231 @@
+/*
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+options { 
+  IGNORE_CASE = true;
+  STATIC = false;
+  UNICODE_INPUT = true;
+} 
+
+PARSER_BEGIN(TagParser)
+package org.apache.sling.tagmodifier.impl;
+
+import com.github.tagstream.*;
+import com.github.tagstream.impl.tag.*;
+import java.util.*;
+
+public class TagParser {
+
+  private static String getTokenHtmlText(Token first, Token cur) {
+    Token t;
+    StringBuilder sb = new StringBuilder();
+
+    for (t=first; t != cur.next; t = t.next) {
+      if (t.specialToken != null) {
+        Token tt=t.specialToken;
+        while (tt.specialToken != null) 
+          tt = tt.specialToken;
+        for (; tt != null; tt = tt.next) 
+          sb.append(tt.image);
+      };
+      sb.append(t.image);
+    };
+    return sb.toString();
+  }
+
+}
+
+PARSER_END(TagParser)
+
+< * >TOKEN :
+{
+  <#SPACE: ( " " | "\t" | "\n" | "\r" | "\u000C" ) >
+| <#ATTR_IDENTIFIER:  (~[" ", "\t", "\n", "\r", "\u000C", "=", "/", ">" ])+ >
+| <#NAME_IDENTIFIER:  (~[" ", "\t", "\n", "\r", "\u000C", "/", ">" ])+ >
+| <#SQUOTE : ( "'" ( ~["'"] )* "'") >
+| <#DQUOTE : ( "\"" ( ~["\""] )* "\"") >
+| <#TAG_END: ">" >
+| <#TAG_SLASHEND: "/>" >
+}
+
+
+<DEFAULT> TOKEN : 
+{
+  <TAG_START:      "<"       > : START_TAG
+| <ENDTAG_START:   "</"      > : START_TAG
+| <COMMENT_START:  "<!--"    > : COMMENT
+| <DECL_START:     "<!"      > : DECLARATION
+| <RAWTEXT:         ( ~["<"] )+ >
+}
+
+
+<START_TAG> TOKEN :
+{
+ <TAG_NAME: <NAME_IDENTIFIER> > : IN_TAG
+| <LST_ERROR: ~[]>          : DEFAULT
+}
+
+<IN_TAG, ATTR_VALUE, IN_DECLARATION> SPECIAL_TOKEN :
+{
+  < (<SPACE>)+ >
+}
+
+<IN_TAG> TOKEN :
+{
+  <ATTR_NAME: <ATTR_IDENTIFIER> >
+| <END_OF_TAG: <TAG_END> | <TAG_SLASHEND> >    : DEFAULT 
+| <ATTR_EQ: "=" >                              : ATTR_VALUE
+| <LIT_ERROR: ~[]>
+}
+
+
+<ATTR_VALUE> TOKEN :
+{
+  <QUOTED_STRING : < SQUOTE > | < DQUOTE > >{matchedToken.image = image.substring(1, lengthOfMatch - 1);} : IN_TAG
+| <ATTR_VAL:  ( ~[">", "\"", "'", " ", "\t", "\n", "\r"] )+ > : IN_TAG
+| <ERROR: ~[]>
+}
+
+<COMMENT> TOKEN : 
+{
+  < COMMENT_END:  "-->" > : DEFAULT 
+| < COMMENT_WORD: ~[] >
+}
+
+<DECLARATION> TOKEN :
+{
+  <DECL_TAG: <NAME_IDENTIFIER> > : IN_DECLARATION
+}
+
+<IN_DECLARATION> TOKEN :
+{
+  <DECL_ATTR: <QUOTED_STRING> | ( ~[">", "\"", "'", " ", "\t", "\n", "\r"] )+ >
+| <DECL_END: <TAG_END> | <TAG_SLASHEND> >  : DEFAULT 
+}
+
+
+Element element() :
+{
+  Element e;
+  Token text;
+}
+{
+(
+    LOOKAHEAD(2) 
+         e = tag()        { return e; }
+  |      e = endHtmlElement()     { return e; }
+  |      e = commentHtmlElement() { return e; }
+  |      e = decltag()    { return e; }
+  | LOOKAHEAD(2) 
+        <TAG_START> text=<LST_ERROR>
+            { return new TextData("<" + text.image); }
+  |   text = <RAWTEXT>     { return new TextData(text.image); }
+  |   <EOF> { return new EndOfFile(); }
+)
+}
+
+/** @return an attribute */
+void attribute(Map<String,AttrValue > alist) : 
+{
+  Token t1, t2=null;
+}
+{
+  t1=<ATTR_NAME> [ <ATTR_EQ> t2= < QUOTED_STRING > | t2 = <ATTR_VAL> ]
+  {
+     if (t2 == null) {
+        alist.put(t1.image,new AttrValue());
+      } else {
+        alist.put(t1.image,new AttrValue(t2.image));
+     }
+  }
+}
+
+Map<String,AttrValue> attributeList() : 
+{
+  Map<String,AttrValue> alist = new HashMap<String,AttrValue>();
+
+}
+{
+  (attribute(alist) )*
+  {
+     return alist;
+  }
+}
+
+
+Element tag() :
+{
+  Token t, et;
+  Map<String,AttrValue> alist;
+  Token firstToken = getToken(1);
+}
+{
+  try {
+    <TAG_START> t=<TAG_NAME> alist=attributeList() et=<END_OF_TAG>
+    { 
+      return new StartTag(t.image, alist); 
+    }
+  } catch (ParseException ex) {
+    token_source.SwitchTo(DEFAULT); 
+    String s = getTokenHtmlText(firstToken, getNextToken());
+    return new TextData(s);
+  }
+}
+
+/** @return the end of a tag */
+Element endHtmlElement() :
+{
+  Token t;
+  Token firstToken = getToken(1);
+}
+{
+  try {
+    <ENDTAG_START> t=<TAG_NAME> <END_OF_TAG>
+    { return new EndTag(t.image); }
+  } catch (ParseException ex) {
+    token_source.SwitchTo(DEFAULT); 
+    String s = getTokenHtmlText(firstToken, getNextToken());
+    return new TextData(s);
+  }
+}
+
+
+Comment commentHtmlElement() :
+{
+  StringBuilder sb = new StringBuilder();
+}
+{
+  <COMMENT_START> ( <COMMENT_WORD> { sb.append(token.image); } )* (<EOF> | <COMMENT_END>)
+  { return new Comment(sb.toString()); }
+}
+
+/** @return the start of a DECLARATION */
+Element decltag() :
+{
+  Token tok = null;
+  Map<String,AttrValue > alist = new HashMap<String,AttrValue>();
+  Token firstToken = getToken(1);
+}
+{
+  try {
+    <DECL_START> tok=<DECL_TAG> (< DECL_ATTR > { alist.put(token.image,new AttrValue()); })* <DECL_END>
+    {
+      return new StartTag(tok.image, alist); 
+    }
+  } catch (ParseException ex) {
+    token_source.SwitchTo(DEFAULT); 
+    String s = getTokenHtmlText(firstToken, getNextToken());
+    return new TextData(s);
+  }
+}
diff --git a/tag-modifier/src/main/resources/entities.json b/tag-modifier/src/main/resources/entities.json
new file mode 100644
index 0000000..6fed08d
--- /dev/null
+++ b/tag-modifier/src/main/resources/entities.json
@@ -0,0 +1,2233 @@
+{
+  "&Aacute;": { "codepoints": [193], "characters": "\u00C1" },
+  "&Aacute": { "codepoints": [193], "characters": "\u00C1" },
+  "&aacute;": { "codepoints": [225], "characters": "\u00E1" },
+  "&aacute": { "codepoints": [225], "characters": "\u00E1" },
+  "&Abreve;": { "codepoints": [258], "characters": "\u0102" },
+  "&abreve;": { "codepoints": [259], "characters": "\u0103" },
+  "&ac;": { "codepoints": [8766], "characters": "\u223E" },
+  "&acd;": { "codepoints": [8767], "characters": "\u223F" },
+  "&acE;": { "codepoints": [8766, 819], "characters": "\u223E\u0333" },
+  "&Acirc;": { "codepoints": [194], "characters": "\u00C2" },
+  "&Acirc": { "codepoints": [194], "characters": "\u00C2" },
+  "&acirc;": { "codepoints": [226], "characters": "\u00E2" },
+  "&acirc": { "codepoints": [226], "characters": "\u00E2" },
+  "&acute;": { "codepoints": [180], "characters": "\u00B4" },
+  "&acute": { "codepoints": [180], "characters": "\u00B4" },
+  "&Acy;": { "codepoints": [1040], "characters": "\u0410" },
+  "&acy;": { "codepoints": [1072], "characters": "\u0430" },
+  "&AElig;": { "codepoints": [198], "characters": "\u00C6" },
+  "&AElig": { "codepoints": [198], "characters": "\u00C6" },
+  "&aelig;": { "codepoints": [230], "characters": "\u00E6" },
+  "&aelig": { "codepoints": [230], "characters": "\u00E6" },
+  "&af;": { "codepoints": [8289], "characters": "\u2061" },
+  "&Afr;": { "codepoints": [120068], "characters": "\uD835\uDD04" },
+  "&afr;": { "codepoints": [120094], "characters": "\uD835\uDD1E" },
+  "&Agrave;": { "codepoints": [192], "characters": "\u00C0" },
+  "&Agrave": { "codepoints": [192], "characters": "\u00C0" },
+  "&agrave;": { "codepoints": [224], "characters": "\u00E0" },
+  "&agrave": { "codepoints": [224], "characters": "\u00E0" },
+  "&alefsym;": { "codepoints": [8501], "characters": "\u2135" },
+  "&aleph;": { "codepoints": [8501], "characters": "\u2135" },
+  "&Alpha;": { "codepoints": [913], "characters": "\u0391" },
+  "&alpha;": { "codepoints": [945], "characters": "\u03B1" },
+  "&Amacr;": { "codepoints": [256], "characters": "\u0100" },
+  "&amacr;": { "codepoints": [257], "characters": "\u0101" },
+  "&amalg;": { "codepoints": [10815], "characters": "\u2A3F" },
+  "&amp;": { "codepoints": [38], "characters": "\u0026" },
+  "&amp": { "codepoints": [38], "characters": "\u0026" },
+  "&AMP;": { "codepoints": [38], "characters": "\u0026" },
+  "&AMP": { "codepoints": [38], "characters": "\u0026" },
+  "&andand;": { "codepoints": [10837], "characters": "\u2A55" },
+  "&And;": { "codepoints": [10835], "characters": "\u2A53" },
+  "&and;": { "codepoints": [8743], "characters": "\u2227" },
+  "&andd;": { "codepoints": [10844], "characters": "\u2A5C" },
+  "&andslope;": { "codepoints": [10840], "characters": "\u2A58" },
+  "&andv;": { "codepoints": [10842], "characters": "\u2A5A" },
+  "&ang;": { "codepoints": [8736], "characters": "\u2220" },
+  "&ange;": { "codepoints": [10660], "characters": "\u29A4" },
+  "&angle;": { "codepoints": [8736], "characters": "\u2220" },
+  "&angmsdaa;": { "codepoints": [10664], "characters": "\u29A8" },
+  "&angmsdab;": { "codepoints": [10665], "characters": "\u29A9" },
+  "&angmsdac;": { "codepoints": [10666], "characters": "\u29AA" },
+  "&angmsdad;": { "codepoints": [10667], "characters": "\u29AB" },
+  "&angmsdae;": { "codepoints": [10668], "characters": "\u29AC" },
+  "&angmsdaf;": { "codepoints": [10669], "characters": "\u29AD" },
+  "&angmsdag;": { "codepoints": [10670], "characters": "\u29AE" },
+  "&angmsdah;": { "codepoints": [10671], "characters": "\u29AF" },
+  "&angmsd;": { "codepoints": [8737], "characters": "\u2221" },
+  "&angrt;": { "codepoints": [8735], "characters": "\u221F" },
+  "&angrtvb;": { "codepoints": [8894], "characters": "\u22BE" },
+  "&angrtvbd;": { "codepoints": [10653], "characters": "\u299D" },
+  "&angsph;": { "codepoints": [8738], "characters": "\u2222" },
+  "&angst;": { "codepoints": [197], "characters": "\u00C5" },
+  "&angzarr;": { "codepoints": [9084], "characters": "\u237C" },
+  "&Aogon;": { "codepoints": [260], "characters": "\u0104" },
+  "&aogon;": { "codepoints": [261], "characters": "\u0105" },
+  "&Aopf;": { "codepoints": [120120], "characters": "\uD835\uDD38" },
+  "&aopf;": { "codepoints": [120146], "characters": "\uD835\uDD52" },
+  "&apacir;": { "codepoints": [10863], "characters": "\u2A6F" },
+  "&ap;": { "codepoints": [8776], "characters": "\u2248" },
+  "&apE;": { "codepoints": [10864], "characters": "\u2A70" },
+  "&ape;": { "codepoints": [8778], "characters": "\u224A" },
+  "&apid;": { "codepoints": [8779], "characters": "\u224B" },
+  "&apos;": { "codepoints": [39], "characters": "\u0027" },
+  "&ApplyFunction;": { "codepoints": [8289], "characters": "\u2061" },
+  "&approx;": { "codepoints": [8776], "characters": "\u2248" },
+  "&approxeq;": { "codepoints": [8778], "characters": "\u224A" },
+  "&Aring;": { "codepoints": [197], "characters": "\u00C5" },
+  "&Aring": { "codepoints": [197], "characters": "\u00C5" },
+  "&aring;": { "codepoints": [229], "characters": "\u00E5" },
+  "&aring": { "codepoints": [229], "characters": "\u00E5" },
+  "&Ascr;": { "codepoints": [119964], "characters": "\uD835\uDC9C" },
+  "&ascr;": { "codepoints": [119990], "characters": "\uD835\uDCB6" },
+  "&Assign;": { "codepoints": [8788], "characters": "\u2254" },
+  "&ast;": { "codepoints": [42], "characters": "\u002A" },
+  "&asymp;": { "codepoints": [8776], "characters": "\u2248" },
+  "&asympeq;": { "codepoints": [8781], "characters": "\u224D" },
+  "&Atilde;": { "codepoints": [195], "characters": "\u00C3" },
+  "&Atilde": { "codepoints": [195], "characters": "\u00C3" },
+  "&atilde;": { "codepoints": [227], "characters": "\u00E3" },
+  "&atilde": { "codepoints": [227], "characters": "\u00E3" },
+  "&Auml;": { "codepoints": [196], "characters": "\u00C4" },
+  "&Auml": { "codepoints": [196], "characters": "\u00C4" },
+  "&auml;": { "codepoints": [228], "characters": "\u00E4" },
+  "&auml": { "codepoints": [228], "characters": "\u00E4" },
+  "&awconint;": { "codepoints": [8755], "characters": "\u2233" },
+  "&awint;": { "codepoints": [10769], "characters": "\u2A11" },
+  "&backcong;": { "codepoints": [8780], "characters": "\u224C" },
+  "&backepsilon;": { "codepoints": [1014], "characters": "\u03F6" },
+  "&backprime;": { "codepoints": [8245], "characters": "\u2035" },
+  "&backsim;": { "codepoints": [8765], "characters": "\u223D" },
+  "&backsimeq;": { "codepoints": [8909], "characters": "\u22CD" },
+  "&Backslash;": { "codepoints": [8726], "characters": "\u2216" },
+  "&Barv;": { "codepoints": [10983], "characters": "\u2AE7" },
+  "&barvee;": { "codepoints": [8893], "characters": "\u22BD" },
+  "&barwed;": { "codepoints": [8965], "characters": "\u2305" },
+  "&Barwed;": { "codepoints": [8966], "characters": "\u2306" },
+  "&barwedge;": { "codepoints": [8965], "characters": "\u2305" },
+  "&bbrk;": { "codepoints": [9141], "characters": "\u23B5" },
+  "&bbrktbrk;": { "codepoints": [9142], "characters": "\u23B6" },
+  "&bcong;": { "codepoints": [8780], "characters": "\u224C" },
+  "&Bcy;": { "codepoints": [1041], "characters": "\u0411" },
+  "&bcy;": { "codepoints": [1073], "characters": "\u0431" },
+  "&bdquo;": { "codepoints": [8222], "characters": "\u201E" },
+  "&becaus;": { "codepoints": [8757], "characters": "\u2235" },
+  "&because;": { "codepoints": [8757], "characters": "\u2235" },
+  "&Because;": { "codepoints": [8757], "characters": "\u2235" },
+  "&bemptyv;": { "codepoints": [10672], "characters": "\u29B0" },
+  "&bepsi;": { "codepoints": [1014], "characters": "\u03F6" },
+  "&bernou;": { "codepoints": [8492], "characters": "\u212C" },
+  "&Bernoullis;": { "codepoints": [8492], "characters": "\u212C" },
+  "&Beta;": { "codepoints": [914], "characters": "\u0392" },
+  "&beta;": { "codepoints": [946], "characters": "\u03B2" },
+  "&beth;": { "codepoints": [8502], "characters": "\u2136" },
+  "&between;": { "codepoints": [8812], "characters": "\u226C" },
+  "&Bfr;": { "codepoints": [120069], "characters": "\uD835\uDD05" },
+  "&bfr;": { "codepoints": [120095], "characters": "\uD835\uDD1F" },
+  "&bigcap;": { "codepoints": [8898], "characters": "\u22C2" },
+  "&bigcirc;": { "codepoints": [9711], "characters": "\u25EF" },
+  "&bigcup;": { "codepoints": [8899], "characters": "\u22C3" },
+  "&bigodot;": { "codepoints": [10752], "characters": "\u2A00" },
+  "&bigoplus;": { "codepoints": [10753], "characters": "\u2A01" },
+  "&bigotimes;": { "codepoints": [10754], "characters": "\u2A02" },
+  "&bigsqcup;": { "codepoints": [10758], "characters": "\u2A06" },
+  "&bigstar;": { "codepoints": [9733], "characters": "\u2605" },
+  "&bigtriangledown;": { "codepoints": [9661], "characters": "\u25BD" },
+  "&bigtriangleup;": { "codepoints": [9651], "characters": "\u25B3" },
+  "&biguplus;": { "codepoints": [10756], "characters": "\u2A04" },
+  "&bigvee;": { "codepoints": [8897], "characters": "\u22C1" },
+  "&bigwedge;": { "codepoints": [8896], "characters": "\u22C0" },
+  "&bkarow;": { "codepoints": [10509], "characters": "\u290D" },
+  "&blacklozenge;": { "codepoints": [10731], "characters": "\u29EB" },
+  "&blacksquare;": { "codepoints": [9642], "characters": "\u25AA" },
+  "&blacktriangle;": { "codepoints": [9652], "characters": "\u25B4" },
+  "&blacktriangledown;": { "codepoints": [9662], "characters": "\u25BE" },
+  "&blacktriangleleft;": { "codepoints": [9666], "characters": "\u25C2" },
+  "&blacktriangleright;": { "codepoints": [9656], "characters": "\u25B8" },
+  "&blank;": { "codepoints": [9251], "characters": "\u2423" },
+  "&blk12;": { "codepoints": [9618], "characters": "\u2592" },
+  "&blk14;": { "codepoints": [9617], "characters": "\u2591" },
+  "&blk34;": { "codepoints": [9619], "characters": "\u2593" },
+  "&block;": { "codepoints": [9608], "characters": "\u2588" },
+  "&bne;": { "codepoints": [61, 8421], "characters": "\u003D\u20E5" },
+  "&bnequiv;": { "codepoints": [8801, 8421], "characters": "\u2261\u20E5" },
+  "&bNot;": { "codepoints": [10989], "characters": "\u2AED" },
+  "&bnot;": { "codepoints": [8976], "characters": "\u2310" },
+  "&Bopf;": { "codepoints": [120121], "characters": "\uD835\uDD39" },
+  "&bopf;": { "codepoints": [120147], "characters": "\uD835\uDD53" },
+  "&bot;": { "codepoints": [8869], "characters": "\u22A5" },
+  "&bottom;": { "codepoints": [8869], "characters": "\u22A5" },
+  "&bowtie;": { "codepoints": [8904], "characters": "\u22C8" },
+  "&boxbox;": { "codepoints": [10697], "characters": "\u29C9" },
+  "&boxdl;": { "codepoints": [9488], "characters": "\u2510" },
+  "&boxdL;": { "codepoints": [9557], "characters": "\u2555" },
+  "&boxDl;": { "codepoints": [9558], "characters": "\u2556" },
+  "&boxDL;": { "codepoints": [9559], "characters": "\u2557" },
+  "&boxdr;": { "codepoints": [9484], "characters": "\u250C" },
+  "&boxdR;": { "codepoints": [9554], "characters": "\u2552" },
+  "&boxDr;": { "codepoints": [9555], "characters": "\u2553" },
+  "&boxDR;": { "codepoints": [9556], "characters": "\u2554" },
+  "&boxh;": { "codepoints": [9472], "characters": "\u2500" },
+  "&boxH;": { "codepoints": [9552], "characters": "\u2550" },
+  "&boxhd;": { "codepoints": [9516], "characters": "\u252C" },
+  "&boxHd;": { "codepoints": [9572], "characters": "\u2564" },
+  "&boxhD;": { "codepoints": [9573], "characters": "\u2565" },
+  "&boxHD;": { "codepoints": [9574], "characters": "\u2566" },
+  "&boxhu;": { "codepoints": [9524], "characters": "\u2534" },
+  "&boxHu;": { "codepoints": [9575], "characters": "\u2567" },
+  "&boxhU;": { "codepoints": [9576], "characters": "\u2568" },
+  "&boxHU;": { "codepoints": [9577], "characters": "\u2569" },
+  "&boxminus;": { "codepoints": [8863], "characters": "\u229F" },
+  "&boxplus;": { "codepoints": [8862], "characters": "\u229E" },
+  "&boxtimes;": { "codepoints": [8864], "characters": "\u22A0" },
+  "&boxul;": { "codepoints": [9496], "characters": "\u2518" },
+  "&boxuL;": { "codepoints": [9563], "characters": "\u255B" },
+  "&boxUl;": { "codepoints": [9564], "characters": "\u255C" },
+  "&boxUL;": { "codepoints": [9565], "characters": "\u255D" },
+  "&boxur;": { "codepoints": [9492], "characters": "\u2514" },
+  "&boxuR;": { "codepoints": [9560], "characters": "\u2558" },
+  "&boxUr;": { "codepoints": [9561], "characters": "\u2559" },
+  "&boxUR;": { "codepoints": [9562], "characters": "\u255A" },
+  "&boxv;": { "codepoints": [9474], "characters": "\u2502" },
+  "&boxV;": { "codepoints": [9553], "characters": "\u2551" },
+  "&boxvh;": { "codepoints": [9532], "characters": "\u253C" },
+  "&boxvH;": { "codepoints": [9578], "characters": "\u256A" },
+  "&boxVh;": { "codepoints": [9579], "characters": "\u256B" },
+  "&boxVH;": { "codepoints": [9580], "characters": "\u256C" },
+  "&boxvl;": { "codepoints": [9508], "characters": "\u2524" },
+  "&boxvL;": { "codepoints": [9569], "characters": "\u2561" },
+  "&boxVl;": { "codepoints": [9570], "characters": "\u2562" },
+  "&boxVL;": { "codepoints": [9571], "characters": "\u2563" },
+  "&boxvr;": { "codepoints": [9500], "characters": "\u251C" },
+  "&boxvR;": { "codepoints": [9566], "characters": "\u255E" },
+  "&boxVr;": { "codepoints": [9567], "characters": "\u255F" },
+  "&boxVR;": { "codepoints": [9568], "characters": "\u2560" },
+  "&bprime;": { "codepoints": [8245], "characters": "\u2035" },
+  "&breve;": { "codepoints": [728], "characters": "\u02D8" },
+  "&Breve;": { "codepoints": [728], "characters": "\u02D8" },
+  "&brvbar;": { "codepoints": [166], "characters": "\u00A6" },
+  "&brvbar": { "codepoints": [166], "characters": "\u00A6" },
+  "&bscr;": { "codepoints": [119991], "characters": "\uD835\uDCB7" },
+  "&Bscr;": { "codepoints": [8492], "characters": "\u212C" },
+  "&bsemi;": { "codepoints": [8271], "characters": "\u204F" },
+  "&bsim;": { "codepoints": [8765], "characters": "\u223D" },
+  "&bsime;": { "codepoints": [8909], "characters": "\u22CD" },
+  "&bsolb;": { "codepoints": [10693], "characters": "\u29C5" },
+  "&bsol;": { "codepoints": [92], "characters": "\u005C" },
+  "&bsolhsub;": { "codepoints": [10184], "characters": "\u27C8" },
+  "&bull;": { "codepoints": [8226], "characters": "\u2022" },
+  "&bullet;": { "codepoints": [8226], "characters": "\u2022" },
+  "&bump;": { "codepoints": [8782], "characters": "\u224E" },
+  "&bumpE;": { "codepoints": [10926], "characters": "\u2AAE" },
+  "&bumpe;": { "codepoints": [8783], "characters": "\u224F" },
+  "&Bumpeq;": { "codepoints": [8782], "characters": "\u224E" },
+  "&bumpeq;": { "codepoints": [8783], "characters": "\u224F" },
+  "&Cacute;": { "codepoints": [262], "characters": "\u0106" },
+  "&cacute;": { "codepoints": [263], "characters": "\u0107" },
+  "&capand;": { "codepoints": [10820], "characters": "\u2A44" },
+  "&capbrcup;": { "codepoints": [10825], "characters": "\u2A49" },
+  "&capcap;": { "codepoints": [10827], "characters": "\u2A4B" },
+  "&cap;": { "codepoints": [8745], "characters": "\u2229" },
+  "&Cap;": { "codepoints": [8914], "characters": "\u22D2" },
+  "&capcup;": { "codepoints": [10823], "characters": "\u2A47" },
+  "&capdot;": { "codepoints": [10816], "characters": "\u2A40" },
+  "&CapitalDifferentialD;": { "codepoints": [8517], "characters": "\u2145" },
+  "&caps;": { "codepoints": [8745, 65024], "characters": "\u2229\uFE00" },
+  "&caret;": { "codepoints": [8257], "characters": "\u2041" },
+  "&caron;": { "codepoints": [711], "characters": "\u02C7" },
+  "&Cayleys;": { "codepoints": [8493], "characters": "\u212D" },
+  "&ccaps;": { "codepoints": [10829], "characters": "\u2A4D" },
+  "&Ccaron;": { "codepoints": [268], "characters": "\u010C" },
+  "&ccaron;": { "codepoints": [269], "characters": "\u010D" },
+  "&Ccedil;": { "codepoints": [199], "characters": "\u00C7" },
+  "&Ccedil": { "codepoints": [199], "characters": "\u00C7" },
+  "&ccedil;": { "codepoints": [231], "characters": "\u00E7" },
+  "&ccedil": { "codepoints": [231], "characters": "\u00E7" },
+  "&Ccirc;": { "codepoints": [264], "characters": "\u0108" },
+  "&ccirc;": { "codepoints": [265], "characters": "\u0109" },
+  "&Cconint;": { "codepoints": [8752], "characters": "\u2230" },
+  "&ccups;": { "codepoints": [10828], "characters": "\u2A4C" },
+  "&ccupssm;": { "codepoints": [10832], "characters": "\u2A50" },
+  "&Cdot;": { "codepoints": [266], "characters": "\u010A" },
+  "&cdot;": { "codepoints": [267], "characters": "\u010B" },
+  "&cedil;": { "codepoints": [184], "characters": "\u00B8" },
+  "&cedil": { "codepoints": [184], "characters": "\u00B8" },
+  "&Cedilla;": { "codepoints": [184], "characters": "\u00B8" },
+  "&cemptyv;": { "codepoints": [10674], "characters": "\u29B2" },
+  "&cent;": { "codepoints": [162], "characters": "\u00A2" },
+  "&cent": { "codepoints": [162], "characters": "\u00A2" },
+  "&centerdot;": { "codepoints": [183], "characters": "\u00B7" },
+  "&CenterDot;": { "codepoints": [183], "characters": "\u00B7" },
+  "&cfr;": { "codepoints": [120096], "characters": "\uD835\uDD20" },
+  "&Cfr;": { "codepoints": [8493], "characters": "\u212D" },
+  "&CHcy;": { "codepoints": [1063], "characters": "\u0427" },
+  "&chcy;": { "codepoints": [1095], "characters": "\u0447" },
+  "&check;": { "codepoints": [10003], "characters": "\u2713" },
+  "&checkmark;": { "codepoints": [10003], "characters": "\u2713" },
+  "&Chi;": { "codepoints": [935], "characters": "\u03A7" },
+  "&chi;": { "codepoints": [967], "characters": "\u03C7" },
+  "&circ;": { "codepoints": [710], "characters": "\u02C6" },
+  "&circeq;": { "codepoints": [8791], "characters": "\u2257" },
+  "&circlearrowleft;": { "codepoints": [8634], "characters": "\u21BA" },
+  "&circlearrowright;": { "codepoints": [8635], "characters": "\u21BB" },
+  "&circledast;": { "codepoints": [8859], "characters": "\u229B" },
+  "&circledcirc;": { "codepoints": [8858], "characters": "\u229A" },
+  "&circleddash;": { "codepoints": [8861], "characters": "\u229D" },
+  "&CircleDot;": { "codepoints": [8857], "characters": "\u2299" },
+  "&circledR;": { "codepoints": [174], "characters": "\u00AE" },
+  "&circledS;": { "codepoints": [9416], "characters": "\u24C8" },
+  "&CircleMinus;": { "codepoints": [8854], "characters": "\u2296" },
+  "&CirclePlus;": { "codepoints": [8853], "characters": "\u2295" },
+  "&CircleTimes;": { "codepoints": [8855], "characters": "\u2297" },
+  "&cir;": { "codepoints": [9675], "characters": "\u25CB" },
+  "&cirE;": { "codepoints": [10691], "characters": "\u29C3" },
+  "&cire;": { "codepoints": [8791], "characters": "\u2257" },
+  "&cirfnint;": { "codepoints": [10768], "characters": "\u2A10" },
+  "&cirmid;": { "codepoints": [10991], "characters": "\u2AEF" },
+  "&cirscir;": { "codepoints": [10690], "characters": "\u29C2" },
+  "&ClockwiseContourIntegral;": { "codepoints": [8754], "characters": "\u2232" },
+  "&CloseCurlyDoubleQuote;": { "codepoints": [8221], "characters": "\u201D" },
+  "&CloseCurlyQuote;": { "codepoints": [8217], "characters": "\u2019" },
+  "&clubs;": { "codepoints": [9827], "characters": "\u2663" },
+  "&clubsuit;": { "codepoints": [9827], "characters": "\u2663" },
+  "&colon;": { "codepoints": [58], "characters": "\u003A" },
+  "&Colon;": { "codepoints": [8759], "characters": "\u2237" },
+  "&Colone;": { "codepoints": [10868], "characters": "\u2A74" },
+  "&colone;": { "codepoints": [8788], "characters": "\u2254" },
+  "&coloneq;": { "codepoints": [8788], "characters": "\u2254" },
+  "&comma;": { "codepoints": [44], "characters": "\u002C" },
+  "&commat;": { "codepoints": [64], "characters": "\u0040" },
+  "&comp;": { "codepoints": [8705], "characters": "\u2201" },
+  "&compfn;": { "codepoints": [8728], "characters": "\u2218" },
+  "&complement;": { "codepoints": [8705], "characters": "\u2201" },
+  "&complexes;": { "codepoints": [8450], "characters": "\u2102" },
+  "&cong;": { "codepoints": [8773], "characters": "\u2245" },
+  "&congdot;": { "codepoints": [10861], "characters": "\u2A6D" },
+  "&Congruent;": { "codepoints": [8801], "characters": "\u2261" },
+  "&conint;": { "codepoints": [8750], "characters": "\u222E" },
+  "&Conint;": { "codepoints": [8751], "characters": "\u222F" },
+  "&ContourIntegral;": { "codepoints": [8750], "characters": "\u222E" },
+  "&copf;": { "codepoints": [120148], "characters": "\uD835\uDD54" },
+  "&Copf;": { "codepoints": [8450], "characters": "\u2102" },
+  "&coprod;": { "codepoints": [8720], "characters": "\u2210" },
+  "&Coproduct;": { "codepoints": [8720], "characters": "\u2210" },
+  "&copy;": { "codepoints": [169], "characters": "\u00A9" },
+  "&copy": { "codepoints": [169], "characters": "\u00A9" },
+  "&COPY;": { "codepoints": [169], "characters": "\u00A9" },
+  "&COPY": { "codepoints": [169], "characters": "\u00A9" },
+  "&copysr;": { "codepoints": [8471], "characters": "\u2117" },
+  "&CounterClockwiseContourIntegral;": { "codepoints": [8755], "characters": "\u2233" },
+  "&crarr;": { "codepoints": [8629], "characters": "\u21B5" },
+  "&cross;": { "codepoints": [10007], "characters": "\u2717" },
+  "&Cross;": { "codepoints": [10799], "characters": "\u2A2F" },
+  "&Cscr;": { "codepoints": [119966], "characters": "\uD835\uDC9E" },
+  "&cscr;": { "codepoints": [119992], "characters": "\uD835\uDCB8" },
+  "&csub;": { "codepoints": [10959], "characters": "\u2ACF" },
+  "&csube;": { "codepoints": [10961], "characters": "\u2AD1" },
+  "&csup;": { "codepoints": [10960], "characters": "\u2AD0" },
+  "&csupe;": { "codepoints": [10962], "characters": "\u2AD2" },
+  "&ctdot;": { "codepoints": [8943], "characters": "\u22EF" },
+  "&cudarrl;": { "codepoints": [10552], "characters": "\u2938" },
+  "&cudarrr;": { "codepoints": [10549], "characters": "\u2935" },
+  "&cuepr;": { "codepoints": [8926], "characters": "\u22DE" },
+  "&cuesc;": { "codepoints": [8927], "characters": "\u22DF" },
+  "&cularr;": { "codepoints": [8630], "characters": "\u21B6" },
+  "&cularrp;": { "codepoints": [10557], "characters": "\u293D" },
+  "&cupbrcap;": { "codepoints": [10824], "characters": "\u2A48" },
+  "&cupcap;": { "codepoints": [10822], "characters": "\u2A46" },
+  "&CupCap;": { "codepoints": [8781], "characters": "\u224D" },
+  "&cup;": { "codepoints": [8746], "characters": "\u222A" },
+  "&Cup;": { "codepoints": [8915], "characters": "\u22D3" },
+  "&cupcup;": { "codepoints": [10826], "characters": "\u2A4A" },
+  "&cupdot;": { "codepoints": [8845], "characters": "\u228D" },
+  "&cupor;": { "codepoints": [10821], "characters": "\u2A45" },
+  "&cups;": { "codepoints": [8746, 65024], "characters": "\u222A\uFE00" },
+  "&curarr;": { "codepoints": [8631], "characters": "\u21B7" },
+  "&curarrm;": { "codepoints": [10556], "characters": "\u293C" },
+  "&curlyeqprec;": { "codepoints": [8926], "characters": "\u22DE" },
+  "&curlyeqsucc;": { "codepoints": [8927], "characters": "\u22DF" },
+  "&curlyvee;": { "codepoints": [8910], "characters": "\u22CE" },
+  "&curlywedge;": { "codepoints": [8911], "characters": "\u22CF" },
+  "&curren;": { "codepoints": [164], "characters": "\u00A4" },
+  "&curren": { "codepoints": [164], "characters": "\u00A4" },
+  "&curvearrowleft;": { "codepoints": [8630], "characters": "\u21B6" },
+  "&curvearrowright;": { "codepoints": [8631], "characters": "\u21B7" },
+  "&cuvee;": { "codepoints": [8910], "characters": "\u22CE" },
+  "&cuwed;": { "codepoints": [8911], "characters": "\u22CF" },
+  "&cwconint;": { "codepoints": [8754], "characters": "\u2232" },
+  "&cwint;": { "codepoints": [8753], "characters": "\u2231" },
+  "&cylcty;": { "codepoints": [9005], "characters": "\u232D" },
+  "&dagger;": { "codepoints": [8224], "characters": "\u2020" },
+  "&Dagger;": { "codepoints": [8225], "characters": "\u2021" },
+  "&daleth;": { "codepoints": [8504], "characters": "\u2138" },
+  "&darr;": { "codepoints": [8595], "characters": "\u2193" },
+  "&Darr;": { "codepoints": [8609], "characters": "\u21A1" },
+  "&dArr;": { "codepoints": [8659], "characters": "\u21D3" },
+  "&dash;": { "codepoints": [8208], "characters": "\u2010" },
+  "&Dashv;": { "codepoints": [10980], "characters": "\u2AE4" },
+  "&dashv;": { "codepoints": [8867], "characters": "\u22A3" },
+  "&dbkarow;": { "codepoints": [10511], "characters": "\u290F" },
+  "&dblac;": { "codepoints": [733], "characters": "\u02DD" },
+  "&Dcaron;": { "codepoints": [270], "characters": "\u010E" },
+  "&dcaron;": { "codepoints": [271], "characters": "\u010F" },
+  "&Dcy;": { "codepoints": [1044], "characters": "\u0414" },
+  "&dcy;": { "codepoints": [1076], "characters": "\u0434" },
+  "&ddagger;": { "codepoints": [8225], "characters": "\u2021" },
+  "&ddarr;": { "codepoints": [8650], "characters": "\u21CA" },
+  "&DD;": { "codepoints": [8517], "characters": "\u2145" },
+  "&dd;": { "codepoints": [8518], "characters": "\u2146" },
+  "&DDotrahd;": { "codepoints": [10513], "characters": "\u2911" },
+  "&ddotseq;": { "codepoints": [10871], "characters": "\u2A77" },
+  "&deg;": { "codepoints": [176], "characters": "\u00B0" },
+  "&deg": { "codepoints": [176], "characters": "\u00B0" },
+  "&Del;": { "codepoints": [8711], "characters": "\u2207" },
+  "&Delta;": { "codepoints": [916], "characters": "\u0394" },
+  "&delta;": { "codepoints": [948], "characters": "\u03B4" },
+  "&demptyv;": { "codepoints": [10673], "characters": "\u29B1" },
+  "&dfisht;": { "codepoints": [10623], "characters": "\u297F" },
+  "&Dfr;": { "codepoints": [120071], "characters": "\uD835\uDD07" },
+  "&dfr;": { "codepoints": [120097], "characters": "\uD835\uDD21" },
+  "&dHar;": { "codepoints": [10597], "characters": "\u2965" },
+  "&dharl;": { "codepoints": [8643], "characters": "\u21C3" },
+  "&dharr;": { "codepoints": [8642], "characters": "\u21C2" },
+  "&DiacriticalAcute;": { "codepoints": [180], "characters": "\u00B4" },
+  "&DiacriticalDot;": { "codepoints": [729], "characters": "\u02D9" },
+  "&DiacriticalDoubleAcute;": { "codepoints": [733], "characters": "\u02DD" },
+  "&DiacriticalGrave;": { "codepoints": [96], "characters": "\u0060" },
+  "&DiacriticalTilde;": { "codepoints": [732], "characters": "\u02DC" },
+  "&diam;": { "codepoints": [8900], "characters": "\u22C4" },
+  "&diamond;": { "codepoints": [8900], "characters": "\u22C4" },
+  "&Diamond;": { "codepoints": [8900], "characters": "\u22C4" },
+  "&diamondsuit;": { "codepoints": [9830], "characters": "\u2666" },
+  "&diams;": { "codepoints": [9830], "characters": "\u2666" },
+  "&die;": { "codepoints": [168], "characters": "\u00A8" },
+  "&DifferentialD;": { "codepoints": [8518], "characters": "\u2146" },
+  "&digamma;": { "codepoints": [989], "characters": "\u03DD" },
+  "&disin;": { "codepoints": [8946], "characters": "\u22F2" },
+  "&div;": { "codepoints": [247], "characters": "\u00F7" },
+  "&divide;": { "codepoints": [247], "characters": "\u00F7" },
+  "&divide": { "codepoints": [247], "characters": "\u00F7" },
+  "&divideontimes;": { "codepoints": [8903], "characters": "\u22C7" },
+  "&divonx;": { "codepoints": [8903], "characters": "\u22C7" },
+  "&DJcy;": { "codepoints": [1026], "characters": "\u0402" },
+  "&djcy;": { "codepoints": [1106], "characters": "\u0452" },
+  "&dlcorn;": { "codepoints": [8990], "characters": "\u231E" },
+  "&dlcrop;": { "codepoints": [8973], "characters": "\u230D" },
+  "&dollar;": { "codepoints": [36], "characters": "\u0024" },
+  "&Dopf;": { "codepoints": [120123], "characters": "\uD835\uDD3B" },
+  "&dopf;": { "codepoints": [120149], "characters": "\uD835\uDD55" },
+  "&Dot;": { "codepoints": [168], "characters": "\u00A8" },
+  "&dot;": { "codepoints": [729], "characters": "\u02D9" },
+  "&DotDot;": { "codepoints": [8412], "characters": "\u20DC" },
+  "&doteq;": { "codepoints": [8784], "characters": "\u2250" },
+  "&doteqdot;": { "codepoints": [8785], "characters": "\u2251" },
+  "&DotEqual;": { "codepoints": [8784], "characters": "\u2250" },
+  "&dotminus;": { "codepoints": [8760], "characters": "\u2238" },
+  "&dotplus;": { "codepoints": [8724], "characters": "\u2214" },
+  "&dotsquare;": { "codepoints": [8865], "characters": "\u22A1" },
+  "&doublebarwedge;": { "codepoints": [8966], "characters": "\u2306" },
+  "&DoubleContourIntegral;": { "codepoints": [8751], "characters": "\u222F" },
+  "&DoubleDot;": { "codepoints": [168], "characters": "\u00A8" },
+  "&DoubleDownArrow;": { "codepoints": [8659], "characters": "\u21D3" },
+  "&DoubleLeftArrow;": { "codepoints": [8656], "characters": "\u21D0" },
+  "&DoubleLeftRightArrow;": { "codepoints": [8660], "characters": "\u21D4" },
+  "&DoubleLeftTee;": { "codepoints": [10980], "characters": "\u2AE4" },
+  "&DoubleLongLeftArrow;": { "codepoints": [10232], "characters": "\u27F8" },
+  "&DoubleLongLeftRightArrow;": { "codepoints": [10234], "characters": "\u27FA" },
+  "&DoubleLongRightArrow;": { "codepoints": [10233], "characters": "\u27F9" },
+  "&DoubleRightArrow;": { "codepoints": [8658], "characters": "\u21D2" },
+  "&DoubleRightTee;": { "codepoints": [8872], "characters": "\u22A8" },
+  "&DoubleUpArrow;": { "codepoints": [8657], "characters": "\u21D1" },
+  "&DoubleUpDownArrow;": { "codepoints": [8661], "characters": "\u21D5" },
+  "&DoubleVerticalBar;": { "codepoints": [8741], "characters": "\u2225" },
+  "&DownArrowBar;": { "codepoints": [10515], "characters": "\u2913" },
+  "&downarrow;": { "codepoints": [8595], "characters": "\u2193" },
+  "&DownArrow;": { "codepoints": [8595], "characters": "\u2193" },
+  "&Downarrow;": { "codepoints": [8659], "characters": "\u21D3" },
+  "&DownArrowUpArrow;": { "codepoints": [8693], "characters": "\u21F5" },
+  "&DownBreve;": { "codepoints": [785], "characters": "\u0311" },
+  "&downdownarrows;": { "codepoints": [8650], "characters": "\u21CA" },
+  "&downharpoonleft;": { "codepoints": [8643], "characters": "\u21C3" },
+  "&downharpoonright;": { "codepoints": [8642], "characters": "\u21C2" },
+  "&DownLeftRightVector;": { "codepoints": [10576], "characters": "\u2950" },
+  "&DownLeftTeeVector;": { "codepoints": [10590], "characters": "\u295E" },
+  "&DownLeftVectorBar;": { "codepoints": [10582], "characters": "\u2956" },
+  "&DownLeftVector;": { "codepoints": [8637], "characters": "\u21BD" },
+  "&DownRightTeeVector;": { "codepoints": [10591], "characters": "\u295F" },
+  "&DownRightVectorBar;": { "codepoints": [10583], "characters": "\u2957" },
+  "&DownRightVector;": { "codepoints": [8641], "characters": "\u21C1" },
+  "&DownTeeArrow;": { "codepoints": [8615], "characters": "\u21A7" },
+  "&DownTee;": { "codepoints": [8868], "characters": "\u22A4" },
+  "&drbkarow;": { "codepoints": [10512], "characters": "\u2910" },
+  "&drcorn;": { "codepoints": [8991], "characters": "\u231F" },
+  "&drcrop;": { "codepoints": [8972], "characters": "\u230C" },
+  "&Dscr;": { "codepoints": [119967], "characters": "\uD835\uDC9F" },
+  "&dscr;": { "codepoints": [119993], "characters": "\uD835\uDCB9" },
+  "&DScy;": { "codepoints": [1029], "characters": "\u0405" },
+  "&dscy;": { "codepoints": [1109], "characters": "\u0455" },
+  "&dsol;": { "codepoints": [10742], "characters": "\u29F6" },
+  "&Dstrok;": { "codepoints": [272], "characters": "\u0110" },
+  "&dstrok;": { "codepoints": [273], "characters": "\u0111" },
+  "&dtdot;": { "codepoints": [8945], "characters": "\u22F1" },
+  "&dtri;": { "codepoints": [9663], "characters": "\u25BF" },
+  "&dtrif;": { "codepoints": [9662], "characters": "\u25BE" },
+  "&duarr;": { "codepoints": [8693], "characters": "\u21F5" },
+  "&duhar;": { "codepoints": [10607], "characters": "\u296F" },
+  "&dwangle;": { "codepoints": [10662], "characters": "\u29A6" },
+  "&DZcy;": { "codepoints": [1039], "characters": "\u040F" },
+  "&dzcy;": { "codepoints": [1119], "characters": "\u045F" },
+  "&dzigrarr;": { "codepoints": [10239], "characters": "\u27FF" },
+  "&Eacute;": { "codepoints": [201], "characters": "\u00C9" },
+  "&Eacute": { "codepoints": [201], "characters": "\u00C9" },
+  "&eacute;": { "codepoints": [233], "characters": "\u00E9" },
+  "&eacute": { "codepoints": [233], "characters": "\u00E9" },
+  "&easter;": { "codepoints": [10862], "characters": "\u2A6E" },
+  "&Ecaron;": { "codepoints": [282], "characters": "\u011A" },
+  "&ecaron;": { "codepoints": [283], "characters": "\u011B" },
+  "&Ecirc;": { "codepoints": [202], "characters": "\u00CA" },
+  "&Ecirc": { "codepoints": [202], "characters": "\u00CA" },
+  "&ecirc;": { "codepoints": [234], "characters": "\u00EA" },
+  "&ecirc": { "codepoints": [234], "characters": "\u00EA" },
+  "&ecir;": { "codepoints": [8790], "characters": "\u2256" },
+  "&ecolon;": { "codepoints": [8789], "characters": "\u2255" },
+  "&Ecy;": { "codepoints": [1069], "characters": "\u042D" },
+  "&ecy;": { "codepoints": [1101], "characters": "\u044D" },
+  "&eDDot;": { "codepoints": [10871], "characters": "\u2A77" },
+  "&Edot;": { "codepoints": [278], "characters": "\u0116" },
+  "&edot;": { "codepoints": [279], "characters": "\u0117" },
+  "&eDot;": { "codepoints": [8785], "characters": "\u2251" },
+  "&ee;": { "codepoints": [8519], "characters": "\u2147" },
+  "&efDot;": { "codepoints": [8786], "characters": "\u2252" },
+  "&Efr;": { "codepoints": [120072], "characters": "\uD835\uDD08" },
+  "&efr;": { "codepoints": [120098], "characters": "\uD835\uDD22" },
+  "&eg;": { "codepoints": [10906], "characters": "\u2A9A" },
+  "&Egrave;": { "codepoints": [200], "characters": "\u00C8" },
+  "&Egrave": { "codepoints": [200], "characters": "\u00C8" },
+  "&egrave;": { "codepoints": [232], "characters": "\u00E8" },
+  "&egrave": { "codepoints": [232], "characters": "\u00E8" },
+  "&egs;": { "codepoints": [10902], "characters": "\u2A96" },
+  "&egsdot;": { "codepoints": [10904], "characters": "\u2A98" },
+  "&el;": { "codepoints": [10905], "characters": "\u2A99" },
+  "&Element;": { "codepoints": [8712], "characters": "\u2208" },
+  "&elinters;": { "codepoints": [9191], "characters": "\u23E7" },
+  "&ell;": { "codepoints": [8467], "characters": "\u2113" },
+  "&els;": { "codepoints": [10901], "characters": "\u2A95" },
+  "&elsdot;": { "codepoints": [10903], "characters": "\u2A97" },
+  "&Emacr;": { "codepoints": [274], "characters": "\u0112" },
+  "&emacr;": { "codepoints": [275], "characters": "\u0113" },
+  "&empty;": { "codepoints": [8709], "characters": "\u2205" },
+  "&emptyset;": { "codepoints": [8709], "characters": "\u2205" },
+  "&EmptySmallSquare;": { "codepoints": [9723], "characters": "\u25FB" },
+  "&emptyv;": { "codepoints": [8709], "characters": "\u2205" },
+  "&EmptyVerySmallSquare;": { "codepoints": [9643], "characters": "\u25AB" },
+  "&emsp13;": { "codepoints": [8196], "characters": "\u2004" },
+  "&emsp14;": { "codepoints": [8197], "characters": "\u2005" },
+  "&emsp;": { "codepoints": [8195], "characters": "\u2003" },
+  "&ENG;": { "codepoints": [330], "characters": "\u014A" },
+  "&eng;": { "codepoints": [331], "characters": "\u014B" },
+  "&ensp;": { "codepoints": [8194], "characters": "\u2002" },
+  "&Eogon;": { "codepoints": [280], "characters": "\u0118" },
+  "&eogon;": { "codepoints": [281], "characters": "\u0119" },
+  "&Eopf;": { "codepoints": [120124], "characters": "\uD835\uDD3C" },
+  "&eopf;": { "codepoints": [120150], "characters": "\uD835\uDD56" },
+  "&epar;": { "codepoints": [8917], "characters": "\u22D5" },
+  "&eparsl;": { "codepoints": [10723], "characters": "\u29E3" },
+  "&eplus;": { "codepoints": [10865], "characters": "\u2A71" },
+  "&epsi;": { "codepoints": [949], "characters": "\u03B5" },
+  "&Epsilon;": { "codepoints": [917], "characters": "\u0395" },
+  "&epsilon;": { "codepoints": [949], "characters": "\u03B5" },
+  "&epsiv;": { "codepoints": [1013], "characters": "\u03F5" },
+  "&eqcirc;": { "codepoints": [8790], "characters": "\u2256" },
+  "&eqcolon;": { "codepoints": [8789], "characters": "\u2255" },
+  "&eqsim;": { "codepoints": [8770], "characters": "\u2242" },
+  "&eqslantgtr;": { "codepoints": [10902], "characters": "\u2A96" },
+  "&eqslantless;": { "codepoints": [10901], "characters": "\u2A95" },
+  "&Equal;": { "codepoints": [10869], "characters": "\u2A75" },
+  "&equals;": { "codepoints": [61], "characters": "\u003D" },
+  "&EqualTilde;": { "codepoints": [8770], "characters": "\u2242" },
+  "&equest;": { "codepoints": [8799], "characters": "\u225F" },
+  "&Equilibrium;": { "codepoints": [8652], "characters": "\u21CC" },
+  "&equiv;": { "codepoints": [8801], "characters": "\u2261" },
+  "&equivDD;": { "codepoints": [10872], "characters": "\u2A78" },
+  "&eqvparsl;": { "codepoints": [10725], "characters": "\u29E5" },
+  "&erarr;": { "codepoints": [10609], "characters": "\u2971" },
+  "&erDot;": { "codepoints": [8787], "characters": "\u2253" },
+  "&escr;": { "codepoints": [8495], "characters": "\u212F" },
+  "&Escr;": { "codepoints": [8496], "characters": "\u2130" },
+  "&esdot;": { "codepoints": [8784], "characters": "\u2250" },
+  "&Esim;": { "codepoints": [10867], "characters": "\u2A73" },
+  "&esim;": { "codepoints": [8770], "characters": "\u2242" },
+  "&Eta;": { "codepoints": [919], "characters": "\u0397" },
+  "&eta;": { "codepoints": [951], "characters": "\u03B7" },
+  "&ETH;": { "codepoints": [208], "characters": "\u00D0" },
+  "&ETH": { "codepoints": [208], "characters": "\u00D0" },
+  "&eth;": { "codepoints": [240], "characters": "\u00F0" },
+  "&eth": { "codepoints": [240], "characters": "\u00F0" },
+  "&Euml;": { "codepoints": [203], "characters": "\u00CB" },
+  "&Euml": { "codepoints": [203], "characters": "\u00CB" },
+  "&euml;": { "codepoints": [235], "characters": "\u00EB" },
+  "&euml": { "codepoints": [235], "characters": "\u00EB" },
+  "&euro;": { "codepoints": [8364], "characters": "\u20AC" },
+  "&excl;": { "codepoints": [33], "characters": "\u0021" },
+  "&exist;": { "codepoints": [8707], "characters": "\u2203" },
+  "&Exists;": { "codepoints": [8707], "characters": "\u2203" },
+  "&expectation;": { "codepoints": [8496], "characters": "\u2130" },
+  "&exponentiale;": { "codepoints": [8519], "characters": "\u2147" },
+  "&ExponentialE;": { "codepoints": [8519], "characters": "\u2147" },
+  "&fallingdotseq;": { "codepoints": [8786], "characters": "\u2252" },
+  "&Fcy;": { "codepoints": [1060], "characters": "\u0424" },
+  "&fcy;": { "codepoints": [1092], "characters": "\u0444" },
+  "&female;": { "codepoints": [9792], "characters": "\u2640" },
+  "&ffilig;": { "codepoints": [64259], "characters": "\uFB03" },
+  "&fflig;": { "codepoints": [64256], "characters": "\uFB00" },
+  "&ffllig;": { "codepoints": [64260], "characters": "\uFB04" },
+  "&Ffr;": { "codepoints": [120073], "characters": "\uD835\uDD09" },
+  "&ffr;": { "codepoints": [120099], "characters": "\uD835\uDD23" },
+  "&filig;": { "codepoints": [64257], "characters": "\uFB01" },
+  "&FilledSmallSquare;": { "codepoints": [9724], "characters": "\u25FC" },
+  "&FilledVerySmallSquare;": { "codepoints": [9642], "characters": "\u25AA" },
+  "&fjlig;": { "codepoints": [102, 106], "characters": "\u0066\u006A" },
+  "&flat;": { "codepoints": [9837], "characters": "\u266D" },
+  "&fllig;": { "codepoints": [64258], "characters": "\uFB02" },
+  "&fltns;": { "codepoints": [9649], "characters": "\u25B1" },
+  "&fnof;": { "codepoints": [402], "characters": "\u0192" },
+  "&Fopf;": { "codepoints": [120125], "characters": "\uD835\uDD3D" },
+  "&fopf;": { "codepoints": [120151], "characters": "\uD835\uDD57" },
+  "&forall;": { "codepoints": [8704], "characters": "\u2200" },
+  "&ForAll;": { "codepoints": [8704], "characters": "\u2200" },
+  "&fork;": { "codepoints": [8916], "characters": "\u22D4" },
+  "&forkv;": { "codepoints": [10969], "characters": "\u2AD9" },
+  "&Fouriertrf;": { "codepoints": [8497], "characters": "\u2131" },
+  "&fpartint;": { "codepoints": [10765], "characters": "\u2A0D" },
+  "&frac12;": { "codepoints": [189], "characters": "\u00BD" },
+  "&frac12": { "codepoints": [189], "characters": "\u00BD" },
+  "&frac13;": { "codepoints": [8531], "characters": "\u2153" },
+  "&frac14;": { "codepoints": [188], "characters": "\u00BC" },
+  "&frac14": { "codepoints": [188], "characters": "\u00BC" },
+  "&frac15;": { "codepoints": [8533], "characters": "\u2155" },
+  "&frac16;": { "codepoints": [8537], "characters": "\u2159" },
+  "&frac18;": { "codepoints": [8539], "characters": "\u215B" },
+  "&frac23;": { "codepoints": [8532], "characters": "\u2154" },
+  "&frac25;": { "codepoints": [8534], "characters": "\u2156" },
+  "&frac34;": { "codepoints": [190], "characters": "\u00BE" },
+  "&frac34": { "codepoints": [190], "characters": "\u00BE" },
+  "&frac35;": { "codepoints": [8535], "characters": "\u2157" },
+  "&frac38;": { "codepoints": [8540], "characters": "\u215C" },
+  "&frac45;": { "codepoints": [8536], "characters": "\u2158" },
+  "&frac56;": { "codepoints": [8538], "characters": "\u215A" },
+  "&frac58;": { "codepoints": [8541], "characters": "\u215D" },
+  "&frac78;": { "codepoints": [8542], "characters": "\u215E" },
+  "&frasl;": { "codepoints": [8260], "characters": "\u2044" },
+  "&frown;": { "codepoints": [8994], "characters": "\u2322" },
+  "&fscr;": { "codepoints": [119995], "characters": "\uD835\uDCBB" },
+  "&Fscr;": { "codepoints": [8497], "characters": "\u2131" },
+  "&gacute;": { "codepoints": [501], "characters": "\u01F5" },
+  "&Gamma;": { "codepoints": [915], "characters": "\u0393" },
+  "&gamma;": { "codepoints": [947], "characters": "\u03B3" },
+  "&Gammad;": { "codepoints": [988], "characters": "\u03DC" },
+  "&gammad;": { "codepoints": [989], "characters": "\u03DD" },
+  "&gap;": { "codepoints": [10886], "characters": "\u2A86" },
+  "&Gbreve;": { "codepoints": [286], "characters": "\u011E" },
+  "&gbreve;": { "codepoints": [287], "characters": "\u011F" },
+  "&Gcedil;": { "codepoints": [290], "characters": "\u0122" },
+  "&Gcirc;": { "codepoints": [284], "characters": "\u011C" },
+  "&gcirc;": { "codepoints": [285], "characters": "\u011D" },
+  "&Gcy;": { "codepoints": [1043], "characters": "\u0413" },
+  "&gcy;": { "codepoints": [1075], "characters": "\u0433" },
+  "&Gdot;": { "codepoints": [288], "characters": "\u0120" },
+  "&gdot;": { "codepoints": [289], "characters": "\u0121" },
+  "&ge;": { "codepoints": [8805], "characters": "\u2265" },
+  "&gE;": { "codepoints": [8807], "characters": "\u2267" },
+  "&gEl;": { "codepoints": [10892], "characters": "\u2A8C" },
+  "&gel;": { "codepoints": [8923], "characters": "\u22DB" },
+  "&geq;": { "codepoints": [8805], "characters": "\u2265" },
+  "&geqq;": { "codepoints": [8807], "characters": "\u2267" },
+  "&geqslant;": { "codepoints": [10878], "characters": "\u2A7E" },
+  "&gescc;": { "codepoints": [10921], "characters": "\u2AA9" },
+  "&ges;": { "codepoints": [10878], "characters": "\u2A7E" },
+  "&gesdot;": { "codepoints": [10880], "characters": "\u2A80" },
+  "&gesdoto;": { "codepoints": [10882], "characters": "\u2A82" },
+  "&gesdotol;": { "codepoints": [10884], "characters": "\u2A84" },
+  "&gesl;": { "codepoints": [8923, 65024], "characters": "\u22DB\uFE00" },
+  "&gesles;": { "codepoints": [10900], "characters": "\u2A94" },
+  "&Gfr;": { "codepoints": [120074], "characters": "\uD835\uDD0A" },
+  "&gfr;": { "codepoints": [120100], "characters": "\uD835\uDD24" },
+  "&gg;": { "codepoints": [8811], "characters": "\u226B" },
+  "&Gg;": { "codepoints": [8921], "characters": "\u22D9" },
+  "&ggg;": { "codepoints": [8921], "characters": "\u22D9" },
+  "&gimel;": { "codepoints": [8503], "characters": "\u2137" },
+  "&GJcy;": { "codepoints": [1027], "characters": "\u0403" },
+  "&gjcy;": { "codepoints": [1107], "characters": "\u0453" },
+  "&gla;": { "codepoints": [10917], "characters": "\u2AA5" },
+  "&gl;": { "codepoints": [8823], "characters": "\u2277" },
+  "&glE;": { "codepoints": [10898], "characters": "\u2A92" },
+  "&glj;": { "codepoints": [10916], "characters": "\u2AA4" },
+  "&gnap;": { "codepoints": [10890], "characters": "\u2A8A" },
+  "&gnapprox;": { "codepoints": [10890], "characters": "\u2A8A" },
+  "&gne;": { "codepoints": [10888], "characters": "\u2A88" },
+  "&gnE;": { "codepoints": [8809], "characters": "\u2269" },
+  "&gneq;": { "codepoints": [10888], "characters": "\u2A88" },
+  "&gneqq;": { "codepoints": [8809], "characters": "\u2269" },
+  "&gnsim;": { "codepoints": [8935], "characters": "\u22E7" },
+  "&Gopf;": { "codepoints": [120126], "characters": "\uD835\uDD3E" },
+  "&gopf;": { "codepoints": [120152], "characters": "\uD835\uDD58" },
+  "&grave;": { "codepoints": [96], "characters": "\u0060" },
+  "&GreaterEqual;": { "codepoints": [8805], "characters": "\u2265" },
+  "&GreaterEqualLess;": { "codepoints": [8923], "characters": "\u22DB" },
+  "&GreaterFullEqual;": { "codepoints": [8807], "characters": "\u2267" },
+  "&GreaterGreater;": { "codepoints": [10914], "characters": "\u2AA2" },
+  "&GreaterLess;": { "codepoints": [8823], "characters": "\u2277" },
+  "&GreaterSlantEqual;": { "codepoints": [10878], "characters": "\u2A7E" },
+  "&GreaterTilde;": { "codepoints": [8819], "characters": "\u2273" },
+  "&Gscr;": { "codepoints": [119970], "characters": "\uD835\uDCA2" },
+  "&gscr;": { "codepoints": [8458], "characters": "\u210A" },
+  "&gsim;": { "codepoints": [8819], "characters": "\u2273" },
+  "&gsime;": { "codepoints": [10894], "characters": "\u2A8E" },
+  "&gsiml;": { "codepoints": [10896], "characters": "\u2A90" },
+  "&gtcc;": { "codepoints": [10919], "characters": "\u2AA7" },
+  "&gtcir;": { "codepoints": [10874], "characters": "\u2A7A" },
+  "&gt;": { "codepoints": [62], "characters": "\u003E" },
+  "&gt": { "codepoints": [62], "characters": "\u003E" },
+  "&GT;": { "codepoints": [62], "characters": "\u003E" },
+  "&GT": { "codepoints": [62], "characters": "\u003E" },
+  "&Gt;": { "codepoints": [8811], "characters": "\u226B" },
+  "&gtdot;": { "codepoints": [8919], "characters": "\u22D7" },
+  "&gtlPar;": { "codepoints": [10645], "characters": "\u2995" },
+  "&gtquest;": { "codepoints": [10876], "characters": "\u2A7C" },
+  "&gtrapprox;": { "codepoints": [10886], "characters": "\u2A86" },
+  "&gtrarr;": { "codepoints": [10616], "characters": "\u2978" },
+  "&gtrdot;": { "codepoints": [8919], "characters": "\u22D7" },
+  "&gtreqless;": { "codepoints": [8923], "characters": "\u22DB" },
+  "&gtreqqless;": { "codepoints": [10892], "characters": "\u2A8C" },
+  "&gtrless;": { "codepoints": [8823], "characters": "\u2277" },
+  "&gtrsim;": { "codepoints": [8819], "characters": "\u2273" },
+  "&gvertneqq;": { "codepoints": [8809, 65024], "characters": "\u2269\uFE00" },
+  "&gvnE;": { "codepoints": [8809, 65024], "characters": "\u2269\uFE00" },
+  "&Hacek;": { "codepoints": [711], "characters": "\u02C7" },
+  "&hairsp;": { "codepoints": [8202], "characters": "\u200A" },
+  "&half;": { "codepoints": [189], "characters": "\u00BD" },
+  "&hamilt;": { "codepoints": [8459], "characters": "\u210B" },
+  "&HARDcy;": { "codepoints": [1066], "characters": "\u042A" },
+  "&hardcy;": { "codepoints": [1098], "characters": "\u044A" },
+  "&harrcir;": { "codepoints": [10568], "characters": "\u2948" },
+  "&harr;": { "codepoints": [8596], "characters": "\u2194" },
+  "&hArr;": { "codepoints": [8660], "characters": "\u21D4" },
+  "&harrw;": { "codepoints": [8621], "characters": "\u21AD" },
+  "&Hat;": { "codepoints": [94], "characters": "\u005E" },
+  "&hbar;": { "codepoints": [8463], "characters": "\u210F" },
+  "&Hcirc;": { "codepoints": [292], "characters": "\u0124" },
+  "&hcirc;": { "codepoints": [293], "characters": "\u0125" },
+  "&hearts;": { "codepoints": [9829], "characters": "\u2665" },
+  "&heartsuit;": { "codepoints": [9829], "characters": "\u2665" },
+  "&hellip;": { "codepoints": [8230], "characters": "\u2026" },
+  "&hercon;": { "codepoints": [8889], "characters": "\u22B9" },
+  "&hfr;": { "codepoints": [120101], "characters": "\uD835\uDD25" },
+  "&Hfr;": { "codepoints": [8460], "characters": "\u210C" },
+  "&HilbertSpace;": { "codepoints": [8459], "characters": "\u210B" },
+  "&hksearow;": { "codepoints": [10533], "characters": "\u2925" },
+  "&hkswarow;": { "codepoints": [10534], "characters": "\u2926" },
+  "&hoarr;": { "codepoints": [8703], "characters": "\u21FF" },
+  "&homtht;": { "codepoints": [8763], "characters": "\u223B" },
+  "&hookleftarrow;": { "codepoints": [8617], "characters": "\u21A9" },
+  "&hookrightarrow;": { "codepoints": [8618], "characters": "\u21AA" },
+  "&hopf;": { "codepoints": [120153], "characters": "\uD835\uDD59" },
+  "&Hopf;": { "codepoints": [8461], "characters": "\u210D" },
+  "&horbar;": { "codepoints": [8213], "characters": "\u2015" },
+  "&HorizontalLine;": { "codepoints": [9472], "characters": "\u2500" },
+  "&hscr;": { "codepoints": [119997], "characters": "\uD835\uDCBD" },
+  "&Hscr;": { "codepoints": [8459], "characters": "\u210B" },
+  "&hslash;": { "codepoints": [8463], "characters": "\u210F" },
+  "&Hstrok;": { "codepoints": [294], "characters": "\u0126" },
+  "&hstrok;": { "codepoints": [295], "characters": "\u0127" },
+  "&HumpDownHump;": { "codepoints": [8782], "characters": "\u224E" },
+  "&HumpEqual;": { "codepoints": [8783], "characters": "\u224F" },
+  "&hybull;": { "codepoints": [8259], "characters": "\u2043" },
+  "&hyphen;": { "codepoints": [8208], "characters": "\u2010" },
+  "&Iacute;": { "codepoints": [205], "characters": "\u00CD" },
+  "&Iacute": { "codepoints": [205], "characters": "\u00CD" },
+  "&iacute;": { "codepoints": [237], "characters": "\u00ED" },
+  "&iacute": { "codepoints": [237], "characters": "\u00ED" },
+  "&ic;": { "codepoints": [8291], "characters": "\u2063" },
+  "&Icirc;": { "codepoints": [206], "characters": "\u00CE" },
+  "&Icirc": { "codepoints": [206], "characters": "\u00CE" },
+  "&icirc;": { "codepoints": [238], "characters": "\u00EE" },
+  "&icirc": { "codepoints": [238], "characters": "\u00EE" },
+  "&Icy;": { "codepoints": [1048], "characters": "\u0418" },
+  "&icy;": { "codepoints": [1080], "characters": "\u0438" },
+  "&Idot;": { "codepoints": [304], "characters": "\u0130" },
+  "&IEcy;": { "codepoints": [1045], "characters": "\u0415" },
+  "&iecy;": { "codepoints": [1077], "characters": "\u0435" },
+  "&iexcl;": { "codepoints": [161], "characters": "\u00A1" },
+  "&iexcl": { "codepoints": [161], "characters": "\u00A1" },
+  "&iff;": { "codepoints": [8660], "characters": "\u21D4" },
+  "&ifr;": { "codepoints": [120102], "characters": "\uD835\uDD26" },
+  "&Ifr;": { "codepoints": [8465], "characters": "\u2111" },
+  "&Igrave;": { "codepoints": [204], "characters": "\u00CC" },
+  "&Igrave": { "codepoints": [204], "characters": "\u00CC" },
+  "&igrave;": { "codepoints": [236], "characters": "\u00EC" },
+  "&igrave": { "codepoints": [236], "characters": "\u00EC" },
+  "&ii;": { "codepoints": [8520], "characters": "\u2148" },
+  "&iiiint;": { "codepoints": [10764], "characters": "\u2A0C" },
+  "&iiint;": { "codepoints": [8749], "characters": "\u222D" },
+  "&iinfin;": { "codepoints": [10716], "characters": "\u29DC" },
+  "&iiota;": { "codepoints": [8489], "characters": "\u2129" },
+  "&IJlig;": { "codepoints": [306], "characters": "\u0132" },
+  "&ijlig;": { "codepoints": [307], "characters": "\u0133" },
+  "&Imacr;": { "codepoints": [298], "characters": "\u012A" },
+  "&imacr;": { "codepoints": [299], "characters": "\u012B" },
+  "&image;": { "codepoints": [8465], "characters": "\u2111" },
+  "&ImaginaryI;": { "codepoints": [8520], "characters": "\u2148" },
+  "&imagline;": { "codepoints": [8464], "characters": "\u2110" },
+  "&imagpart;": { "codepoints": [8465], "characters": "\u2111" },
+  "&imath;": { "codepoints": [305], "characters": "\u0131" },
+  "&Im;": { "codepoints": [8465], "characters": "\u2111" },
+  "&imof;": { "codepoints": [8887], "characters": "\u22B7" },
+  "&imped;": { "codepoints": [437], "characters": "\u01B5" },
+  "&Implies;": { "codepoints": [8658], "characters": "\u21D2" },
+  "&incare;": { "codepoints": [8453], "characters": "\u2105" },
+  "&in;": { "codepoints": [8712], "characters": "\u2208" },
+  "&infin;": { "codepoints": [8734], "characters": "\u221E" },
+  "&infintie;": { "codepoints": [10717], "characters": "\u29DD" },
+  "&inodot;": { "codepoints": [305], "characters": "\u0131" },
+  "&intcal;": { "codepoints": [8890], "characters": "\u22BA" },
+  "&int;": { "codepoints": [8747], "characters": "\u222B" },
+  "&Int;": { "codepoints": [8748], "characters": "\u222C" },
+  "&integers;": { "codepoints": [8484], "characters": "\u2124" },
+  "&Integral;": { "codepoints": [8747], "characters": "\u222B" },
+  "&intercal;": { "codepoints": [8890], "characters": "\u22BA" },
+  "&Intersection;": { "codepoints": [8898], "characters": "\u22C2" },
+  "&intlarhk;": { "codepoints": [10775], "characters": "\u2A17" },
+  "&intprod;": { "codepoints": [10812], "characters": "\u2A3C" },
+  "&InvisibleComma;": { "codepoints": [8291], "characters": "\u2063" },
+  "&InvisibleTimes;": { "codepoints": [8290], "characters": "\u2062" },
+  "&IOcy;": { "codepoints": [1025], "characters": "\u0401" },
+  "&iocy;": { "codepoints": [1105], "characters": "\u0451" },
+  "&Iogon;": { "codepoints": [302], "characters": "\u012E" },
+  "&iogon;": { "codepoints": [303], "characters": "\u012F" },
+  "&Iopf;": { "codepoints": [120128], "characters": "\uD835\uDD40" },
+  "&iopf;": { "codepoints": [120154], "characters": "\uD835\uDD5A" },
+  "&Iota;": { "codepoints": [921], "characters": "\u0399" },
+  "&iota;": { "codepoints": [953], "characters": "\u03B9" },
+  "&iprod;": { "codepoints": [10812], "characters": "\u2A3C" },
+  "&iquest;": { "codepoints": [191], "characters": "\u00BF" },
+  "&iquest": { "codepoints": [191], "characters": "\u00BF" },
+  "&iscr;": { "codepoints": [119998], "characters": "\uD835\uDCBE" },
+  "&Iscr;": { "codepoints": [8464], "characters": "\u2110" },
+  "&isin;": { "codepoints": [8712], "characters": "\u2208" },
+  "&isindot;": { "codepoints": [8949], "characters": "\u22F5" },
+  "&isinE;": { "codepoints": [8953], "characters": "\u22F9" },
+  "&isins;": { "codepoints": [8948], "characters": "\u22F4" },
+  "&isinsv;": { "codepoints": [8947], "characters": "\u22F3" },
+  "&isinv;": { "codepoints": [8712], "characters": "\u2208" },
+  "&it;": { "codepoints": [8290], "characters": "\u2062" },
+  "&Itilde;": { "codepoints": [296], "characters": "\u0128" },
+  "&itilde;": { "codepoints": [297], "characters": "\u0129" },
+  "&Iukcy;": { "codepoints": [1030], "characters": "\u0406" },
+  "&iukcy;": { "codepoints": [1110], "characters": "\u0456" },
+  "&Iuml;": { "codepoints": [207], "characters": "\u00CF" },
+  "&Iuml": { "codepoints": [207], "characters": "\u00CF" },
+  "&iuml;": { "codepoints": [239], "characters": "\u00EF" },
+  "&iuml": { "codepoints": [239], "characters": "\u00EF" },
+  "&Jcirc;": { "codepoints": [308], "characters": "\u0134" },
+  "&jcirc;": { "codepoints": [309], "characters": "\u0135" },
+  "&Jcy;": { "codepoints": [1049], "characters": "\u0419" },
+  "&jcy;": { "codepoints": [1081], "characters": "\u0439" },
+  "&Jfr;": { "codepoints": [120077], "characters": "\uD835\uDD0D" },
+  "&jfr;": { "codepoints": [120103], "characters": "\uD835\uDD27" },
+  "&jmath;": { "codepoints": [567], "characters": "\u0237" },
+  "&Jopf;": { "codepoints": [120129], "characters": "\uD835\uDD41" },
+  "&jopf;": { "codepoints": [120155], "characters": "\uD835\uDD5B" },
+  "&Jscr;": { "codepoints": [119973], "characters": "\uD835\uDCA5" },
+  "&jscr;": { "codepoints": [119999], "characters": "\uD835\uDCBF" },
+  "&Jsercy;": { "codepoints": [1032], "characters": "\u0408" },
+  "&jsercy;": { "codepoints": [1112], "characters": "\u0458" },
+  "&Jukcy;": { "codepoints": [1028], "characters": "\u0404" },
+  "&jukcy;": { "codepoints": [1108], "characters": "\u0454" },
+  "&Kappa;": { "codepoints": [922], "characters": "\u039A" },
+  "&kappa;": { "codepoints": [954], "characters": "\u03BA" },
+  "&kappav;": { "codepoints": [1008], "characters": "\u03F0" },
+  "&Kcedil;": { "codepoints": [310], "characters": "\u0136" },
+  "&kcedil;": { "codepoints": [311], "characters": "\u0137" },
+  "&Kcy;": { "codepoints": [1050], "characters": "\u041A" },
+  "&kcy;": { "codepoints": [1082], "characters": "\u043A" },
+  "&Kfr;": { "codepoints": [120078], "characters": "\uD835\uDD0E" },
+  "&kfr;": { "codepoints": [120104], "characters": "\uD835\uDD28" },
+  "&kgreen;": { "codepoints": [312], "characters": "\u0138" },
+  "&KHcy;": { "codepoints": [1061], "characters": "\u0425" },
+  "&khcy;": { "codepoints": [1093], "characters": "\u0445" },
+  "&KJcy;": { "codepoints": [1036], "characters": "\u040C" },
+  "&kjcy;": { "codepoints": [1116], "characters": "\u045C" },
+  "&Kopf;": { "codepoints": [120130], "characters": "\uD835\uDD42" },
+  "&kopf;": { "codepoints": [120156], "characters": "\uD835\uDD5C" },
+  "&Kscr;": { "codepoints": [119974], "characters": "\uD835\uDCA6" },
+  "&kscr;": { "codepoints": [120000], "characters": "\uD835\uDCC0" },
+  "&lAarr;": { "codepoints": [8666], "characters": "\u21DA" },
+  "&Lacute;": { "codepoints": [313], "characters": "\u0139" },
+  "&lacute;": { "codepoints": [314], "characters": "\u013A" },
+  "&laemptyv;": { "codepoints": [10676], "characters": "\u29B4" },
+  "&lagran;": { "codepoints": [8466], "characters": "\u2112" },
+  "&Lambda;": { "codepoints": [923], "characters": "\u039B" },
+  "&lambda;": { "codepoints": [955], "characters": "\u03BB" },
+  "&lang;": { "codepoints": [10216], "characters": "\u27E8" },
+  "&Lang;": { "codepoints": [10218], "characters": "\u27EA" },
+  "&langd;": { "codepoints": [10641], "characters": "\u2991" },
+  "&langle;": { "codepoints": [10216], "characters": "\u27E8" },
+  "&lap;": { "codepoints": [10885], "characters": "\u2A85" },
+  "&Laplacetrf;": { "codepoints": [8466], "characters": "\u2112" },
+  "&laquo;": { "codepoints": [171], "characters": "\u00AB" },
+  "&laquo": { "codepoints": [171], "characters": "\u00AB" },
+  "&larrb;": { "codepoints": [8676], "characters": "\u21E4" },
+  "&larrbfs;": { "codepoints": [10527], "characters": "\u291F" },
+  "&larr;": { "codepoints": [8592], "characters": "\u2190" },
+  "&Larr;": { "codepoints": [8606], "characters": "\u219E" },
+  "&lArr;": { "codepoints": [8656], "characters": "\u21D0" },
+  "&larrfs;": { "codepoints": [10525], "characters": "\u291D" },
+  "&larrhk;": { "codepoints": [8617], "characters": "\u21A9" },
+  "&larrlp;": { "codepoints": [8619], "characters": "\u21AB" },
+  "&larrpl;": { "codepoints": [10553], "characters": "\u2939" },
+  "&larrsim;": { "codepoints": [10611], "characters": "\u2973" },
+  "&larrtl;": { "codepoints": [8610], "characters": "\u21A2" },
+  "&latail;": { "codepoints": [10521], "characters": "\u2919" },
+  "&lAtail;": { "codepoints": [10523], "characters": "\u291B" },
+  "&lat;": { "codepoints": [10923], "characters": "\u2AAB" },
+  "&late;": { "codepoints": [10925], "characters": "\u2AAD" },
+  "&lates;": { "codepoints": [10925, 65024], "characters": "\u2AAD\uFE00" },
+  "&lbarr;": { "codepoints": [10508], "characters": "\u290C" },
+  "&lBarr;": { "codepoints": [10510], "characters": "\u290E" },
+  "&lbbrk;": { "codepoints": [10098], "characters": "\u2772" },
+  "&lbrace;": { "codepoints": [123], "characters": "\u007B" },
+  "&lbrack;": { "codepoints": [91], "characters": "\u005B" },
+  "&lbrke;": { "codepoints": [10635], "characters": "\u298B" },
+  "&lbrksld;": { "codepoints": [10639], "characters": "\u298F" },
+  "&lbrkslu;": { "codepoints": [10637], "characters": "\u298D" },
+  "&Lcaron;": { "codepoints": [317], "characters": "\u013D" },
+  "&lcaron;": { "codepoints": [318], "characters": "\u013E" },
+  "&Lcedil;": { "codepoints": [315], "characters": "\u013B" },
+  "&lcedil;": { "codepoints": [316], "characters": "\u013C" },
+  "&lceil;": { "codepoints": [8968], "characters": "\u2308" },
+  "&lcub;": { "codepoints": [123], "characters": "\u007B" },
+  "&Lcy;": { "codepoints": [1051], "characters": "\u041B" },
+  "&lcy;": { "codepoints": [1083], "characters": "\u043B" },
+  "&ldca;": { "codepoints": [10550], "characters": "\u2936" },
+  "&ldquo;": { "codepoints": [8220], "characters": "\u201C" },
+  "&ldquor;": { "codepoints": [8222], "characters": "\u201E" },
+  "&ldrdhar;": { "codepoints": [10599], "characters": "\u2967" },
+  "&ldrushar;": { "codepoints": [10571], "characters": "\u294B" },
+  "&ldsh;": { "codepoints": [8626], "characters": "\u21B2" },
+  "&le;": { "codepoints": [8804], "characters": "\u2264" },
+  "&lE;": { "codepoints": [8806], "characters": "\u2266" },
+  "&LeftAngleBracket;": { "codepoints": [10216], "characters": "\u27E8" },
+  "&LeftArrowBar;": { "codepoints": [8676], "characters": "\u21E4" },
+  "&leftarrow;": { "codepoints": [8592], "characters": "\u2190" },
+  "&LeftArrow;": { "codepoints": [8592], "characters": "\u2190" },
+  "&Leftarrow;": { "codepoints": [8656], "characters": "\u21D0" },
+  "&LeftArrowRightArrow;": { "codepoints": [8646], "characters": "\u21C6" },
+  "&leftarrowtail;": { "codepoints": [8610], "characters": "\u21A2" },
+  "&LeftCeiling;": { "codepoints": [8968], "characters": "\u2308" },
+  "&LeftDoubleBracket;": { "codepoints": [10214], "characters": "\u27E6" },
+  "&LeftDownTeeVector;": { "codepoints": [10593], "characters": "\u2961" },
+  "&LeftDownVectorBar;": { "codepoints": [10585], "characters": "\u2959" },
+  "&LeftDownVector;": { "codepoints": [8643], "characters": "\u21C3" },
+  "&LeftFloor;": { "codepoints": [8970], "characters": "\u230A" },
+  "&leftharpoondown;": { "codepoints": [8637], "characters": "\u21BD" },
+  "&leftharpoonup;": { "codepoints": [8636], "characters": "\u21BC" },
+  "&leftleftarrows;": { "codepoints": [8647], "characters": "\u21C7" },
+  "&leftrightarrow;": { "codepoints": [8596], "characters": "\u2194" },
+  "&LeftRightArrow;": { "codepoints": [8596], "characters": "\u2194" },
+  "&Leftrightarrow;": { "codepoints": [8660], "characters": "\u21D4" },
+  "&leftrightarrows;": { "codepoints": [8646], "characters": "\u21C6" },
+  "&leftrightharpoons;": { "codepoints": [8651], "characters": "\u21CB" },
+  "&leftrightsquigarrow;": { "codepoints": [8621], "characters": "\u21AD" },
+  "&LeftRightVector;": { "codepoints": [10574], "characters": "\u294E" },
+  "&LeftTeeArrow;": { "codepoints": [8612], "characters": "\u21A4" },
+  "&LeftTee;": { "codepoints": [8867], "characters": "\u22A3" },
+  "&LeftTeeVector;": { "codepoints": [10586], "characters": "\u295A" },
+  "&leftthreetimes;": { "codepoints": [8907], "characters": "\u22CB" },
+  "&LeftTriangleBar;": { "codepoints": [10703], "characters": "\u29CF" },
+  "&LeftTriangle;": { "codepoints": [8882], "characters": "\u22B2" },
+  "&LeftTriangleEqual;": { "codepoints": [8884], "characters": "\u22B4" },
+  "&LeftUpDownVector;": { "codepoints": [10577], "characters": "\u2951" },
+  "&LeftUpTeeVector;": { "codepoints": [10592], "characters": "\u2960" },
+  "&LeftUpVectorBar;": { "codepoints": [10584], "characters": "\u2958" },
+  "&LeftUpVector;": { "codepoints": [8639], "characters": "\u21BF" },
+  "&LeftVectorBar;": { "codepoints": [10578], "characters": "\u2952" },
+  "&LeftVector;": { "codepoints": [8636], "characters": "\u21BC" },
+  "&lEg;": { "codepoints": [10891], "characters": "\u2A8B" },
+  "&leg;": { "codepoints": [8922], "characters": "\u22DA" },
+  "&leq;": { "codepoints": [8804], "characters": "\u2264" },
+  "&leqq;": { "codepoints": [8806], "characters": "\u2266" },
+  "&leqslant;": { "codepoints": [10877], "characters": "\u2A7D" },
+  "&lescc;": { "codepoints": [10920], "characters": "\u2AA8" },
+  "&les;": { "codepoints": [10877], "characters": "\u2A7D" },
+  "&lesdot;": { "codepoints": [10879], "characters": "\u2A7F" },
+  "&lesdoto;": { "codepoints": [10881], "characters": "\u2A81" },
+  "&lesdotor;": { "codepoints": [10883], "characters": "\u2A83" },
+  "&lesg;": { "codepoints": [8922, 65024], "characters": "\u22DA\uFE00" },
+  "&lesges;": { "codepoints": [10899], "characters": "\u2A93" },
+  "&lessapprox;": { "codepoints": [10885], "characters": "\u2A85" },
+  "&lessdot;": { "codepoints": [8918], "characters": "\u22D6" },
+  "&lesseqgtr;": { "codepoints": [8922], "characters": "\u22DA" },
+  "&lesseqqgtr;": { "codepoints": [10891], "characters": "\u2A8B" },
+  "&LessEqualGreater;": { "codepoints": [8922], "characters": "\u22DA" },
+  "&LessFullEqual;": { "codepoints": [8806], "characters": "\u2266" },
+  "&LessGreater;": { "codepoints": [8822], "characters": "\u2276" },
+  "&lessgtr;": { "codepoints": [8822], "characters": "\u2276" },
+  "&LessLess;": { "codepoints": [10913], "characters": "\u2AA1" },
+  "&lesssim;": { "codepoints": [8818], "characters": "\u2272" },
+  "&LessSlantEqual;": { "codepoints": [10877], "characters": "\u2A7D" },
+  "&LessTilde;": { "codepoints": [8818], "characters": "\u2272" },
+  "&lfisht;": { "codepoints": [10620], "characters": "\u297C" },
+  "&lfloor;": { "codepoints": [8970], "characters": "\u230A" },
+  "&Lfr;": { "codepoints": [120079], "characters": "\uD835\uDD0F" },
+  "&lfr;": { "codepoints": [120105], "characters": "\uD835\uDD29" },
+  "&lg;": { "codepoints": [8822], "characters": "\u2276" },
+  "&lgE;": { "codepoints": [10897], "characters": "\u2A91" },
+  "&lHar;": { "codepoints": [10594], "characters": "\u2962" },
+  "&lhard;": { "codepoints": [8637], "characters": "\u21BD" },
+  "&lharu;": { "codepoints": [8636], "characters": "\u21BC" },
+  "&lharul;": { "codepoints": [10602], "characters": "\u296A" },
+  "&lhblk;": { "codepoints": [9604], "characters": "\u2584" },
+  "&LJcy;": { "codepoints": [1033], "characters": "\u0409" },
+  "&ljcy;": { "codepoints": [1113], "characters": "\u0459" },
+  "&llarr;": { "codepoints": [8647], "characters": "\u21C7" },
+  "&ll;": { "codepoints": [8810], "characters": "\u226A" },
+  "&Ll;": { "codepoints": [8920], "characters": "\u22D8" },
+  "&llcorner;": { "codepoints": [8990], "characters": "\u231E" },
+  "&Lleftarrow;": { "codepoints": [8666], "characters": "\u21DA" },
+  "&llhard;": { "codepoints": [10603], "characters": "\u296B" },
+  "&lltri;": { "codepoints": [9722], "characters": "\u25FA" },
+  "&Lmidot;": { "codepoints": [319], "characters": "\u013F" },
+  "&lmidot;": { "codepoints": [320], "characters": "\u0140" },
+  "&lmoustache;": { "codepoints": [9136], "characters": "\u23B0" },
+  "&lmoust;": { "codepoints": [9136], "characters": "\u23B0" },
+  "&lnap;": { "codepoints": [10889], "characters": "\u2A89" },
+  "&lnapprox;": { "codepoints": [10889], "characters": "\u2A89" },
+  "&lne;": { "codepoints": [10887], "characters": "\u2A87" },
+  "&lnE;": { "codepoints": [8808], "characters": "\u2268" },
+  "&lneq;": { "codepoints": [10887], "characters": "\u2A87" },
+  "&lneqq;": { "codepoints": [8808], "characters": "\u2268" },
+  "&lnsim;": { "codepoints": [8934], "characters": "\u22E6" },
+  "&loang;": { "codepoints": [10220], "characters": "\u27EC" },
+  "&loarr;": { "codepoints": [8701], "characters": "\u21FD" },
+  "&lobrk;": { "codepoints": [10214], "characters": "\u27E6" },
+  "&longleftarrow;": { "codepoints": [10229], "characters": "\u27F5" },
+  "&LongLeftArrow;": { "codepoints": [10229], "characters": "\u27F5" },
+  "&Longleftarrow;": { "codepoints": [10232], "characters": "\u27F8" },
+  "&longleftrightarrow;": { "codepoints": [10231], "characters": "\u27F7" },
+  "&LongLeftRightArrow;": { "codepoints": [10231], "characters": "\u27F7" },
+  "&Longleftrightarrow;": { "codepoints": [10234], "characters": "\u27FA" },
+  "&longmapsto;": { "codepoints": [10236], "characters": "\u27FC" },
+  "&longrightarrow;": { "codepoints": [10230], "characters": "\u27F6" },
+  "&LongRightArrow;": { "codepoints": [10230], "characters": "\u27F6" },
+  "&Longrightarrow;": { "codepoints": [10233], "characters": "\u27F9" },
+  "&looparrowleft;": { "codepoints": [8619], "characters": "\u21AB" },
+  "&looparrowright;": { "codepoints": [8620], "characters": "\u21AC" },
+  "&lopar;": { "codepoints": [10629], "characters": "\u2985" },
+  "&Lopf;": { "codepoints": [120131], "characters": "\uD835\uDD43" },
+  "&lopf;": { "codepoints": [120157], "characters": "\uD835\uDD5D" },
+  "&loplus;": { "codepoints": [10797], "characters": "\u2A2D" },
+  "&lotimes;": { "codepoints": [10804], "characters": "\u2A34" },
+  "&lowast;": { "codepoints": [8727], "characters": "\u2217" },
+  "&lowbar;": { "codepoints": [95], "characters": "\u005F" },
+  "&LowerLeftArrow;": { "codepoints": [8601], "characters": "\u2199" },
+  "&LowerRightArrow;": { "codepoints": [8600], "characters": "\u2198" },
+  "&loz;": { "codepoints": [9674], "characters": "\u25CA" },
+  "&lozenge;": { "codepoints": [9674], "characters": "\u25CA" },
+  "&lozf;": { "codepoints": [10731], "characters": "\u29EB" },
+  "&lpar;": { "codepoints": [40], "characters": "\u0028" },
+  "&lparlt;": { "codepoints": [10643], "characters": "\u2993" },
+  "&lrarr;": { "codepoints": [8646], "characters": "\u21C6" },
+  "&lrcorner;": { "codepoints": [8991], "characters": "\u231F" },
+  "&lrhar;": { "codepoints": [8651], "characters": "\u21CB" },
+  "&lrhard;": { "codepoints": [10605], "characters": "\u296D" },
+  "&lrm;": { "codepoints": [8206], "characters": "\u200E" },
+  "&lrtri;": { "codepoints": [8895], "characters": "\u22BF" },
+  "&lsaquo;": { "codepoints": [8249], "characters": "\u2039" },
+  "&lscr;": { "codepoints": [120001], "characters": "\uD835\uDCC1" },
+  "&Lscr;": { "codepoints": [8466], "characters": "\u2112" },
+  "&lsh;": { "codepoints": [8624], "characters": "\u21B0" },
+  "&Lsh;": { "codepoints": [8624], "characters": "\u21B0" },
+  "&lsim;": { "codepoints": [8818], "characters": "\u2272" },
+  "&lsime;": { "codepoints": [10893], "characters": "\u2A8D" },
+  "&lsimg;": { "codepoints": [10895], "characters": "\u2A8F" },
+  "&lsqb;": { "codepoints": [91], "characters": "\u005B" },
+  "&lsquo;": { "codepoints": [8216], "characters": "\u2018" },
+  "&lsquor;": { "codepoints": [8218], "characters": "\u201A" },
+  "&Lstrok;": { "codepoints": [321], "characters": "\u0141" },
+  "&lstrok;": { "codepoints": [322], "characters": "\u0142" },
+  "&ltcc;": { "codepoints": [10918], "characters": "\u2AA6" },
+  "&ltcir;": { "codepoints": [10873], "characters": "\u2A79" },
+  "&lt;": { "codepoints": [60], "characters": "\u003C" },
+  "&lt": { "codepoints": [60], "characters": "\u003C" },
+  "&LT;": { "codepoints": [60], "characters": "\u003C" },
+  "&LT": { "codepoints": [60], "characters": "\u003C" },
+  "&Lt;": { "codepoints": [8810], "characters": "\u226A" },
+  "&ltdot;": { "codepoints": [8918], "characters": "\u22D6" },
+  "&lthree;": { "codepoints": [8907], "characters": "\u22CB" },
+  "&ltimes;": { "codepoints": [8905], "characters": "\u22C9" },
+  "&ltlarr;": { "codepoints": [10614], "characters": "\u2976" },
+  "&ltquest;": { "codepoints": [10875], "characters": "\u2A7B" },
+  "&ltri;": { "codepoints": [9667], "characters": "\u25C3" },
+  "&ltrie;": { "codepoints": [8884], "characters": "\u22B4" },
+  "&ltrif;": { "codepoints": [9666], "characters": "\u25C2" },
+  "&ltrPar;": { "codepoints": [10646], "characters": "\u2996" },
+  "&lurdshar;": { "codepoints": [10570], "characters": "\u294A" },
+  "&luruhar;": { "codepoints": [10598], "characters": "\u2966" },
+  "&lvertneqq;": { "codepoints": [8808, 65024], "characters": "\u2268\uFE00" },
+  "&lvnE;": { "codepoints": [8808, 65024], "characters": "\u2268\uFE00" },
+  "&macr;": { "codepoints": [175], "characters": "\u00AF" },
+  "&macr": { "codepoints": [175], "characters": "\u00AF" },
+  "&male;": { "codepoints": [9794], "characters": "\u2642" },
+  "&malt;": { "codepoints": [10016], "characters": "\u2720" },
+  "&maltese;": { "codepoints": [10016], "characters": "\u2720" },
+  "&Map;": { "codepoints": [10501], "characters": "\u2905" },
+  "&map;": { "codepoints": [8614], "characters": "\u21A6" },
+  "&mapsto;": { "codepoints": [8614], "characters": "\u21A6" },
+  "&mapstodown;": { "codepoints": [8615], "characters": "\u21A7" },
+  "&mapstoleft;": { "codepoints": [8612], "characters": "\u21A4" },
+  "&mapstoup;": { "codepoints": [8613], "characters": "\u21A5" },
+  "&marker;": { "codepoints": [9646], "characters": "\u25AE" },
+  "&mcomma;": { "codepoints": [10793], "characters": "\u2A29" },
+  "&Mcy;": { "codepoints": [1052], "characters": "\u041C" },
+  "&mcy;": { "codepoints": [1084], "characters": "\u043C" },
+  "&mdash;": { "codepoints": [8212], "characters": "\u2014" },
+  "&mDDot;": { "codepoints": [8762], "characters": "\u223A" },
+  "&measuredangle;": { "codepoints": [8737], "characters": "\u2221" },
+  "&MediumSpace;": { "codepoints": [8287], "characters": "\u205F" },
+  "&Mellintrf;": { "codepoints": [8499], "characters": "\u2133" },
+  "&Mfr;": { "codepoints": [120080], "characters": "\uD835\uDD10" },
+  "&mfr;": { "codepoints": [120106], "characters": "\uD835\uDD2A" },
+  "&mho;": { "codepoints": [8487], "characters": "\u2127" },
+  "&micro;": { "codepoints": [181], "characters": "\u00B5" },
+  "&micro": { "codepoints": [181], "characters": "\u00B5" },
+  "&midast;": { "codepoints": [42], "characters": "\u002A" },
+  "&midcir;": { "codepoints": [10992], "characters": "\u2AF0" },
+  "&mid;": { "codepoints": [8739], "characters": "\u2223" },
+  "&middot;": { "codepoints": [183], "characters": "\u00B7" },
+  "&middot": { "codepoints": [183], "characters": "\u00B7" },
+  "&minusb;": { "codepoints": [8863], "characters": "\u229F" },
+  "&minus;": { "codepoints": [8722], "characters": "\u2212" },
+  "&minusd;": { "codepoints": [8760], "characters": "\u2238" },
+  "&minusdu;": { "codepoints": [10794], "characters": "\u2A2A" },
+  "&MinusPlus;": { "codepoints": [8723], "characters": "\u2213" },
+  "&mlcp;": { "codepoints": [10971], "characters": "\u2ADB" },
+  "&mldr;": { "codepoints": [8230], "characters": "\u2026" },
+  "&mnplus;": { "codepoints": [8723], "characters": "\u2213" },
+  "&models;": { "codepoints": [8871], "characters": "\u22A7" },
+  "&Mopf;": { "codepoints": [120132], "characters": "\uD835\uDD44" },
+  "&mopf;": { "codepoints": [120158], "characters": "\uD835\uDD5E" },
+  "&mp;": { "codepoints": [8723], "characters": "\u2213" },
+  "&mscr;": { "codepoints": [120002], "characters": "\uD835\uDCC2" },
+  "&Mscr;": { "codepoints": [8499], "characters": "\u2133" },
+  "&mstpos;": { "codepoints": [8766], "characters": "\u223E" },
+  "&Mu;": { "codepoints": [924], "characters": "\u039C" },
+  "&mu;": { "codepoints": [956], "characters": "\u03BC" },
+  "&multimap;": { "codepoints": [8888], "characters": "\u22B8" },
+  "&mumap;": { "codepoints": [8888], "characters": "\u22B8" },
+  "&nabla;": { "codepoints": [8711], "characters": "\u2207" },
+  "&Nacute;": { "codepoints": [323], "characters": "\u0143" },
+  "&nacute;": { "codepoints": [324], "characters": "\u0144" },
+  "&nang;": { "codepoints": [8736, 8402], "characters": "\u2220\u20D2" },
+  "&nap;": { "codepoints": [8777], "characters": "\u2249" },
+  "&napE;": { "codepoints": [10864, 824], "characters": "\u2A70\u0338" },
+  "&napid;": { "codepoints": [8779, 824], "characters": "\u224B\u0338" },
+  "&napos;": { "codepoints": [329], "characters": "\u0149" },
+  "&napprox;": { "codepoints": [8777], "characters": "\u2249" },
+  "&natural;": { "codepoints": [9838], "characters": "\u266E" },
+  "&naturals;": { "codepoints": [8469], "characters": "\u2115" },
+  "&natur;": { "codepoints": [9838], "characters": "\u266E" },
+  "&nbsp;": { "codepoints": [160], "characters": "\u00A0" },
+  "&nbsp": { "codepoints": [160], "characters": "\u00A0" },
+  "&nbump;": { "codepoints": [8782, 824], "characters": "\u224E\u0338" },
+  "&nbumpe;": { "codepoints": [8783, 824], "characters": "\u224F\u0338" },
+  "&ncap;": { "codepoints": [10819], "characters": "\u2A43" },
+  "&Ncaron;": { "codepoints": [327], "characters": "\u0147" },
+  "&ncaron;": { "codepoints": [328], "characters": "\u0148" },
+  "&Ncedil;": { "codepoints": [325], "characters": "\u0145" },
+  "&ncedil;": { "codepoints": [326], "characters": "\u0146" },
+  "&ncong;": { "codepoints": [8775], "characters": "\u2247" },
+  "&ncongdot;": { "codepoints": [10861, 824], "characters": "\u2A6D\u0338" },
+  "&ncup;": { "codepoints": [10818], "characters": "\u2A42" },
+  "&Ncy;": { "codepoints": [1053], "characters": "\u041D" },
+  "&ncy;": { "codepoints": [1085], "characters": "\u043D" },
+  "&ndash;": { "codepoints": [8211], "characters": "\u2013" },
+  "&nearhk;": { "codepoints": [10532], "characters": "\u2924" },
+  "&nearr;": { "codepoints": [8599], "characters": "\u2197" },
+  "&neArr;": { "codepoints": [8663], "characters": "\u21D7" },
+  "&nearrow;": { "codepoints": [8599], "characters": "\u2197" },
+  "&ne;": { "codepoints": [8800], "characters": "\u2260" },
+  "&nedot;": { "codepoints": [8784, 824], "characters": "\u2250\u0338" },
+  "&NegativeMediumSpace;": { "codepoints": [8203], "characters": "\u200B" },
+  "&NegativeThickSpace;": { "codepoints": [8203], "characters": "\u200B" },
+  "&NegativeThinSpace;": { "codepoints": [8203], "characters": "\u200B" },
+  "&NegativeVeryThinSpace;": { "codepoints": [8203], "characters": "\u200B" },
+  "&nequiv;": { "codepoints": [8802], "characters": "\u2262" },
+  "&nesear;": { "codepoints": [10536], "characters": "\u2928" },
+  "&nesim;": { "codepoints": [8770, 824], "characters": "\u2242\u0338" },
+  "&NestedGreaterGreater;": { "codepoints": [8811], "characters": "\u226B" },
+  "&NestedLessLess;": { "codepoints": [8810], "characters": "\u226A" },
+  "&NewLine;": { "codepoints": [10], "characters": "\u000A" },
+  "&nexist;": { "codepoints": [8708], "characters": "\u2204" },
+  "&nexists;": { "codepoints": [8708], "characters": "\u2204" },
+  "&Nfr;": { "codepoints": [120081], "characters": "\uD835\uDD11" },
+  "&nfr;": { "codepoints": [120107], "characters": "\uD835\uDD2B" },
+  "&ngE;": { "codepoints": [8807, 824], "characters": "\u2267\u0338" },
+  "&nge;": { "codepoints": [8817], "characters": "\u2271" },
+  "&ngeq;": { "codepoints": [8817], "characters": "\u2271" },
+  "&ngeqq;": { "codepoints": [8807, 824], "characters": "\u2267\u0338" },
+  "&ngeqslant;": { "codepoints": [10878, 824], "characters": "\u2A7E\u0338" },
+  "&nges;": { "codepoints": [10878, 824], "characters": "\u2A7E\u0338" },
+  "&nGg;": { "codepoints": [8921, 824], "characters": "\u22D9\u0338" },
+  "&ngsim;": { "codepoints": [8821], "characters": "\u2275" },
+  "&nGt;": { "codepoints": [8811, 8402], "characters": "\u226B\u20D2" },
+  "&ngt;": { "codepoints": [8815], "characters": "\u226F" },
+  "&ngtr;": { "codepoints": [8815], "characters": "\u226F" },
+  "&nGtv;": { "codepoints": [8811, 824], "characters": "\u226B\u0338" },
+  "&nharr;": { "codepoints": [8622], "characters": "\u21AE" },
+  "&nhArr;": { "codepoints": [8654], "characters": "\u21CE" },
+  "&nhpar;": { "codepoints": [10994], "characters": "\u2AF2" },
+  "&ni;": { "codepoints": [8715], "characters": "\u220B" },
+  "&nis;": { "codepoints": [8956], "characters": "\u22FC" },
+  "&nisd;": { "codepoints": [8954], "characters": "\u22FA" },
+  "&niv;": { "codepoints": [8715], "characters": "\u220B" },
+  "&NJcy;": { "codepoints": [1034], "characters": "\u040A" },
+  "&njcy;": { "codepoints": [1114], "characters": "\u045A" },
+  "&nlarr;": { "codepoints": [8602], "characters": "\u219A" },
+  "&nlArr;": { "codepoints": [8653], "characters": "\u21CD" },
+  "&nldr;": { "codepoints": [8229], "characters": "\u2025" },
+  "&nlE;": { "codepoints": [8806, 824], "characters": "\u2266\u0338" },
+  "&nle;": { "codepoints": [8816], "characters": "\u2270" },
+  "&nleftarrow;": { "codepoints": [8602], "characters": "\u219A" },
+  "&nLeftarrow;": { "codepoints": [8653], "characters": "\u21CD" },
+  "&nleftrightarrow;": { "codepoints": [8622], "characters": "\u21AE" },
+  "&nLeftrightarrow;": { "codepoints": [8654], "characters": "\u21CE" },
+  "&nleq;": { "codepoints": [8816], "characters": "\u2270" },
+  "&nleqq;": { "codepoints": [8806, 824], "characters": "\u2266\u0338" },
+  "&nleqslant;": { "codepoints": [10877, 824], "characters": "\u2A7D\u0338" },
+  "&nles;": { "codepoints": [10877, 824], "characters": "\u2A7D\u0338" },
+  "&nless;": { "codepoints": [8814], "characters": "\u226E" },
+  "&nLl;": { "codepoints": [8920, 824], "characters": "\u22D8\u0338" },
+  "&nlsim;": { "codepoints": [8820], "characters": "\u2274" },
+  "&nLt;": { "codepoints": [8810, 8402], "characters": "\u226A\u20D2" },
+  "&nlt;": { "codepoints": [8814], "characters": "\u226E" },
+  "&nltri;": { "codepoints": [8938], "characters": "\u22EA" },
+  "&nltrie;": { "codepoints": [8940], "characters": "\u22EC" },
+  "&nLtv;": { "codepoints": [8810, 824], "characters": "\u226A\u0338" },
+  "&nmid;": { "codepoints": [8740], "characters": "\u2224" },
+  "&NoBreak;": { "codepoints": [8288], "characters": "\u2060" },
+  "&NonBreakingSpace;": { "codepoints": [160], "characters": "\u00A0" },
+  "&nopf;": { "codepoints": [120159], "characters": "\uD835\uDD5F" },
+  "&Nopf;": { "codepoints": [8469], "characters": "\u2115" },
+  "&Not;": { "codepoints": [10988], "characters": "\u2AEC" },
+  "&not;": { "codepoints": [172], "characters": "\u00AC" },
+  "&not": { "codepoints": [172], "characters": "\u00AC" },
+  "&NotCongruent;": { "codepoints": [8802], "characters": "\u2262" },
+  "&NotCupCap;": { "codepoints": [8813], "characters": "\u226D" },
+  "&NotDoubleVerticalBar;": { "codepoints": [8742], "characters": "\u2226" },
+  "&NotElement;": { "codepoints": [8713], "characters": "\u2209" },
+  "&NotEqual;": { "codepoints": [8800], "characters": "\u2260" },
+  "&NotEqualTilde;": { "codepoints": [8770, 824], "characters": "\u2242\u0338" },
+  "&NotExists;": { "codepoints": [8708], "characters": "\u2204" },
+  "&NotGreater;": { "codepoints": [8815], "characters": "\u226F" },
+  "&NotGreaterEqual;": { "codepoints": [8817], "characters": "\u2271" },
+  "&NotGreaterFullEqual;": { "codepoints": [8807, 824], "characters": "\u2267\u0338" },
+  "&NotGreaterGreater;": { "codepoints": [8811, 824], "characters": "\u226B\u0338" },
+  "&NotGreaterLess;": { "codepoints": [8825], "characters": "\u2279" },
+  "&NotGreaterSlantEqual;": { "codepoints": [10878, 824], "characters": "\u2A7E\u0338" },
+  "&NotGreaterTilde;": { "codepoints": [8821], "characters": "\u2275" },
+  "&NotHumpDownHump;": { "codepoints": [8782, 824], "characters": "\u224E\u0338" },
+  "&NotHumpEqual;": { "codepoints": [8783, 824], "characters": "\u224F\u0338" },
+  "&notin;": { "codepoints": [8713], "characters": "\u2209" },
+  "&notindot;": { "codepoints": [8949, 824], "characters": "\u22F5\u0338" },
+  "&notinE;": { "codepoints": [8953, 824], "characters": "\u22F9\u0338" },
+  "&notinva;": { "codepoints": [8713], "characters": "\u2209" },
+  "&notinvb;": { "codepoints": [8951], "characters": "\u22F7" },
+  "&notinvc;": { "codepoints": [8950], "characters": "\u22F6" },
+  "&NotLeftTriangleBar;": { "codepoints": [10703, 824], "characters": "\u29CF\u0338" },
+  "&NotLeftTriangle;": { "codepoints": [8938], "characters": "\u22EA" },
+  "&NotLeftTriangleEqual;": { "codepoints": [8940], "characters": "\u22EC" },
+  "&NotLess;": { "codepoints": [8814], "characters": "\u226E" },
+  "&NotLessEqual;": { "codepoints": [8816], "characters": "\u2270" },
+  "&NotLessGreater;": { "codepoints": [8824], "characters": "\u2278" },
+  "&NotLessLess;": { "codepoints": [8810, 824], "characters": "\u226A\u0338" },
+  "&NotLessSlantEqual;": { "codepoints": [10877, 824], "characters": "\u2A7D\u0338" },
+  "&NotLessTilde;": { "codepoints": [8820], "characters": "\u2274" },
+  "&NotNestedGreaterGreater;": { "codepoints": [10914, 824], "characters": "\u2AA2\u0338" },
+  "&NotNestedLessLess;": { "codepoints": [10913, 824], "characters": "\u2AA1\u0338" },
+  "&notni;": { "codepoints": [8716], "characters": "\u220C" },
+  "&notniva;": { "codepoints": [8716], "characters": "\u220C" },
+  "&notnivb;": { "codepoints": [8958], "characters": "\u22FE" },
+  "&notnivc;": { "codepoints": [8957], "characters": "\u22FD" },
+  "&NotPrecedes;": { "codepoints": [8832], "characters": "\u2280" },
+  "&NotPrecedesEqual;": { "codepoints": [10927, 824], "characters": "\u2AAF\u0338" },
+  "&NotPrecedesSlantEqual;": { "codepoints": [8928], "characters": "\u22E0" },
+  "&NotReverseElement;": { "codepoints": [8716], "characters": "\u220C" },
+  "&NotRightTriangleBar;": { "codepoints": [10704, 824], "characters": "\u29D0\u0338" },
+  "&NotRightTriangle;": { "codepoints": [8939], "characters": "\u22EB" },
+  "&NotRightTriangleEqual;": { "codepoints": [8941], "characters": "\u22ED" },
+  "&NotSquareSubset;": { "codepoints": [8847, 824], "characters": "\u228F\u0338" },
+  "&NotSquareSubsetEqual;": { "codepoints": [8930], "characters": "\u22E2" },
+  "&NotSquareSuperset;": { "codepoints": [8848, 824], "characters": "\u2290\u0338" },
+  "&NotSquareSupersetEqual;": { "codepoints": [8931], "characters": "\u22E3" },
+  "&NotSubset;": { "codepoints": [8834, 8402], "characters": "\u2282\u20D2" },
+  "&NotSubsetEqual;": { "codepoints": [8840], "characters": "\u2288" },
+  "&NotSucceeds;": { "codepoints": [8833], "characters": "\u2281" },
+  "&NotSucceedsEqual;": { "codepoints": [10928, 824], "characters": "\u2AB0\u0338" },
+  "&NotSucceedsSlantEqual;": { "codepoints": [8929], "characters": "\u22E1" },
+  "&NotSucceedsTilde;": { "codepoints": [8831, 824], "characters": "\u227F\u0338" },
+  "&NotSuperset;": { "codepoints": [8835, 8402], "characters": "\u2283\u20D2" },
+  "&NotSupersetEqual;": { "codepoints": [8841], "characters": "\u2289" },
+  "&NotTilde;": { "codepoints": [8769], "characters": "\u2241" },
+  "&NotTildeEqual;": { "codepoints": [8772], "characters": "\u2244" },
+  "&NotTildeFullEqual;": { "codepoints": [8775], "characters": "\u2247" },
+  "&NotTildeTilde;": { "codepoints": [8777], "characters": "\u2249" },
+  "&NotVerticalBar;": { "codepoints": [8740], "characters": "\u2224" },
+  "&nparallel;": { "codepoints": [8742], "characters": "\u2226" },
+  "&npar;": { "codepoints": [8742], "characters": "\u2226" },
+  "&nparsl;": { "codepoints": [11005, 8421], "characters": "\u2AFD\u20E5" },
+  "&npart;": { "codepoints": [8706, 824], "characters": "\u2202\u0338" },
+  "&npolint;": { "codepoints": [10772], "characters": "\u2A14" },
+  "&npr;": { "codepoints": [8832], "characters": "\u2280" },
+  "&nprcue;": { "codepoints": [8928], "characters": "\u22E0" },
+  "&nprec;": { "codepoints": [8832], "characters": "\u2280" },
+  "&npreceq;": { "codepoints": [10927, 824], "characters": "\u2AAF\u0338" },
+  "&npre;": { "codepoints": [10927, 824], "characters": "\u2AAF\u0338" },
+  "&nrarrc;": { "codepoints": [10547, 824], "characters": "\u2933\u0338" },
+  "&nrarr;": { "codepoints": [8603], "characters": "\u219B" },
+  "&nrArr;": { "codepoints": [8655], "characters": "\u21CF" },
+  "&nrarrw;": { "codepoints": [8605, 824], "characters": "\u219D\u0338" },
+  "&nrightarrow;": { "codepoints": [8603], "characters": "\u219B" },
+  "&nRightarrow;": { "codepoints": [8655], "characters": "\u21CF" },
+  "&nrtri;": { "codepoints": [8939], "characters": "\u22EB" },
+  "&nrtrie;": { "codepoints": [8941], "characters": "\u22ED" },
+  "&nsc;": { "codepoints": [8833], "characters": "\u2281" },
+  "&nsccue;": { "codepoints": [8929], "characters": "\u22E1" },
+  "&nsce;": { "codepoints": [10928, 824], "characters": "\u2AB0\u0338" },
+  "&Nscr;": { "codepoints": [119977], "characters": "\uD835\uDCA9" },
+  "&nscr;": { "codepoints": [120003], "characters": "\uD835\uDCC3" },
+  "&nshortmid;": { "codepoints": [8740], "characters": "\u2224" },
+  "&nshortparallel;": { "codepoints": [8742], "characters": "\u2226" },
+  "&nsim;": { "codepoints": [8769], "characters": "\u2241" },
+  "&nsime;": { "codepoints": [8772], "characters": "\u2244" },
+  "&nsimeq;": { "codepoints": [8772], "characters": "\u2244" },
+  "&nsmid;": { "codepoints": [8740], "characters": "\u2224" },
+  "&nspar;": { "codepoints": [8742], "characters": "\u2226" },
+  "&nsqsube;": { "codepoints": [8930], "characters": "\u22E2" },
+  "&nsqsupe;": { "codepoints": [8931], "characters": "\u22E3" },
+  "&nsub;": { "codepoints": [8836], "characters": "\u2284" },
+  "&nsubE;": { "codepoints": [10949, 824], "characters": "\u2AC5\u0338" },
+  "&nsube;": { "codepoints": [8840], "characters": "\u2288" },
+  "&nsubset;": { "codepoints": [8834, 8402], "characters": "\u2282\u20D2" },
+  "&nsubseteq;": { "codepoints": [8840], "characters": "\u2288" },
+  "&nsubseteqq;": { "codepoints": [10949, 824], "characters": "\u2AC5\u0338" },
+  "&nsucc;": { "codepoints": [8833], "characters": "\u2281" },
+  "&nsucceq;": { "codepoints": [10928, 824], "characters": "\u2AB0\u0338" },
+  "&nsup;": { "codepoints": [8837], "characters": "\u2285" },
+  "&nsupE;": { "codepoints": [10950, 824], "characters": "\u2AC6\u0338" },
+  "&nsupe;": { "codepoints": [8841], "characters": "\u2289" },
+  "&nsupset;": { "codepoints": [8835, 8402], "characters": "\u2283\u20D2" },
+  "&nsupseteq;": { "codepoints": [8841], "characters": "\u2289" },
+  "&nsupseteqq;": { "codepoints": [10950, 824], "characters": "\u2AC6\u0338" },
+  "&ntgl;": { "codepoints": [8825], "characters": "\u2279" },
+  "&Ntilde;": { "codepoints": [209], "characters": "\u00D1" },
+  "&Ntilde": { "codepoints": [209], "characters": "\u00D1" },
+  "&ntilde;": { "codepoints": [241], "characters": "\u00F1" },
+  "&ntilde": { "codepoints": [241], "characters": "\u00F1" },
+  "&ntlg;": { "codepoints": [8824], "characters": "\u2278" },
+  "&ntriangleleft;": { "codepoints": [8938], "characters": "\u22EA" },
+  "&ntrianglelefteq;": { "codepoints": [8940], "characters": "\u22EC" },
+  "&ntriangleright;": { "codepoints": [8939], "characters": "\u22EB" },
+  "&ntrianglerighteq;": { "codepoints": [8941], "characters": "\u22ED" },
+  "&Nu;": { "codepoints": [925], "characters": "\u039D" },
+  "&nu;": { "codepoints": [957], "characters": "\u03BD" },
+  "&num;": { "codepoints": [35], "characters": "\u0023" },
+  "&numero;": { "codepoints": [8470], "characters": "\u2116" },
+  "&numsp;": { "codepoints": [8199], "characters": "\u2007" },
+  "&nvap;": { "codepoints": [8781, 8402], "characters": "\u224D\u20D2" },
+  "&nvdash;": { "codepoints": [8876], "characters": "\u22AC" },
+  "&nvDash;": { "codepoints": [8877], "characters": "\u22AD" },
+  "&nVdash;": { "codepoints": [8878], "characters": "\u22AE" },
+  "&nVDash;": { "codepoints": [8879], "characters": "\u22AF" },
+  "&nvge;": { "codepoints": [8805, 8402], "characters": "\u2265\u20D2" },
+  "&nvgt;": { "codepoints": [62, 8402], "characters": "\u003E\u20D2" },
+  "&nvHarr;": { "codepoints": [10500], "characters": "\u2904" },
+  "&nvinfin;": { "codepoints": [10718], "characters": "\u29DE" },
+  "&nvlArr;": { "codepoints": [10498], "characters": "\u2902" },
+  "&nvle;": { "codepoints": [8804, 8402], "characters": "\u2264\u20D2" },
+  "&nvlt;": { "codepoints": [60, 8402], "characters": "\u003C\u20D2" },
+  "&nvltrie;": { "codepoints": [8884, 8402], "characters": "\u22B4\u20D2" },
+  "&nvrArr;": { "codepoints": [10499], "characters": "\u2903" },
+  "&nvrtrie;": { "codepoints": [8885, 8402], "characters": "\u22B5\u20D2" },
+  "&nvsim;": { "codepoints": [8764, 8402], "characters": "\u223C\u20D2" },
+  "&nwarhk;": { "codepoints": [10531], "characters": "\u2923" },
+  "&nwarr;": { "codepoints": [8598], "characters": "\u2196" },
+  "&nwArr;": { "codepoints": [8662], "characters": "\u21D6" },
+  "&nwarrow;": { "codepoints": [8598], "characters": "\u2196" },
+  "&nwnear;": { "codepoints": [10535], "characters": "\u2927" },
+  "&Oacute;": { "codepoints": [211], "characters": "\u00D3" },
+  "&Oacute": { "codepoints": [211], "characters": "\u00D3" },
+  "&oacute;": { "codepoints": [243], "characters": "\u00F3" },
+  "&oacute": { "codepoints": [243], "characters": "\u00F3" },
+  "&oast;": { "codepoints": [8859], "characters": "\u229B" },
+  "&Ocirc;": { "codepoints": [212], "characters": "\u00D4" },
+  "&Ocirc": { "codepoints": [212], "characters": "\u00D4" },
+  "&ocirc;": { "codepoints": [244], "characters": "\u00F4" },
+  "&ocirc": { "codepoints": [244], "characters": "\u00F4" },
+  "&ocir;": { "codepoints": [8858], "characters": "\u229A" },
+  "&Ocy;": { "codepoints": [1054], "characters": "\u041E" },
+  "&ocy;": { "codepoints": [1086], "characters": "\u043E" },
+  "&odash;": { "codepoints": [8861], "characters": "\u229D" },
+  "&Odblac;": { "codepoints": [336], "characters": "\u0150" },
+  "&odblac;": { "codepoints": [337], "characters": "\u0151" },
+  "&odiv;": { "codepoints": [10808], "characters": "\u2A38" },
+  "&odot;": { "codepoints": [8857], "characters": "\u2299" },
+  "&odsold;": { "codepoints": [10684], "characters": "\u29BC" },
+  "&OElig;": { "codepoints": [338], "characters": "\u0152" },
+  "&oelig;": { "codepoints": [339], "characters": "\u0153" },
+  "&ofcir;": { "codepoints": [10687], "characters": "\u29BF" },
+  "&Ofr;": { "codepoints": [120082], "characters": "\uD835\uDD12" },
+  "&ofr;": { "codepoints": [120108], "characters": "\uD835\uDD2C" },
+  "&ogon;": { "codepoints": [731], "characters": "\u02DB" },
+  "&Ograve;": { "codepoints": [210], "characters": "\u00D2" },
+  "&Ograve": { "codepoints": [210], "characters": "\u00D2" },
+  "&ograve;": { "codepoints": [242], "characters": "\u00F2" },
+  "&ograve": { "codepoints": [242], "characters": "\u00F2" },
+  "&ogt;": { "codepoints": [10689], "characters": "\u29C1" },
+  "&ohbar;": { "codepoints": [10677], "characters": "\u29B5" },
+  "&ohm;": { "codepoints": [937], "characters": "\u03A9" },
+  "&oint;": { "codepoints": [8750], "characters": "\u222E" },
+  "&olarr;": { "codepoints": [8634], "characters": "\u21BA" },
+  "&olcir;": { "codepoints": [10686], "characters": "\u29BE" },
+  "&olcross;": { "codepoints": [10683], "characters": "\u29BB" },
+  "&oline;": { "codepoints": [8254], "characters": "\u203E" },
+  "&olt;": { "codepoints": [10688], "characters": "\u29C0" },
+  "&Omacr;": { "codepoints": [332], "characters": "\u014C" },
+  "&omacr;": { "codepoints": [333], "characters": "\u014D" },
+  "&Omega;": { "codepoints": [937], "characters": "\u03A9" },
+  "&omega;": { "codepoints": [969], "characters": "\u03C9" },
+  "&Omicron;": { "codepoints": [927], "characters": "\u039F" },
+  "&omicron;": { "codepoints": [959], "characters": "\u03BF" },
+  "&omid;": { "codepoints": [10678], "characters": "\u29B6" },
+  "&ominus;": { "codepoints": [8854], "characters": "\u2296" },
+  "&Oopf;": { "codepoints": [120134], "characters": "\uD835\uDD46" },
+  "&oopf;": { "codepoints": [120160], "characters": "\uD835\uDD60" },
+  "&opar;": { "codepoints": [10679], "characters": "\u29B7" },
+  "&OpenCurlyDoubleQuote;": { "codepoints": [8220], "characters": "\u201C" },
+  "&OpenCurlyQuote;": { "codepoints": [8216], "characters": "\u2018" },
+  "&operp;": { "codepoints": [10681], "characters": "\u29B9" },
+  "&oplus;": { "codepoints": [8853], "characters": "\u2295" },
+  "&orarr;": { "codepoints": [8635], "characters": "\u21BB" },
+  "&Or;": { "codepoints": [10836], "characters": "\u2A54" },
+  "&or;": { "codepoints": [8744], "characters": "\u2228" },
+  "&ord;": { "codepoints": [10845], "characters": "\u2A5D" },
+  "&order;": { "codepoints": [8500], "characters": "\u2134" },
+  "&orderof;": { "codepoints": [8500], "characters": "\u2134" },
+  "&ordf;": { "codepoints": [170], "characters": "\u00AA" },
+  "&ordf": { "codepoints": [170], "characters": "\u00AA" },
+  "&ordm;": { "codepoints": [186], "characters": "\u00BA" },
+  "&ordm": { "codepoints": [186], "characters": "\u00BA" },
+  "&origof;": { "codepoints": [8886], "characters": "\u22B6" },
+  "&oror;": { "codepoints": [10838], "characters": "\u2A56" },
+  "&orslope;": { "codepoints": [10839], "characters": "\u2A57" },
+  "&orv;": { "codepoints": [10843], "characters": "\u2A5B" },
+  "&oS;": { "codepoints": [9416], "characters": "\u24C8" },
+  "&Oscr;": { "codepoints": [119978], "characters": "\uD835\uDCAA" },
+  "&oscr;": { "codepoints": [8500], "characters": "\u2134" },
+  "&Oslash;": { "codepoints": [216], "characters": "\u00D8" },
+  "&Oslash": { "codepoints": [216], "characters": "\u00D8" },
+  "&oslash;": { "codepoints": [248], "characters": "\u00F8" },
+  "&oslash": { "codepoints": [248], "characters": "\u00F8" },
+  "&osol;": { "codepoints": [8856], "characters": "\u2298" },
+  "&Otilde;": { "codepoints": [213], "characters": "\u00D5" },
+  "&Otilde": { "codepoints": [213], "characters": "\u00D5" },
+  "&otilde;": { "codepoints": [245], "characters": "\u00F5" },
+  "&otilde": { "codepoints": [245], "characters": "\u00F5" },
+  "&otimesas;": { "codepoints": [10806], "characters": "\u2A36" },
+  "&Otimes;": { "codepoints": [10807], "characters": "\u2A37" },
+  "&otimes;": { "codepoints": [8855], "characters": "\u2297" },
+  "&Ouml;": { "codepoints": [214], "characters": "\u00D6" },
+  "&Ouml": { "codepoints": [214], "characters": "\u00D6" },
+  "&ouml;": { "codepoints": [246], "characters": "\u00F6" },
+  "&ouml": { "codepoints": [246], "characters": "\u00F6" },
+  "&ovbar;": { "codepoints": [9021], "characters": "\u233D" },
+  "&OverBar;": { "codepoints": [8254], "characters": "\u203E" },
+  "&OverBrace;": { "codepoints": [9182], "characters": "\u23DE" },
+  "&OverBracket;": { "codepoints": [9140], "characters": "\u23B4" },
+  "&OverParenthesis;": { "codepoints": [9180], "characters": "\u23DC" },
+  "&para;": { "codepoints": [182], "characters": "\u00B6" },
+  "&para": { "codepoints": [182], "characters": "\u00B6" },
+  "&parallel;": { "codepoints": [8741], "characters": "\u2225" },
+  "&par;": { "codepoints": [8741], "characters": "\u2225" },
+  "&parsim;": { "codepoints": [10995], "characters": "\u2AF3" },
+  "&parsl;": { "codepoints": [11005], "characters": "\u2AFD" },
+  "&part;": { "codepoints": [8706], "characters": "\u2202" },
+  "&PartialD;": { "codepoints": [8706], "characters": "\u2202" },
+  "&Pcy;": { "codepoints": [1055], "characters": "\u041F" },
+  "&pcy;": { "codepoints": [1087], "characters": "\u043F" },
+  "&percnt;": { "codepoints": [37], "characters": "\u0025" },
+  "&period;": { "codepoints": [46], "characters": "\u002E" },
+  "&permil;": { "codepoints": [8240], "characters": "\u2030" },
+  "&perp;": { "codepoints": [8869], "characters": "\u22A5" },
+  "&pertenk;": { "codepoints": [8241], "characters": "\u2031" },
+  "&Pfr;": { "codepoints": [120083], "characters": "\uD835\uDD13" },
+  "&pfr;": { "codepoints": [120109], "characters": "\uD835\uDD2D" },
+  "&Phi;": { "codepoints": [934], "characters": "\u03A6" },
+  "&phi;": { "codepoints": [966], "characters": "\u03C6" },
+  "&phiv;": { "codepoints": [981], "characters": "\u03D5" },
+  "&phmmat;": { "codepoints": [8499], "characters": "\u2133" },
+  "&phone;": { "codepoints": [9742], "characters": "\u260E" },
+  "&Pi;": { "codepoints": [928], "characters": "\u03A0" },
+  "&pi;": { "codepoints": [960], "characters": "\u03C0" },
+  "&pitchfork;": { "codepoints": [8916], "characters": "\u22D4" },
+  "&piv;": { "codepoints": [982], "characters": "\u03D6" },
+  "&planck;": { "codepoints": [8463], "characters": "\u210F" },
+  "&planckh;": { "codepoints": [8462], "characters": "\u210E" },
+  "&plankv;": { "codepoints": [8463], "characters": "\u210F" },
+  "&plusacir;": { "codepoints": [10787], "characters": "\u2A23" },
+  "&plusb;": { "codepoints": [8862], "characters": "\u229E" },
+  "&pluscir;": { "codepoints": [10786], "characters": "\u2A22" },
+  "&plus;": { "codepoints": [43], "characters": "\u002B" },
+  "&plusdo;": { "codepoints": [8724], "characters": "\u2214" },
+  "&plusdu;": { "codepoints": [10789], "characters": "\u2A25" },
+  "&pluse;": { "codepoints": [10866], "characters": "\u2A72" },
+  "&PlusMinus;": { "codepoints": [177], "characters": "\u00B1" },
+  "&plusmn;": { "codepoints": [177], "characters": "\u00B1" },
+  "&plusmn": { "codepoints": [177], "characters": "\u00B1" },
+  "&plussim;": { "codepoints": [10790], "characters": "\u2A26" },
+  "&plustwo;": { "codepoints": [10791], "characters": "\u2A27" },
+  "&pm;": { "codepoints": [177], "characters": "\u00B1" },
+  "&Poincareplane;": { "codepoints": [8460], "characters": "\u210C" },
+  "&pointint;": { "codepoints": [10773], "characters": "\u2A15" },
+  "&popf;": { "codepoints": [120161], "characters": "\uD835\uDD61" },
+  "&Popf;": { "codepoints": [8473], "characters": "\u2119" },
+  "&pound;": { "codepoints": [163], "characters": "\u00A3" },
+  "&pound": { "codepoints": [163], "characters": "\u00A3" },
+  "&prap;": { "codepoints": [10935], "characters": "\u2AB7" },
+  "&Pr;": { "codepoints": [10939], "characters": "\u2ABB" },
+  "&pr;": { "codepoints": [8826], "characters": "\u227A" },
+  "&prcue;": { "codepoints": [8828], "characters": "\u227C" },
+  "&precapprox;": { "codepoints": [10935], "characters": "\u2AB7" },
+  "&prec;": { "codepoints": [8826], "characters": "\u227A" },
+  "&preccurlyeq;": { "codepoints": [8828], "characters": "\u227C" },
+  "&Precedes;": { "codepoints": [8826], "characters": "\u227A" },
+  "&PrecedesEqual;": { "codepoints": [10927], "characters": "\u2AAF" },
+  "&PrecedesSlantEqual;": { "codepoints": [8828], "characters": "\u227C" },
+  "&PrecedesTilde;": { "codepoints": [8830], "characters": "\u227E" },
+  "&preceq;": { "codepoints": [10927], "characters": "\u2AAF" },
+  "&precnapprox;": { "codepoints": [10937], "characters": "\u2AB9" },
+  "&precneqq;": { "codepoints": [10933], "characters": "\u2AB5" },
+  "&precnsim;": { "codepoints": [8936], "characters": "\u22E8" },
+  "&pre;": { "codepoints": [10927], "characters": "\u2AAF" },
+  "&prE;": { "codepoints": [10931], "characters": "\u2AB3" },
+  "&precsim;": { "codepoints": [8830], "characters": "\u227E" },
+  "&prime;": { "codepoints": [8242], "characters": "\u2032" },
+  "&Prime;": { "codepoints": [8243], "characters": "\u2033" },
+  "&primes;": { "codepoints": [8473], "characters": "\u2119" },
+  "&prnap;": { "codepoints": [10937], "characters": "\u2AB9" },
+  "&prnE;": { "codepoints": [10933], "characters": "\u2AB5" },
+  "&prnsim;": { "codepoints": [8936], "characters": "\u22E8" },
+  "&prod;": { "codepoints": [8719], "characters": "\u220F" },
+  "&Product;": { "codepoints": [8719], "characters": "\u220F" },
+  "&profalar;": { "codepoints": [9006], "characters": "\u232E" },
+  "&profline;": { "codepoints": [8978], "characters": "\u2312" },
+  "&profsurf;": { "codepoints": [8979], "characters": "\u2313" },
+  "&prop;": { "codepoints": [8733], "characters": "\u221D" },
+  "&Proportional;": { "codepoints": [8733], "characters": "\u221D" },
+  "&Proportion;": { "codepoints": [8759], "characters": "\u2237" },
+  "&propto;": { "codepoints": [8733], "characters": "\u221D" },
+  "&prsim;": { "codepoints": [8830], "characters": "\u227E" },
+  "&prurel;": { "codepoints": [8880], "characters": "\u22B0" },
+  "&Pscr;": { "codepoints": [119979], "characters": "\uD835\uDCAB" },
+  "&pscr;": { "codepoints": [120005], "characters": "\uD835\uDCC5" },
+  "&Psi;": { "codepoints": [936], "characters": "\u03A8" },
+  "&psi;": { "codepoints": [968], "characters": "\u03C8" },
+  "&puncsp;": { "codepoints": [8200], "characters": "\u2008" },
+  "&Qfr;": { "codepoints": [120084], "characters": "\uD835\uDD14" },
+  "&qfr;": { "codepoints": [120110], "characters": "\uD835\uDD2E" },
+  "&qint;": { "codepoints": [10764], "characters": "\u2A0C" },
+  "&qopf;": { "codepoints": [120162], "characters": "\uD835\uDD62" },
+  "&Qopf;": { "codepoints": [8474], "characters": "\u211A" },
+  "&qprime;": { "codepoints": [8279], "characters": "\u2057" },
+  "&Qscr;": { "codepoints": [119980], "characters": "\uD835\uDCAC" },
+  "&qscr;": { "codepoints": [120006], "characters": "\uD835\uDCC6" },
+  "&quaternions;": { "codepoints": [8461], "characters": "\u210D" },
+  "&quatint;": { "codepoints": [10774], "characters": "\u2A16" },
+  "&quest;": { "codepoints": [63], "characters": "\u003F" },
+  "&questeq;": { "codepoints": [8799], "characters": "\u225F" },
+  "&quot;": { "codepoints": [34], "characters": "\u0022" },
+  "&quot": { "codepoints": [34], "characters": "\u0022" },
+  "&QUOT;": { "codepoints": [34], "characters": "\u0022" },
+  "&QUOT": { "codepoints": [34], "characters": "\u0022" },
+  "&rAarr;": { "codepoints": [8667], "characters": "\u21DB" },
+  "&race;": { "codepoints": [8765, 817], "characters": "\u223D\u0331" },
+  "&Racute;": { "codepoints": [340], "characters": "\u0154" },
+  "&racute;": { "codepoints": [341], "characters": "\u0155" },
+  "&radic;": { "codepoints": [8730], "characters": "\u221A" },
+  "&raemptyv;": { "codepoints": [10675], "characters": "\u29B3" },
+  "&rang;": { "codepoints": [10217], "characters": "\u27E9" },
+  "&Rang;": { "codepoints": [10219], "characters": "\u27EB" },
+  "&rangd;": { "codepoints": [10642], "characters": "\u2992" },
+  "&range;": { "codepoints": [10661], "characters": "\u29A5" },
+  "&rangle;": { "codepoints": [10217], "characters": "\u27E9" },
+  "&raquo;": { "codepoints": [187], "characters": "\u00BB" },
+  "&raquo": { "codepoints": [187], "characters": "\u00BB" },
+  "&rarrap;": { "codepoints": [10613], "characters": "\u2975" },
+  "&rarrb;": { "codepoints": [8677], "characters": "\u21E5" },
+  "&rarrbfs;": { "codepoints": [10528], "characters": "\u2920" },
+  "&rarrc;": { "codepoints": [10547], "characters": "\u2933" },
+  "&rarr;": { "codepoints": [8594], "characters": "\u2192" },
+  "&Rarr;": { "codepoints": [8608], "characters": "\u21A0" },
+  "&rArr;": { "codepoints": [8658], "characters": "\u21D2" },
+  "&rarrfs;": { "codepoints": [10526], "characters": "\u291E" },
+  "&rarrhk;": { "codepoints": [8618], "characters": "\u21AA" },
+  "&rarrlp;": { "codepoints": [8620], "characters": "\u21AC" },
+  "&rarrpl;": { "codepoints": [10565], "characters": "\u2945" },
+  "&rarrsim;": { "codepoints": [10612], "characters": "\u2974" },
+  "&Rarrtl;": { "codepoints": [10518], "characters": "\u2916" },
+  "&rarrtl;": { "codepoints": [8611], "characters": "\u21A3" },
+  "&rarrw;": { "codepoints": [8605], "characters": "\u219D" },
+  "&ratail;": { "codepoints": [10522], "characters": "\u291A" },
+  "&rAtail;": { "codepoints": [10524], "characters": "\u291C" },
+  "&ratio;": { "codepoints": [8758], "characters": "\u2236" },
+  "&rationals;": { "codepoints": [8474], "characters": "\u211A" },
+  "&rbarr;": { "codepoints": [10509], "characters": "\u290D" },
+  "&rBarr;": { "codepoints": [10511], "characters": "\u290F" },
+  "&RBarr;": { "codepoints": [10512], "characters": "\u2910" },
+  "&rbbrk;": { "codepoints": [10099], "characters": "\u2773" },
+  "&rbrace;": { "codepoints": [125], "characters": "\u007D" },
+  "&rbrack;": { "codepoints": [93], "characters": "\u005D" },
+  "&rbrke;": { "codepoints": [10636], "characters": "\u298C" },
+  "&rbrksld;": { "codepoints": [10638], "characters": "\u298E" },
+  "&rbrkslu;": { "codepoints": [10640], "characters": "\u2990" },
+  "&Rcaron;": { "codepoints": [344], "characters": "\u0158" },
+  "&rcaron;": { "codepoints": [345], "characters": "\u0159" },
+  "&Rcedil;": { "codepoints": [342], "characters": "\u0156" },
+  "&rcedil;": { "codepoints": [343], "characters": "\u0157" },
+  "&rceil;": { "codepoints": [8969], "characters": "\u2309" },
+  "&rcub;": { "codepoints": [125], "characters": "\u007D" },
+  "&Rcy;": { "codepoints": [1056], "characters": "\u0420" },
+  "&rcy;": { "codepoints": [1088], "characters": "\u0440" },
+  "&rdca;": { "codepoints": [10551], "characters": "\u2937" },
+  "&rdldhar;": { "codepoints": [10601], "characters": "\u2969" },
+  "&rdquo;": { "codepoints": [8221], "characters": "\u201D" },
+  "&rdquor;": { "codepoints": [8221], "characters": "\u201D" },
+  "&rdsh;": { "codepoints": [8627], "characters": "\u21B3" },
+  "&real;": { "codepoints": [8476], "characters": "\u211C" },
+  "&realine;": { "codepoints": [8475], "characters": "\u211B" },
+  "&realpart;": { "codepoints": [8476], "characters": "\u211C" },
+  "&reals;": { "codepoints": [8477], "characters": "\u211D" },
+  "&Re;": { "codepoints": [8476], "characters": "\u211C" },
+  "&rect;": { "codepoints": [9645], "characters": "\u25AD" },
+  "&reg;": { "codepoints": [174], "characters": "\u00AE" },
+  "&reg": { "codepoints": [174], "characters": "\u00AE" },
+  "&REG;": { "codepoints": [174], "characters": "\u00AE" },
+  "&REG": { "codepoints": [174], "characters": "\u00AE" },
+  "&ReverseElement;": { "codepoints": [8715], "characters": "\u220B" },
+  "&ReverseEquilibrium;": { "codepoints": [8651], "characters": "\u21CB" },
+  "&ReverseUpEquilibrium;": { "codepoints": [10607], "characters": "\u296F" },
+  "&rfisht;": { "codepoints": [10621], "characters": "\u297D" },
+  "&rfloor;": { "codepoints": [8971], "characters": "\u230B" },
+  "&rfr;": { "codepoints": [120111], "characters": "\uD835\uDD2F" },
+  "&Rfr;": { "codepoints": [8476], "characters": "\u211C" },
+  "&rHar;": { "codepoints": [10596], "characters": "\u2964" },
+  "&rhard;": { "codepoints": [8641], "characters": "\u21C1" },
+  "&rharu;": { "codepoints": [8640], "characters": "\u21C0" },
+  "&rharul;": { "codepoints": [10604], "characters": "\u296C" },
+  "&Rho;": { "codepoints": [929], "characters": "\u03A1" },
+  "&rho;": { "codepoints": [961], "characters": "\u03C1" },
+  "&rhov;": { "codepoints": [1009], "characters": "\u03F1" },
+  "&RightAngleBracket;": { "codepoints": [10217], "characters": "\u27E9" },
+  "&RightArrowBar;": { "codepoints": [8677], "characters": "\u21E5" },
+  "&rightarrow;": { "codepoints": [8594], "characters": "\u2192" },
+  "&RightArrow;": { "codepoints": [8594], "characters": "\u2192" },
+  "&Rightarrow;": { "codepoints": [8658], "characters": "\u21D2" },
+  "&RightArrowLeftArrow;": { "codepoints": [8644], "characters": "\u21C4" },
+  "&rightarrowtail;": { "codepoints": [8611], "characters": "\u21A3" },
+  "&RightCeiling;": { "codepoints": [8969], "characters": "\u2309" },
+  "&RightDoubleBracket;": { "codepoints": [10215], "characters": "\u27E7" },
+  "&RightDownTeeVector;": { "codepoints": [10589], "characters": "\u295D" },
+  "&RightDownVectorBar;": { "codepoints": [10581], "characters": "\u2955" },
+  "&RightDownVector;": { "codepoints": [8642], "characters": "\u21C2" },
+  "&RightFloor;": { "codepoints": [8971], "characters": "\u230B" },
+  "&rightharpoondown;": { "codepoints": [8641], "characters": "\u21C1" },
+  "&rightharpoonup;": { "codepoints": [8640], "characters": "\u21C0" },
+  "&rightleftarrows;": { "codepoints": [8644], "characters": "\u21C4" },
+  "&rightleftharpoons;": { "codepoints": [8652], "characters": "\u21CC" },
+  "&rightrightarrows;": { "codepoints": [8649], "characters": "\u21C9" },
+  "&rightsquigarrow;": { "codepoints": [8605], "characters": "\u219D" },
+  "&RightTeeArrow;": { "codepoints": [8614], "characters": "\u21A6" },
+  "&RightTee;": { "codepoints": [8866], "characters": "\u22A2" },
+  "&RightTeeVector;": { "codepoints": [10587], "characters": "\u295B" },
+  "&rightthreetimes;": { "codepoints": [8908], "characters": "\u22CC" },
+  "&RightTriangleBar;": { "codepoints": [10704], "characters": "\u29D0" },
+  "&RightTriangle;": { "codepoints": [8883], "characters": "\u22B3" },
+  "&RightTriangleEqual;": { "codepoints": [8885], "characters": "\u22B5" },
+  "&RightUpDownVector;": { "codepoints": [10575], "characters": "\u294F" },
+  "&RightUpTeeVector;": { "codepoints": [10588], "characters": "\u295C" },
+  "&RightUpVectorBar;": { "codepoints": [10580], "characters": "\u2954" },
+  "&RightUpVector;": { "codepoints": [8638], "characters": "\u21BE" },
+  "&RightVectorBar;": { "codepoints": [10579], "characters": "\u2953" },
+  "&RightVector;": { "codepoints": [8640], "characters": "\u21C0" },
+  "&ring;": { "codepoints": [730], "characters": "\u02DA" },
+  "&risingdotseq;": { "codepoints": [8787], "characters": "\u2253" },
+  "&rlarr;": { "codepoints": [8644], "characters": "\u21C4" },
+  "&rlhar;": { "codepoints": [8652], "characters": "\u21CC" },
+  "&rlm;": { "codepoints": [8207], "characters": "\u200F" },
+  "&rmoustache;": { "codepoints": [9137], "characters": "\u23B1" },
+  "&rmoust;": { "codepoints": [9137], "characters": "\u23B1" },
+  "&rnmid;": { "codepoints": [10990], "characters": "\u2AEE" },
+  "&roang;": { "codepoints": [10221], "characters": "\u27ED" },
+  "&roarr;": { "codepoints": [8702], "characters": "\u21FE" },
+  "&robrk;": { "codepoints": [10215], "characters": "\u27E7" },
+  "&ropar;": { "codepoints": [10630], "characters": "\u2986" },
+  "&ropf;": { "codepoints": [120163], "characters": "\uD835\uDD63" },
+  "&Ropf;": { "codepoints": [8477], "characters": "\u211D" },
+  "&roplus;": { "codepoints": [10798], "characters": "\u2A2E" },
+  "&rotimes;": { "codepoints": [10805], "characters": "\u2A35" },
+  "&RoundImplies;": { "codepoints": [10608], "characters": "\u2970" },
+  "&rpar;": { "codepoints": [41], "characters": "\u0029" },
+  "&rpargt;": { "codepoints": [10644], "characters": "\u2994" },
+  "&rppolint;": { "codepoints": [10770], "characters": "\u2A12" },
+  "&rrarr;": { "codepoints": [8649], "characters": "\u21C9" },
+  "&Rrightarrow;": { "codepoints": [8667], "characters": "\u21DB" },
+  "&rsaquo;": { "codepoints": [8250], "characters": "\u203A" },
+  "&rscr;": { "codepoints": [120007], "characters": "\uD835\uDCC7" },
+  "&Rscr;": { "codepoints": [8475], "characters": "\u211B" },
+  "&rsh;": { "codepoints": [8625], "characters": "\u21B1" },
+  "&Rsh;": { "codepoints": [8625], "characters": "\u21B1" },
+  "&rsqb;": { "codepoints": [93], "characters": "\u005D" },
+  "&rsquo;": { "codepoints": [8217], "characters": "\u2019" },
+  "&rsquor;": { "codepoints": [8217], "characters": "\u2019" },
+  "&rthree;": { "codepoints": [8908], "characters": "\u22CC" },
+  "&rtimes;": { "codepoints": [8906], "characters": "\u22CA" },
+  "&rtri;": { "codepoints": [9657], "characters": "\u25B9" },
+  "&rtrie;": { "codepoints": [8885], "characters": "\u22B5" },
+  "&rtrif;": { "codepoints": [9656], "characters": "\u25B8" },
+  "&rtriltri;": { "codepoints": [10702], "characters": "\u29CE" },
+  "&RuleDelayed;": { "codepoints": [10740], "characters": "\u29F4" },
+  "&ruluhar;": { "codepoints": [10600], "characters": "\u2968" },
+  "&rx;": { "codepoints": [8478], "characters": "\u211E" },
+  "&Sacute;": { "codepoints": [346], "characters": "\u015A" },
+  "&sacute;": { "codepoints": [347], "characters": "\u015B" },
+  "&sbquo;": { "codepoints": [8218], "characters": "\u201A" },
+  "&scap;": { "codepoints": [10936], "characters": "\u2AB8" },
+  "&Scaron;": { "codepoints": [352], "characters": "\u0160" },
+  "&scaron;": { "codepoints": [353], "characters": "\u0161" },
+  "&Sc;": { "codepoints": [10940], "characters": "\u2ABC" },
+  "&sc;": { "codepoints": [8827], "characters": "\u227B" },
+  "&sccue;": { "codepoints": [8829], "characters": "\u227D" },
+  "&sce;": { "codepoints": [10928], "characters": "\u2AB0" },
+  "&scE;": { "codepoints": [10932], "characters": "\u2AB4" },
+  "&Scedil;": { "codepoints": [350], "characters": "\u015E" },
+  "&scedil;": { "codepoints": [351], "characters": "\u015F" },
+  "&Scirc;": { "codepoints": [348], "characters": "\u015C" },
+  "&scirc;": { "codepoints": [349], "characters": "\u015D" },
+  "&scnap;": { "codepoints": [10938], "characters": "\u2ABA" },
+  "&scnE;": { "codepoints": [10934], "characters": "\u2AB6" },
+  "&scnsim;": { "codepoints": [8937], "characters": "\u22E9" },
+  "&scpolint;": { "codepoints": [10771], "characters": "\u2A13" },
+  "&scsim;": { "codepoints": [8831], "characters": "\u227F" },
+  "&Scy;": { "codepoints": [1057], "characters": "\u0421" },
+  "&scy;": { "codepoints": [1089], "characters": "\u0441" },
+  "&sdotb;": { "codepoints": [8865], "characters": "\u22A1" },
+  "&sdot;": { "codepoints": [8901], "characters": "\u22C5" },
+  "&sdote;": { "codepoints": [10854], "characters": "\u2A66" },
+  "&searhk;": { "codepoints": [10533], "characters": "\u2925" },
+  "&searr;": { "codepoints": [8600], "characters": "\u2198" },
+  "&seArr;": { "codepoints": [8664], "characters": "\u21D8" },
+  "&searrow;": { "codepoints": [8600], "characters": "\u2198" },
+  "&sect;": { "codepoints": [167], "characters": "\u00A7" },
+  "&sect": { "codepoints": [167], "characters": "\u00A7" },
+  "&semi;": { "codepoints": [59], "characters": "\u003B" },
+  "&seswar;": { "codepoints": [10537], "characters": "\u2929" },
+  "&setminus;": { "codepoints": [8726], "characters": "\u2216" },
+  "&setmn;": { "codepoints": [8726], "characters": "\u2216" },
+  "&sext;": { "codepoints": [10038], "characters": "\u2736" },
+  "&Sfr;": { "codepoints": [120086], "characters": "\uD835\uDD16" },
+  "&sfr;": { "codepoints": [120112], "characters": "\uD835\uDD30" },
+  "&sfrown;": { "codepoints": [8994], "characters": "\u2322" },
+  "&sharp;": { "codepoints": [9839], "characters": "\u266F" },
+  "&SHCHcy;": { "codepoints": [1065], "characters": "\u0429" },
+  "&shchcy;": { "codepoints": [1097], "characters": "\u0449" },
+  "&SHcy;": { "codepoints": [1064], "characters": "\u0428" },
+  "&shcy;": { "codepoints": [1096], "characters": "\u0448" },
+  "&ShortDownArrow;": { "codepoints": [8595], "characters": "\u2193" },
+  "&ShortLeftArrow;": { "codepoints": [8592], "characters": "\u2190" },
+  "&shortmid;": { "codepoints": [8739], "characters": "\u2223" },
+  "&shortparallel;": { "codepoints": [8741], "characters": "\u2225" },
+  "&ShortRightArrow;": { "codepoints": [8594], "characters": "\u2192" },
+  "&ShortUpArrow;": { "codepoints": [8593], "characters": "\u2191" },
+  "&shy;": { "codepoints": [173], "characters": "\u00AD" },
+  "&shy": { "codepoints": [173], "characters": "\u00AD" },
+  "&Sigma;": { "codepoints": [931], "characters": "\u03A3" },
+  "&sigma;": { "codepoints": [963], "characters": "\u03C3" },
+  "&sigmaf;": { "codepoints": [962], "characters": "\u03C2" },
+  "&sigmav;": { "codepoints": [962], "characters": "\u03C2" },
+  "&sim;": { "codepoints": [8764], "characters": "\u223C" },
+  "&simdot;": { "codepoints": [10858], "characters": "\u2A6A" },
+  "&sime;": { "codepoints": [8771], "characters": "\u2243" },
+  "&simeq;": { "codepoints": [8771], "characters": "\u2243" },
+  "&simg;": { "codepoints": [10910], "characters": "\u2A9E" },
+  "&simgE;": { "codepoints": [10912], "characters": "\u2AA0" },
+  "&siml;": { "codepoints": [10909], "characters": "\u2A9D" },
+  "&simlE;": { "codepoints": [10911], "characters": "\u2A9F" },
+  "&simne;": { "codepoints": [8774], "characters": "\u2246" },
+  "&simplus;": { "codepoints": [10788], "characters": "\u2A24" },
+  "&simrarr;": { "codepoints": [10610], "characters": "\u2972" },
+  "&slarr;": { "codepoints": [8592], "characters": "\u2190" },
+  "&SmallCircle;": { "codepoints": [8728], "characters": "\u2218" },
+  "&smallsetminus;": { "codepoints": [8726], "characters": "\u2216" },
+  "&smashp;": { "codepoints": [10803], "characters": "\u2A33" },
+  "&smeparsl;": { "codepoints": [10724], "characters": "\u29E4" },
+  "&smid;": { "codepoints": [8739], "characters": "\u2223" },
+  "&smile;": { "codepoints": [8995], "characters": "\u2323" },
+  "&smt;": { "codepoints": [10922], "characters": "\u2AAA" },
+  "&smte;": { "codepoints": [10924], "characters": "\u2AAC" },
+  "&smtes;": { "codepoints": [10924, 65024], "characters": "\u2AAC\uFE00" },
+  "&SOFTcy;": { "codepoints": [1068], "characters": "\u042C" },
+  "&softcy;": { "codepoints": [1100], "characters": "\u044C" },
+  "&solbar;": { "codepoints": [9023], "characters": "\u233F" },
+  "&solb;": { "codepoints": [10692], "characters": "\u29C4" },
+  "&sol;": { "codepoints": [47], "characters": "\u002F" },
+  "&Sopf;": { "codepoints": [120138], "characters": "\uD835\uDD4A" },
+  "&sopf;": { "codepoints": [120164], "characters": "\uD835\uDD64" },
+  "&spades;": { "codepoints": [9824], "characters": "\u2660" },
+  "&spadesuit;": { "codepoints": [9824], "characters": "\u2660" },
+  "&spar;": { "codepoints": [8741], "characters": "\u2225" },
+  "&sqcap;": { "codepoints": [8851], "characters": "\u2293" },
+  "&sqcaps;": { "codepoints": [8851, 65024], "characters": "\u2293\uFE00" },
+  "&sqcup;": { "codepoints": [8852], "characters": "\u2294" },
+  "&sqcups;": { "codepoints": [8852, 65024], "characters": "\u2294\uFE00" },
+  "&Sqrt;": { "codepoints": [8730], "characters": "\u221A" },
+  "&sqsub;": { "codepoints": [8847], "characters": "\u228F" },
+  "&sqsube;": { "codepoints": [8849], "characters": "\u2291" },
+  "&sqsubset;": { "codepoints": [8847], "characters": "\u228F" },
+  "&sqsubseteq;": { "codepoints": [8849], "characters": "\u2291" },
+  "&sqsup;": { "codepoints": [8848], "characters": "\u2290" },
+  "&sqsupe;": { "codepoints": [8850], "characters": "\u2292" },
+  "&sqsupset;": { "codepoints": [8848], "characters": "\u2290" },
+  "&sqsupseteq;": { "codepoints": [8850], "characters": "\u2292" },
+  "&square;": { "codepoints": [9633], "characters": "\u25A1" },
+  "&Square;": { "codepoints": [9633], "characters": "\u25A1" },
+  "&SquareIntersection;": { "codepoints": [8851], "characters": "\u2293" },
+  "&SquareSubset;": { "codepoints": [8847], "characters": "\u228F" },
+  "&SquareSubsetEqual;": { "codepoints": [8849], "characters": "\u2291" },
+  "&SquareSuperset;": { "codepoints": [8848], "characters": "\u2290" },
+  "&SquareSupersetEqual;": { "codepoints": [8850], "characters": "\u2292" },
+  "&SquareUnion;": { "codepoints": [8852], "characters": "\u2294" },
+  "&squarf;": { "codepoints": [9642], "characters": "\u25AA" },
+  "&squ;": { "codepoints": [9633], "characters": "\u25A1" },
+  "&squf;": { "codepoints": [9642], "characters": "\u25AA" },
+  "&srarr;": { "codepoints": [8594], "characters": "\u2192" },
+  "&Sscr;": { "codepoints": [119982], "characters": "\uD835\uDCAE" },
+  "&sscr;": { "codepoints": [120008], "characters": "\uD835\uDCC8" },
+  "&ssetmn;": { "codepoints": [8726], "characters": "\u2216" },
+  "&ssmile;": { "codepoints": [8995], "characters": "\u2323" },
+  "&sstarf;": { "codepoints": [8902], "characters": "\u22C6" },
+  "&Star;": { "codepoints": [8902], "characters": "\u22C6" },
+  "&star;": { "codepoints": [9734], "characters": "\u2606" },
+  "&starf;": { "codepoints": [9733], "characters": "\u2605" },
+  "&straightepsilon;": { "codepoints": [1013], "characters": "\u03F5" },
+  "&straightphi;": { "codepoints": [981], "characters": "\u03D5" },
+  "&strns;": { "codepoints": [175], "characters": "\u00AF" },
+  "&sub;": { "codepoints": [8834], "characters": "\u2282" },
+  "&Sub;": { "codepoints": [8912], "characters": "\u22D0" },
+  "&subdot;": { "codepoints": [10941], "characters": "\u2ABD" },
+  "&subE;": { "codepoints": [10949], "characters": "\u2AC5" },
+  "&sube;": { "codepoints": [8838], "characters": "\u2286" },
+  "&subedot;": { "codepoints": [10947], "characters": "\u2AC3" },
+  "&submult;": { "codepoints": [10945], "characters": "\u2AC1" },
+  "&subnE;": { "codepoints": [10955], "characters": "\u2ACB" },
+  "&subne;": { "codepoints": [8842], "characters": "\u228A" },
+  "&subplus;": { "codepoints": [10943], "characters": "\u2ABF" },
+  "&subrarr;": { "codepoints": [10617], "characters": "\u2979" },
+  "&subset;": { "codepoints": [8834], "characters": "\u2282" },
+  "&Subset;": { "codepoints": [8912], "characters": "\u22D0" },
+  "&subseteq;": { "codepoints": [8838], "characters": "\u2286" },
+  "&subseteqq;": { "codepoints": [10949], "characters": "\u2AC5" },
+  "&SubsetEqual;": { "codepoints": [8838], "characters": "\u2286" },
+  "&subsetneq;": { "codepoints": [8842], "characters": "\u228A" },
+  "&subsetneqq;": { "codepoints": [10955], "characters": "\u2ACB" },
+  "&subsim;": { "codepoints": [10951], "characters": "\u2AC7" },
+  "&subsub;": { "codepoints": [10965], "characters": "\u2AD5" },
+  "&subsup;": { "codepoints": [10963], "characters": "\u2AD3" },
+  "&succapprox;": { "codepoints": [10936], "characters": "\u2AB8" },
+  "&succ;": { "codepoints": [8827], "characters": "\u227B" },
+  "&succcurlyeq;": { "codepoints": [8829], "characters": "\u227D" },
+  "&Succeeds;": { "codepoints": [8827], "characters": "\u227B" },
+  "&SucceedsEqual;": { "codepoints": [10928], "characters": "\u2AB0" },
+  "&SucceedsSlantEqual;": { "codepoints": [8829], "characters": "\u227D" },
+  "&SucceedsTilde;": { "codepoints": [8831], "characters": "\u227F" },
+  "&succeq;": { "codepoints": [10928], "characters": "\u2AB0" },
+  "&succnapprox;": { "codepoints": [10938], "characters": "\u2ABA" },
+  "&succneqq;": { "codepoints": [10934], "characters": "\u2AB6" },
+  "&succnsim;": { "codepoints": [8937], "characters": "\u22E9" },
+  "&succsim;": { "codepoints": [8831], "characters": "\u227F" },
+  "&SuchThat;": { "codepoints": [8715], "characters": "\u220B" },
+  "&sum;": { "codepoints": [8721], "characters": "\u2211" },
+  "&Sum;": { "codepoints": [8721], "characters": "\u2211" },
+  "&sung;": { "codepoints": [9834], "characters": "\u266A" },
+  "&sup1;": { "codepoints": [185], "characters": "\u00B9" },
+  "&sup1": { "codepoints": [185], "characters": "\u00B9" },
+  "&sup2;": { "codepoints": [178], "characters": "\u00B2" },
+  "&sup2": { "codepoints": [178], "characters": "\u00B2" },
+  "&sup3;": { "codepoints": [179], "characters": "\u00B3" },
+  "&sup3": { "codepoints": [179], "characters": "\u00B3" },
+  "&sup;": { "codepoints": [8835], "characters": "\u2283" },
+  "&Sup;": { "codepoints": [8913], "characters": "\u22D1" },
+  "&supdot;": { "codepoints": [10942], "characters": "\u2ABE" },
+  "&supdsub;": { "codepoints": [10968], "characters": "\u2AD8" },
+  "&supE;": { "codepoints": [10950], "characters": "\u2AC6" },
+  "&supe;": { "codepoints": [8839], "characters": "\u2287" },
+  "&supedot;": { "codepoints": [10948], "characters": "\u2AC4" },
+  "&Superset;": { "codepoints": [8835], "characters": "\u2283" },
+  "&SupersetEqual;": { "codepoints": [8839], "characters": "\u2287" },
+  "&suphsol;": { "codepoints": [10185], "characters": "\u27C9" },
+  "&suphsub;": { "codepoints": [10967], "characters": "\u2AD7" },
+  "&suplarr;": { "codepoints": [10619], "characters": "\u297B" },
+  "&supmult;": { "codepoints": [10946], "characters": "\u2AC2" },
+  "&supnE;": { "codepoints": [10956], "characters": "\u2ACC" },
+  "&supne;": { "codepoints": [8843], "characters": "\u228B" },
+  "&supplus;": { "codepoints": [10944], "characters": "\u2AC0" },
+  "&supset;": { "codepoints": [8835], "characters": "\u2283" },
+  "&Supset;": { "codepoints": [8913], "characters": "\u22D1" },
+  "&supseteq;": { "codepoints": [8839], "characters": "\u2287" },
+  "&supseteqq;": { "codepoints": [10950], "characters": "\u2AC6" },
+  "&supsetneq;": { "codepoints": [8843], "characters": "\u228B" },
+  "&supsetneqq;": { "codepoints": [10956], "characters": "\u2ACC" },
+  "&supsim;": { "codepoints": [10952], "characters": "\u2AC8" },
+  "&supsub;": { "codepoints": [10964], "characters": "\u2AD4" },
+  "&supsup;": { "codepoints": [10966], "characters": "\u2AD6" },
+  "&swarhk;": { "codepoints": [10534], "characters": "\u2926" },
+  "&swarr;": { "codepoints": [8601], "characters": "\u2199" },
+  "&swArr;": { "codepoints": [8665], "characters": "\u21D9" },
+  "&swarrow;": { "codepoints": [8601], "characters": "\u2199" },
+  "&swnwar;": { "codepoints": [10538], "characters": "\u292A" },
+  "&szlig;": { "codepoints": [223], "characters": "\u00DF" },
+  "&szlig": { "codepoints": [223], "characters": "\u00DF" },
+  "&Tab;": { "codepoints": [9], "characters": "\u0009" },
+  "&target;": { "codepoints": [8982], "characters": "\u2316" },
+  "&Tau;": { "codepoints": [932], "characters": "\u03A4" },
+  "&tau;": { "codepoints": [964], "characters": "\u03C4" },
+  "&tbrk;": { "codepoints": [9140], "characters": "\u23B4" },
+  "&Tcaron;": { "codepoints": [356], "characters": "\u0164" },
+  "&tcaron;": { "codepoints": [357], "characters": "\u0165" },
+  "&Tcedil;": { "codepoints": [354], "characters": "\u0162" },
+  "&tcedil;": { "codepoints": [355], "characters": "\u0163" },
+  "&Tcy;": { "codepoints": [1058], "characters": "\u0422" },
+  "&tcy;": { "codepoints": [1090], "characters": "\u0442" },
+  "&tdot;": { "codepoints": [8411], "characters": "\u20DB" },
+  "&telrec;": { "codepoints": [8981], "characters": "\u2315" },
+  "&Tfr;": { "codepoints": [120087], "characters": "\uD835\uDD17" },
+  "&tfr;": { "codepoints": [120113], "characters": "\uD835\uDD31" },
+  "&there4;": { "codepoints": [8756], "characters": "\u2234" },
+  "&therefore;": { "codepoints": [8756], "characters": "\u2234" },
+  "&Therefore;": { "codepoints": [8756], "characters": "\u2234" },
+  "&Theta;": { "codepoints": [920], "characters": "\u0398" },
+  "&theta;": { "codepoints": [952], "characters": "\u03B8" },
+  "&thetasym;": { "codepoints": [977], "characters": "\u03D1" },
+  "&thetav;": { "codepoints": [977], "characters": "\u03D1" },
+  "&thickapprox;": { "codepoints": [8776], "characters": "\u2248" },
+  "&thicksim;": { "codepoints": [8764], "characters": "\u223C" },
+  "&ThickSpace;": { "codepoints": [8287, 8202], "characters": "\u205F\u200A" },
+  "&ThinSpace;": { "codepoints": [8201], "characters": "\u2009" },
+  "&thinsp;": { "codepoints": [8201], "characters": "\u2009" },
+  "&thkap;": { "codepoints": [8776], "characters": "\u2248" },
+  "&thksim;": { "codepoints": [8764], "characters": "\u223C" },
+  "&THORN;": { "codepoints": [222], "characters": "\u00DE" },
+  "&THORN": { "codepoints": [222], "characters": "\u00DE" },
+  "&thorn;": { "codepoints": [254], "characters": "\u00FE" },
+  "&thorn": { "codepoints": [254], "characters": "\u00FE" },
+  "&tilde;": { "codepoints": [732], "characters": "\u02DC" },
+  "&Tilde;": { "codepoints": [8764], "characters": "\u223C" },
+  "&TildeEqual;": { "codepoints": [8771], "characters": "\u2243" },
+  "&TildeFullEqual;": { "codepoints": [8773], "characters": "\u2245" },
+  "&TildeTilde;": { "codepoints": [8776], "characters": "\u2248" },
+  "&timesbar;": { "codepoints": [10801], "characters": "\u2A31" },
+  "&timesb;": { "codepoints": [8864], "characters": "\u22A0" },
+  "&times;": { "codepoints": [215], "characters": "\u00D7" },
+  "&times": { "codepoints": [215], "characters": "\u00D7" },
+  "&timesd;": { "codepoints": [10800], "characters": "\u2A30" },
+  "&tint;": { "codepoints": [8749], "characters": "\u222D" },
+  "&toea;": { "codepoints": [10536], "characters": "\u2928" },
+  "&topbot;": { "codepoints": [9014], "characters": "\u2336" },
+  "&topcir;": { "codepoints": [10993], "characters": "\u2AF1" },
+  "&top;": { "codepoints": [8868], "characters": "\u22A4" },
+  "&Topf;": { "codepoints": [120139], "characters": "\uD835\uDD4B" },
+  "&topf;": { "codepoints": [120165], "characters": "\uD835\uDD65" },
+  "&topfork;": { "codepoints": [10970], "characters": "\u2ADA" },
+  "&tosa;": { "codepoints": [10537], "characters": "\u2929" },
+  "&tprime;": { "codepoints": [8244], "characters": "\u2034" },
+  "&trade;": { "codepoints": [8482], "characters": "\u2122" },
+  "&TRADE;": { "codepoints": [8482], "characters": "\u2122" },
+  "&triangle;": { "codepoints": [9653], "characters": "\u25B5" },
+  "&triangledown;": { "codepoints": [9663], "characters": "\u25BF" },
+  "&triangleleft;": { "codepoints": [9667], "characters": "\u25C3" },
+  "&trianglelefteq;": { "codepoints": [8884], "characters": "\u22B4" },
+  "&triangleq;": { "codepoints": [8796], "characters": "\u225C" },
+  "&triangleright;": { "codepoints": [9657], "characters": "\u25B9" },
+  "&trianglerighteq;": { "codepoints": [8885], "characters": "\u22B5" },
+  "&tridot;": { "codepoints": [9708], "characters": "\u25EC" },
+  "&trie;": { "codepoints": [8796], "characters": "\u225C" },
+  "&triminus;": { "codepoints": [10810], "characters": "\u2A3A" },
+  "&TripleDot;": { "codepoints": [8411], "characters": "\u20DB" },
+  "&triplus;": { "codepoints": [10809], "characters": "\u2A39" },
+  "&trisb;": { "codepoints": [10701], "characters": "\u29CD" },
+  "&tritime;": { "codepoints": [10811], "characters": "\u2A3B" },
+  "&trpezium;": { "codepoints": [9186], "characters": "\u23E2" },
+  "&Tscr;": { "codepoints": [119983], "characters": "\uD835\uDCAF" },
+  "&tscr;": { "codepoints": [120009], "characters": "\uD835\uDCC9" },
+  "&TScy;": { "codepoints": [1062], "characters": "\u0426" },
+  "&tscy;": { "codepoints": [1094], "characters": "\u0446" },
+  "&TSHcy;": { "codepoints": [1035], "characters": "\u040B" },
+  "&tshcy;": { "codepoints": [1115], "characters": "\u045B" },
+  "&Tstrok;": { "codepoints": [358], "characters": "\u0166" },
+  "&tstrok;": { "codepoints": [359], "characters": "\u0167" },
+  "&twixt;": { "codepoints": [8812], "characters": "\u226C" },
+  "&twoheadleftarrow;": { "codepoints": [8606], "characters": "\u219E" },
+  "&twoheadrightarrow;": { "codepoints": [8608], "characters": "\u21A0" },
+  "&Uacute;": { "codepoints": [218], "characters": "\u00DA" },
+  "&Uacute": { "codepoints": [218], "characters": "\u00DA" },
+  "&uacute;": { "codepoints": [250], "characters": "\u00FA" },
+  "&uacute": { "codepoints": [250], "characters": "\u00FA" },
+  "&uarr;": { "codepoints": [8593], "characters": "\u2191" },
+  "&Uarr;": { "codepoints": [8607], "characters": "\u219F" },
+  "&uArr;": { "codepoints": [8657], "characters": "\u21D1" },
+  "&Uarrocir;": { "codepoints": [10569], "characters": "\u2949" },
+  "&Ubrcy;": { "codepoints": [1038], "characters": "\u040E" },
+  "&ubrcy;": { "codepoints": [1118], "characters": "\u045E" },
+  "&Ubreve;": { "codepoints": [364], "characters": "\u016C" },
+  "&ubreve;": { "codepoints": [365], "characters": "\u016D" },
+  "&Ucirc;": { "codepoints": [219], "characters": "\u00DB" },
+  "&Ucirc": { "codepoints": [219], "characters": "\u00DB" },
+  "&ucirc;": { "codepoints": [251], "characters": "\u00FB" },
+  "&ucirc": { "codepoints": [251], "characters": "\u00FB" },
+  "&Ucy;": { "codepoints": [1059], "characters": "\u0423" },
+  "&ucy;": { "codepoints": [1091], "characters": "\u0443" },
+  "&udarr;": { "codepoints": [8645], "characters": "\u21C5" },
+  "&Udblac;": { "codepoints": [368], "characters": "\u0170" },
+  "&udblac;": { "codepoints": [369], "characters": "\u0171" },
+  "&udhar;": { "codepoints": [10606], "characters": "\u296E" },
+  "&ufisht;": { "codepoints": [10622], "characters": "\u297E" },
+  "&Ufr;": { "codepoints": [120088], "characters": "\uD835\uDD18" },
+  "&ufr;": { "codepoints": [120114], "characters": "\uD835\uDD32" },
+  "&Ugrave;": { "codepoints": [217], "characters": "\u00D9" },
+  "&Ugrave": { "codepoints": [217], "characters": "\u00D9" },
+  "&ugrave;": { "codepoints": [249], "characters": "\u00F9" },
+  "&ugrave": { "codepoints": [249], "characters": "\u00F9" },
+  "&uHar;": { "codepoints": [10595], "characters": "\u2963" },
+  "&uharl;": { "codepoints": [8639], "characters": "\u21BF" },
+  "&uharr;": { "codepoints": [8638], "characters": "\u21BE" },
+  "&uhblk;": { "codepoints": [9600], "characters": "\u2580" },
+  "&ulcorn;": { "codepoints": [8988], "characters": "\u231C" },
+  "&ulcorner;": { "codepoints": [8988], "characters": "\u231C" },
+  "&ulcrop;": { "codepoints": [8975], "characters": "\u230F" },
+  "&ultri;": { "codepoints": [9720], "characters": "\u25F8" },
+  "&Umacr;": { "codepoints": [362], "characters": "\u016A" },
+  "&umacr;": { "codepoints": [363], "characters": "\u016B" },
+  "&uml;": { "codepoints": [168], "characters": "\u00A8" },
+  "&uml": { "codepoints": [168], "characters": "\u00A8" },
+  "&UnderBar;": { "codepoints": [95], "characters": "\u005F" },
+  "&UnderBrace;": { "codepoints": [9183], "characters": "\u23DF" },
+  "&UnderBracket;": { "codepoints": [9141], "characters": "\u23B5" },
+  "&UnderParenthesis;": { "codepoints": [9181], "characters": "\u23DD" },
+  "&Union;": { "codepoints": [8899], "characters": "\u22C3" },
+  "&UnionPlus;": { "codepoints": [8846], "characters": "\u228E" },
+  "&Uogon;": { "codepoints": [370], "characters": "\u0172" },
+  "&uogon;": { "codepoints": [371], "characters": "\u0173" },
+  "&Uopf;": { "codepoints": [120140], "characters": "\uD835\uDD4C" },
+  "&uopf;": { "codepoints": [120166], "characters": "\uD835\uDD66" },
+  "&UpArrowBar;": { "codepoints": [10514], "characters": "\u2912" },
+  "&uparrow;": { "codepoints": [8593], "characters": "\u2191" },
+  "&UpArrow;": { "codepoints": [8593], "characters": "\u2191" },
+  "&Uparrow;": { "codepoints": [8657], "characters": "\u21D1" },
+  "&UpArrowDownArrow;": { "codepoints": [8645], "characters": "\u21C5" },
+  "&updownarrow;": { "codepoints": [8597], "characters": "\u2195" },
+  "&UpDownArrow;": { "codepoints": [8597], "characters": "\u2195" },
+  "&Updownarrow;": { "codepoints": [8661], "characters": "\u21D5" },
+  "&UpEquilibrium;": { "codepoints": [10606], "characters": "\u296E" },
+  "&upharpoonleft;": { "codepoints": [8639], "characters": "\u21BF" },
+  "&upharpoonright;": { "codepoints": [8638], "characters": "\u21BE" },
+  "&uplus;": { "codepoints": [8846], "characters": "\u228E" },
+  "&UpperLeftArrow;": { "codepoints": [8598], "characters": "\u2196" },
+  "&UpperRightArrow;": { "codepoints": [8599], "characters": "\u2197" },
+  "&upsi;": { "codepoints": [965], "characters": "\u03C5" },
+  "&Upsi;": { "codepoints": [978], "characters": "\u03D2" },
+  "&upsih;": { "codepoints": [978], "characters": "\u03D2" },
+  "&Upsilon;": { "codepoints": [933], "characters": "\u03A5" },
+  "&upsilon;": { "codepoints": [965], "characters": "\u03C5" },
+  "&UpTeeArrow;": { "codepoints": [8613], "characters": "\u21A5" },
+  "&UpTee;": { "codepoints": [8869], "characters": "\u22A5" },
+  "&upuparrows;": { "codepoints": [8648], "characters": "\u21C8" },
+  "&urcorn;": { "codepoints": [8989], "characters": "\u231D" },
+  "&urcorner;": { "codepoints": [8989], "characters": "\u231D" },
+  "&urcrop;": { "codepoints": [8974], "characters": "\u230E" },
+  "&Uring;": { "codepoints": [366], "characters": "\u016E" },
+  "&uring;": { "codepoints": [367], "characters": "\u016F" },
+  "&urtri;": { "codepoints": [9721], "characters": "\u25F9" },
+  "&Uscr;": { "codepoints": [119984], "characters": "\uD835\uDCB0" },
+  "&uscr;": { "codepoints": [120010], "characters": "\uD835\uDCCA" },
+  "&utdot;": { "codepoints": [8944], "characters": "\u22F0" },
+  "&Utilde;": { "codepoints": [360], "characters": "\u0168" },
+  "&utilde;": { "codepoints": [361], "characters": "\u0169" },
+  "&utri;": { "codepoints": [9653], "characters": "\u25B5" },
+  "&utrif;": { "codepoints": [9652], "characters": "\u25B4" },
+  "&uuarr;": { "codepoints": [8648], "characters": "\u21C8" },
+  "&Uuml;": { "codepoints": [220], "characters": "\u00DC" },
+  "&Uuml": { "codepoints": [220], "characters": "\u00DC" },
+  "&uuml;": { "codepoints": [252], "characters": "\u00FC" },
+  "&uuml": { "codepoints": [252], "characters": "\u00FC" },
+  "&uwangle;": { "codepoints": [10663], "characters": "\u29A7" },
+  "&vangrt;": { "codepoints": [10652], "characters": "\u299C" },
+  "&varepsilon;": { "codepoints": [1013], "characters": "\u03F5" },
+  "&varkappa;": { "codepoints": [1008], "characters": "\u03F0" },
+  "&varnothing;": { "codepoints": [8709], "characters": "\u2205" },
+  "&varphi;": { "codepoints": [981], "characters": "\u03D5" },
+  "&varpi;": { "codepoints": [982], "characters": "\u03D6" },
+  "&varpropto;": { "codepoints": [8733], "characters": "\u221D" },
+  "&varr;": { "codepoints": [8597], "characters": "\u2195" },
+  "&vArr;": { "codepoints": [8661], "characters": "\u21D5" },
+  "&varrho;": { "codepoints": [1009], "characters": "\u03F1" },
+  "&varsigma;": { "codepoints": [962], "characters": "\u03C2" },
+  "&varsubsetneq;": { "codepoints": [8842, 65024], "characters": "\u228A\uFE00" },
+  "&varsubsetneqq;": { "codepoints": [10955, 65024], "characters": "\u2ACB\uFE00" },
+  "&varsupsetneq;": { "codepoints": [8843, 65024], "characters": "\u228B\uFE00" },
+  "&varsupsetneqq;": { "codepoints": [10956, 65024], "characters": "\u2ACC\uFE00" },
+  "&vartheta;": { "codepoints": [977], "characters": "\u03D1" },
+  "&vartriangleleft;": { "codepoints": [8882], "characters": "\u22B2" },
+  "&vartriangleright;": { "codepoints": [8883], "characters": "\u22B3" },
+  "&vBar;": { "codepoints": [10984], "characters": "\u2AE8" },
+  "&Vbar;": { "codepoints": [10987], "characters": "\u2AEB" },
+  "&vBarv;": { "codepoints": [10985], "characters": "\u2AE9" },
+  "&Vcy;": { "codepoints": [1042], "characters": "\u0412" },
+  "&vcy;": { "codepoints": [1074], "characters": "\u0432" },
+  "&vdash;": { "codepoints": [8866], "characters": "\u22A2" },
+  "&vDash;": { "codepoints": [8872], "characters": "\u22A8" },
+  "&Vdash;": { "codepoints": [8873], "characters": "\u22A9" },
+  "&VDash;": { "codepoints": [8875], "characters": "\u22AB" },
+  "&Vdashl;": { "codepoints": [10982], "characters": "\u2AE6" },
+  "&veebar;": { "codepoints": [8891], "characters": "\u22BB" },
+  "&vee;": { "codepoints": [8744], "characters": "\u2228" },
+  "&Vee;": { "codepoints": [8897], "characters": "\u22C1" },
+  "&veeeq;": { "codepoints": [8794], "characters": "\u225A" },
+  "&vellip;": { "codepoints": [8942], "characters": "\u22EE" },
+  "&verbar;": { "codepoints": [124], "characters": "\u007C" },
+  "&Verbar;": { "codepoints": [8214], "characters": "\u2016" },
+  "&vert;": { "codepoints": [124], "characters": "\u007C" },
+  "&Vert;": { "codepoints": [8214], "characters": "\u2016" },
+  "&VerticalBar;": { "codepoints": [8739], "characters": "\u2223" },
+  "&VerticalLine;": { "codepoints": [124], "characters": "\u007C" },
+  "&VerticalSeparator;": { "codepoints": [10072], "characters": "\u2758" },
+  "&VerticalTilde;": { "codepoints": [8768], "characters": "\u2240" },
+  "&VeryThinSpace;": { "codepoints": [8202], "characters": "\u200A" },
+  "&Vfr;": { "codepoints": [120089], "characters": "\uD835\uDD19" },
+  "&vfr;": { "codepoints": [120115], "characters": "\uD835\uDD33" },
+  "&vltri;": { "codepoints": [8882], "characters": "\u22B2" },
+  "&vnsub;": { "codepoints": [8834, 8402], "characters": "\u2282\u20D2" },
+  "&vnsup;": { "codepoints": [8835, 8402], "characters": "\u2283\u20D2" },
+  "&Vopf;": { "codepoints": [120141], "characters": "\uD835\uDD4D" },
+  "&vopf;": { "codepoints": [120167], "characters": "\uD835\uDD67" },
+  "&vprop;": { "codepoints": [8733], "characters": "\u221D" },
+  "&vrtri;": { "codepoints": [8883], "characters": "\u22B3" },
+  "&Vscr;": { "codepoints": [119985], "characters": "\uD835\uDCB1" },
+  "&vscr;": { "codepoints": [120011], "characters": "\uD835\uDCCB" },
+  "&vsubnE;": { "codepoints": [10955, 65024], "characters": "\u2ACB\uFE00" },
+  "&vsubne;": { "codepoints": [8842, 65024], "characters": "\u228A\uFE00" },
+  "&vsupnE;": { "codepoints": [10956, 65024], "characters": "\u2ACC\uFE00" },
+  "&vsupne;": { "codepoints": [8843, 65024], "characters": "\u228B\uFE00" },
+  "&Vvdash;": { "codepoints": [8874], "characters": "\u22AA" },
+  "&vzigzag;": { "codepoints": [10650], "characters": "\u299A" },
+  "&Wcirc;": { "codepoints": [372], "characters": "\u0174" },
+  "&wcirc;": { "codepoints": [373], "characters": "\u0175" },
+  "&wedbar;": { "codepoints": [10847], "characters": "\u2A5F" },
+  "&wedge;": { "codepoints": [8743], "characters": "\u2227" },
+  "&Wedge;": { "codepoints": [8896], "characters": "\u22C0" },
+  "&wedgeq;": { "codepoints": [8793], "characters": "\u2259" },
+  "&weierp;": { "codepoints": [8472], "characters": "\u2118" },
+  "&Wfr;": { "codepoints": [120090], "characters": "\uD835\uDD1A" },
+  "&wfr;": { "codepoints": [120116], "characters": "\uD835\uDD34" },
+  "&Wopf;": { "codepoints": [120142], "characters": "\uD835\uDD4E" },
+  "&wopf;": { "codepoints": [120168], "characters": "\uD835\uDD68" },
+  "&wp;": { "codepoints": [8472], "characters": "\u2118" },
+  "&wr;": { "codepoints": [8768], "characters": "\u2240" },
+  "&wreath;": { "codepoints": [8768], "characters": "\u2240" },
+  "&Wscr;": { "codepoints": [119986], "characters": "\uD835\uDCB2" },
+  "&wscr;": { "codepoints": [120012], "characters": "\uD835\uDCCC" },
+  "&xcap;": { "codepoints": [8898], "characters": "\u22C2" },
+  "&xcirc;": { "codepoints": [9711], "characters": "\u25EF" },
+  "&xcup;": { "codepoints": [8899], "characters": "\u22C3" },
+  "&xdtri;": { "codepoints": [9661], "characters": "\u25BD" },
+  "&Xfr;": { "codepoints": [120091], "characters": "\uD835\uDD1B" },
+  "&xfr;": { "codepoints": [120117], "characters": "\uD835\uDD35" },
+  "&xharr;": { "codepoints": [10231], "characters": "\u27F7" },
+  "&xhArr;": { "codepoints": [10234], "characters": "\u27FA" },
+  "&Xi;": { "codepoints": [926], "characters": "\u039E" },
+  "&xi;": { "codepoints": [958], "characters": "\u03BE" },
+  "&xlarr;": { "codepoints": [10229], "characters": "\u27F5" },
+  "&xlArr;": { "codepoints": [10232], "characters": "\u27F8" },
+  "&xmap;": { "codepoints": [10236], "characters": "\u27FC" },
+  "&xnis;": { "codepoints": [8955], "characters": "\u22FB" },
+  "&xodot;": { "codepoints": [10752], "characters": "\u2A00" },
+  "&Xopf;": { "codepoints": [120143], "characters": "\uD835\uDD4F" },
+  "&xopf;": { "codepoints": [120169], "characters": "\uD835\uDD69" },
+  "&xoplus;": { "codepoints": [10753], "characters": "\u2A01" },
+  "&xotime;": { "codepoints": [10754], "characters": "\u2A02" },
+  "&xrarr;": { "codepoints": [10230], "characters": "\u27F6" },
+  "&xrArr;": { "codepoints": [10233], "characters": "\u27F9" },
+  "&Xscr;": { "codepoints": [119987], "characters": "\uD835\uDCB3" },
+  "&xscr;": { "codepoints": [120013], "characters": "\uD835\uDCCD" },
+  "&xsqcup;": { "codepoints": [10758], "characters": "\u2A06" },
+  "&xuplus;": { "codepoints": [10756], "characters": "\u2A04" },
+  "&xutri;": { "codepoints": [9651], "characters": "\u25B3" },
+  "&xvee;": { "codepoints": [8897], "characters": "\u22C1" },
+  "&xwedge;": { "codepoints": [8896], "characters": "\u22C0" },
+  "&Yacute;": { "codepoints": [221], "characters": "\u00DD" },
+  "&Yacute": { "codepoints": [221], "characters": "\u00DD" },
+  "&yacute;": { "codepoints": [253], "characters": "\u00FD" },
+  "&yacute": { "codepoints": [253], "characters": "\u00FD" },
+  "&YAcy;": { "codepoints": [1071], "characters": "\u042F" },
+  "&yacy;": { "codepoints": [1103], "characters": "\u044F" },
+  "&Ycirc;": { "codepoints": [374], "characters": "\u0176" },
+  "&ycirc;": { "codepoints": [375], "characters": "\u0177" },
+  "&Ycy;": { "codepoints": [1067], "characters": "\u042B" },
+  "&ycy;": { "codepoints": [1099], "characters": "\u044B" },
+  "&yen;": { "codepoints": [165], "characters": "\u00A5" },
+  "&yen": { "codepoints": [165], "characters": "\u00A5" },
+  "&Yfr;": { "codepoints": [120092], "characters": "\uD835\uDD1C" },
+  "&yfr;": { "codepoints": [120118], "characters": "\uD835\uDD36" },
+  "&YIcy;": { "codepoints": [1031], "characters": "\u0407" },
+  "&yicy;": { "codepoints": [1111], "characters": "\u0457" },
+  "&Yopf;": { "codepoints": [120144], "characters": "\uD835\uDD50" },
+  "&yopf;": { "codepoints": [120170], "characters": "\uD835\uDD6A" },
+  "&Yscr;": { "codepoints": [119988], "characters": "\uD835\uDCB4" },
+  "&yscr;": { "codepoints": [120014], "characters": "\uD835\uDCCE" },
+  "&YUcy;": { "codepoints": [1070], "characters": "\u042E" },
+  "&yucy;": { "codepoints": [1102], "characters": "\u044E" },
+  "&yuml;": { "codepoints": [255], "characters": "\u00FF" },
+  "&yuml": { "codepoints": [255], "characters": "\u00FF" },
+  "&Yuml;": { "codepoints": [376], "characters": "\u0178" },
+  "&Zacute;": { "codepoints": [377], "characters": "\u0179" },
+  "&zacute;": { "codepoints": [378], "characters": "\u017A" },
+  "&Zcaron;": { "codepoints": [381], "characters": "\u017D" },
+  "&zcaron;": { "codepoints": [382], "characters": "\u017E" },
+  "&Zcy;": { "codepoints": [1047], "characters": "\u0417" },
+  "&zcy;": { "codepoints": [1079], "characters": "\u0437" },
+  "&Zdot;": { "codepoints": [379], "characters": "\u017B" },
+  "&zdot;": { "codepoints": [380], "characters": "\u017C" },
+  "&zeetrf;": { "codepoints": [8488], "characters": "\u2128" },
+  "&ZeroWidthSpace;": { "codepoints": [8203], "characters": "\u200B" },
+  "&Zeta;": { "codepoints": [918], "characters": "\u0396" },
+  "&zeta;": { "codepoints": [950], "characters": "\u03B6" },
+  "&zfr;": { "codepoints": [120119], "characters": "\uD835\uDD37" },
+  "&Zfr;": { "codepoints": [8488], "characters": "\u2128" },
+  "&ZHcy;": { "codepoints": [1046], "characters": "\u0416" },
+  "&zhcy;": { "codepoints": [1078], "characters": "\u0436" },
+  "&zigrarr;": { "codepoints": [8669], "characters": "\u21DD" },
+  "&zopf;": { "codepoints": [120171], "characters": "\uD835\uDD6B" },
+  "&Zopf;": { "codepoints": [8484], "characters": "\u2124" },
+  "&Zscr;": { "codepoints": [119989], "characters": "\uD835\uDCB5" },
+  "&zscr;": { "codepoints": [120015], "characters": "\uD835\uDCCF" },
+  "&zwj;": { "codepoints": [8205], "characters": "\u200D" },
+  "&zwnj;": { "codepoints": [8204], "characters": "\u200C" }
+}
diff --git a/tag-modifier/src/main/resources/structure.json b/tag-modifier/src/main/resources/structure.json
new file mode 100644
index 0000000..cd880f7
--- /dev/null
+++ b/tag-modifier/src/main/resources/structure.json
@@ -0,0 +1,87 @@
+{
+    "a" :{
+        "type" : ["flow","phrasing", "palpable"],
+        "context" : ["phrasing"],
+        "contentModel" : {
+            "type" : "transparent",
+            "reject" : ["interactive"]
+        },
+        "attributeModifier" : {
+            "href" : {
+                "type" : "interactive"
+            }
+        }
+    },
+    "abbr" :{
+        "type" : ["flow","phrasing", "palpable"],
+        "context" : ["phrasing"],
+        "contentModel" : {
+            "type" : "phrasing"
+        }
+    },
+    "address" :{
+        "type" : ["flow", "palpable"],
+        "context" : ["flow"],
+        "contentModel" : {
+            "type" : "flow",
+            "reject" : ["heading", "sectioning"],
+            "rejectTags" : ["header", "footer", "address"]
+        },
+        "attributeModifier" : {
+            "href" : {
+                "type" : "interactive"
+            }
+        }
+    },
+    "article" :{
+        "type" : ["flow", "sectioning", "palpable"],
+        "context" : ["flow"],
+        "contentModel" : {
+            "type" : "flow",
+            "rejectTags" : ["main"]
+        }
+    },
+    "aside" :{
+        "type" : ["flow", "sectioning", "palpable"],
+        "context" : ["flow"],
+        "contentModel" : {
+            "type" : "flow",
+            "rejectTags" : ["main"]
+        }
+    },
+    "audio" :{
+        "type" : ["flow", "phrasing", "embedded"],
+        "context" : ["embedded"],
+        "contentModel" : {
+            "type" : "transparent",
+            "rejectTags" : ["audio", "video"]
+        },
+        "attributeModifier" : {
+            "controls" : {
+                "type" : ["interactive","palpable"]
+            }
+        }
+    },
+    "b" :{
+        "type" : ["flow", "phrasing", "palpable"],
+        "context" : ["phrasing"],
+        "contentModel" : {
+            "type" : "flow",
+            "reject" : ["heading", "sectioning"],
+            "rejectTags" : ["header", "footer", "address"]
+        },
+        "attributeModifier" : {
+            "href" : {
+                "type" : "interactive"
+            }
+        }
+    },
+    "p" :{
+        "type" : ["flow", "palpable"],
+        "context" : ["flow"],
+        "contentModel" : {
+            "type" : "phrasing"
+        }
+    }
+    
+}
\ No newline at end of file
diff --git a/tag-modifier/src/test/java/com/github/htmlparser/HtmlParseTest.java b/tag-modifier/src/test/java/com/github/htmlparser/HtmlParseTest.java
new file mode 100644
index 0000000..91c023e
--- /dev/null
+++ b/tag-modifier/src/test/java/com/github/htmlparser/HtmlParseTest.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.htmlparser;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.InputStream;
+import java.text.ParseException;
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+import org.apache.sling.tagmodifier.Element;
+import org.apache.sling.tagmodifier.ElementType;
+import org.apache.sling.tagmodifier.Tag;
+import org.apache.sling.tagmodifier.TagMapping;
+import org.apache.sling.tagmodifier.consumer.HtmlSAXSupport;
+import org.apache.sling.tagmodifier.util.HtmlStreams;
+import org.junit.Before;
+import org.junit.Test;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.DefaultHandler2;
+
+public class HtmlParseTest {
+
+    Stream<Element> stream;
+
+    @Before
+    public void setUp() throws ParseException, Exception {
+        InputStream is = this.getClass().getResourceAsStream("/demo.html");
+        stream = Tag.stream(is, "UTF-8");
+    }
+
+    @Test
+    public void docParseTagTest() throws Exception {
+        long count = stream.filter(elem -> elem.getType() == ElementType.START_TAG).count();
+        assertEquals(902, count);
+    }
+
+    @Test
+    public void docParseAllTest() throws Exception {
+        long count = stream.count();
+        assertEquals(2928, count);
+    }
+
+    @Test
+    public void docParseAllTestToString() throws Exception {
+        stream.map(HtmlStreams.TO_HTML).count();
+    }
+
+    @Test
+    public void docParseSAXTest() {
+        HtmlSAXSupport support = new HtmlSAXSupport(new DefaultHandler2() {
+            @Override
+            public void startElement(String uri, String localName, String qName, Attributes attributes)
+                    throws SAXException {
+                //System.out.println(localName);
+            }
+
+        }, new DefaultHandler2());
+        stream.forEach(support);
+    }
+
+    @Test
+    public void docParseTagTest3() throws Exception {
+        long count = stream.flatMap(TagMapping.map((element, process) -> {
+            if (element.containsAttribute("href")) {
+                //System.out.println(element.getAttributeValue("href"));
+                process.next(element);
+            }
+        })).count();
+        assertEquals(356, count);
+    }
+
+    private static Function<Element, Stream<Element>> CONVERT_LINKS = TagMapping.map((element, process) -> {
+        if (element.containsAttribute("href")) {
+            String value = element.getAttributeValue("href");
+            if (value != null && value.startsWith("/")) {
+                element.setAttribute("href", "http://www.apache.org" + value);
+            }
+        }
+        if (element.containsAttribute("src")) {
+            String value = element.getAttributeValue("src");
+            if (value != null && value.startsWith("/")) {
+                element.setAttribute("src", "http://www.apache.org" + value);
+            }
+        }
+        process.next(element);
+    });
+
+    @Test
+    public void convertLinkTest() throws Exception {
+        long count = stream.flatMap(CONVERT_LINKS).count();
+        assertEquals(2928, count);
+    }
+
+    @Test
+    public void convertLinkAndPrintTest() throws Exception {
+        //stream.flatMap(CONVERT_LINKS).map(HtmlStreams.TO_HTML).forEach(System.out::print);
+    }
+
+}
diff --git a/tag-modifier/src/test/java/com/github/htmlparser/UnusualHtmlTest.java b/tag-modifier/src/test/java/com/github/htmlparser/UnusualHtmlTest.java
new file mode 100644
index 0000000..0ac95ef
--- /dev/null
+++ b/tag-modifier/src/test/java/com/github/htmlparser/UnusualHtmlTest.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.htmlparser;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.InputStream;
+import java.text.ParseException;
+import java.util.stream.Stream;
+
+import org.apache.sling.tagmodifier.Element;
+import org.apache.sling.tagmodifier.ElementType;
+import org.apache.sling.tagmodifier.Tag;
+import org.apache.sling.tagmodifier.TagMapping;
+import org.junit.Before;
+import org.junit.Test;
+
+public class UnusualHtmlTest {
+
+    private Stream<Element> stream;
+
+    @Before
+    public void setUp() throws ParseException, Exception {
+        InputStream is = this.getClass().getResourceAsStream("/fail.html");
+        stream = Tag.stream(is, "UTF-8");
+    }
+    
+    @Test
+    public void docParseTagTest() throws Exception {
+        long count = stream.filter(elem -> elem.getType() != ElementType.TEXT ).count();
+        assertEquals(4, count);
+    }
+
+    @Test
+    public void docParseTagTest2() throws Exception {
+        long count = stream.filter(elem -> elem.getType() == ElementType.TEXT ).count();
+        assertEquals(7, count);
+    }
+    
+    @Test
+    public void docParseTagTest3() throws Exception {
+        long count = stream.flatMap(TagMapping.map((element,process) ->{
+            if (element.containsAttribute("href")) {
+                process.next(element, element);
+            }
+        })).count();
+        assertEquals(0, count);
+    }
+    
+}
diff --git a/tag-modifier/src/test/resources/demo.html b/tag-modifier/src/test/resources/demo.html
new file mode 100644
index 0000000..18a7366
--- /dev/null
+++ b/tag-modifier/src/test/resources/demo.html
@@ -0,0 +1,864 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="utf-8">
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <meta name="description" content="Home page of The Apache Software Foundation">
+  
+  <link rel="apple-touch-icon" sizes="57x57" href="/favicons/apple-touch-icon-57x57.png">
+  <link rel="apple-touch-icon" sizes="60x60" href="/favicons/apple-touch-icon-60x60.png">
+  <link rel="apple-touch-icon" sizes="72x72" href="/favicons/apple-touch-icon-72x72.png">
+  <link rel="apple-touch-icon" sizes="76x76" href="/favicons/apple-touch-icon-76x76.png">
+  <link rel="apple-touch-icon" sizes="114x114" href="/favicons/apple-touch-icon-114x114.png">
+  <link rel="apple-touch-icon" sizes="120x120" href="/favicons/apple-touch-icon-120x120.png">
+  <link rel="apple-touch-icon" sizes="144x144" href="/favicons/apple-touch-icon-144x144.png">
+  <link rel="apple-touch-icon" sizes="152x152" href="/favicons/apple-touch-icon-152x152.png">
+  <link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-touch-icon-180x180.png">
+  <link rel="icon" type="image/png" href="/favicons/favicon-32x32.png" sizes="32x32">
+  <link rel="icon" type="image/png" href="/favicons/favicon-194x194.png" sizes="194x194">
+  <link rel="icon" type="image/png" href="/favicons/favicon-96x96.png" sizes="96x96">
+  <link rel="icon" type="image/png" href="/favicons/android-chrome-192x192.png" sizes="192x192">
+  <link rel="icon" type="image/png" href="/favicons/favicon-16x16.png" sizes="16x16">
+  <link rel="manifest" href="/favicons/manifest.json">
+  <link rel="shortcut icon" href="/favicons/favicon.ico">
+  <meta name="msapplication-TileColor" content="#603cba">
+  <meta name="msapplication-TileImage" content="/favicons/mstile-144x144.png">
+  <meta name="msapplication-config" content="/favicons/browserconfig.xml">
+  <meta name="theme-color" content="#303284">
+
+  <title>Welcome to The Apache Software Foundation!</title>
+  <link href='https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700%7cDroid+Serif:400,700' rel='stylesheet' type='text/css'>
+  <link href="/css/min.bootstrap.css" rel="stylesheet">
+  <link href="/css/styles.css" rel="stylesheet">  
+    
+
+    
+
+</head>
+
+<body>
+<!-- Navigation -->  
+<header>
+  <nav class="navbar navbar-default navbar-fixed-top">
+    <div class="container">
+      <div class="navbar-header">
+        <button class="navbar-toggle" type="button" data-toggle="collapse" data-target="#mainnav-collapse">
+          <span class="sr-only">Toggle navigation</span>
+          <span class="icon-bar"></span>
+          <span class="icon-bar"></span>
+          <span class="icon-bar"></span>
+        </button>
+        <a href="#" class="navbar-brand"><span class="glyphicon glyphicon-home"></span></a>
+      </div>
+      <div class="collapse navbar-collapse" id="mainnav-collapse">
+        <div style="line-height:20px; padding-top:5px; float:left"><a href="/">Home</a></div>
+        <ul class="nav navbar-nav navbar-right">
+          <li class="dropdown">
+          	<a href="#" class="dropdown-toggle" data-toggle="dropdown">About <span class="caret"></span></a>
+          	<ul class="dropdown-menu" role="menu">
+      				<li><a href="/foundation">Overview</a></li>
+      				<li><a href="/foundation/members.html">Members</a></li>
+      				<li><a href="/foundation/how-it-works.html">Process</a></li>
+      				<li><a href="/foundation/sponsorship.html">Sponsorship</a></li>
+      				<li><a href="/foundation/glossary.html">Glossary</a></li>
+      				<li><a href="/foundation/preFAQ.html">FAQ</a></li>
+      				<li><a href="/foundation/policies/conduct.html">Code of Conduct</a></li>
+      				<li><a href="/foundation/contact.html ">Contact</a></li>      				
+          	</ul>
+          </li>
+			<li><a href="/index.html#projects-list">Projects</a></li>
+  				<li class="dropdown">
+	        	<a href="#" class="dropdown-toggle" data-toggle="dropdown">People <span class="caret"></span></a>
+	        	<ul class="dropdown-menu" role="menu">
+  						<li><a href="http://people.apache.org/">Overview</a></li>
+  						<li><a href="http://people.apache.org/committer-index.html">Committers</a></li>
+  						<li><a href="/foundation/how-it-works.html#meritocracy">Meritocracy</a></li>
+  						<li><a href="/foundation/how-it-works.html#roles">Roles</a></li>
+      				<li><a href="/foundation/policies/conduct.html">Code of Conduct</a></li>
+  						<li><a href="http://planet.apache.org/">Planet Apache</a></li>
+	        	</ul>
+	        </li>
+          <li class="dropdown">
+            <a href="#" class="dropdown-toggle" data-toggle="dropdown">Get Involved <span class="caret"></span></a>
+            <ul class="dropdown-menu" role="menu">
+              <li><a href="/foundation/getinvolved.html">Overview</a></li>
+      				<li><a href="http://community.apache.org/">Community Development</a></li>
+      				<li><a href="/foundation/policies/conduct.html">Code of Conduct</a></li>
+                    <li><a href="http://helpwanted.apache.org/">Help Wanted</a></li>
+      				<li><a href="http://www.apachecon.com/">ApacheCon</a></li>
+            </ul>
+  				</li>
+          <li><a href="/dyn/closer.cgi">Download</a></li>
+          <li class="dropdown">
+          	<a href="#" class="dropdown-toggle" data-toggle="dropdown">Support Apache <span class="caret"></span></a>
+          	<ul class="dropdown-menu" role="menu">
+      				<li><a href="/foundation/sponsorship.html">Sponsorship</a></li>
+      				<li><a href="/foundation/contributing.html">Donations</a></li>
+      				<li><a href="/foundation/buy_stuff.html">Buy Stuff</a></li>
+      				<li><a href="/foundation/thanks.html">Thanks</a></li>
+          	</ul>
+          </li>
+        </ul>
+      </div>
+    </div>
+  </nav>
+</header>
+<!-- / Navigation -->
+<div class="container">
+  <div class="row">
+        <div class="col-md-6 col-sm-5 col-xs-12">
+      <img src="/img/asf_logo.png" alt="Apache Logo" style="max-width: 100%;">
+    </div>
+    <div class="col-md-3 col-sm-3 col-xs-6">
+    <a href="http://apache.org/foundation/contributing.html" title="Support Apache">
+      <img src="/images/SupportApache-small.png" style="height: 150px; width: 150px; margin-top: 5px; margin-bottom: 5px;">
+    </a>
+    </div>
+    <div class="col-md-3 col-sm-4 col-xs-6">
+      <div class="input-group" style="margin-bottom: 5px;">
+				<script>
+  (function() {
+    var cx = '005703438322411770421:5mgshgrgx2u';
+    var gcse = document.createElement('script');
+    gcse.type = 'text/javascript';
+    gcse.async = true;
+    gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
+        '//cse.google.com/cse.js?cx=' + cx;
+    var s = document.getElementsByTagName('script')[0];
+    s.parentNode.insertBefore(gcse, s);
+  })();
+</script>
+		  <gcse:searchbox-only></gcse:searchbox-only>
+			</div>
+			<a role="button" class="btn btn-block btn-default btn-xs" href="/foundation/governance/">The Apache Way</a>
+			<a role="button" class="btn btn-block btn-default btn-xs" href="https://community.apache.org/contributors/">Contribute</a>
+			<a role="button" class="btn btn-block btn-default btn-xs" href="/foundation/thanks.html">ASF Sponsors</a>
+    </div>
+  </div>
+</div>
+
+<!-- Apache Statements Section -->
+<section class="bg-gray" >
+  <div class="container">
+    <div class="row">
+      <div class="col-md-4">
+        <style type="text/css">
+/* The following code is added by mdx_elementid.py
+   It was originally lifted from http://subversion.apache.org/style/site.css */
+/*
+ * Hide class="elementid-permalink", except when an enclosing heading
+ * has the :hover property.
+ */
+.headerlink, .elementid-permalink {
+  visibility: hidden;
+}
+h2:hover > .headerlink, h3:hover > .headerlink, h1:hover > .headerlink, h6:hover > .headerlink, h4:hover > .headerlink, h5:hover > .headerlink, dt:hover > .elementid-permalink { visibility: visible }</style>
+<h3>Open.</h3>
+
+<h5 class="no-btm-margin">The Apache Software Foundation</h5>
+
+<p class="small">provides support for the Apache Community of Open Source software projects, which provide software products for the public good.</p>
+      </div>
+      <div class="col-md-4">
+        <style type="text/css">
+/* The following code is added by mdx_elementid.py
+   It was originally lifted from http://subversion.apache.org/style/site.css */
+/*
+ * Hide class="elementid-permalink", except when an enclosing heading
+ * has the :hover property.
+ */
+.headerlink, .elementid-permalink {
+  visibility: hidden;
+}
+h2:hover > .headerlink, h3:hover > .headerlink, h1:hover > .headerlink, h6:hover > .headerlink, h4:hover > .headerlink, h5:hover > .headerlink, dt:hover > .elementid-permalink { visibility: visible }</style>
+<h3>Innovation.</h3>
+
+<h5 class="no-btm-margin">Apache projects are defined</h5>
+
+<p class="small">by collaborative consensus based processes, an open, pragmatic software license and a desire to create high quality software that leads the way in its field.</p>
+      </div>
+      <div class="col-md-4">
+        <style type="text/css">
+/* The following code is added by mdx_elementid.py
+   It was originally lifted from http://subversion.apache.org/style/site.css */
+/*
+ * Hide class="elementid-permalink", except when an enclosing heading
+ * has the :hover property.
+ */
+.headerlink, .elementid-permalink {
+  visibility: hidden;
+}
+h2:hover > .headerlink, h3:hover > .headerlink, h1:hover > .headerlink, h6:hover > .headerlink, h4:hover > .headerlink, h5:hover > .headerlink, dt:hover > .elementid-permalink { visibility: visible }</style>
+<h3>Community.</h3>
+
+<h5 class="no-btm-margin">We consider ourselves</h5>
+
+<p class="small">not simply a group of projects sharing a server, but rather a community of developers and users.</p>
+      </div>
+    </div>
+  </div>
+</section>
+<!-- / Apache Statements Section -->
+<!-- ApacheCon etc -->
+<section class="bg-gray" style="background: #F9F9F9; padding-top: 10px; padding-bottom: 0px; border-top: 1px solid #666; border-bottom: 1px solid #666;">
+  <div class="container">
+    <div class="row">
+      <div class="col-md-3">
+        <style type="text/css">
+/* The following code is added by mdx_elementid.py
+   It was originally lifted from http://subversion.apache.org/style/site.css */
+/*
+ * Hide class="elementid-permalink", except when an enclosing heading
+ * has the :hover property.
+ */
+.headerlink, .elementid-permalink {
+  visibility: hidden;
+}
+h2:hover > .headerlink, h3:hover > .headerlink, h1:hover > .headerlink, h6:hover > .headerlink, h4:hover > .headerlink, h5:hover > .headerlink, dt:hover > .elementid-permalink { visibility: visible }</style>
+<p><a href="https://blogs.apache.org/foundation/entry/the-apache-software-foundation-celebrates">
+<img src="images/ASF-at-19-board.jpg" style="width: 95%; max-width: 260px;"/>
+</a></p>
+      </div>
+      <div class="col-md-6">
+        <style type="text/css">
+/* The following code is added by mdx_elementid.py
+   It was originally lifted from http://subversion.apache.org/style/site.css */
+/*
+ * Hide class="elementid-permalink", except when an enclosing heading
+ * has the :hover property.
+ */
+.headerlink, .elementid-permalink {
+  visibility: hidden;
+}
+h2:hover > .headerlink, h3:hover > .headerlink, h1:hover > .headerlink, h6:hover > .headerlink, h4:hover > .headerlink, h5:hover > .headerlink, dt:hover > .elementid-permalink { visibility: visible }</style>
+<h4>APACHE IS OPEN</h4>
+
+<p class="small">
+<b><i>"The Apache Software Foundation is a cornerstone of the modern Open Source software ecosystem – supporting some of the most widely used and important software solutions powering today's Internet economy."</i>
+– Mark Driver, Research Vice President, Gartner
+</b>
+<p>Lauded among the most successful influencers in Open Source, The Apache Software Foundation's commitment to collaborative development has long served as a model for producing consistently high quality software that advances the future of open development. <a href="https://s.apache.org/PIRA">https://s.apache.org/PIRA</a></p>
+
+</p>
+      </div>
+      <div class="col-md-3">
+        <style type="text/css">
+/* The following code is added by mdx_elementid.py
+   It was originally lifted from http://subversion.apache.org/style/site.css */
+/*
+ * Hide class="elementid-permalink", except when an enclosing heading
+ * has the :hover property.
+ */
+.headerlink, .elementid-permalink {
+  visibility: hidden;
+}
+h2:hover > .headerlink, h3:hover > .headerlink, h1:hover > .headerlink, h6:hover > .headerlink, h4:hover > .headerlink, h5:hover > .headerlink, dt:hover > .elementid-permalink { visibility: visible }</style>
+<p style="text-align: center; vertical-align: middle; padding-top: 24px;">
+<a href="https://apachecon.com">
+<img src="images/acna18-glossy-wide.png" style="width: 95%; max-width: 260px; height: 108px;" title="ApacheCon North America"/><br/>
+Register for ApacheCon!
+</a>
+</p>
+      </div>
+    </div>
+  </div>
+</section>
+<!-- /ApacheCon etc -->
+<!-- Apache Featured Projects Section    -->
+<section class="container">
+  <div class="row">
+    <div class="col-md-12">
+      <h2>Apache Projects</h2>
+      <p>The all-volunteer ASF develops, stewards, and incubates more than 350 Open Source projects and initiatives that cover a wide range of technologies. 
+        From Accumulo to Zookeeper, if you are looking for a rewarding experience in Open Source and industry leading software, chances are you are going to find it here.
... 620 lines suppressed ...