diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..0433176 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,50 @@ +language: objective-c +osx_image: xcode9.2 +env: + global: + - LC_CTYPE=en_US.UTF-8 + - LANG=en_US.UTF-8 + - PROJECT=libcmark_gfm.xcodeproj + - IOS_FRAMEWORK_SCHEME="libcmark_gfm-iOS" + - MACOS_FRAMEWORK_SCHEME="libcmark_gfm-macOS" + - TVOS_FRAMEWORK_SCHEME="libcmark_gfm-tvOS" + - WATCHOS_FRAMEWORK_SCHEME="libcmark_gfm-watchOS" + - IOS_SDK=iphonesimulator11.2 + - MACOS_SDK=macosx10.13 + - TVOS_SDK=appletvsimulator11.2 + - WATCHOS_SDK=watchsimulator4.2 + matrix: + - DESTINATION="OS=4.2,name=Apple Watch Series 3 - 42mm" SCHEME="$WATCHOS_FRAMEWORK_SCHEME" SDK="$WATCHOS_SDK" RUN_TESTS="NO" POD_LINT="NO" + + - DESTINATION="OS=11.2,name=Apple TV 4K" SCHEME="$TVOS_FRAMEWORK_SCHEME" SDK="$TVOS_SDK" RUN_TESTS="YES" POD_LINT="NO" + + - DESTINATION="arch=x86_64" SCHEME="$MACOS_FRAMEWORK_SCHEME" SDK="$MACOS_SDK" RUN_TESTS="YES" POD_LINT="NO" + + - DESTINATION="OS=11.2,name=iPhone X" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK" RUN_TESTS="YES" POD_LINT="YES" + +before_install: + - gem install cocoapods --pre --no-rdoc --no-ri --no-document --quiet +script: + - pod install + - set -o pipefail + - xcodebuild -version + - xcodebuild -showsdks + + # Build Framework in Debug and Run Tests if specified + - if [ $RUN_TESTS == "YES" ]; then + xcodebuild -project "$PROJECT" -scheme "$SCHEME" -sdk "$SDK" -destination "$DESTINATION" -configuration Debug ONLY_ACTIVE_ARCH=NO ENABLE_TESTABILITY=YES test | xcpretty; + else + xcodebuild -project "$PROJECT" -scheme "$SCHEME" -sdk "$SDK" -destination "$DESTINATION" -configuration Debug ONLY_ACTIVE_ARCH=NO build | xcpretty; + fi + + # Build Framework in Release and Run Tests if specified + - if [ $RUN_TESTS == "YES" ]; then + xcodebuild -project "$PROJECT" -scheme "$SCHEME" -sdk "$SDK" -destination "$DESTINATION" -configuration Release ONLY_ACTIVE_ARCH=NO ENABLE_TESTABILITY=YES test | xcpretty; + else + xcodebuild -project "$PROJECT" -scheme "$SCHEME" -sdk "$SDK" -destination "$DESTINATION" -configuration Release ONLY_ACTIVE_ARCH=NO build | xcpretty; + fi + + # Run `pod lib lint` if specified + - if [ $POD_LINT == "YES" ]; then + pod lib lint; + fi diff --git a/Package.swift b/Package.swift new file mode 100644 index 0000000..d268e3d --- /dev/null +++ b/Package.swift @@ -0,0 +1,17 @@ +// swift-tools-version:4.0 + +import PackageDescription + +let package = Package( + name: "libcmark_gfm", + products: [ + .library( + name: "libcmark_gfm", + targets: ["libcmark_gfm"]), + ], + targets: [ + .target( + name: "libcmark_gfm", + dependencies: []) + ] +) diff --git a/README.md b/README.md new file mode 100644 index 0000000..b5934ed --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# libcmark_gfm + +Swift compatible framework for cmark-gfm. Works with CocoaPods, Carthage, and the Swift Package Manager. + +[![](https://travis-ci.org/KristopherGBaker/libcmark_gfm.svg?branch=master)](https://travis-ci.org/KristopherGBaker/libcmark_gfm) diff --git a/Sources/Info.plist b/Sources/Info.plist new file mode 100644 index 0000000..188487b --- /dev/null +++ b/Sources/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSHumanReadableCopyright + Copyright © 2017 Kristopher Baker. All rights reserved. + NSPrincipalClass + + + diff --git a/Sources/libcmark_gfm/arena.c b/Sources/libcmark_gfm/arena.c new file mode 100644 index 0000000..801fb3c --- /dev/null +++ b/Sources/libcmark_gfm/arena.c @@ -0,0 +1,103 @@ +#include +#include +#include +#include "cmark.h" +#include "cmark_extension_api.h" + +static struct arena_chunk { + size_t sz, used; + uint8_t push_point; + void *ptr; + struct arena_chunk *prev; +} *A = NULL; + +static struct arena_chunk *alloc_arena_chunk(size_t sz, struct arena_chunk *prev) { + struct arena_chunk *c = (struct arena_chunk *)calloc(1, sizeof(*c)); + if (!c) + abort(); + c->sz = sz; + c->ptr = calloc(1, sz); + if (!c->ptr) + abort(); + c->prev = prev; + return c; +} + +void cmark_arena_push(void) { + if (!A) + return; + A->push_point = 1; + A = alloc_arena_chunk(10240, A); +} + +int cmark_arena_pop(void) { + if (!A) + return 0; + while (A && !A->push_point) { + free(A->ptr); + struct arena_chunk *n = A->prev; + free(A); + A = n; + } + if (A) + A->push_point = 0; + return 1; +} + +static void init_arena(void) { + A = alloc_arena_chunk(4 * 1048576, NULL); +} + +void cmark_arena_reset(void) { + while (A) { + free(A->ptr); + struct arena_chunk *n = A->prev; + free(A); + A = n; + } +} + +static void *arena_calloc(size_t nmem, size_t size) { + if (!A) + init_arena(); + + size_t sz = nmem * size + sizeof(size_t); + + // Round allocation sizes to largest integer size to + // ensure returned memory is correctly aligned + const size_t align = sizeof(size_t) - 1; + sz = (sz + align) & ~align; + + if (sz > A->sz) { + A->prev = alloc_arena_chunk(sz, A->prev); + return (uint8_t *) A->prev->ptr + sizeof(size_t); + } + if (sz > A->sz - A->used) { + A = alloc_arena_chunk(A->sz + A->sz / 2, A); + } + void *ptr = (uint8_t *) A->ptr + A->used; + A->used += sz; + *((size_t *) ptr) = sz - sizeof(size_t); + return (uint8_t *) ptr + sizeof(size_t); +} + +static void *arena_realloc(void *ptr, size_t size) { + if (!A) + init_arena(); + + void *new_ptr = arena_calloc(1, size); + if (ptr) + memcpy(new_ptr, ptr, ((size_t *) ptr)[-1]); + return new_ptr; +} + +static void arena_free(void *ptr) { + (void) ptr; + /* no-op */ +} + +cmark_mem CMARK_ARENA_MEM_ALLOCATOR = {arena_calloc, arena_realloc, arena_free}; + +cmark_mem *cmark_get_arena_mem_allocator() { + return &CMARK_ARENA_MEM_ALLOCATOR; +} diff --git a/Sources/libcmark_gfm/autolink.c b/Sources/libcmark_gfm/autolink.c new file mode 100644 index 0000000..a1bdbf7 --- /dev/null +++ b/Sources/libcmark_gfm/autolink.c @@ -0,0 +1,421 @@ +#include "autolink.h" +#include "parser.h" +#include +#include + +#if defined(_WIN32) +#define strncasecmp _strnicmp +#else +#include +#endif + +static int is_valid_hostchar(const uint8_t *link, size_t link_len) { + int32_t ch; + int r = cmark_utf8proc_iterate(link, (bufsize_t)link_len, &ch); + if (r < 0) + return 0; + return !cmark_utf8proc_is_space(ch) && !cmark_utf8proc_is_punctuation(ch); +} + +static int sd_autolink_issafe(const uint8_t *link, size_t link_len) { + static const size_t valid_uris_count = 3; + static const char *valid_uris[] = {"http://", "https://", "ftp://"}; + + size_t i; + + for (i = 0; i < valid_uris_count; ++i) { + size_t len = strlen(valid_uris[i]); + + if (link_len > len && strncasecmp((char *)link, valid_uris[i], len) == 0 && + is_valid_hostchar(link + len, link_len - len)) + return 1; + } + + return 0; +} + +static size_t autolink_delim(uint8_t *data, size_t link_end) { + uint8_t cclose, copen; + size_t i; + + for (i = 0; i < link_end; ++i) + if (data[i] == '<') { + link_end = i; + break; + } + + while (link_end > 0) { + cclose = data[link_end - 1]; + + switch (cclose) { + case ')': + copen = '('; + break; + default: + copen = 0; + } + + if (strchr("?!.,:*_~'\"", data[link_end - 1]) != NULL) + link_end--; + + else if (data[link_end - 1] == ';') { + size_t new_end = link_end - 2; + + while (new_end > 0 && cmark_isalpha(data[new_end])) + new_end--; + + if (new_end < link_end - 2 && data[new_end] == '&') + link_end = new_end; + else + link_end--; + } else if (copen != 0) { + size_t closing = 0; + size_t opening = 0; + i = 0; + + /* Allow any number of matching brackets (as recognised in copen/cclose) + * at the end of the URL. If there is a greater number of closing + * brackets than opening ones, we remove one character from the end of + * the link. + * + * Examples (input text => output linked portion): + * + * http://www.pokemon.com/Pikachu_(Electric) + * => http://www.pokemon.com/Pikachu_(Electric) + * + * http://www.pokemon.com/Pikachu_((Electric) + * => http://www.pokemon.com/Pikachu_((Electric) + * + * http://www.pokemon.com/Pikachu_(Electric)) + * => http://www.pokemon.com/Pikachu_(Electric) + * + * http://www.pokemon.com/Pikachu_((Electric)) + * => http://www.pokemon.com/Pikachu_((Electric)) + */ + + while (i < link_end) { + if (data[i] == copen) + opening++; + else if (data[i] == cclose) + closing++; + + i++; + } + + if (closing <= opening) + break; + + link_end--; + } else + break; + } + + return link_end; +} + +static size_t check_domain(uint8_t *data, size_t size, int allow_short) { + size_t i, np = 0, uscore1 = 0, uscore2 = 0; + + for (i = 1; i < size - 1; i++) { + if (data[i] == '_') + uscore2++; + else if (data[i] == '.') { + uscore1 = uscore2; + uscore2 = 0; + np++; + } else if (!is_valid_hostchar(data + i, size - i) && data[i] != '-') + break; + } + + if (uscore1 > 0 || uscore2 > 0) + return 0; + + if (allow_short) { + /* We don't need a valid domain in the strict sense (with + * least one dot; so just make sure it's composed of valid + * domain characters and return the length of the the valid + * sequence. */ + return i; + } else { + /* a valid domain needs to have at least a dot. + * that's as far as we get */ + return np ? i : 0; + } +} + +static cmark_node *www_match(cmark_parser *parser, cmark_node *parent, + cmark_inline_parser *inline_parser) { + cmark_chunk *chunk = cmark_inline_parser_get_chunk(inline_parser); + size_t max_rewind = cmark_inline_parser_get_offset(inline_parser); + uint8_t *data = chunk->data + max_rewind; + size_t size = chunk->len - max_rewind; + int start = cmark_inline_parser_get_column(inline_parser); + + size_t link_end; + + if (max_rewind > 0 && strchr("*_~(", data[-1]) == NULL && + !cmark_isspace(data[-1])) + return 0; + + if (size < 4 || memcmp(data, "www.", strlen("www.")) != 0) + return 0; + + link_end = check_domain(data, size, 0); + + if (link_end == 0) + return NULL; + + while (link_end < size && !cmark_isspace(data[link_end])) + link_end++; + + link_end = autolink_delim(data, link_end); + + if (link_end == 0) + return NULL; + + cmark_inline_parser_set_offset(inline_parser, (int)(max_rewind + link_end)); + + cmark_node *node = cmark_node_new_with_mem(CMARK_NODE_LINK, parser->mem); + + cmark_strbuf buf; + cmark_strbuf_init(parser->mem, &buf, 10); + cmark_strbuf_puts(&buf, "http://"); + cmark_strbuf_put(&buf, data, (bufsize_t)link_end); + node->as.link.url = cmark_chunk_buf_detach(&buf); + + cmark_node *text = cmark_node_new_with_mem(CMARK_NODE_TEXT, parser->mem); + text->as.literal = + cmark_chunk_dup(chunk, (bufsize_t)max_rewind, (bufsize_t)link_end); + cmark_node_append_child(node, text); + + node->start_line = text->start_line = + node->end_line = text->end_line = + cmark_inline_parser_get_line(inline_parser); + + node->start_column = text->start_column = start - 1; + node->end_column = text->end_column = cmark_inline_parser_get_column(inline_parser) - 1; + + return node; +} + +static cmark_node *url_match(cmark_parser *parser, cmark_node *parent, + cmark_inline_parser *inline_parser) { + size_t link_end, domain_len; + int rewind = 0; + + cmark_chunk *chunk = cmark_inline_parser_get_chunk(inline_parser); + int max_rewind = cmark_inline_parser_get_offset(inline_parser); + uint8_t *data = chunk->data + max_rewind; + size_t size = chunk->len - max_rewind; + + if (size < 4 || data[1] != '/' || data[2] != '/') + return 0; + + while (rewind < max_rewind && cmark_isalpha(data[-rewind - 1])) + rewind++; + + if (!sd_autolink_issafe(data - rewind, size + rewind)) + return 0; + + link_end = strlen("://"); + + domain_len = check_domain(data + link_end, size - link_end, 1); + + if (domain_len == 0) + return 0; + + link_end += domain_len; + while (link_end < size && !cmark_isspace(data[link_end])) + link_end++; + + link_end = autolink_delim(data, link_end); + + if (link_end == 0) + return NULL; + + cmark_inline_parser_set_offset(inline_parser, (int)(max_rewind + link_end)); + cmark_node_unput(parent, rewind); + + cmark_node *node = cmark_node_new_with_mem(CMARK_NODE_LINK, parser->mem); + + cmark_chunk url = cmark_chunk_dup(chunk, max_rewind - rewind, + (bufsize_t)(link_end + rewind)); + node->as.link.url = url; + + cmark_node *text = cmark_node_new_with_mem(CMARK_NODE_TEXT, parser->mem); + text->as.literal = url; + cmark_node_append_child(node, text); + + return node; +} + +static cmark_node *match(cmark_syntax_extension *ext, cmark_parser *parser, + cmark_node *parent, unsigned char c, + cmark_inline_parser *inline_parser) { + if (cmark_inline_parser_in_bracket(inline_parser, false) || + cmark_inline_parser_in_bracket(inline_parser, true)) + return NULL; + + if (c == ':') + return url_match(parser, parent, inline_parser); + + if (c == 'w') + return www_match(parser, parent, inline_parser); + + return NULL; + + // note that we could end up re-consuming something already a + // part of an inline, because we don't track when the last + // inline was finished in inlines.c. +} + +static void postprocess_text(cmark_parser *parser, cmark_node *text, int offset) { + size_t link_end; + uint8_t *data = text->as.literal.data, + *at; + size_t size = text->as.literal.len; + int rewind, max_rewind, + nb = 0, np = 0, ns = 0; + + if (offset < 0 || (size_t)offset >= size) + return; + + data += offset; + size -= offset; + + at = (uint8_t *)memchr(data, '@', size); + if (!at) + return; + + max_rewind = (int)(at - data); + data += max_rewind; + size -= max_rewind; + + for (rewind = 0; rewind < max_rewind; ++rewind) { + uint8_t c = data[-rewind - 1]; + + if (cmark_isalnum(c)) + continue; + + if (strchr(".+-_", c) != NULL) + continue; + + if (c == '/') + ns++; + + break; + } + + if (rewind == 0 || ns > 0) { + postprocess_text(parser, text, max_rewind + 1 + offset); + return; + } + + for (link_end = 0; link_end < size; ++link_end) { + uint8_t c = data[link_end]; + + if (cmark_isalnum(c)) + continue; + + if (c == '@') + nb++; + else if (c == '.' && link_end < size - 1 && cmark_isalnum(data[link_end + 1])) + np++; + else if (c != '-' && c != '_') + break; + } + + if (link_end < 2 || nb != 1 || np == 0 || + (!cmark_isalpha(data[link_end - 1]) && data[link_end - 1] != '.')) { + postprocess_text(parser, text, max_rewind + 1 + offset); + return; + } + + link_end = autolink_delim(data, link_end); + + if (link_end == 0) { + postprocess_text(parser, text, max_rewind + 1 + offset); + return; + } + + cmark_chunk_to_cstr(parser->mem, &text->as.literal); + + cmark_node *link_node = cmark_node_new_with_mem(CMARK_NODE_LINK, parser->mem); + cmark_strbuf buf; + cmark_strbuf_init(parser->mem, &buf, 10); + cmark_strbuf_puts(&buf, "mailto:"); + cmark_strbuf_put(&buf, data - rewind, (bufsize_t)(link_end + rewind)); + link_node->as.link.url = cmark_chunk_buf_detach(&buf); + + cmark_node *link_text = cmark_node_new_with_mem(CMARK_NODE_TEXT, parser->mem); + cmark_chunk email = cmark_chunk_dup( + &text->as.literal, + offset + max_rewind - rewind, + (bufsize_t)(link_end + rewind)); + cmark_chunk_to_cstr(parser->mem, &email); + link_text->as.literal = email; + cmark_node_append_child(link_node, link_text); + + cmark_node_insert_after(text, link_node); + + cmark_node *post = cmark_node_new_with_mem(CMARK_NODE_TEXT, parser->mem); + post->as.literal = cmark_chunk_dup(&text->as.literal, + (bufsize_t)(offset + max_rewind + link_end), + (bufsize_t)(size - link_end)); + cmark_chunk_to_cstr(parser->mem, &post->as.literal); + + cmark_node_insert_after(link_node, post); + + text->as.literal.len = offset + max_rewind - rewind; + text->as.literal.data[text->as.literal.len] = 0; + + postprocess_text(parser, post, 0); +} + +static cmark_node *postprocess(cmark_syntax_extension *ext, cmark_parser *parser, cmark_node *root) { + cmark_iter *iter; + cmark_event_type ev; + cmark_node *node; + bool in_link = false; + + cmark_consolidate_text_nodes(root); + iter = cmark_iter_new(root); + + while ((ev = cmark_iter_next(iter)) != CMARK_EVENT_DONE) { + node = cmark_iter_get_node(iter); + if (in_link) { + if (ev == CMARK_EVENT_EXIT && node->type == CMARK_NODE_LINK) { + in_link = false; + } + continue; + } + + if (ev == CMARK_EVENT_ENTER && node->type == CMARK_NODE_LINK) { + in_link = true; + continue; + } + + if (ev == CMARK_EVENT_ENTER && node->type == CMARK_NODE_TEXT) { + postprocess_text(parser, node, 0); + } + } + + cmark_iter_free(iter); + + return root; +} + +cmark_syntax_extension *create_autolink_extension(void) { + cmark_syntax_extension *ext = cmark_syntax_extension_new("autolink"); + cmark_llist *special_chars = NULL; + + cmark_syntax_extension_set_match_inline_func(ext, match); + cmark_syntax_extension_set_postprocess_func(ext, postprocess); + + cmark_mem *mem = cmark_get_default_mem_allocator(); + special_chars = cmark_llist_append(mem, special_chars, (void *)':'); + special_chars = cmark_llist_append(mem, special_chars, (void *)'w'); + cmark_syntax_extension_set_special_inline_chars(ext, special_chars); + + return ext; +} diff --git a/Sources/libcmark_gfm/blocks.c b/Sources/libcmark_gfm/blocks.c new file mode 100644 index 0000000..fb5dcf2 --- /dev/null +++ b/Sources/libcmark_gfm/blocks.c @@ -0,0 +1,1519 @@ +/** + * Block parsing implementation. + * + * For a high-level overview of the block parsing process, + * see http://spec.commonmark.org/0.24/#phase-1-block-structure + */ + +#include +#include +#include + +#include "cmark_ctype.h" +#include "syntax_extension.h" +#include "config.h" +#include "parser.h" +#include "cmark.h" +#include "node.h" +#include "references.h" +#include "utf8.h" +#include "scanners.h" +#include "inlines.h" +#include "houdini.h" +#include "buffer.h" +#include "footnotes.h" + +#define CODE_INDENT 4 +#define TAB_STOP 4 + +#ifndef MIN +#define MIN(x, y) ((x < y) ? x : y) +#endif + +#define peek_at(i, n) (i)->data[n] + +static bool S_last_line_blank(const cmark_node *node) { + return (node->flags & CMARK_NODE__LAST_LINE_BLANK) != 0; +} + +static CMARK_INLINE cmark_node_type S_type(const cmark_node *node) { + return (cmark_node_type)node->type; +} + +static void S_set_last_line_blank(cmark_node *node, bool is_blank) { + if (is_blank) + node->flags |= CMARK_NODE__LAST_LINE_BLANK; + else + node->flags &= ~CMARK_NODE__LAST_LINE_BLANK; +} + +static CMARK_INLINE bool S_is_line_end_char(char c) { + return (c == '\n' || c == '\r'); +} + +static CMARK_INLINE bool S_is_space_or_tab(char c) { + return (c == ' ' || c == '\t'); +} + +static void S_parser_feed(cmark_parser *parser, const unsigned char *buffer, + size_t len, bool eof); + +static void S_process_line(cmark_parser *parser, const unsigned char *buffer, + bufsize_t bytes); + +static cmark_node *make_block(cmark_mem *mem, cmark_node_type tag, + int start_line, int start_column) { + cmark_node *e; + + e = (cmark_node *)mem->calloc(1, sizeof(*e)); + cmark_strbuf_init(mem, &e->content, 32); + e->type = (uint16_t)tag; + e->flags = CMARK_NODE__OPEN; + e->start_line = start_line; + e->start_column = start_column; + e->end_line = start_line; + + return e; +} + +// Create a root document node. +static cmark_node *make_document(cmark_mem *mem) { + cmark_node *e = make_block(mem, CMARK_NODE_DOCUMENT, 1, 1); + return e; +} + +int cmark_parser_attach_syntax_extension(cmark_parser *parser, + cmark_syntax_extension *extension) { + parser->syntax_extensions = cmark_llist_append(parser->mem, parser->syntax_extensions, extension); + if (extension->match_inline || extension->insert_inline_from_delim) { + parser->inline_syntax_extensions = cmark_llist_append( + parser->mem, parser->inline_syntax_extensions, extension); + } + + return 1; +} + +static void cmark_parser_dispose(cmark_parser *parser) { + if (parser->root) + cmark_node_free(parser->root); + + if (parser->refmap) + cmark_map_free(parser->refmap); +} + +static void cmark_parser_reset(cmark_parser *parser) { + cmark_llist *saved_exts = parser->syntax_extensions; + cmark_llist *saved_inline_exts = parser->inline_syntax_extensions; + int saved_options = parser->options; + cmark_mem *saved_mem = parser->mem; + + cmark_parser_dispose(parser); + + memset(parser, 0, sizeof(cmark_parser)); + parser->mem = saved_mem; + + cmark_strbuf_init(parser->mem, &parser->curline, 256); + cmark_strbuf_init(parser->mem, &parser->linebuf, 0); + + cmark_node *document = make_document(parser->mem); + + parser->refmap = cmark_reference_map_new(parser->mem); + parser->root = document; + parser->current = document; + + parser->last_buffer_ended_with_cr = false; + + parser->syntax_extensions = saved_exts; + parser->inline_syntax_extensions = saved_inline_exts; + parser->options = saved_options; +} + +cmark_parser *cmark_parser_new_with_mem(int options, cmark_mem *mem) { + cmark_parser *parser = (cmark_parser *)mem->calloc(1, sizeof(cmark_parser)); + parser->mem = mem; + parser->options = options; + cmark_parser_reset(parser); + return parser; +} + +cmark_parser *cmark_parser_new(int options) { + extern cmark_mem CMARK_DEFAULT_MEM_ALLOCATOR; + return cmark_parser_new_with_mem(options, &CMARK_DEFAULT_MEM_ALLOCATOR); +} + +void cmark_parser_free(cmark_parser *parser) { + cmark_mem *mem = parser->mem; + cmark_parser_dispose(parser); + cmark_strbuf_free(&parser->curline); + cmark_strbuf_free(&parser->linebuf); + cmark_llist_free(parser->mem, parser->syntax_extensions); + cmark_llist_free(parser->mem, parser->inline_syntax_extensions); + mem->free(parser); +} + +static cmark_node *finalize(cmark_parser *parser, cmark_node *b); + +// Returns true if line has only space characters, else false. +static bool is_blank(cmark_strbuf *s, bufsize_t offset) { + while (offset < s->size) { + switch (s->ptr[offset]) { + case '\r': + case '\n': + return true; + case ' ': + offset++; + break; + case '\t': + offset++; + break; + default: + return false; + } + } + + return true; +} + +static CMARK_INLINE bool accepts_lines(cmark_node_type block_type) { + return (block_type == CMARK_NODE_PARAGRAPH || + block_type == CMARK_NODE_HEADING || + block_type == CMARK_NODE_CODE_BLOCK); +} + +static CMARK_INLINE bool contains_inlines(cmark_node *node) { + if (node->extension && node->extension->contains_inlines_func) { + return node->extension->contains_inlines_func(node->extension, node) != 0; + } + + return (node->type == CMARK_NODE_PARAGRAPH || + node->type == CMARK_NODE_HEADING); +} + +static void add_line(cmark_node *node, cmark_chunk *ch, cmark_parser *parser) { + int chars_to_tab; + int i; + assert(node->flags & CMARK_NODE__OPEN); + if (parser->partially_consumed_tab) { + parser->offset += 1; // skip over tab + // add space characters: + chars_to_tab = TAB_STOP - (parser->column % TAB_STOP); + for (i = 0; i < chars_to_tab; i++) { + cmark_strbuf_putc(&node->content, ' '); + } + } + cmark_strbuf_put(&node->content, ch->data + parser->offset, + ch->len - parser->offset); +} + +static void remove_trailing_blank_lines(cmark_strbuf *ln) { + bufsize_t i; + unsigned char c; + + for (i = ln->size - 1; i >= 0; --i) { + c = ln->ptr[i]; + + if (c != ' ' && c != '\t' && !S_is_line_end_char(c)) + break; + } + + if (i < 0) { + cmark_strbuf_clear(ln); + return; + } + + for (; i < ln->size; ++i) { + c = ln->ptr[i]; + + if (!S_is_line_end_char(c)) + continue; + + cmark_strbuf_truncate(ln, i); + break; + } +} + +// Check to see if a node ends with a blank line, descending +// if needed into lists and sublists. +static bool ends_with_blank_line(cmark_node *node) { + cmark_node *cur = node; + while (cur != NULL) { + if (S_last_line_blank(cur)) { + return true; + } + if (S_type(cur) == CMARK_NODE_LIST || S_type(cur) == CMARK_NODE_ITEM) { + cur = cur->last_child; + } else { + cur = NULL; + } + } + return false; +} + +static cmark_node *finalize(cmark_parser *parser, cmark_node *b) { + bufsize_t pos; + cmark_node *item; + cmark_node *subitem; + cmark_node *parent; + + parent = b->parent; + assert(b->flags & + CMARK_NODE__OPEN); // shouldn't call finalize on closed blocks + b->flags &= ~CMARK_NODE__OPEN; + + if (parser->curline.size == 0) { + // end of input - line number has not been incremented + b->end_line = parser->line_number; + b->end_column = parser->last_line_length; + } else if (S_type(b) == CMARK_NODE_DOCUMENT || + (S_type(b) == CMARK_NODE_CODE_BLOCK && b->as.code.fenced) || + (S_type(b) == CMARK_NODE_HEADING && b->as.heading.setext)) { + b->end_line = parser->line_number; + b->end_column = parser->curline.size; + if (b->end_column && parser->curline.ptr[b->end_column - 1] == '\n') + b->end_column -= 1; + if (b->end_column && parser->curline.ptr[b->end_column - 1] == '\r') + b->end_column -= 1; + } else { + b->end_line = parser->line_number - 1; + b->end_column = parser->last_line_length; + } + + cmark_strbuf *node_content = &b->content; + + switch (S_type(b)) { + case CMARK_NODE_PARAGRAPH: + { + cmark_chunk chunk = {node_content->ptr, node_content->size, 0}; + while (chunk.len && chunk.data[0] == '[' && + (pos = cmark_parse_reference_inline(parser->mem, &chunk, parser->refmap))) { + + chunk.data += pos; + chunk.len -= pos; + } + cmark_strbuf_drop(node_content, (node_content->size - chunk.len)); + if (is_blank(node_content, 0)) { + // remove blank node (former reference def) + cmark_node_free(b); + } + break; + } + + case CMARK_NODE_CODE_BLOCK: + if (!b->as.code.fenced) { // indented code + remove_trailing_blank_lines(node_content); + cmark_strbuf_putc(node_content, '\n'); + } else { + // first line of contents becomes info + for (pos = 0; pos < node_content->size; ++pos) { + if (S_is_line_end_char(node_content->ptr[pos])) + break; + } + assert(pos < node_content->size); + + cmark_strbuf tmp = CMARK_BUF_INIT(parser->mem); + houdini_unescape_html_f(&tmp, node_content->ptr, pos); + cmark_strbuf_trim(&tmp); + cmark_strbuf_unescape(&tmp); + b->as.code.info = cmark_chunk_buf_detach(&tmp); + + if (node_content->ptr[pos] == '\r') + pos += 1; + if (node_content->ptr[pos] == '\n') + pos += 1; + cmark_strbuf_drop(node_content, pos); + } + b->as.code.literal = cmark_chunk_buf_detach(node_content); + break; + + case CMARK_NODE_HTML_BLOCK: + b->as.literal = cmark_chunk_buf_detach(node_content); + break; + + case CMARK_NODE_LIST: // determine tight/loose status + b->as.list.tight = true; // tight by default + item = b->first_child; + + while (item) { + // check for non-final non-empty list item ending with blank line: + if (S_last_line_blank(item) && item->next) { + b->as.list.tight = false; + break; + } + // recurse into children of list item, to see if there are + // spaces between them: + subitem = item->first_child; + while (subitem) { + if (ends_with_blank_line(subitem) && (item->next || subitem->next)) { + b->as.list.tight = false; + break; + } + subitem = subitem->next; + } + if (!(b->as.list.tight)) { + break; + } + item = item->next; + } + + break; + + default: + break; + } + + return parent; +} + +// Add a node as child of another. Return pointer to child. +static cmark_node *add_child(cmark_parser *parser, cmark_node *parent, + cmark_node_type block_type, int start_column) { + assert(parent); + + // if 'parent' isn't the kind of node that can accept this child, + // then back up til we hit a node that can. + while (!cmark_node_can_contain_type(parent, block_type)) { + parent = finalize(parser, parent); + } + + cmark_node *child = + make_block(parser->mem, block_type, parser->line_number, start_column); + child->parent = parent; + + if (parent->last_child) { + parent->last_child->next = child; + child->prev = parent->last_child; + } else { + parent->first_child = child; + child->prev = NULL; + } + parent->last_child = child; + return child; +} + +void cmark_manage_extensions_special_characters(cmark_parser *parser, int add) { + cmark_llist *tmp_ext; + + for (tmp_ext = parser->inline_syntax_extensions; tmp_ext; tmp_ext=tmp_ext->next) { + cmark_syntax_extension *ext = (cmark_syntax_extension *) tmp_ext->data; + cmark_llist *tmp_char; + for (tmp_char = ext->special_inline_chars; tmp_char; tmp_char=tmp_char->next) { + unsigned char c = (unsigned char)(size_t)tmp_char->data; + if (add) + cmark_inlines_add_special_character(c, ext->emphasis); + else + cmark_inlines_remove_special_character(c, ext->emphasis); + } + } +} + +// Walk through node and all children, recursively, parsing +// string content into inline content where appropriate. +static void process_inlines(cmark_parser *parser, + cmark_map *refmap, int options) { + cmark_iter *iter = cmark_iter_new(parser->root); + cmark_node *cur; + cmark_event_type ev_type; + + cmark_manage_extensions_special_characters(parser, true); + + while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) { + cur = cmark_iter_get_node(iter); + if (ev_type == CMARK_EVENT_ENTER) { + if (contains_inlines(cur)) { + cmark_parse_inlines(parser, cur, refmap, options); + } + } + } + + cmark_manage_extensions_special_characters(parser, false); + + cmark_iter_free(iter); +} + +static int sort_footnote_by_ix(const void *_a, const void *_b) { + cmark_footnote *a = *(cmark_footnote **)_a; + cmark_footnote *b = *(cmark_footnote **)_b; + return (int)a->ix - (int)b->ix; +} + +static void process_footnotes(cmark_parser *parser) { + // * Collect definitions in a map. + // * Iterate the references in the document in order, assigning indices to + // definitions in the order they're seen. + // * Write out the footnotes at the bottom of the document in index order. + + cmark_map *map = cmark_footnote_map_new(parser->mem); + + cmark_iter *iter = cmark_iter_new(parser->root); + cmark_node *cur; + cmark_event_type ev_type; + + while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) { + cur = cmark_iter_get_node(iter); + if (ev_type == CMARK_EVENT_EXIT && cur->type == CMARK_NODE_FOOTNOTE_DEFINITION) { + cmark_node_unlink(cur); + cmark_footnote_create(map, cur); + } + } + + cmark_iter_free(iter); + iter = cmark_iter_new(parser->root); + unsigned int ix = 0; + + while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) { + cur = cmark_iter_get_node(iter); + if (ev_type == CMARK_EVENT_EXIT && cur->type == CMARK_NODE_FOOTNOTE_REFERENCE) { + cmark_footnote *footnote = (cmark_footnote *)cmark_map_lookup(map, &cur->as.literal); + if (footnote) { + if (!footnote->ix) + footnote->ix = ++ix; + + char n[32]; + snprintf(n, sizeof(n), "%d", footnote->ix); + cmark_chunk_free(parser->mem, &cur->as.literal); + cmark_strbuf buf = CMARK_BUF_INIT(parser->mem); + cmark_strbuf_puts(&buf, n); + + cur->as.literal = cmark_chunk_buf_detach(&buf); + } else { + cmark_node *text = (cmark_node *)parser->mem->calloc(1, sizeof(*text)); + cmark_strbuf_init(parser->mem, &text->content, 0); + text->type = (uint16_t) CMARK_NODE_TEXT; + + cmark_strbuf buf = CMARK_BUF_INIT(parser->mem); + cmark_strbuf_puts(&buf, "[^"); + cmark_strbuf_put(&buf, cur->as.literal.data, cur->as.literal.len); + cmark_strbuf_putc(&buf, ']'); + + text->as.literal = cmark_chunk_buf_detach(&buf); + cmark_node_insert_after(cur, text); + cmark_node_free(cur); + } + } + } + + cmark_iter_free(iter); + + if (map->sorted) { + qsort(map->sorted, map->size, sizeof(cmark_map_entry *), sort_footnote_by_ix); + for (unsigned int i = 0; i < map->size; ++i) { + cmark_footnote *footnote = (cmark_footnote *)map->sorted[i]; + if (!footnote->ix) + continue; + cmark_node_append_child(parser->root, footnote->node); + footnote->node = NULL; + } + } + + cmark_map_free(map); +} + +// Attempts to parse a list item marker (bullet or enumerated). +// On success, returns length of the marker, and populates +// data with the details. On failure, returns 0. +static bufsize_t parse_list_marker(cmark_mem *mem, cmark_chunk *input, + bufsize_t pos, bool interrupts_paragraph, + cmark_list **dataptr) { + unsigned char c; + bufsize_t startpos; + cmark_list *data; + bufsize_t i; + + startpos = pos; + c = peek_at(input, pos); + + if (c == '*' || c == '-' || c == '+') { + pos++; + if (!cmark_isspace(peek_at(input, pos))) { + return 0; + } + + if (interrupts_paragraph) { + i = pos; + // require non-blank content after list marker: + while (S_is_space_or_tab(peek_at(input, i))) { + i++; + } + if (peek_at(input, i) == '\n') { + return 0; + } + } + + data = (cmark_list *)mem->calloc(1, sizeof(*data)); + data->marker_offset = 0; // will be adjusted later + data->list_type = CMARK_BULLET_LIST; + data->bullet_char = c; + data->start = 0; + data->delimiter = CMARK_NO_DELIM; + data->tight = false; + } else if (cmark_isdigit(c)) { + int start = 0; + int digits = 0; + + do { + start = (10 * start) + (peek_at(input, pos) - '0'); + pos++; + digits++; + // We limit to 9 digits to avoid overflow, + // assuming max int is 2^31 - 1 + // This also seems to be the limit for 'start' in some browsers. + } while (digits < 9 && cmark_isdigit(peek_at(input, pos))); + + if (interrupts_paragraph && start != 1) { + return 0; + } + c = peek_at(input, pos); + if (c == '.' || c == ')') { + pos++; + if (!cmark_isspace(peek_at(input, pos))) { + return 0; + } + if (interrupts_paragraph) { + // require non-blank content after list marker: + i = pos; + while (S_is_space_or_tab(peek_at(input, i))) { + i++; + } + if (S_is_line_end_char(peek_at(input, i))) { + return 0; + } + } + + data = (cmark_list *)mem->calloc(1, sizeof(*data)); + data->marker_offset = 0; // will be adjusted later + data->list_type = CMARK_ORDERED_LIST; + data->bullet_char = 0; + data->start = start; + data->delimiter = (c == '.' ? CMARK_PERIOD_DELIM : CMARK_PAREN_DELIM); + data->tight = false; + } else { + return 0; + } + } else { + return 0; + } + + *dataptr = data; + return (pos - startpos); +} + +// Return 1 if list item belongs in list, else 0. +static int lists_match(cmark_list *list_data, cmark_list *item_data) { + return (list_data->list_type == item_data->list_type && + list_data->delimiter == item_data->delimiter && + // list_data->marker_offset == item_data.marker_offset && + list_data->bullet_char == item_data->bullet_char); +} + +static cmark_node *finalize_document(cmark_parser *parser) { + while (parser->current != parser->root) { + parser->current = finalize(parser, parser->current); + } + + finalize(parser, parser->root); + process_inlines(parser, parser->refmap, parser->options); + if (parser->options & CMARK_OPT_FOOTNOTES) + process_footnotes(parser); + + return parser->root; +} + +cmark_node *cmark_parse_file(FILE *f, int options) { + unsigned char buffer[4096]; + cmark_parser *parser = cmark_parser_new(options); + size_t bytes; + cmark_node *document; + + while ((bytes = fread(buffer, 1, sizeof(buffer), f)) > 0) { + bool eof = bytes < sizeof(buffer); + S_parser_feed(parser, buffer, bytes, eof); + if (eof) { + break; + } + } + + document = cmark_parser_finish(parser); + cmark_parser_free(parser); + return document; +} + +cmark_node *cmark_parse_document(const char *buffer, size_t len, int options) { + cmark_parser *parser = cmark_parser_new(options); + cmark_node *document; + + S_parser_feed(parser, (const unsigned char *)buffer, len, true); + + document = cmark_parser_finish(parser); + cmark_parser_free(parser); + return document; +} + +void cmark_parser_feed(cmark_parser *parser, const char *buffer, size_t len) { + S_parser_feed(parser, (const unsigned char *)buffer, len, false); +} + +void cmark_parser_feed_reentrant(cmark_parser *parser, const char *buffer, size_t len) { + cmark_strbuf saved_linebuf; + + cmark_strbuf_init(parser->mem, &saved_linebuf, 0); + cmark_strbuf_puts(&saved_linebuf, cmark_strbuf_cstr(&parser->linebuf)); + cmark_strbuf_clear(&parser->linebuf); + + S_parser_feed(parser, (const unsigned char *)buffer, len, true); + + cmark_strbuf_sets(&parser->linebuf, cmark_strbuf_cstr(&saved_linebuf)); + cmark_strbuf_free(&saved_linebuf); +} + +static void S_parser_feed(cmark_parser *parser, const unsigned char *buffer, + size_t len, bool eof) { + const unsigned char *end = buffer + len; + static const uint8_t repl[] = {239, 191, 189}; + + if (parser->last_buffer_ended_with_cr && *buffer == '\n') { + // skip NL if last buffer ended with CR ; see #117 + buffer++; + } + parser->last_buffer_ended_with_cr = false; + while (buffer < end) { + const unsigned char *eol; + bufsize_t chunk_len; + bool process = false; + for (eol = buffer; eol < end; ++eol) { + if (S_is_line_end_char(*eol)) { + process = true; + break; + } + if (*eol == '\0' && eol < end) { + break; + } + } + if (eol >= end && eof) { + process = true; + } + + chunk_len = (bufsize_t)(eol - buffer); + if (process) { + if (parser->linebuf.size > 0) { + cmark_strbuf_put(&parser->linebuf, buffer, chunk_len); + S_process_line(parser, parser->linebuf.ptr, parser->linebuf.size); + cmark_strbuf_clear(&parser->linebuf); + } else { + S_process_line(parser, buffer, chunk_len); + } + } else { + if (eol < end && *eol == '\0') { + // omit NULL byte + cmark_strbuf_put(&parser->linebuf, buffer, chunk_len); + // add replacement character + cmark_strbuf_put(&parser->linebuf, repl, 3); + } else { + cmark_strbuf_put(&parser->linebuf, buffer, chunk_len); + } + } + + buffer += chunk_len; + if (buffer < end) { + if (*buffer == '\0') { + // skip over NULL + buffer++; + } else { + // skip over line ending characters + if (*buffer == '\r') { + buffer++; + if (buffer == end) + parser->last_buffer_ended_with_cr = true; + } + if (buffer < end && *buffer == '\n') + buffer++; + } + } + } +} + +static void chop_trailing_hashtags(cmark_chunk *ch) { + bufsize_t n, orig_n; + + cmark_chunk_rtrim(ch); + orig_n = n = ch->len - 1; + + // if string ends in space followed by #s, remove these: + while (n >= 0 && peek_at(ch, n) == '#') + n--; + + // Check for a space before the final #s: + if (n != orig_n && n >= 0 && S_is_space_or_tab(peek_at(ch, n))) { + ch->len = n; + cmark_chunk_rtrim(ch); + } +} + +// Find first nonspace character from current offset, setting +// parser->first_nonspace, parser->first_nonspace_column, +// parser->indent, and parser->blank. Does not advance parser->offset. +static void S_find_first_nonspace(cmark_parser *parser, cmark_chunk *input) { + char c; + int chars_to_tab = TAB_STOP - (parser->column % TAB_STOP); + + parser->first_nonspace = parser->offset; + parser->first_nonspace_column = parser->column; + while ((c = peek_at(input, parser->first_nonspace))) { + if (c == ' ') { + parser->first_nonspace += 1; + parser->first_nonspace_column += 1; + chars_to_tab = chars_to_tab - 1; + if (chars_to_tab == 0) { + chars_to_tab = TAB_STOP; + } + } else if (c == '\t') { + parser->first_nonspace += 1; + parser->first_nonspace_column += chars_to_tab; + chars_to_tab = TAB_STOP; + } else { + break; + } + } + + parser->indent = parser->first_nonspace_column - parser->column; + parser->blank = S_is_line_end_char(peek_at(input, parser->first_nonspace)); +} + +// Advance parser->offset and parser->column. parser->offset is the +// byte position in input; parser->column is a virtual column number +// that takes into account tabs. (Multibyte characters are not taken +// into account, because the Markdown line prefixes we are interested in +// analyzing are entirely ASCII.) The count parameter indicates +// how far to advance the offset. If columns is true, then count +// indicates a number of columns; otherwise, a number of bytes. +// If advancing a certain number of columns partially consumes +// a tab character, parser->partially_consumed_tab is set to true. +static void S_advance_offset(cmark_parser *parser, cmark_chunk *input, + bufsize_t count, bool columns) { + char c; + int chars_to_tab; + int chars_to_advance; + while (count > 0 && (c = peek_at(input, parser->offset))) { + if (c == '\t') { + chars_to_tab = TAB_STOP - (parser->column % TAB_STOP); + if (columns) { + parser->partially_consumed_tab = chars_to_tab > count; + chars_to_advance = MIN(count, chars_to_tab); + parser->column += chars_to_advance; + parser->offset += (parser->partially_consumed_tab ? 0 : 1); + count -= chars_to_advance; + } else { + parser->partially_consumed_tab = false; + parser->column += chars_to_tab; + parser->offset += 1; + count -= 1; + } + } else { + parser->partially_consumed_tab = false; + parser->offset += 1; + parser->column += 1; // assume ascii; block starts are ascii + count -= 1; + } + } +} + +static bool S_last_child_is_open(cmark_node *container) { + return container->last_child && + (container->last_child->flags & CMARK_NODE__OPEN); +} + +static bool parse_block_quote_prefix(cmark_parser *parser, cmark_chunk *input) { + bool res = false; + bufsize_t matched = 0; + + matched = + parser->indent <= 3 && peek_at(input, parser->first_nonspace) == '>'; + if (matched) { + + S_advance_offset(parser, input, parser->indent + 1, true); + + if (S_is_space_or_tab(peek_at(input, parser->offset))) { + S_advance_offset(parser, input, 1, true); + } + + res = true; + } + return res; +} + +static bool parse_footnote_definition_block_prefix(cmark_parser *parser, cmark_chunk *input, + cmark_node *container) { + if (parser->indent >= 4) { + S_advance_offset(parser, input, 4, true); + return true; + } else if (input->len > 0 && (input->data[0] == '\n' || (input->data[0] == '\r' && input->data[1] == '\n'))) { + return true; + } + + return false; +} + +static bool parse_node_item_prefix(cmark_parser *parser, cmark_chunk *input, + cmark_node *container) { + bool res = false; + + if (parser->indent >= + container->as.list.marker_offset + container->as.list.padding) { + S_advance_offset(parser, input, container->as.list.marker_offset + + container->as.list.padding, + true); + res = true; + } else if (parser->blank && container->first_child != NULL) { + // if container->first_child is NULL, then the opening line + // of the list item was blank after the list marker; in this + // case, we are done with the list item. + S_advance_offset(parser, input, parser->first_nonspace - parser->offset, + false); + res = true; + } + return res; +} + +static bool parse_code_block_prefix(cmark_parser *parser, cmark_chunk *input, + cmark_node *container, + bool *should_continue) { + bool res = false; + + if (!container->as.code.fenced) { // indented + if (parser->indent >= CODE_INDENT) { + S_advance_offset(parser, input, CODE_INDENT, true); + res = true; + } else if (parser->blank) { + S_advance_offset(parser, input, parser->first_nonspace - parser->offset, + false); + res = true; + } + } else { // fenced + bufsize_t matched = 0; + + if (parser->indent <= 3 && (peek_at(input, parser->first_nonspace) == + container->as.code.fence_char)) { + matched = scan_close_code_fence(input, parser->first_nonspace); + } + + if (matched >= container->as.code.fence_length) { + // closing fence - and since we're at + // the end of a line, we can stop processing it: + *should_continue = false; + S_advance_offset(parser, input, matched, false); + parser->current = finalize(parser, container); + } else { + // skip opt. spaces of fence parser->offset + int i = container->as.code.fence_offset; + + while (i > 0 && S_is_space_or_tab(peek_at(input, parser->offset))) { + S_advance_offset(parser, input, 1, true); + i--; + } + res = true; + } + } + + return res; +} + +static bool parse_html_block_prefix(cmark_parser *parser, + cmark_node *container) { + bool res = false; + int html_block_type = container->as.html_block_type; + + assert(html_block_type >= 1 && html_block_type <= 7); + switch (html_block_type) { + case 1: + case 2: + case 3: + case 4: + case 5: + // these types of blocks can accept blanks + res = true; + break; + case 6: + case 7: + res = !parser->blank; + break; + } + + return res; +} + +static bool parse_extension_block(cmark_parser *parser, + cmark_node *container, + cmark_chunk *input) +{ + bool res = false; + + if (container->extension->last_block_matches) { + if (container->extension->last_block_matches( + container->extension, parser, input->data, input->len, container)) + res = true; + } + + return res; +} + +/** + * For each containing node, try to parse the associated line start. + * + * Will not close unmatched blocks, as we may have a lazy continuation + * line -> http://spec.commonmark.org/0.24/#lazy-continuation-line + * + * Returns: The last matching node, or NULL + */ +static cmark_node *check_open_blocks(cmark_parser *parser, cmark_chunk *input, + bool *all_matched) { + bool should_continue = true; + *all_matched = false; + cmark_node *container = parser->root; + cmark_node_type cont_type; + + while (S_last_child_is_open(container)) { + container = container->last_child; + cont_type = S_type(container); + + S_find_first_nonspace(parser, input); + + if (container->extension) { + if (!parse_extension_block(parser, container, input)) + goto done; + continue; + } + + switch (cont_type) { + case CMARK_NODE_BLOCK_QUOTE: + if (!parse_block_quote_prefix(parser, input)) + goto done; + break; + case CMARK_NODE_ITEM: + if (!parse_node_item_prefix(parser, input, container)) + goto done; + break; + case CMARK_NODE_CODE_BLOCK: + if (!parse_code_block_prefix(parser, input, container, &should_continue)) + goto done; + break; + case CMARK_NODE_HEADING: + // a heading can never contain more than one line + goto done; + case CMARK_NODE_HTML_BLOCK: + if (!parse_html_block_prefix(parser, container)) + goto done; + break; + case CMARK_NODE_PARAGRAPH: + if (parser->blank) + goto done; + break; + case CMARK_NODE_FOOTNOTE_DEFINITION: + if (!parse_footnote_definition_block_prefix(parser, input, container)) + goto done; + break; + default: + break; + } + } + + *all_matched = true; + +done: + if (!*all_matched) { + container = container->parent; // back up to last matching node + } + + if (!should_continue) { + container = NULL; + } + + return container; +} + +static void open_new_blocks(cmark_parser *parser, cmark_node **container, + cmark_chunk *input, bool all_matched) { + bool indented; + cmark_list *data = NULL; + bool maybe_lazy = S_type(parser->current) == CMARK_NODE_PARAGRAPH; + cmark_node_type cont_type = S_type(*container); + bufsize_t matched = 0; + int lev = 0; + bool save_partially_consumed_tab; + int save_offset; + int save_column; + + while (cont_type != CMARK_NODE_CODE_BLOCK && + cont_type != CMARK_NODE_HTML_BLOCK) { + + S_find_first_nonspace(parser, input); + indented = parser->indent >= CODE_INDENT; + + if (!indented && peek_at(input, parser->first_nonspace) == '>') { + + bufsize_t blockquote_startpos = parser->first_nonspace; + + S_advance_offset(parser, input, + parser->first_nonspace + 1 - parser->offset, false); + // optional following character + if (S_is_space_or_tab(peek_at(input, parser->offset))) { + S_advance_offset(parser, input, 1, true); + } + *container = add_child(parser, *container, CMARK_NODE_BLOCK_QUOTE, + blockquote_startpos + 1); + + } else if (!indented && (matched = scan_atx_heading_start( + input, parser->first_nonspace))) { + bufsize_t hashpos; + int level = 0; + bufsize_t heading_startpos = parser->first_nonspace; + + S_advance_offset(parser, input, + parser->first_nonspace + matched - parser->offset, + false); + *container = add_child(parser, *container, CMARK_NODE_HEADING, + heading_startpos + 1); + + hashpos = cmark_chunk_strchr(input, '#', parser->first_nonspace); + + while (peek_at(input, hashpos) == '#') { + level++; + hashpos++; + } + + (*container)->as.heading.level = level; + (*container)->as.heading.setext = false; + (*container)->internal_offset = matched; + + } else if (!indented && (matched = scan_open_code_fence( + input, parser->first_nonspace))) { + *container = add_child(parser, *container, CMARK_NODE_CODE_BLOCK, + parser->first_nonspace + 1); + (*container)->as.code.fenced = true; + (*container)->as.code.fence_char = peek_at(input, parser->first_nonspace); + (*container)->as.code.fence_length = (matched > 255) ? 255 : (uint8_t)matched; + (*container)->as.code.fence_offset = + (int8_t)(parser->first_nonspace - parser->offset); + (*container)->as.code.info = cmark_chunk_literal(""); + S_advance_offset(parser, input, + parser->first_nonspace + matched - parser->offset, + false); + + } else if (!indented && ((matched = scan_html_block_start( + input, parser->first_nonspace)) || + (cont_type != CMARK_NODE_PARAGRAPH && + (matched = scan_html_block_start_7( + input, parser->first_nonspace))))) { + *container = add_child(parser, *container, CMARK_NODE_HTML_BLOCK, + parser->first_nonspace + 1); + (*container)->as.html_block_type = matched; + // note, we don't adjust parser->offset because the tag is part of the + // text + } else if (!indented && cont_type == CMARK_NODE_PARAGRAPH && + (lev = + scan_setext_heading_line(input, parser->first_nonspace))) { + (*container)->type = (uint16_t)CMARK_NODE_HEADING; + (*container)->as.heading.level = lev; + (*container)->as.heading.setext = true; + S_advance_offset(parser, input, input->len - 1 - parser->offset, false); + } else if (!indented && + !(cont_type == CMARK_NODE_PARAGRAPH && !all_matched) && + (matched = scan_thematic_break(input, parser->first_nonspace))) { + // it's only now that we know the line is not part of a setext heading: + *container = add_child(parser, *container, CMARK_NODE_THEMATIC_BREAK, + parser->first_nonspace + 1); + S_advance_offset(parser, input, input->len - 1 - parser->offset, false); + } else if (!indented && + parser->options & CMARK_OPT_FOOTNOTES && + (matched = scan_footnote_definition(input, parser->first_nonspace))) { + cmark_chunk c = cmark_chunk_dup(input, parser->first_nonspace + 2, matched - 2); + cmark_chunk_to_cstr(parser->mem, &c); + + while (c.data[c.len - 1] != ']') + --c.len; + --c.len; + + S_advance_offset(parser, input, parser->first_nonspace + matched - parser->offset, false); + *container = add_child(parser, *container, CMARK_NODE_FOOTNOTE_DEFINITION, parser->first_nonspace + matched + 1); + (*container)->as.literal = c; + + (*container)->internal_offset = matched; + } else if ((!indented || cont_type == CMARK_NODE_LIST) && + (matched = parse_list_marker( + parser->mem, input, parser->first_nonspace, + (*container)->type == CMARK_NODE_PARAGRAPH, &data))) { + + // Note that we can have new list items starting with >= 4 + // spaces indent, as long as the list container is still open. + int i = 0; + + // compute padding: + S_advance_offset(parser, input, + parser->first_nonspace + matched - parser->offset, + false); + + save_partially_consumed_tab = parser->partially_consumed_tab; + save_offset = parser->offset; + save_column = parser->column; + + while (parser->column - save_column <= 5 && + S_is_space_or_tab(peek_at(input, parser->offset))) { + S_advance_offset(parser, input, 1, true); + } + + i = parser->column - save_column; + if (i >= 5 || i < 1 || + // only spaces after list marker: + S_is_line_end_char(peek_at(input, parser->offset))) { + data->padding = matched + 1; + parser->offset = save_offset; + parser->column = save_column; + parser->partially_consumed_tab = save_partially_consumed_tab; + if (i > 0) { + S_advance_offset(parser, input, 1, true); + } + } else { + data->padding = matched + i; + } + + // check container; if it's a list, see if this list item + // can continue the list; otherwise, create a list container. + + data->marker_offset = parser->indent; + + if (cont_type != CMARK_NODE_LIST || + !lists_match(&((*container)->as.list), data)) { + *container = add_child(parser, *container, CMARK_NODE_LIST, + parser->first_nonspace + 1); + + memcpy(&((*container)->as.list), data, sizeof(*data)); + } + + // add the list item + *container = add_child(parser, *container, CMARK_NODE_ITEM, + parser->first_nonspace + 1); + /* TODO: static */ + memcpy(&((*container)->as.list), data, sizeof(*data)); + parser->mem->free(data); + } else if (indented && !maybe_lazy && !parser->blank) { + S_advance_offset(parser, input, CODE_INDENT, true); + *container = add_child(parser, *container, CMARK_NODE_CODE_BLOCK, + parser->offset + 1); + (*container)->as.code.fenced = false; + (*container)->as.code.fence_char = 0; + (*container)->as.code.fence_length = 0; + (*container)->as.code.fence_offset = 0; + (*container)->as.code.info = cmark_chunk_literal(""); + } else { + cmark_llist *tmp; + cmark_node *new_container = NULL; + + for (tmp = parser->syntax_extensions; tmp; tmp=tmp->next) { + cmark_syntax_extension *ext = (cmark_syntax_extension *) tmp->data; + + if (ext->try_opening_block) { + new_container = ext->try_opening_block( + ext, indented, parser, *container, input->data, input->len); + + if (new_container) { + *container = new_container; + break; + } + } + } + + if (!new_container) { + break; + } + } + + if (accepts_lines(S_type(*container))) { + // if it's a line container, it can't contain other containers + break; + } + + cont_type = S_type(*container); + maybe_lazy = false; + } +} + +static void add_text_to_container(cmark_parser *parser, cmark_node *container, + cmark_node *last_matched_container, + cmark_chunk *input) { + cmark_node *tmp; + // what remains at parser->offset is a text line. add the text to the + // appropriate container. + + S_find_first_nonspace(parser, input); + + if (parser->blank && container->last_child) + S_set_last_line_blank(container->last_child, true); + + // block quote lines are never blank as they start with > + // and we don't count blanks in fenced code for purposes of tight/loose + // lists or breaking out of lists. we also don't set last_line_blank + // on an empty list item. + const cmark_node_type ctype = S_type(container); + const bool last_line_blank = + (parser->blank && ctype != CMARK_NODE_BLOCK_QUOTE && + ctype != CMARK_NODE_HEADING && ctype != CMARK_NODE_THEMATIC_BREAK && + !(ctype == CMARK_NODE_CODE_BLOCK && container->as.code.fenced) && + !(ctype == CMARK_NODE_ITEM && container->first_child == NULL && + container->start_line == parser->line_number)); + + S_set_last_line_blank(container, last_line_blank); + + tmp = container; + while (tmp->parent) { + S_set_last_line_blank(tmp->parent, false); + tmp = tmp->parent; + } + + // If the last line processed belonged to a paragraph node, + // and we didn't match all of the line prefixes for the open containers, + // and we didn't start any new containers, + // and the line isn't blank, + // then treat this as a "lazy continuation line" and add it to + // the open paragraph. + if (parser->current != last_matched_container && + container == last_matched_container && !parser->blank && + S_type(parser->current) == CMARK_NODE_PARAGRAPH) { + add_line(parser->current, input, parser); + } else { // not a lazy continuation + // Finalize any blocks that were not matched and set cur to container: + while (parser->current != last_matched_container) { + parser->current = finalize(parser, parser->current); + assert(parser->current != NULL); + } + + if (S_type(container) == CMARK_NODE_CODE_BLOCK) { + add_line(container, input, parser); + } else if (S_type(container) == CMARK_NODE_HTML_BLOCK) { + add_line(container, input, parser); + + int matches_end_condition; + switch (container->as.html_block_type) { + case 1: + // , , + matches_end_condition = + scan_html_block_end_1(input, parser->first_nonspace); + break; + case 2: + // --> + matches_end_condition = + scan_html_block_end_2(input, parser->first_nonspace); + break; + case 3: + // ?> + matches_end_condition = + scan_html_block_end_3(input, parser->first_nonspace); + break; + case 4: + // > + matches_end_condition = + scan_html_block_end_4(input, parser->first_nonspace); + break; + case 5: + // ]]> + matches_end_condition = + scan_html_block_end_5(input, parser->first_nonspace); + break; + default: + matches_end_condition = 0; + break; + } + + if (matches_end_condition) { + container = finalize(parser, container); + assert(parser->current != NULL); + } + } else if (parser->blank) { + // ??? do nothing + } else if (accepts_lines(S_type(container))) { + if (S_type(container) == CMARK_NODE_HEADING && + container->as.heading.setext == false) { + chop_trailing_hashtags(input); + } + S_advance_offset(parser, input, parser->first_nonspace - parser->offset, + false); + add_line(container, input, parser); + } else { + // create paragraph container for line + container = add_child(parser, container, CMARK_NODE_PARAGRAPH, + parser->first_nonspace + 1); + S_advance_offset(parser, input, parser->first_nonspace - parser->offset, + false); + add_line(container, input, parser); + } + + parser->current = container; + } +} + +/* See http://spec.commonmark.org/0.24/#phase-1-block-structure */ +static void S_process_line(cmark_parser *parser, const unsigned char *buffer, + bufsize_t bytes) { + cmark_node *last_matched_container; + bool all_matched = true; + cmark_node *container; + cmark_chunk input; + cmark_node *current; + + cmark_strbuf_clear(&parser->curline); + + if (parser->options & CMARK_OPT_VALIDATE_UTF8) + cmark_utf8proc_check(&parser->curline, buffer, bytes); + else + cmark_strbuf_put(&parser->curline, buffer, bytes); + + bytes = parser->curline.size; + + // ensure line ends with a newline: + if (bytes == 0 || !S_is_line_end_char(parser->curline.ptr[bytes - 1])) + cmark_strbuf_putc(&parser->curline, '\n'); + + parser->offset = 0; + parser->column = 0; + parser->blank = false; + parser->partially_consumed_tab = false; + + input.data = parser->curline.ptr; + input.len = parser->curline.size; + input.alloc = 0; + + // Skip UTF-8 BOM. + if (parser->line_number == 0 && + input.len >= 3 && + memcmp(input.data, "\xef\xbb\xbf", 3) == 0) + parser->offset += 3; + + parser->line_number++; + + last_matched_container = check_open_blocks(parser, &input, &all_matched); + + if (!last_matched_container) + goto finished; + + container = last_matched_container; + + current = parser->current; + + open_new_blocks(parser, &container, &input, all_matched); + + /* parser->current might have changed if feed_reentrant was called */ + if (current == parser->current) + add_text_to_container(parser, container, last_matched_container, &input); + +finished: + parser->last_line_length = input.len; + if (parser->last_line_length && + input.data[parser->last_line_length - 1] == '\n') + parser->last_line_length -= 1; + if (parser->last_line_length && + input.data[parser->last_line_length - 1] == '\r') + parser->last_line_length -= 1; + + cmark_strbuf_clear(&parser->curline); +} + +cmark_node *cmark_parser_finish(cmark_parser *parser) { + cmark_node *res; + cmark_llist *extensions; + + /* Parser was already finished once */ + if (parser->root == NULL) + return NULL; + + if (parser->linebuf.size) { + S_process_line(parser, parser->linebuf.ptr, parser->linebuf.size); + cmark_strbuf_clear(&parser->linebuf); + } + + finalize_document(parser); + + cmark_consolidate_text_nodes(parser->root); + + cmark_strbuf_free(&parser->curline); + cmark_strbuf_free(&parser->linebuf); + +#if CMARK_DEBUG_NODES + if (cmark_node_check(parser->root, stderr)) { + abort(); + } +#endif + + for (extensions = parser->syntax_extensions; extensions; extensions = extensions->next) { + cmark_syntax_extension *ext = (cmark_syntax_extension *) extensions->data; + if (ext->postprocess_func) { + cmark_node *processed = ext->postprocess_func(ext, parser, parser->root); + if (processed) + parser->root = processed; + } + } + + res = parser->root; + parser->root = NULL; + + cmark_parser_reset(parser); + + return res; +} + +int cmark_parser_get_line_number(cmark_parser *parser) { + return parser->line_number; +} + +bufsize_t cmark_parser_get_offset(cmark_parser *parser) { + return parser->offset; +} + +bufsize_t cmark_parser_get_column(cmark_parser *parser) { + return parser->column; +} + +int cmark_parser_get_first_nonspace(cmark_parser *parser) { + return parser->first_nonspace; +} + +int cmark_parser_get_first_nonspace_column(cmark_parser *parser) { + return parser->first_nonspace_column; +} + +int cmark_parser_get_indent(cmark_parser *parser) { + return parser->indent; +} + +int cmark_parser_is_blank(cmark_parser *parser) { + return parser->blank; +} + +int cmark_parser_has_partially_consumed_tab(cmark_parser *parser) { + return parser->partially_consumed_tab; +} + +int cmark_parser_get_last_line_length(cmark_parser *parser) { + return parser->last_line_length; +} + +cmark_node *cmark_parser_add_child(cmark_parser *parser, + cmark_node *parent, + cmark_node_type block_type, + int start_column) { + return add_child(parser, parent, block_type, start_column); +} + +void cmark_parser_advance_offset(cmark_parser *parser, + const char *input, + int count, + int columns) { + cmark_chunk input_chunk = cmark_chunk_literal(input); + + S_advance_offset(parser, &input_chunk, count, columns != 0); +} + +void cmark_parser_set_backslash_ispunct_func(cmark_parser *parser, + cmark_ispunct_func func) { + parser->backslash_ispunct = func; +} + +cmark_llist *cmark_parser_get_syntax_extensions(cmark_parser *parser) { + return parser->syntax_extensions; +} diff --git a/Sources/libcmark_gfm/buffer.c b/Sources/libcmark_gfm/buffer.c new file mode 100644 index 0000000..c7934e5 --- /dev/null +++ b/Sources/libcmark_gfm/buffer.c @@ -0,0 +1,278 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "config.h" +#include "cmark_ctype.h" +#include "buffer.h" + +/* Used as default value for cmark_strbuf->ptr so that people can always + * assume ptr is non-NULL and zero terminated even for new cmark_strbufs. + */ +unsigned char cmark_strbuf__initbuf[1]; + +#ifndef MIN +#define MIN(x, y) ((x < y) ? x : y) +#endif + +void cmark_strbuf_init(cmark_mem *mem, cmark_strbuf *buf, + bufsize_t initial_size) { + buf->mem = mem; + buf->asize = 0; + buf->size = 0; + buf->ptr = cmark_strbuf__initbuf; + + if (initial_size > 0) + cmark_strbuf_grow(buf, initial_size); +} + +static CMARK_INLINE void S_strbuf_grow_by(cmark_strbuf *buf, bufsize_t add) { + cmark_strbuf_grow(buf, buf->size + add); +} + +void cmark_strbuf_grow(cmark_strbuf *buf, bufsize_t target_size) { + assert(target_size > 0); + + if (target_size < buf->asize) + return; + + if (target_size > (bufsize_t)(INT32_MAX / 2)) { + fprintf(stderr, + "[cmark] cmark_strbuf_grow requests buffer with size > %d, aborting\n", + (INT32_MAX / 2)); + abort(); + } + + /* Oversize the buffer by 50% to guarantee amortized linear time + * complexity on append operations. */ + bufsize_t new_size = target_size + target_size / 2; + new_size += 1; + new_size = (new_size + 7) & ~7; + + buf->ptr = (unsigned char *)buf->mem->realloc(buf->asize ? buf->ptr : NULL, + new_size); + buf->asize = new_size; +} + +bufsize_t cmark_strbuf_len(const cmark_strbuf *buf) { return buf->size; } + +void cmark_strbuf_free(cmark_strbuf *buf) { + if (!buf) + return; + + if (buf->ptr != cmark_strbuf__initbuf) + buf->mem->free(buf->ptr); + + cmark_strbuf_init(buf->mem, buf, 0); +} + +void cmark_strbuf_clear(cmark_strbuf *buf) { + buf->size = 0; + + if (buf->asize > 0) + buf->ptr[0] = '\0'; +} + +void cmark_strbuf_set(cmark_strbuf *buf, const unsigned char *data, + bufsize_t len) { + if (len <= 0 || data == NULL) { + cmark_strbuf_clear(buf); + } else { + if (data != buf->ptr) { + if (len >= buf->asize) + cmark_strbuf_grow(buf, len); + memmove(buf->ptr, data, len); + } + buf->size = len; + buf->ptr[buf->size] = '\0'; + } +} + +void cmark_strbuf_sets(cmark_strbuf *buf, const char *string) { + cmark_strbuf_set(buf, (const unsigned char *)string, + string ? (bufsize_t)strlen(string) : 0); +} + +void cmark_strbuf_putc(cmark_strbuf *buf, int c) { + S_strbuf_grow_by(buf, 1); + buf->ptr[buf->size++] = (unsigned char)(c & 0xFF); + buf->ptr[buf->size] = '\0'; +} + +void cmark_strbuf_put(cmark_strbuf *buf, const unsigned char *data, + bufsize_t len) { + if (len <= 0) + return; + + S_strbuf_grow_by(buf, len); + memmove(buf->ptr + buf->size, data, len); + buf->size += len; + buf->ptr[buf->size] = '\0'; +} + +void cmark_strbuf_puts(cmark_strbuf *buf, const char *string) { + cmark_strbuf_put(buf, (const unsigned char *)string, (bufsize_t)strlen(string)); +} + +void cmark_strbuf_copy_cstr(char *data, bufsize_t datasize, + const cmark_strbuf *buf) { + bufsize_t copylen; + + assert(buf); + if (!data || datasize <= 0) + return; + + data[0] = '\0'; + + if (buf->size == 0 || buf->asize <= 0) + return; + + copylen = buf->size; + if (copylen > datasize - 1) + copylen = datasize - 1; + memmove(data, buf->ptr, copylen); + data[copylen] = '\0'; +} + +void cmark_strbuf_swap(cmark_strbuf *buf_a, cmark_strbuf *buf_b) { + cmark_strbuf t = *buf_a; + *buf_a = *buf_b; + *buf_b = t; +} + +unsigned char *cmark_strbuf_detach(cmark_strbuf *buf) { + unsigned char *data = buf->ptr; + + if (buf->asize == 0) { + /* return an empty string */ + return (unsigned char *)buf->mem->calloc(1, 1); + } + + cmark_strbuf_init(buf->mem, buf, 0); + return data; +} + +int cmark_strbuf_cmp(const cmark_strbuf *a, const cmark_strbuf *b) { + int result = memcmp(a->ptr, b->ptr, MIN(a->size, b->size)); + return (result != 0) ? result + : (a->size < b->size) ? -1 : (a->size > b->size) ? 1 : 0; +} + +bufsize_t cmark_strbuf_strchr(const cmark_strbuf *buf, int c, bufsize_t pos) { + if (pos >= buf->size) + return -1; + if (pos < 0) + pos = 0; + + const unsigned char *p = + (unsigned char *)memchr(buf->ptr + pos, c, buf->size - pos); + if (!p) + return -1; + + return (bufsize_t)(p - (const unsigned char *)buf->ptr); +} + +bufsize_t cmark_strbuf_strrchr(const cmark_strbuf *buf, int c, bufsize_t pos) { + if (pos < 0 || buf->size == 0) + return -1; + if (pos >= buf->size) + pos = buf->size - 1; + + bufsize_t i; + for (i = pos; i >= 0; i--) { + if (buf->ptr[i] == (unsigned char)c) + return i; + } + + return -1; +} + +void cmark_strbuf_truncate(cmark_strbuf *buf, bufsize_t len) { + if (len < 0) + len = 0; + + if (len < buf->size) { + buf->size = len; + buf->ptr[buf->size] = '\0'; + } +} + +void cmark_strbuf_drop(cmark_strbuf *buf, bufsize_t n) { + if (n > 0) { + if (n > buf->size) + n = buf->size; + buf->size = buf->size - n; + if (buf->size) + memmove(buf->ptr, buf->ptr + n, buf->size); + + buf->ptr[buf->size] = '\0'; + } +} + +void cmark_strbuf_rtrim(cmark_strbuf *buf) { + if (!buf->size) + return; + + while (buf->size > 0) { + if (!cmark_isspace(buf->ptr[buf->size - 1])) + break; + + buf->size--; + } + + buf->ptr[buf->size] = '\0'; +} + +void cmark_strbuf_trim(cmark_strbuf *buf) { + bufsize_t i = 0; + + if (!buf->size) + return; + + while (i < buf->size && cmark_isspace(buf->ptr[i])) + i++; + + cmark_strbuf_drop(buf, i); + + cmark_strbuf_rtrim(buf); +} + +// Destructively modify string, collapsing consecutive +// space and newline characters into a single space. +void cmark_strbuf_normalize_whitespace(cmark_strbuf *s) { + bool last_char_was_space = false; + bufsize_t r, w; + + for (r = 0, w = 0; r < s->size; ++r) { + if (cmark_isspace(s->ptr[r])) { + if (!last_char_was_space) { + s->ptr[w++] = ' '; + last_char_was_space = true; + } + } else { + s->ptr[w++] = s->ptr[r]; + last_char_was_space = false; + } + } + + cmark_strbuf_truncate(s, w); +} + +// Destructively unescape a string: remove backslashes before punctuation chars. +extern void cmark_strbuf_unescape(cmark_strbuf *buf) { + bufsize_t r, w; + + for (r = 0, w = 0; r < buf->size; ++r) { + if (buf->ptr[r] == '\\' && cmark_ispunct(buf->ptr[r + 1])) + r++; + + buf->ptr[w++] = buf->ptr[r]; + } + + cmark_strbuf_truncate(buf, w); +} diff --git a/Sources/libcmark_gfm/case_fold_switch.inc b/Sources/libcmark_gfm/case_fold_switch.inc new file mode 100644 index 0000000..28e223e --- /dev/null +++ b/Sources/libcmark_gfm/case_fold_switch.inc @@ -0,0 +1,4327 @@ + switch (c) { + case 0x0041: + bufpush(0x0061); + break; + case 0x0042: + bufpush(0x0062); + break; + case 0x0043: + bufpush(0x0063); + break; + case 0x0044: + bufpush(0x0064); + break; + case 0x0045: + bufpush(0x0065); + break; + case 0x0046: + bufpush(0x0066); + break; + case 0x0047: + bufpush(0x0067); + break; + case 0x0048: + bufpush(0x0068); + break; + case 0x0049: + bufpush(0x0069); + break; + case 0x004A: + bufpush(0x006A); + break; + case 0x004B: + bufpush(0x006B); + break; + case 0x004C: + bufpush(0x006C); + break; + case 0x004D: + bufpush(0x006D); + break; + case 0x004E: + bufpush(0x006E); + break; + case 0x004F: + bufpush(0x006F); + break; + case 0x0050: + bufpush(0x0070); + break; + case 0x0051: + bufpush(0x0071); + break; + case 0x0052: + bufpush(0x0072); + break; + case 0x0053: + bufpush(0x0073); + break; + case 0x0054: + bufpush(0x0074); + break; + case 0x0055: + bufpush(0x0075); + break; + case 0x0056: + bufpush(0x0076); + break; + case 0x0057: + bufpush(0x0077); + break; + case 0x0058: + bufpush(0x0078); + break; + case 0x0059: + bufpush(0x0079); + break; + case 0x005A: + bufpush(0x007A); + break; + case 0x00B5: + bufpush(0x03BC); + break; + case 0x00C0: + bufpush(0x00E0); + break; + case 0x00C1: + bufpush(0x00E1); + break; + case 0x00C2: + bufpush(0x00E2); + break; + case 0x00C3: + bufpush(0x00E3); + break; + case 0x00C4: + bufpush(0x00E4); + break; + case 0x00C5: + bufpush(0x00E5); + break; + case 0x00C6: + bufpush(0x00E6); + break; + case 0x00C7: + bufpush(0x00E7); + break; + case 0x00C8: + bufpush(0x00E8); + break; + case 0x00C9: + bufpush(0x00E9); + break; + case 0x00CA: + bufpush(0x00EA); + break; + case 0x00CB: + bufpush(0x00EB); + break; + case 0x00CC: + bufpush(0x00EC); + break; + case 0x00CD: + bufpush(0x00ED); + break; + case 0x00CE: + bufpush(0x00EE); + break; + case 0x00CF: + bufpush(0x00EF); + break; + case 0x00D0: + bufpush(0x00F0); + break; + case 0x00D1: + bufpush(0x00F1); + break; + case 0x00D2: + bufpush(0x00F2); + break; + case 0x00D3: + bufpush(0x00F3); + break; + case 0x00D4: + bufpush(0x00F4); + break; + case 0x00D5: + bufpush(0x00F5); + break; + case 0x00D6: + bufpush(0x00F6); + break; + case 0x00D8: + bufpush(0x00F8); + break; + case 0x00D9: + bufpush(0x00F9); + break; + case 0x00DA: + bufpush(0x00FA); + break; + case 0x00DB: + bufpush(0x00FB); + break; + case 0x00DC: + bufpush(0x00FC); + break; + case 0x00DD: + bufpush(0x00FD); + break; + case 0x00DE: + bufpush(0x00FE); + break; + case 0x00DF: + bufpush(0x0073); + bufpush(0x0073); + break; + case 0x0100: + bufpush(0x0101); + break; + case 0x0102: + bufpush(0x0103); + break; + case 0x0104: + bufpush(0x0105); + break; + case 0x0106: + bufpush(0x0107); + break; + case 0x0108: + bufpush(0x0109); + break; + case 0x010A: + bufpush(0x010B); + break; + case 0x010C: + bufpush(0x010D); + break; + case 0x010E: + bufpush(0x010F); + break; + case 0x0110: + bufpush(0x0111); + break; + case 0x0112: + bufpush(0x0113); + break; + case 0x0114: + bufpush(0x0115); + break; + case 0x0116: + bufpush(0x0117); + break; + case 0x0118: + bufpush(0x0119); + break; + case 0x011A: + bufpush(0x011B); + break; + case 0x011C: + bufpush(0x011D); + break; + case 0x011E: + bufpush(0x011F); + break; + case 0x0120: + bufpush(0x0121); + break; + case 0x0122: + bufpush(0x0123); + break; + case 0x0124: + bufpush(0x0125); + break; + case 0x0126: + bufpush(0x0127); + break; + case 0x0128: + bufpush(0x0129); + break; + case 0x012A: + bufpush(0x012B); + break; + case 0x012C: + bufpush(0x012D); + break; + case 0x012E: + bufpush(0x012F); + break; + case 0x0130: + bufpush(0x0069); + bufpush(0x0307); + break; + case 0x0132: + bufpush(0x0133); + break; + case 0x0134: + bufpush(0x0135); + break; + case 0x0136: + bufpush(0x0137); + break; + case 0x0139: + bufpush(0x013A); + break; + case 0x013B: + bufpush(0x013C); + break; + case 0x013D: + bufpush(0x013E); + break; + case 0x013F: + bufpush(0x0140); + break; + case 0x0141: + bufpush(0x0142); + break; + case 0x0143: + bufpush(0x0144); + break; + case 0x0145: + bufpush(0x0146); + break; + case 0x0147: + bufpush(0x0148); + break; + case 0x0149: + bufpush(0x02BC); + bufpush(0x006E); + break; + case 0x014A: + bufpush(0x014B); + break; + case 0x014C: + bufpush(0x014D); + break; + case 0x014E: + bufpush(0x014F); + break; + case 0x0150: + bufpush(0x0151); + break; + case 0x0152: + bufpush(0x0153); + break; + case 0x0154: + bufpush(0x0155); + break; + case 0x0156: + bufpush(0x0157); + break; + case 0x0158: + bufpush(0x0159); + break; + case 0x015A: + bufpush(0x015B); + break; + case 0x015C: + bufpush(0x015D); + break; + case 0x015E: + bufpush(0x015F); + break; + case 0x0160: + bufpush(0x0161); + break; + case 0x0162: + bufpush(0x0163); + break; + case 0x0164: + bufpush(0x0165); + break; + case 0x0166: + bufpush(0x0167); + break; + case 0x0168: + bufpush(0x0169); + break; + case 0x016A: + bufpush(0x016B); + break; + case 0x016C: + bufpush(0x016D); + break; + case 0x016E: + bufpush(0x016F); + break; + case 0x0170: + bufpush(0x0171); + break; + case 0x0172: + bufpush(0x0173); + break; + case 0x0174: + bufpush(0x0175); + break; + case 0x0176: + bufpush(0x0177); + break; + case 0x0178: + bufpush(0x00FF); + break; + case 0x0179: + bufpush(0x017A); + break; + case 0x017B: + bufpush(0x017C); + break; + case 0x017D: + bufpush(0x017E); + break; + case 0x017F: + bufpush(0x0073); + break; + case 0x0181: + bufpush(0x0253); + break; + case 0x0182: + bufpush(0x0183); + break; + case 0x0184: + bufpush(0x0185); + break; + case 0x0186: + bufpush(0x0254); + break; + case 0x0187: + bufpush(0x0188); + break; + case 0x0189: + bufpush(0x0256); + break; + case 0x018A: + bufpush(0x0257); + break; + case 0x018B: + bufpush(0x018C); + break; + case 0x018E: + bufpush(0x01DD); + break; + case 0x018F: + bufpush(0x0259); + break; + case 0x0190: + bufpush(0x025B); + break; + case 0x0191: + bufpush(0x0192); + break; + case 0x0193: + bufpush(0x0260); + break; + case 0x0194: + bufpush(0x0263); + break; + case 0x0196: + bufpush(0x0269); + break; + case 0x0197: + bufpush(0x0268); + break; + case 0x0198: + bufpush(0x0199); + break; + case 0x019C: + bufpush(0x026F); + break; + case 0x019D: + bufpush(0x0272); + break; + case 0x019F: + bufpush(0x0275); + break; + case 0x01A0: + bufpush(0x01A1); + break; + case 0x01A2: + bufpush(0x01A3); + break; + case 0x01A4: + bufpush(0x01A5); + break; + case 0x01A6: + bufpush(0x0280); + break; + case 0x01A7: + bufpush(0x01A8); + break; + case 0x01A9: + bufpush(0x0283); + break; + case 0x01AC: + bufpush(0x01AD); + break; + case 0x01AE: + bufpush(0x0288); + break; + case 0x01AF: + bufpush(0x01B0); + break; + case 0x01B1: + bufpush(0x028A); + break; + case 0x01B2: + bufpush(0x028B); + break; + case 0x01B3: + bufpush(0x01B4); + break; + case 0x01B5: + bufpush(0x01B6); + break; + case 0x01B7: + bufpush(0x0292); + break; + case 0x01B8: + bufpush(0x01B9); + break; + case 0x01BC: + bufpush(0x01BD); + break; + case 0x01C4: + bufpush(0x01C6); + break; + case 0x01C5: + bufpush(0x01C6); + break; + case 0x01C7: + bufpush(0x01C9); + break; + case 0x01C8: + bufpush(0x01C9); + break; + case 0x01CA: + bufpush(0x01CC); + break; + case 0x01CB: + bufpush(0x01CC); + break; + case 0x01CD: + bufpush(0x01CE); + break; + case 0x01CF: + bufpush(0x01D0); + break; + case 0x01D1: + bufpush(0x01D2); + break; + case 0x01D3: + bufpush(0x01D4); + break; + case 0x01D5: + bufpush(0x01D6); + break; + case 0x01D7: + bufpush(0x01D8); + break; + case 0x01D9: + bufpush(0x01DA); + break; + case 0x01DB: + bufpush(0x01DC); + break; + case 0x01DE: + bufpush(0x01DF); + break; + case 0x01E0: + bufpush(0x01E1); + break; + case 0x01E2: + bufpush(0x01E3); + break; + case 0x01E4: + bufpush(0x01E5); + break; + case 0x01E6: + bufpush(0x01E7); + break; + case 0x01E8: + bufpush(0x01E9); + break; + case 0x01EA: + bufpush(0x01EB); + break; + case 0x01EC: + bufpush(0x01ED); + break; + case 0x01EE: + bufpush(0x01EF); + break; + case 0x01F0: + bufpush(0x006A); + bufpush(0x030C); + break; + case 0x01F1: + bufpush(0x01F3); + break; + case 0x01F2: + bufpush(0x01F3); + break; + case 0x01F4: + bufpush(0x01F5); + break; + case 0x01F6: + bufpush(0x0195); + break; + case 0x01F7: + bufpush(0x01BF); + break; + case 0x01F8: + bufpush(0x01F9); + break; + case 0x01FA: + bufpush(0x01FB); + break; + case 0x01FC: + bufpush(0x01FD); + break; + case 0x01FE: + bufpush(0x01FF); + break; + case 0x0200: + bufpush(0x0201); + break; + case 0x0202: + bufpush(0x0203); + break; + case 0x0204: + bufpush(0x0205); + break; + case 0x0206: + bufpush(0x0207); + break; + case 0x0208: + bufpush(0x0209); + break; + case 0x020A: + bufpush(0x020B); + break; + case 0x020C: + bufpush(0x020D); + break; + case 0x020E: + bufpush(0x020F); + break; + case 0x0210: + bufpush(0x0211); + break; + case 0x0212: + bufpush(0x0213); + break; + case 0x0214: + bufpush(0x0215); + break; + case 0x0216: + bufpush(0x0217); + break; + case 0x0218: + bufpush(0x0219); + break; + case 0x021A: + bufpush(0x021B); + break; + case 0x021C: + bufpush(0x021D); + break; + case 0x021E: + bufpush(0x021F); + break; + case 0x0220: + bufpush(0x019E); + break; + case 0x0222: + bufpush(0x0223); + break; + case 0x0224: + bufpush(0x0225); + break; + case 0x0226: + bufpush(0x0227); + break; + case 0x0228: + bufpush(0x0229); + break; + case 0x022A: + bufpush(0x022B); + break; + case 0x022C: + bufpush(0x022D); + break; + case 0x022E: + bufpush(0x022F); + break; + case 0x0230: + bufpush(0x0231); + break; + case 0x0232: + bufpush(0x0233); + break; + case 0x023A: + bufpush(0x2C65); + break; + case 0x023B: + bufpush(0x023C); + break; + case 0x023D: + bufpush(0x019A); + break; + case 0x023E: + bufpush(0x2C66); + break; + case 0x0241: + bufpush(0x0242); + break; + case 0x0243: + bufpush(0x0180); + break; + case 0x0244: + bufpush(0x0289); + break; + case 0x0245: + bufpush(0x028C); + break; + case 0x0246: + bufpush(0x0247); + break; + case 0x0248: + bufpush(0x0249); + break; + case 0x024A: + bufpush(0x024B); + break; + case 0x024C: + bufpush(0x024D); + break; + case 0x024E: + bufpush(0x024F); + break; + case 0x0345: + bufpush(0x03B9); + break; + case 0x0370: + bufpush(0x0371); + break; + case 0x0372: + bufpush(0x0373); + break; + case 0x0376: + bufpush(0x0377); + break; + case 0x037F: + bufpush(0x03F3); + break; + case 0x0386: + bufpush(0x03AC); + break; + case 0x0388: + bufpush(0x03AD); + break; + case 0x0389: + bufpush(0x03AE); + break; + case 0x038A: + bufpush(0x03AF); + break; + case 0x038C: + bufpush(0x03CC); + break; + case 0x038E: + bufpush(0x03CD); + break; + case 0x038F: + bufpush(0x03CE); + break; + case 0x0390: + bufpush(0x03B9); + bufpush(0x0308); + bufpush(0x0301); + break; + case 0x0391: + bufpush(0x03B1); + break; + case 0x0392: + bufpush(0x03B2); + break; + case 0x0393: + bufpush(0x03B3); + break; + case 0x0394: + bufpush(0x03B4); + break; + case 0x0395: + bufpush(0x03B5); + break; + case 0x0396: + bufpush(0x03B6); + break; + case 0x0397: + bufpush(0x03B7); + break; + case 0x0398: + bufpush(0x03B8); + break; + case 0x0399: + bufpush(0x03B9); + break; + case 0x039A: + bufpush(0x03BA); + break; + case 0x039B: + bufpush(0x03BB); + break; + case 0x039C: + bufpush(0x03BC); + break; + case 0x039D: + bufpush(0x03BD); + break; + case 0x039E: + bufpush(0x03BE); + break; + case 0x039F: + bufpush(0x03BF); + break; + case 0x03A0: + bufpush(0x03C0); + break; + case 0x03A1: + bufpush(0x03C1); + break; + case 0x03A3: + bufpush(0x03C3); + break; + case 0x03A4: + bufpush(0x03C4); + break; + case 0x03A5: + bufpush(0x03C5); + break; + case 0x03A6: + bufpush(0x03C6); + break; + case 0x03A7: + bufpush(0x03C7); + break; + case 0x03A8: + bufpush(0x03C8); + break; + case 0x03A9: + bufpush(0x03C9); + break; + case 0x03AA: + bufpush(0x03CA); + break; + case 0x03AB: + bufpush(0x03CB); + break; + case 0x03B0: + bufpush(0x03C5); + bufpush(0x0308); + bufpush(0x0301); + break; + case 0x03C2: + bufpush(0x03C3); + break; + case 0x03CF: + bufpush(0x03D7); + break; + case 0x03D0: + bufpush(0x03B2); + break; + case 0x03D1: + bufpush(0x03B8); + break; + case 0x03D5: + bufpush(0x03C6); + break; + case 0x03D6: + bufpush(0x03C0); + break; + case 0x03D8: + bufpush(0x03D9); + break; + case 0x03DA: + bufpush(0x03DB); + break; + case 0x03DC: + bufpush(0x03DD); + break; + case 0x03DE: + bufpush(0x03DF); + break; + case 0x03E0: + bufpush(0x03E1); + break; + case 0x03E2: + bufpush(0x03E3); + break; + case 0x03E4: + bufpush(0x03E5); + break; + case 0x03E6: + bufpush(0x03E7); + break; + case 0x03E8: + bufpush(0x03E9); + break; + case 0x03EA: + bufpush(0x03EB); + break; + case 0x03EC: + bufpush(0x03ED); + break; + case 0x03EE: + bufpush(0x03EF); + break; + case 0x03F0: + bufpush(0x03BA); + break; + case 0x03F1: + bufpush(0x03C1); + break; + case 0x03F4: + bufpush(0x03B8); + break; + case 0x03F5: + bufpush(0x03B5); + break; + case 0x03F7: + bufpush(0x03F8); + break; + case 0x03F9: + bufpush(0x03F2); + break; + case 0x03FA: + bufpush(0x03FB); + break; + case 0x03FD: + bufpush(0x037B); + break; + case 0x03FE: + bufpush(0x037C); + break; + case 0x03FF: + bufpush(0x037D); + break; + case 0x0400: + bufpush(0x0450); + break; + case 0x0401: + bufpush(0x0451); + break; + case 0x0402: + bufpush(0x0452); + break; + case 0x0403: + bufpush(0x0453); + break; + case 0x0404: + bufpush(0x0454); + break; + case 0x0405: + bufpush(0x0455); + break; + case 0x0406: + bufpush(0x0456); + break; + case 0x0407: + bufpush(0x0457); + break; + case 0x0408: + bufpush(0x0458); + break; + case 0x0409: + bufpush(0x0459); + break; + case 0x040A: + bufpush(0x045A); + break; + case 0x040B: + bufpush(0x045B); + break; + case 0x040C: + bufpush(0x045C); + break; + case 0x040D: + bufpush(0x045D); + break; + case 0x040E: + bufpush(0x045E); + break; + case 0x040F: + bufpush(0x045F); + break; + case 0x0410: + bufpush(0x0430); + break; + case 0x0411: + bufpush(0x0431); + break; + case 0x0412: + bufpush(0x0432); + break; + case 0x0413: + bufpush(0x0433); + break; + case 0x0414: + bufpush(0x0434); + break; + case 0x0415: + bufpush(0x0435); + break; + case 0x0416: + bufpush(0x0436); + break; + case 0x0417: + bufpush(0x0437); + break; + case 0x0418: + bufpush(0x0438); + break; + case 0x0419: + bufpush(0x0439); + break; + case 0x041A: + bufpush(0x043A); + break; + case 0x041B: + bufpush(0x043B); + break; + case 0x041C: + bufpush(0x043C); + break; + case 0x041D: + bufpush(0x043D); + break; + case 0x041E: + bufpush(0x043E); + break; + case 0x041F: + bufpush(0x043F); + break; + case 0x0420: + bufpush(0x0440); + break; + case 0x0421: + bufpush(0x0441); + break; + case 0x0422: + bufpush(0x0442); + break; + case 0x0423: + bufpush(0x0443); + break; + case 0x0424: + bufpush(0x0444); + break; + case 0x0425: + bufpush(0x0445); + break; + case 0x0426: + bufpush(0x0446); + break; + case 0x0427: + bufpush(0x0447); + break; + case 0x0428: + bufpush(0x0448); + break; + case 0x0429: + bufpush(0x0449); + break; + case 0x042A: + bufpush(0x044A); + break; + case 0x042B: + bufpush(0x044B); + break; + case 0x042C: + bufpush(0x044C); + break; + case 0x042D: + bufpush(0x044D); + break; + case 0x042E: + bufpush(0x044E); + break; + case 0x042F: + bufpush(0x044F); + break; + case 0x0460: + bufpush(0x0461); + break; + case 0x0462: + bufpush(0x0463); + break; + case 0x0464: + bufpush(0x0465); + break; + case 0x0466: + bufpush(0x0467); + break; + case 0x0468: + bufpush(0x0469); + break; + case 0x046A: + bufpush(0x046B); + break; + case 0x046C: + bufpush(0x046D); + break; + case 0x046E: + bufpush(0x046F); + break; + case 0x0470: + bufpush(0x0471); + break; + case 0x0472: + bufpush(0x0473); + break; + case 0x0474: + bufpush(0x0475); + break; + case 0x0476: + bufpush(0x0477); + break; + case 0x0478: + bufpush(0x0479); + break; + case 0x047A: + bufpush(0x047B); + break; + case 0x047C: + bufpush(0x047D); + break; + case 0x047E: + bufpush(0x047F); + break; + case 0x0480: + bufpush(0x0481); + break; + case 0x048A: + bufpush(0x048B); + break; + case 0x048C: + bufpush(0x048D); + break; + case 0x048E: + bufpush(0x048F); + break; + case 0x0490: + bufpush(0x0491); + break; + case 0x0492: + bufpush(0x0493); + break; + case 0x0494: + bufpush(0x0495); + break; + case 0x0496: + bufpush(0x0497); + break; + case 0x0498: + bufpush(0x0499); + break; + case 0x049A: + bufpush(0x049B); + break; + case 0x049C: + bufpush(0x049D); + break; + case 0x049E: + bufpush(0x049F); + break; + case 0x04A0: + bufpush(0x04A1); + break; + case 0x04A2: + bufpush(0x04A3); + break; + case 0x04A4: + bufpush(0x04A5); + break; + case 0x04A6: + bufpush(0x04A7); + break; + case 0x04A8: + bufpush(0x04A9); + break; + case 0x04AA: + bufpush(0x04AB); + break; + case 0x04AC: + bufpush(0x04AD); + break; + case 0x04AE: + bufpush(0x04AF); + break; + case 0x04B0: + bufpush(0x04B1); + break; + case 0x04B2: + bufpush(0x04B3); + break; + case 0x04B4: + bufpush(0x04B5); + break; + case 0x04B6: + bufpush(0x04B7); + break; + case 0x04B8: + bufpush(0x04B9); + break; + case 0x04BA: + bufpush(0x04BB); + break; + case 0x04BC: + bufpush(0x04BD); + break; + case 0x04BE: + bufpush(0x04BF); + break; + case 0x04C0: + bufpush(0x04CF); + break; + case 0x04C1: + bufpush(0x04C2); + break; + case 0x04C3: + bufpush(0x04C4); + break; + case 0x04C5: + bufpush(0x04C6); + break; + case 0x04C7: + bufpush(0x04C8); + break; + case 0x04C9: + bufpush(0x04CA); + break; + case 0x04CB: + bufpush(0x04CC); + break; + case 0x04CD: + bufpush(0x04CE); + break; + case 0x04D0: + bufpush(0x04D1); + break; + case 0x04D2: + bufpush(0x04D3); + break; + case 0x04D4: + bufpush(0x04D5); + break; + case 0x04D6: + bufpush(0x04D7); + break; + case 0x04D8: + bufpush(0x04D9); + break; + case 0x04DA: + bufpush(0x04DB); + break; + case 0x04DC: + bufpush(0x04DD); + break; + case 0x04DE: + bufpush(0x04DF); + break; + case 0x04E0: + bufpush(0x04E1); + break; + case 0x04E2: + bufpush(0x04E3); + break; + case 0x04E4: + bufpush(0x04E5); + break; + case 0x04E6: + bufpush(0x04E7); + break; + case 0x04E8: + bufpush(0x04E9); + break; + case 0x04EA: + bufpush(0x04EB); + break; + case 0x04EC: + bufpush(0x04ED); + break; + case 0x04EE: + bufpush(0x04EF); + break; + case 0x04F0: + bufpush(0x04F1); + break; + case 0x04F2: + bufpush(0x04F3); + break; + case 0x04F4: + bufpush(0x04F5); + break; + case 0x04F6: + bufpush(0x04F7); + break; + case 0x04F8: + bufpush(0x04F9); + break; + case 0x04FA: + bufpush(0x04FB); + break; + case 0x04FC: + bufpush(0x04FD); + break; + case 0x04FE: + bufpush(0x04FF); + break; + case 0x0500: + bufpush(0x0501); + break; + case 0x0502: + bufpush(0x0503); + break; + case 0x0504: + bufpush(0x0505); + break; + case 0x0506: + bufpush(0x0507); + break; + case 0x0508: + bufpush(0x0509); + break; + case 0x050A: + bufpush(0x050B); + break; + case 0x050C: + bufpush(0x050D); + break; + case 0x050E: + bufpush(0x050F); + break; + case 0x0510: + bufpush(0x0511); + break; + case 0x0512: + bufpush(0x0513); + break; + case 0x0514: + bufpush(0x0515); + break; + case 0x0516: + bufpush(0x0517); + break; + case 0x0518: + bufpush(0x0519); + break; + case 0x051A: + bufpush(0x051B); + break; + case 0x051C: + bufpush(0x051D); + break; + case 0x051E: + bufpush(0x051F); + break; + case 0x0520: + bufpush(0x0521); + break; + case 0x0522: + bufpush(0x0523); + break; + case 0x0524: + bufpush(0x0525); + break; + case 0x0526: + bufpush(0x0527); + break; + case 0x0528: + bufpush(0x0529); + break; + case 0x052A: + bufpush(0x052B); + break; + case 0x052C: + bufpush(0x052D); + break; + case 0x052E: + bufpush(0x052F); + break; + case 0x0531: + bufpush(0x0561); + break; + case 0x0532: + bufpush(0x0562); + break; + case 0x0533: + bufpush(0x0563); + break; + case 0x0534: + bufpush(0x0564); + break; + case 0x0535: + bufpush(0x0565); + break; + case 0x0536: + bufpush(0x0566); + break; + case 0x0537: + bufpush(0x0567); + break; + case 0x0538: + bufpush(0x0568); + break; + case 0x0539: + bufpush(0x0569); + break; + case 0x053A: + bufpush(0x056A); + break; + case 0x053B: + bufpush(0x056B); + break; + case 0x053C: + bufpush(0x056C); + break; + case 0x053D: + bufpush(0x056D); + break; + case 0x053E: + bufpush(0x056E); + break; + case 0x053F: + bufpush(0x056F); + break; + case 0x0540: + bufpush(0x0570); + break; + case 0x0541: + bufpush(0x0571); + break; + case 0x0542: + bufpush(0x0572); + break; + case 0x0543: + bufpush(0x0573); + break; + case 0x0544: + bufpush(0x0574); + break; + case 0x0545: + bufpush(0x0575); + break; + case 0x0546: + bufpush(0x0576); + break; + case 0x0547: + bufpush(0x0577); + break; + case 0x0548: + bufpush(0x0578); + break; + case 0x0549: + bufpush(0x0579); + break; + case 0x054A: + bufpush(0x057A); + break; + case 0x054B: + bufpush(0x057B); + break; + case 0x054C: + bufpush(0x057C); + break; + case 0x054D: + bufpush(0x057D); + break; + case 0x054E: + bufpush(0x057E); + break; + case 0x054F: + bufpush(0x057F); + break; + case 0x0550: + bufpush(0x0580); + break; + case 0x0551: + bufpush(0x0581); + break; + case 0x0552: + bufpush(0x0582); + break; + case 0x0553: + bufpush(0x0583); + break; + case 0x0554: + bufpush(0x0584); + break; + case 0x0555: + bufpush(0x0585); + break; + case 0x0556: + bufpush(0x0586); + break; + case 0x0587: + bufpush(0x0565); + bufpush(0x0582); + break; + case 0x10A0: + bufpush(0x2D00); + break; + case 0x10A1: + bufpush(0x2D01); + break; + case 0x10A2: + bufpush(0x2D02); + break; + case 0x10A3: + bufpush(0x2D03); + break; + case 0x10A4: + bufpush(0x2D04); + break; + case 0x10A5: + bufpush(0x2D05); + break; + case 0x10A6: + bufpush(0x2D06); + break; + case 0x10A7: + bufpush(0x2D07); + break; + case 0x10A8: + bufpush(0x2D08); + break; + case 0x10A9: + bufpush(0x2D09); + break; + case 0x10AA: + bufpush(0x2D0A); + break; + case 0x10AB: + bufpush(0x2D0B); + break; + case 0x10AC: + bufpush(0x2D0C); + break; + case 0x10AD: + bufpush(0x2D0D); + break; + case 0x10AE: + bufpush(0x2D0E); + break; + case 0x10AF: + bufpush(0x2D0F); + break; + case 0x10B0: + bufpush(0x2D10); + break; + case 0x10B1: + bufpush(0x2D11); + break; + case 0x10B2: + bufpush(0x2D12); + break; + case 0x10B3: + bufpush(0x2D13); + break; + case 0x10B4: + bufpush(0x2D14); + break; + case 0x10B5: + bufpush(0x2D15); + break; + case 0x10B6: + bufpush(0x2D16); + break; + case 0x10B7: + bufpush(0x2D17); + break; + case 0x10B8: + bufpush(0x2D18); + break; + case 0x10B9: + bufpush(0x2D19); + break; + case 0x10BA: + bufpush(0x2D1A); + break; + case 0x10BB: + bufpush(0x2D1B); + break; + case 0x10BC: + bufpush(0x2D1C); + break; + case 0x10BD: + bufpush(0x2D1D); + break; + case 0x10BE: + bufpush(0x2D1E); + break; + case 0x10BF: + bufpush(0x2D1F); + break; + case 0x10C0: + bufpush(0x2D20); + break; + case 0x10C1: + bufpush(0x2D21); + break; + case 0x10C2: + bufpush(0x2D22); + break; + case 0x10C3: + bufpush(0x2D23); + break; + case 0x10C4: + bufpush(0x2D24); + break; + case 0x10C5: + bufpush(0x2D25); + break; + case 0x10C7: + bufpush(0x2D27); + break; + case 0x10CD: + bufpush(0x2D2D); + break; + case 0x13F8: + bufpush(0x13F0); + break; + case 0x13F9: + bufpush(0x13F1); + break; + case 0x13FA: + bufpush(0x13F2); + break; + case 0x13FB: + bufpush(0x13F3); + break; + case 0x13FC: + bufpush(0x13F4); + break; + case 0x13FD: + bufpush(0x13F5); + break; + case 0x1C80: + bufpush(0x0432); + break; + case 0x1C81: + bufpush(0x0434); + break; + case 0x1C82: + bufpush(0x043E); + break; + case 0x1C83: + bufpush(0x0441); + break; + case 0x1C84: + bufpush(0x0442); + break; + case 0x1C85: + bufpush(0x0442); + break; + case 0x1C86: + bufpush(0x044A); + break; + case 0x1C87: + bufpush(0x0463); + break; + case 0x1C88: + bufpush(0xA64B); + break; + case 0x1E00: + bufpush(0x1E01); + break; + case 0x1E02: + bufpush(0x1E03); + break; + case 0x1E04: + bufpush(0x1E05); + break; + case 0x1E06: + bufpush(0x1E07); + break; + case 0x1E08: + bufpush(0x1E09); + break; + case 0x1E0A: + bufpush(0x1E0B); + break; + case 0x1E0C: + bufpush(0x1E0D); + break; + case 0x1E0E: + bufpush(0x1E0F); + break; + case 0x1E10: + bufpush(0x1E11); + break; + case 0x1E12: + bufpush(0x1E13); + break; + case 0x1E14: + bufpush(0x1E15); + break; + case 0x1E16: + bufpush(0x1E17); + break; + case 0x1E18: + bufpush(0x1E19); + break; + case 0x1E1A: + bufpush(0x1E1B); + break; + case 0x1E1C: + bufpush(0x1E1D); + break; + case 0x1E1E: + bufpush(0x1E1F); + break; + case 0x1E20: + bufpush(0x1E21); + break; + case 0x1E22: + bufpush(0x1E23); + break; + case 0x1E24: + bufpush(0x1E25); + break; + case 0x1E26: + bufpush(0x1E27); + break; + case 0x1E28: + bufpush(0x1E29); + break; + case 0x1E2A: + bufpush(0x1E2B); + break; + case 0x1E2C: + bufpush(0x1E2D); + break; + case 0x1E2E: + bufpush(0x1E2F); + break; + case 0x1E30: + bufpush(0x1E31); + break; + case 0x1E32: + bufpush(0x1E33); + break; + case 0x1E34: + bufpush(0x1E35); + break; + case 0x1E36: + bufpush(0x1E37); + break; + case 0x1E38: + bufpush(0x1E39); + break; + case 0x1E3A: + bufpush(0x1E3B); + break; + case 0x1E3C: + bufpush(0x1E3D); + break; + case 0x1E3E: + bufpush(0x1E3F); + break; + case 0x1E40: + bufpush(0x1E41); + break; + case 0x1E42: + bufpush(0x1E43); + break; + case 0x1E44: + bufpush(0x1E45); + break; + case 0x1E46: + bufpush(0x1E47); + break; + case 0x1E48: + bufpush(0x1E49); + break; + case 0x1E4A: + bufpush(0x1E4B); + break; + case 0x1E4C: + bufpush(0x1E4D); + break; + case 0x1E4E: + bufpush(0x1E4F); + break; + case 0x1E50: + bufpush(0x1E51); + break; + case 0x1E52: + bufpush(0x1E53); + break; + case 0x1E54: + bufpush(0x1E55); + break; + case 0x1E56: + bufpush(0x1E57); + break; + case 0x1E58: + bufpush(0x1E59); + break; + case 0x1E5A: + bufpush(0x1E5B); + break; + case 0x1E5C: + bufpush(0x1E5D); + break; + case 0x1E5E: + bufpush(0x1E5F); + break; + case 0x1E60: + bufpush(0x1E61); + break; + case 0x1E62: + bufpush(0x1E63); + break; + case 0x1E64: + bufpush(0x1E65); + break; + case 0x1E66: + bufpush(0x1E67); + break; + case 0x1E68: + bufpush(0x1E69); + break; + case 0x1E6A: + bufpush(0x1E6B); + break; + case 0x1E6C: + bufpush(0x1E6D); + break; + case 0x1E6E: + bufpush(0x1E6F); + break; + case 0x1E70: + bufpush(0x1E71); + break; + case 0x1E72: + bufpush(0x1E73); + break; + case 0x1E74: + bufpush(0x1E75); + break; + case 0x1E76: + bufpush(0x1E77); + break; + case 0x1E78: + bufpush(0x1E79); + break; + case 0x1E7A: + bufpush(0x1E7B); + break; + case 0x1E7C: + bufpush(0x1E7D); + break; + case 0x1E7E: + bufpush(0x1E7F); + break; + case 0x1E80: + bufpush(0x1E81); + break; + case 0x1E82: + bufpush(0x1E83); + break; + case 0x1E84: + bufpush(0x1E85); + break; + case 0x1E86: + bufpush(0x1E87); + break; + case 0x1E88: + bufpush(0x1E89); + break; + case 0x1E8A: + bufpush(0x1E8B); + break; + case 0x1E8C: + bufpush(0x1E8D); + break; + case 0x1E8E: + bufpush(0x1E8F); + break; + case 0x1E90: + bufpush(0x1E91); + break; + case 0x1E92: + bufpush(0x1E93); + break; + case 0x1E94: + bufpush(0x1E95); + break; + case 0x1E96: + bufpush(0x0068); + bufpush(0x0331); + break; + case 0x1E97: + bufpush(0x0074); + bufpush(0x0308); + break; + case 0x1E98: + bufpush(0x0077); + bufpush(0x030A); + break; + case 0x1E99: + bufpush(0x0079); + bufpush(0x030A); + break; + case 0x1E9A: + bufpush(0x0061); + bufpush(0x02BE); + break; + case 0x1E9B: + bufpush(0x1E61); + break; + case 0x1E9E: + bufpush(0x0073); + bufpush(0x0073); + break; + case 0x1EA0: + bufpush(0x1EA1); + break; + case 0x1EA2: + bufpush(0x1EA3); + break; + case 0x1EA4: + bufpush(0x1EA5); + break; + case 0x1EA6: + bufpush(0x1EA7); + break; + case 0x1EA8: + bufpush(0x1EA9); + break; + case 0x1EAA: + bufpush(0x1EAB); + break; + case 0x1EAC: + bufpush(0x1EAD); + break; + case 0x1EAE: + bufpush(0x1EAF); + break; + case 0x1EB0: + bufpush(0x1EB1); + break; + case 0x1EB2: + bufpush(0x1EB3); + break; + case 0x1EB4: + bufpush(0x1EB5); + break; + case 0x1EB6: + bufpush(0x1EB7); + break; + case 0x1EB8: + bufpush(0x1EB9); + break; + case 0x1EBA: + bufpush(0x1EBB); + break; + case 0x1EBC: + bufpush(0x1EBD); + break; + case 0x1EBE: + bufpush(0x1EBF); + break; + case 0x1EC0: + bufpush(0x1EC1); + break; + case 0x1EC2: + bufpush(0x1EC3); + break; + case 0x1EC4: + bufpush(0x1EC5); + break; + case 0x1EC6: + bufpush(0x1EC7); + break; + case 0x1EC8: + bufpush(0x1EC9); + break; + case 0x1ECA: + bufpush(0x1ECB); + break; + case 0x1ECC: + bufpush(0x1ECD); + break; + case 0x1ECE: + bufpush(0x1ECF); + break; + case 0x1ED0: + bufpush(0x1ED1); + break; + case 0x1ED2: + bufpush(0x1ED3); + break; + case 0x1ED4: + bufpush(0x1ED5); + break; + case 0x1ED6: + bufpush(0x1ED7); + break; + case 0x1ED8: + bufpush(0x1ED9); + break; + case 0x1EDA: + bufpush(0x1EDB); + break; + case 0x1EDC: + bufpush(0x1EDD); + break; + case 0x1EDE: + bufpush(0x1EDF); + break; + case 0x1EE0: + bufpush(0x1EE1); + break; + case 0x1EE2: + bufpush(0x1EE3); + break; + case 0x1EE4: + bufpush(0x1EE5); + break; + case 0x1EE6: + bufpush(0x1EE7); + break; + case 0x1EE8: + bufpush(0x1EE9); + break; + case 0x1EEA: + bufpush(0x1EEB); + break; + case 0x1EEC: + bufpush(0x1EED); + break; + case 0x1EEE: + bufpush(0x1EEF); + break; + case 0x1EF0: + bufpush(0x1EF1); + break; + case 0x1EF2: + bufpush(0x1EF3); + break; + case 0x1EF4: + bufpush(0x1EF5); + break; + case 0x1EF6: + bufpush(0x1EF7); + break; + case 0x1EF8: + bufpush(0x1EF9); + break; + case 0x1EFA: + bufpush(0x1EFB); + break; + case 0x1EFC: + bufpush(0x1EFD); + break; + case 0x1EFE: + bufpush(0x1EFF); + break; + case 0x1F08: + bufpush(0x1F00); + break; + case 0x1F09: + bufpush(0x1F01); + break; + case 0x1F0A: + bufpush(0x1F02); + break; + case 0x1F0B: + bufpush(0x1F03); + break; + case 0x1F0C: + bufpush(0x1F04); + break; + case 0x1F0D: + bufpush(0x1F05); + break; + case 0x1F0E: + bufpush(0x1F06); + break; + case 0x1F0F: + bufpush(0x1F07); + break; + case 0x1F18: + bufpush(0x1F10); + break; + case 0x1F19: + bufpush(0x1F11); + break; + case 0x1F1A: + bufpush(0x1F12); + break; + case 0x1F1B: + bufpush(0x1F13); + break; + case 0x1F1C: + bufpush(0x1F14); + break; + case 0x1F1D: + bufpush(0x1F15); + break; + case 0x1F28: + bufpush(0x1F20); + break; + case 0x1F29: + bufpush(0x1F21); + break; + case 0x1F2A: + bufpush(0x1F22); + break; + case 0x1F2B: + bufpush(0x1F23); + break; + case 0x1F2C: + bufpush(0x1F24); + break; + case 0x1F2D: + bufpush(0x1F25); + break; + case 0x1F2E: + bufpush(0x1F26); + break; + case 0x1F2F: + bufpush(0x1F27); + break; + case 0x1F38: + bufpush(0x1F30); + break; + case 0x1F39: + bufpush(0x1F31); + break; + case 0x1F3A: + bufpush(0x1F32); + break; + case 0x1F3B: + bufpush(0x1F33); + break; + case 0x1F3C: + bufpush(0x1F34); + break; + case 0x1F3D: + bufpush(0x1F35); + break; + case 0x1F3E: + bufpush(0x1F36); + break; + case 0x1F3F: + bufpush(0x1F37); + break; + case 0x1F48: + bufpush(0x1F40); + break; + case 0x1F49: + bufpush(0x1F41); + break; + case 0x1F4A: + bufpush(0x1F42); + break; + case 0x1F4B: + bufpush(0x1F43); + break; + case 0x1F4C: + bufpush(0x1F44); + break; + case 0x1F4D: + bufpush(0x1F45); + break; + case 0x1F50: + bufpush(0x03C5); + bufpush(0x0313); + break; + case 0x1F52: + bufpush(0x03C5); + bufpush(0x0313); + bufpush(0x0300); + break; + case 0x1F54: + bufpush(0x03C5); + bufpush(0x0313); + bufpush(0x0301); + break; + case 0x1F56: + bufpush(0x03C5); + bufpush(0x0313); + bufpush(0x0342); + break; + case 0x1F59: + bufpush(0x1F51); + break; + case 0x1F5B: + bufpush(0x1F53); + break; + case 0x1F5D: + bufpush(0x1F55); + break; + case 0x1F5F: + bufpush(0x1F57); + break; + case 0x1F68: + bufpush(0x1F60); + break; + case 0x1F69: + bufpush(0x1F61); + break; + case 0x1F6A: + bufpush(0x1F62); + break; + case 0x1F6B: + bufpush(0x1F63); + break; + case 0x1F6C: + bufpush(0x1F64); + break; + case 0x1F6D: + bufpush(0x1F65); + break; + case 0x1F6E: + bufpush(0x1F66); + break; + case 0x1F6F: + bufpush(0x1F67); + break; + case 0x1F80: + bufpush(0x1F00); + bufpush(0x03B9); + break; + case 0x1F81: + bufpush(0x1F01); + bufpush(0x03B9); + break; + case 0x1F82: + bufpush(0x1F02); + bufpush(0x03B9); + break; + case 0x1F83: + bufpush(0x1F03); + bufpush(0x03B9); + break; + case 0x1F84: + bufpush(0x1F04); + bufpush(0x03B9); + break; + case 0x1F85: + bufpush(0x1F05); + bufpush(0x03B9); + break; + case 0x1F86: + bufpush(0x1F06); + bufpush(0x03B9); + break; + case 0x1F87: + bufpush(0x1F07); + bufpush(0x03B9); + break; + case 0x1F88: + bufpush(0x1F00); + bufpush(0x03B9); + break; + case 0x1F89: + bufpush(0x1F01); + bufpush(0x03B9); + break; + case 0x1F8A: + bufpush(0x1F02); + bufpush(0x03B9); + break; + case 0x1F8B: + bufpush(0x1F03); + bufpush(0x03B9); + break; + case 0x1F8C: + bufpush(0x1F04); + bufpush(0x03B9); + break; + case 0x1F8D: + bufpush(0x1F05); + bufpush(0x03B9); + break; + case 0x1F8E: + bufpush(0x1F06); + bufpush(0x03B9); + break; + case 0x1F8F: + bufpush(0x1F07); + bufpush(0x03B9); + break; + case 0x1F90: + bufpush(0x1F20); + bufpush(0x03B9); + break; + case 0x1F91: + bufpush(0x1F21); + bufpush(0x03B9); + break; + case 0x1F92: + bufpush(0x1F22); + bufpush(0x03B9); + break; + case 0x1F93: + bufpush(0x1F23); + bufpush(0x03B9); + break; + case 0x1F94: + bufpush(0x1F24); + bufpush(0x03B9); + break; + case 0x1F95: + bufpush(0x1F25); + bufpush(0x03B9); + break; + case 0x1F96: + bufpush(0x1F26); + bufpush(0x03B9); + break; + case 0x1F97: + bufpush(0x1F27); + bufpush(0x03B9); + break; + case 0x1F98: + bufpush(0x1F20); + bufpush(0x03B9); + break; + case 0x1F99: + bufpush(0x1F21); + bufpush(0x03B9); + break; + case 0x1F9A: + bufpush(0x1F22); + bufpush(0x03B9); + break; + case 0x1F9B: + bufpush(0x1F23); + bufpush(0x03B9); + break; + case 0x1F9C: + bufpush(0x1F24); + bufpush(0x03B9); + break; + case 0x1F9D: + bufpush(0x1F25); + bufpush(0x03B9); + break; + case 0x1F9E: + bufpush(0x1F26); + bufpush(0x03B9); + break; + case 0x1F9F: + bufpush(0x1F27); + bufpush(0x03B9); + break; + case 0x1FA0: + bufpush(0x1F60); + bufpush(0x03B9); + break; + case 0x1FA1: + bufpush(0x1F61); + bufpush(0x03B9); + break; + case 0x1FA2: + bufpush(0x1F62); + bufpush(0x03B9); + break; + case 0x1FA3: + bufpush(0x1F63); + bufpush(0x03B9); + break; + case 0x1FA4: + bufpush(0x1F64); + bufpush(0x03B9); + break; + case 0x1FA5: + bufpush(0x1F65); + bufpush(0x03B9); + break; + case 0x1FA6: + bufpush(0x1F66); + bufpush(0x03B9); + break; + case 0x1FA7: + bufpush(0x1F67); + bufpush(0x03B9); + break; + case 0x1FA8: + bufpush(0x1F60); + bufpush(0x03B9); + break; + case 0x1FA9: + bufpush(0x1F61); + bufpush(0x03B9); + break; + case 0x1FAA: + bufpush(0x1F62); + bufpush(0x03B9); + break; + case 0x1FAB: + bufpush(0x1F63); + bufpush(0x03B9); + break; + case 0x1FAC: + bufpush(0x1F64); + bufpush(0x03B9); + break; + case 0x1FAD: + bufpush(0x1F65); + bufpush(0x03B9); + break; + case 0x1FAE: + bufpush(0x1F66); + bufpush(0x03B9); + break; + case 0x1FAF: + bufpush(0x1F67); + bufpush(0x03B9); + break; + case 0x1FB2: + bufpush(0x1F70); + bufpush(0x03B9); + break; + case 0x1FB3: + bufpush(0x03B1); + bufpush(0x03B9); + break; + case 0x1FB4: + bufpush(0x03AC); + bufpush(0x03B9); + break; + case 0x1FB6: + bufpush(0x03B1); + bufpush(0x0342); + break; + case 0x1FB7: + bufpush(0x03B1); + bufpush(0x0342); + bufpush(0x03B9); + break; + case 0x1FB8: + bufpush(0x1FB0); + break; + case 0x1FB9: + bufpush(0x1FB1); + break; + case 0x1FBA: + bufpush(0x1F70); + break; + case 0x1FBB: + bufpush(0x1F71); + break; + case 0x1FBC: + bufpush(0x03B1); + bufpush(0x03B9); + break; + case 0x1FBE: + bufpush(0x03B9); + break; + case 0x1FC2: + bufpush(0x1F74); + bufpush(0x03B9); + break; + case 0x1FC3: + bufpush(0x03B7); + bufpush(0x03B9); + break; + case 0x1FC4: + bufpush(0x03AE); + bufpush(0x03B9); + break; + case 0x1FC6: + bufpush(0x03B7); + bufpush(0x0342); + break; + case 0x1FC7: + bufpush(0x03B7); + bufpush(0x0342); + bufpush(0x03B9); + break; + case 0x1FC8: + bufpush(0x1F72); + break; + case 0x1FC9: + bufpush(0x1F73); + break; + case 0x1FCA: + bufpush(0x1F74); + break; + case 0x1FCB: + bufpush(0x1F75); + break; + case 0x1FCC: + bufpush(0x03B7); + bufpush(0x03B9); + break; + case 0x1FD2: + bufpush(0x03B9); + bufpush(0x0308); + bufpush(0x0300); + break; + case 0x1FD3: + bufpush(0x03B9); + bufpush(0x0308); + bufpush(0x0301); + break; + case 0x1FD6: + bufpush(0x03B9); + bufpush(0x0342); + break; + case 0x1FD7: + bufpush(0x03B9); + bufpush(0x0308); + bufpush(0x0342); + break; + case 0x1FD8: + bufpush(0x1FD0); + break; + case 0x1FD9: + bufpush(0x1FD1); + break; + case 0x1FDA: + bufpush(0x1F76); + break; + case 0x1FDB: + bufpush(0x1F77); + break; + case 0x1FE2: + bufpush(0x03C5); + bufpush(0x0308); + bufpush(0x0300); + break; + case 0x1FE3: + bufpush(0x03C5); + bufpush(0x0308); + bufpush(0x0301); + break; + case 0x1FE4: + bufpush(0x03C1); + bufpush(0x0313); + break; + case 0x1FE6: + bufpush(0x03C5); + bufpush(0x0342); + break; + case 0x1FE7: + bufpush(0x03C5); + bufpush(0x0308); + bufpush(0x0342); + break; + case 0x1FE8: + bufpush(0x1FE0); + break; + case 0x1FE9: + bufpush(0x1FE1); + break; + case 0x1FEA: + bufpush(0x1F7A); + break; + case 0x1FEB: + bufpush(0x1F7B); + break; + case 0x1FEC: + bufpush(0x1FE5); + break; + case 0x1FF2: + bufpush(0x1F7C); + bufpush(0x03B9); + break; + case 0x1FF3: + bufpush(0x03C9); + bufpush(0x03B9); + break; + case 0x1FF4: + bufpush(0x03CE); + bufpush(0x03B9); + break; + case 0x1FF6: + bufpush(0x03C9); + bufpush(0x0342); + break; + case 0x1FF7: + bufpush(0x03C9); + bufpush(0x0342); + bufpush(0x03B9); + break; + case 0x1FF8: + bufpush(0x1F78); + break; + case 0x1FF9: + bufpush(0x1F79); + break; + case 0x1FFA: + bufpush(0x1F7C); + break; + case 0x1FFB: + bufpush(0x1F7D); + break; + case 0x1FFC: + bufpush(0x03C9); + bufpush(0x03B9); + break; + case 0x2126: + bufpush(0x03C9); + break; + case 0x212A: + bufpush(0x006B); + break; + case 0x212B: + bufpush(0x00E5); + break; + case 0x2132: + bufpush(0x214E); + break; + case 0x2160: + bufpush(0x2170); + break; + case 0x2161: + bufpush(0x2171); + break; + case 0x2162: + bufpush(0x2172); + break; + case 0x2163: + bufpush(0x2173); + break; + case 0x2164: + bufpush(0x2174); + break; + case 0x2165: + bufpush(0x2175); + break; + case 0x2166: + bufpush(0x2176); + break; + case 0x2167: + bufpush(0x2177); + break; + case 0x2168: + bufpush(0x2178); + break; + case 0x2169: + bufpush(0x2179); + break; + case 0x216A: + bufpush(0x217A); + break; + case 0x216B: + bufpush(0x217B); + break; + case 0x216C: + bufpush(0x217C); + break; + case 0x216D: + bufpush(0x217D); + break; + case 0x216E: + bufpush(0x217E); + break; + case 0x216F: + bufpush(0x217F); + break; + case 0x2183: + bufpush(0x2184); + break; + case 0x24B6: + bufpush(0x24D0); + break; + case 0x24B7: + bufpush(0x24D1); + break; + case 0x24B8: + bufpush(0x24D2); + break; + case 0x24B9: + bufpush(0x24D3); + break; + case 0x24BA: + bufpush(0x24D4); + break; + case 0x24BB: + bufpush(0x24D5); + break; + case 0x24BC: + bufpush(0x24D6); + break; + case 0x24BD: + bufpush(0x24D7); + break; + case 0x24BE: + bufpush(0x24D8); + break; + case 0x24BF: + bufpush(0x24D9); + break; + case 0x24C0: + bufpush(0x24DA); + break; + case 0x24C1: + bufpush(0x24DB); + break; + case 0x24C2: + bufpush(0x24DC); + break; + case 0x24C3: + bufpush(0x24DD); + break; + case 0x24C4: + bufpush(0x24DE); + break; + case 0x24C5: + bufpush(0x24DF); + break; + case 0x24C6: + bufpush(0x24E0); + break; + case 0x24C7: + bufpush(0x24E1); + break; + case 0x24C8: + bufpush(0x24E2); + break; + case 0x24C9: + bufpush(0x24E3); + break; + case 0x24CA: + bufpush(0x24E4); + break; + case 0x24CB: + bufpush(0x24E5); + break; + case 0x24CC: + bufpush(0x24E6); + break; + case 0x24CD: + bufpush(0x24E7); + break; + case 0x24CE: + bufpush(0x24E8); + break; + case 0x24CF: + bufpush(0x24E9); + break; + case 0x2C00: + bufpush(0x2C30); + break; + case 0x2C01: + bufpush(0x2C31); + break; + case 0x2C02: + bufpush(0x2C32); + break; + case 0x2C03: + bufpush(0x2C33); + break; + case 0x2C04: + bufpush(0x2C34); + break; + case 0x2C05: + bufpush(0x2C35); + break; + case 0x2C06: + bufpush(0x2C36); + break; + case 0x2C07: + bufpush(0x2C37); + break; + case 0x2C08: + bufpush(0x2C38); + break; + case 0x2C09: + bufpush(0x2C39); + break; + case 0x2C0A: + bufpush(0x2C3A); + break; + case 0x2C0B: + bufpush(0x2C3B); + break; + case 0x2C0C: + bufpush(0x2C3C); + break; + case 0x2C0D: + bufpush(0x2C3D); + break; + case 0x2C0E: + bufpush(0x2C3E); + break; + case 0x2C0F: + bufpush(0x2C3F); + break; + case 0x2C10: + bufpush(0x2C40); + break; + case 0x2C11: + bufpush(0x2C41); + break; + case 0x2C12: + bufpush(0x2C42); + break; + case 0x2C13: + bufpush(0x2C43); + break; + case 0x2C14: + bufpush(0x2C44); + break; + case 0x2C15: + bufpush(0x2C45); + break; + case 0x2C16: + bufpush(0x2C46); + break; + case 0x2C17: + bufpush(0x2C47); + break; + case 0x2C18: + bufpush(0x2C48); + break; + case 0x2C19: + bufpush(0x2C49); + break; + case 0x2C1A: + bufpush(0x2C4A); + break; + case 0x2C1B: + bufpush(0x2C4B); + break; + case 0x2C1C: + bufpush(0x2C4C); + break; + case 0x2C1D: + bufpush(0x2C4D); + break; + case 0x2C1E: + bufpush(0x2C4E); + break; + case 0x2C1F: + bufpush(0x2C4F); + break; + case 0x2C20: + bufpush(0x2C50); + break; + case 0x2C21: + bufpush(0x2C51); + break; + case 0x2C22: + bufpush(0x2C52); + break; + case 0x2C23: + bufpush(0x2C53); + break; + case 0x2C24: + bufpush(0x2C54); + break; + case 0x2C25: + bufpush(0x2C55); + break; + case 0x2C26: + bufpush(0x2C56); + break; + case 0x2C27: + bufpush(0x2C57); + break; + case 0x2C28: + bufpush(0x2C58); + break; + case 0x2C29: + bufpush(0x2C59); + break; + case 0x2C2A: + bufpush(0x2C5A); + break; + case 0x2C2B: + bufpush(0x2C5B); + break; + case 0x2C2C: + bufpush(0x2C5C); + break; + case 0x2C2D: + bufpush(0x2C5D); + break; + case 0x2C2E: + bufpush(0x2C5E); + break; + case 0x2C60: + bufpush(0x2C61); + break; + case 0x2C62: + bufpush(0x026B); + break; + case 0x2C63: + bufpush(0x1D7D); + break; + case 0x2C64: + bufpush(0x027D); + break; + case 0x2C67: + bufpush(0x2C68); + break; + case 0x2C69: + bufpush(0x2C6A); + break; + case 0x2C6B: + bufpush(0x2C6C); + break; + case 0x2C6D: + bufpush(0x0251); + break; + case 0x2C6E: + bufpush(0x0271); + break; + case 0x2C6F: + bufpush(0x0250); + break; + case 0x2C70: + bufpush(0x0252); + break; + case 0x2C72: + bufpush(0x2C73); + break; + case 0x2C75: + bufpush(0x2C76); + break; + case 0x2C7E: + bufpush(0x023F); + break; + case 0x2C7F: + bufpush(0x0240); + break; + case 0x2C80: + bufpush(0x2C81); + break; + case 0x2C82: + bufpush(0x2C83); + break; + case 0x2C84: + bufpush(0x2C85); + break; + case 0x2C86: + bufpush(0x2C87); + break; + case 0x2C88: + bufpush(0x2C89); + break; + case 0x2C8A: + bufpush(0x2C8B); + break; + case 0x2C8C: + bufpush(0x2C8D); + break; + case 0x2C8E: + bufpush(0x2C8F); + break; + case 0x2C90: + bufpush(0x2C91); + break; + case 0x2C92: + bufpush(0x2C93); + break; + case 0x2C94: + bufpush(0x2C95); + break; + case 0x2C96: + bufpush(0x2C97); + break; + case 0x2C98: + bufpush(0x2C99); + break; + case 0x2C9A: + bufpush(0x2C9B); + break; + case 0x2C9C: + bufpush(0x2C9D); + break; + case 0x2C9E: + bufpush(0x2C9F); + break; + case 0x2CA0: + bufpush(0x2CA1); + break; + case 0x2CA2: + bufpush(0x2CA3); + break; + case 0x2CA4: + bufpush(0x2CA5); + break; + case 0x2CA6: + bufpush(0x2CA7); + break; + case 0x2CA8: + bufpush(0x2CA9); + break; + case 0x2CAA: + bufpush(0x2CAB); + break; + case 0x2CAC: + bufpush(0x2CAD); + break; + case 0x2CAE: + bufpush(0x2CAF); + break; + case 0x2CB0: + bufpush(0x2CB1); + break; + case 0x2CB2: + bufpush(0x2CB3); + break; + case 0x2CB4: + bufpush(0x2CB5); + break; + case 0x2CB6: + bufpush(0x2CB7); + break; + case 0x2CB8: + bufpush(0x2CB9); + break; + case 0x2CBA: + bufpush(0x2CBB); + break; + case 0x2CBC: + bufpush(0x2CBD); + break; + case 0x2CBE: + bufpush(0x2CBF); + break; + case 0x2CC0: + bufpush(0x2CC1); + break; + case 0x2CC2: + bufpush(0x2CC3); + break; + case 0x2CC4: + bufpush(0x2CC5); + break; + case 0x2CC6: + bufpush(0x2CC7); + break; + case 0x2CC8: + bufpush(0x2CC9); + break; + case 0x2CCA: + bufpush(0x2CCB); + break; + case 0x2CCC: + bufpush(0x2CCD); + break; + case 0x2CCE: + bufpush(0x2CCF); + break; + case 0x2CD0: + bufpush(0x2CD1); + break; + case 0x2CD2: + bufpush(0x2CD3); + break; + case 0x2CD4: + bufpush(0x2CD5); + break; + case 0x2CD6: + bufpush(0x2CD7); + break; + case 0x2CD8: + bufpush(0x2CD9); + break; + case 0x2CDA: + bufpush(0x2CDB); + break; + case 0x2CDC: + bufpush(0x2CDD); + break; + case 0x2CDE: + bufpush(0x2CDF); + break; + case 0x2CE0: + bufpush(0x2CE1); + break; + case 0x2CE2: + bufpush(0x2CE3); + break; + case 0x2CEB: + bufpush(0x2CEC); + break; + case 0x2CED: + bufpush(0x2CEE); + break; + case 0x2CF2: + bufpush(0x2CF3); + break; + case 0xA640: + bufpush(0xA641); + break; + case 0xA642: + bufpush(0xA643); + break; + case 0xA644: + bufpush(0xA645); + break; + case 0xA646: + bufpush(0xA647); + break; + case 0xA648: + bufpush(0xA649); + break; + case 0xA64A: + bufpush(0xA64B); + break; + case 0xA64C: + bufpush(0xA64D); + break; + case 0xA64E: + bufpush(0xA64F); + break; + case 0xA650: + bufpush(0xA651); + break; + case 0xA652: + bufpush(0xA653); + break; + case 0xA654: + bufpush(0xA655); + break; + case 0xA656: + bufpush(0xA657); + break; + case 0xA658: + bufpush(0xA659); + break; + case 0xA65A: + bufpush(0xA65B); + break; + case 0xA65C: + bufpush(0xA65D); + break; + case 0xA65E: + bufpush(0xA65F); + break; + case 0xA660: + bufpush(0xA661); + break; + case 0xA662: + bufpush(0xA663); + break; + case 0xA664: + bufpush(0xA665); + break; + case 0xA666: + bufpush(0xA667); + break; + case 0xA668: + bufpush(0xA669); + break; + case 0xA66A: + bufpush(0xA66B); + break; + case 0xA66C: + bufpush(0xA66D); + break; + case 0xA680: + bufpush(0xA681); + break; + case 0xA682: + bufpush(0xA683); + break; + case 0xA684: + bufpush(0xA685); + break; + case 0xA686: + bufpush(0xA687); + break; + case 0xA688: + bufpush(0xA689); + break; + case 0xA68A: + bufpush(0xA68B); + break; + case 0xA68C: + bufpush(0xA68D); + break; + case 0xA68E: + bufpush(0xA68F); + break; + case 0xA690: + bufpush(0xA691); + break; + case 0xA692: + bufpush(0xA693); + break; + case 0xA694: + bufpush(0xA695); + break; + case 0xA696: + bufpush(0xA697); + break; + case 0xA698: + bufpush(0xA699); + break; + case 0xA69A: + bufpush(0xA69B); + break; + case 0xA722: + bufpush(0xA723); + break; + case 0xA724: + bufpush(0xA725); + break; + case 0xA726: + bufpush(0xA727); + break; + case 0xA728: + bufpush(0xA729); + break; + case 0xA72A: + bufpush(0xA72B); + break; + case 0xA72C: + bufpush(0xA72D); + break; + case 0xA72E: + bufpush(0xA72F); + break; + case 0xA732: + bufpush(0xA733); + break; + case 0xA734: + bufpush(0xA735); + break; + case 0xA736: + bufpush(0xA737); + break; + case 0xA738: + bufpush(0xA739); + break; + case 0xA73A: + bufpush(0xA73B); + break; + case 0xA73C: + bufpush(0xA73D); + break; + case 0xA73E: + bufpush(0xA73F); + break; + case 0xA740: + bufpush(0xA741); + break; + case 0xA742: + bufpush(0xA743); + break; + case 0xA744: + bufpush(0xA745); + break; + case 0xA746: + bufpush(0xA747); + break; + case 0xA748: + bufpush(0xA749); + break; + case 0xA74A: + bufpush(0xA74B); + break; + case 0xA74C: + bufpush(0xA74D); + break; + case 0xA74E: + bufpush(0xA74F); + break; + case 0xA750: + bufpush(0xA751); + break; + case 0xA752: + bufpush(0xA753); + break; + case 0xA754: + bufpush(0xA755); + break; + case 0xA756: + bufpush(0xA757); + break; + case 0xA758: + bufpush(0xA759); + break; + case 0xA75A: + bufpush(0xA75B); + break; + case 0xA75C: + bufpush(0xA75D); + break; + case 0xA75E: + bufpush(0xA75F); + break; + case 0xA760: + bufpush(0xA761); + break; + case 0xA762: + bufpush(0xA763); + break; + case 0xA764: + bufpush(0xA765); + break; + case 0xA766: + bufpush(0xA767); + break; + case 0xA768: + bufpush(0xA769); + break; + case 0xA76A: + bufpush(0xA76B); + break; + case 0xA76C: + bufpush(0xA76D); + break; + case 0xA76E: + bufpush(0xA76F); + break; + case 0xA779: + bufpush(0xA77A); + break; + case 0xA77B: + bufpush(0xA77C); + break; + case 0xA77D: + bufpush(0x1D79); + break; + case 0xA77E: + bufpush(0xA77F); + break; + case 0xA780: + bufpush(0xA781); + break; + case 0xA782: + bufpush(0xA783); + break; + case 0xA784: + bufpush(0xA785); + break; + case 0xA786: + bufpush(0xA787); + break; + case 0xA78B: + bufpush(0xA78C); + break; + case 0xA78D: + bufpush(0x0265); + break; + case 0xA790: + bufpush(0xA791); + break; + case 0xA792: + bufpush(0xA793); + break; + case 0xA796: + bufpush(0xA797); + break; + case 0xA798: + bufpush(0xA799); + break; + case 0xA79A: + bufpush(0xA79B); + break; + case 0xA79C: + bufpush(0xA79D); + break; + case 0xA79E: + bufpush(0xA79F); + break; + case 0xA7A0: + bufpush(0xA7A1); + break; + case 0xA7A2: + bufpush(0xA7A3); + break; + case 0xA7A4: + bufpush(0xA7A5); + break; + case 0xA7A6: + bufpush(0xA7A7); + break; + case 0xA7A8: + bufpush(0xA7A9); + break; + case 0xA7AA: + bufpush(0x0266); + break; + case 0xA7AB: + bufpush(0x025C); + break; + case 0xA7AC: + bufpush(0x0261); + break; + case 0xA7AD: + bufpush(0x026C); + break; + case 0xA7AE: + bufpush(0x026A); + break; + case 0xA7B0: + bufpush(0x029E); + break; + case 0xA7B1: + bufpush(0x0287); + break; + case 0xA7B2: + bufpush(0x029D); + break; + case 0xA7B3: + bufpush(0xAB53); + break; + case 0xA7B4: + bufpush(0xA7B5); + break; + case 0xA7B6: + bufpush(0xA7B7); + break; + case 0xAB70: + bufpush(0x13A0); + break; + case 0xAB71: + bufpush(0x13A1); + break; + case 0xAB72: + bufpush(0x13A2); + break; + case 0xAB73: + bufpush(0x13A3); + break; + case 0xAB74: + bufpush(0x13A4); + break; + case 0xAB75: + bufpush(0x13A5); + break; + case 0xAB76: + bufpush(0x13A6); + break; + case 0xAB77: + bufpush(0x13A7); + break; + case 0xAB78: + bufpush(0x13A8); + break; + case 0xAB79: + bufpush(0x13A9); + break; + case 0xAB7A: + bufpush(0x13AA); + break; + case 0xAB7B: + bufpush(0x13AB); + break; + case 0xAB7C: + bufpush(0x13AC); + break; + case 0xAB7D: + bufpush(0x13AD); + break; + case 0xAB7E: + bufpush(0x13AE); + break; + case 0xAB7F: + bufpush(0x13AF); + break; + case 0xAB80: + bufpush(0x13B0); + break; + case 0xAB81: + bufpush(0x13B1); + break; + case 0xAB82: + bufpush(0x13B2); + break; + case 0xAB83: + bufpush(0x13B3); + break; + case 0xAB84: + bufpush(0x13B4); + break; + case 0xAB85: + bufpush(0x13B5); + break; + case 0xAB86: + bufpush(0x13B6); + break; + case 0xAB87: + bufpush(0x13B7); + break; + case 0xAB88: + bufpush(0x13B8); + break; + case 0xAB89: + bufpush(0x13B9); + break; + case 0xAB8A: + bufpush(0x13BA); + break; + case 0xAB8B: + bufpush(0x13BB); + break; + case 0xAB8C: + bufpush(0x13BC); + break; + case 0xAB8D: + bufpush(0x13BD); + break; + case 0xAB8E: + bufpush(0x13BE); + break; + case 0xAB8F: + bufpush(0x13BF); + break; + case 0xAB90: + bufpush(0x13C0); + break; + case 0xAB91: + bufpush(0x13C1); + break; + case 0xAB92: + bufpush(0x13C2); + break; + case 0xAB93: + bufpush(0x13C3); + break; + case 0xAB94: + bufpush(0x13C4); + break; + case 0xAB95: + bufpush(0x13C5); + break; + case 0xAB96: + bufpush(0x13C6); + break; + case 0xAB97: + bufpush(0x13C7); + break; + case 0xAB98: + bufpush(0x13C8); + break; + case 0xAB99: + bufpush(0x13C9); + break; + case 0xAB9A: + bufpush(0x13CA); + break; + case 0xAB9B: + bufpush(0x13CB); + break; + case 0xAB9C: + bufpush(0x13CC); + break; + case 0xAB9D: + bufpush(0x13CD); + break; + case 0xAB9E: + bufpush(0x13CE); + break; + case 0xAB9F: + bufpush(0x13CF); + break; + case 0xABA0: + bufpush(0x13D0); + break; + case 0xABA1: + bufpush(0x13D1); + break; + case 0xABA2: + bufpush(0x13D2); + break; + case 0xABA3: + bufpush(0x13D3); + break; + case 0xABA4: + bufpush(0x13D4); + break; + case 0xABA5: + bufpush(0x13D5); + break; + case 0xABA6: + bufpush(0x13D6); + break; + case 0xABA7: + bufpush(0x13D7); + break; + case 0xABA8: + bufpush(0x13D8); + break; + case 0xABA9: + bufpush(0x13D9); + break; + case 0xABAA: + bufpush(0x13DA); + break; + case 0xABAB: + bufpush(0x13DB); + break; + case 0xABAC: + bufpush(0x13DC); + break; + case 0xABAD: + bufpush(0x13DD); + break; + case 0xABAE: + bufpush(0x13DE); + break; + case 0xABAF: + bufpush(0x13DF); + break; + case 0xABB0: + bufpush(0x13E0); + break; + case 0xABB1: + bufpush(0x13E1); + break; + case 0xABB2: + bufpush(0x13E2); + break; + case 0xABB3: + bufpush(0x13E3); + break; + case 0xABB4: + bufpush(0x13E4); + break; + case 0xABB5: + bufpush(0x13E5); + break; + case 0xABB6: + bufpush(0x13E6); + break; + case 0xABB7: + bufpush(0x13E7); + break; + case 0xABB8: + bufpush(0x13E8); + break; + case 0xABB9: + bufpush(0x13E9); + break; + case 0xABBA: + bufpush(0x13EA); + break; + case 0xABBB: + bufpush(0x13EB); + break; + case 0xABBC: + bufpush(0x13EC); + break; + case 0xABBD: + bufpush(0x13ED); + break; + case 0xABBE: + bufpush(0x13EE); + break; + case 0xABBF: + bufpush(0x13EF); + break; + case 0xFB00: + bufpush(0x0066); + bufpush(0x0066); + break; + case 0xFB01: + bufpush(0x0066); + bufpush(0x0069); + break; + case 0xFB02: + bufpush(0x0066); + bufpush(0x006C); + break; + case 0xFB03: + bufpush(0x0066); + bufpush(0x0066); + bufpush(0x0069); + break; + case 0xFB04: + bufpush(0x0066); + bufpush(0x0066); + bufpush(0x006C); + break; + case 0xFB05: + bufpush(0x0073); + bufpush(0x0074); + break; + case 0xFB06: + bufpush(0x0073); + bufpush(0x0074); + break; + case 0xFB13: + bufpush(0x0574); + bufpush(0x0576); + break; + case 0xFB14: + bufpush(0x0574); + bufpush(0x0565); + break; + case 0xFB15: + bufpush(0x0574); + bufpush(0x056B); + break; + case 0xFB16: + bufpush(0x057E); + bufpush(0x0576); + break; + case 0xFB17: + bufpush(0x0574); + bufpush(0x056D); + break; + case 0xFF21: + bufpush(0xFF41); + break; + case 0xFF22: + bufpush(0xFF42); + break; + case 0xFF23: + bufpush(0xFF43); + break; + case 0xFF24: + bufpush(0xFF44); + break; + case 0xFF25: + bufpush(0xFF45); + break; + case 0xFF26: + bufpush(0xFF46); + break; + case 0xFF27: + bufpush(0xFF47); + break; + case 0xFF28: + bufpush(0xFF48); + break; + case 0xFF29: + bufpush(0xFF49); + break; + case 0xFF2A: + bufpush(0xFF4A); + break; + case 0xFF2B: + bufpush(0xFF4B); + break; + case 0xFF2C: + bufpush(0xFF4C); + break; + case 0xFF2D: + bufpush(0xFF4D); + break; + case 0xFF2E: + bufpush(0xFF4E); + break; + case 0xFF2F: + bufpush(0xFF4F); + break; + case 0xFF30: + bufpush(0xFF50); + break; + case 0xFF31: + bufpush(0xFF51); + break; + case 0xFF32: + bufpush(0xFF52); + break; + case 0xFF33: + bufpush(0xFF53); + break; + case 0xFF34: + bufpush(0xFF54); + break; + case 0xFF35: + bufpush(0xFF55); + break; + case 0xFF36: + bufpush(0xFF56); + break; + case 0xFF37: + bufpush(0xFF57); + break; + case 0xFF38: + bufpush(0xFF58); + break; + case 0xFF39: + bufpush(0xFF59); + break; + case 0xFF3A: + bufpush(0xFF5A); + break; + case 0x10400: + bufpush(0x10428); + break; + case 0x10401: + bufpush(0x10429); + break; + case 0x10402: + bufpush(0x1042A); + break; + case 0x10403: + bufpush(0x1042B); + break; + case 0x10404: + bufpush(0x1042C); + break; + case 0x10405: + bufpush(0x1042D); + break; + case 0x10406: + bufpush(0x1042E); + break; + case 0x10407: + bufpush(0x1042F); + break; + case 0x10408: + bufpush(0x10430); + break; + case 0x10409: + bufpush(0x10431); + break; + case 0x1040A: + bufpush(0x10432); + break; + case 0x1040B: + bufpush(0x10433); + break; + case 0x1040C: + bufpush(0x10434); + break; + case 0x1040D: + bufpush(0x10435); + break; + case 0x1040E: + bufpush(0x10436); + break; + case 0x1040F: + bufpush(0x10437); + break; + case 0x10410: + bufpush(0x10438); + break; + case 0x10411: + bufpush(0x10439); + break; + case 0x10412: + bufpush(0x1043A); + break; + case 0x10413: + bufpush(0x1043B); + break; + case 0x10414: + bufpush(0x1043C); + break; + case 0x10415: + bufpush(0x1043D); + break; + case 0x10416: + bufpush(0x1043E); + break; + case 0x10417: + bufpush(0x1043F); + break; + case 0x10418: + bufpush(0x10440); + break; + case 0x10419: + bufpush(0x10441); + break; + case 0x1041A: + bufpush(0x10442); + break; + case 0x1041B: + bufpush(0x10443); + break; + case 0x1041C: + bufpush(0x10444); + break; + case 0x1041D: + bufpush(0x10445); + break; + case 0x1041E: + bufpush(0x10446); + break; + case 0x1041F: + bufpush(0x10447); + break; + case 0x10420: + bufpush(0x10448); + break; + case 0x10421: + bufpush(0x10449); + break; + case 0x10422: + bufpush(0x1044A); + break; + case 0x10423: + bufpush(0x1044B); + break; + case 0x10424: + bufpush(0x1044C); + break; + case 0x10425: + bufpush(0x1044D); + break; + case 0x10426: + bufpush(0x1044E); + break; + case 0x10427: + bufpush(0x1044F); + break; + case 0x104B0: + bufpush(0x104D8); + break; + case 0x104B1: + bufpush(0x104D9); + break; + case 0x104B2: + bufpush(0x104DA); + break; + case 0x104B3: + bufpush(0x104DB); + break; + case 0x104B4: + bufpush(0x104DC); + break; + case 0x104B5: + bufpush(0x104DD); + break; + case 0x104B6: + bufpush(0x104DE); + break; + case 0x104B7: + bufpush(0x104DF); + break; + case 0x104B8: + bufpush(0x104E0); + break; + case 0x104B9: + bufpush(0x104E1); + break; + case 0x104BA: + bufpush(0x104E2); + break; + case 0x104BB: + bufpush(0x104E3); + break; + case 0x104BC: + bufpush(0x104E4); + break; + case 0x104BD: + bufpush(0x104E5); + break; + case 0x104BE: + bufpush(0x104E6); + break; + case 0x104BF: + bufpush(0x104E7); + break; + case 0x104C0: + bufpush(0x104E8); + break; + case 0x104C1: + bufpush(0x104E9); + break; + case 0x104C2: + bufpush(0x104EA); + break; + case 0x104C3: + bufpush(0x104EB); + break; + case 0x104C4: + bufpush(0x104EC); + break; + case 0x104C5: + bufpush(0x104ED); + break; + case 0x104C6: + bufpush(0x104EE); + break; + case 0x104C7: + bufpush(0x104EF); + break; + case 0x104C8: + bufpush(0x104F0); + break; + case 0x104C9: + bufpush(0x104F1); + break; + case 0x104CA: + bufpush(0x104F2); + break; + case 0x104CB: + bufpush(0x104F3); + break; + case 0x104CC: + bufpush(0x104F4); + break; + case 0x104CD: + bufpush(0x104F5); + break; + case 0x104CE: + bufpush(0x104F6); + break; + case 0x104CF: + bufpush(0x104F7); + break; + case 0x104D0: + bufpush(0x104F8); + break; + case 0x104D1: + bufpush(0x104F9); + break; + case 0x104D2: + bufpush(0x104FA); + break; + case 0x104D3: + bufpush(0x104FB); + break; + case 0x10C80: + bufpush(0x10CC0); + break; + case 0x10C81: + bufpush(0x10CC1); + break; + case 0x10C82: + bufpush(0x10CC2); + break; + case 0x10C83: + bufpush(0x10CC3); + break; + case 0x10C84: + bufpush(0x10CC4); + break; + case 0x10C85: + bufpush(0x10CC5); + break; + case 0x10C86: + bufpush(0x10CC6); + break; + case 0x10C87: + bufpush(0x10CC7); + break; + case 0x10C88: + bufpush(0x10CC8); + break; + case 0x10C89: + bufpush(0x10CC9); + break; + case 0x10C8A: + bufpush(0x10CCA); + break; + case 0x10C8B: + bufpush(0x10CCB); + break; + case 0x10C8C: + bufpush(0x10CCC); + break; + case 0x10C8D: + bufpush(0x10CCD); + break; + case 0x10C8E: + bufpush(0x10CCE); + break; + case 0x10C8F: + bufpush(0x10CCF); + break; + case 0x10C90: + bufpush(0x10CD0); + break; + case 0x10C91: + bufpush(0x10CD1); + break; + case 0x10C92: + bufpush(0x10CD2); + break; + case 0x10C93: + bufpush(0x10CD3); + break; + case 0x10C94: + bufpush(0x10CD4); + break; + case 0x10C95: + bufpush(0x10CD5); + break; + case 0x10C96: + bufpush(0x10CD6); + break; + case 0x10C97: + bufpush(0x10CD7); + break; + case 0x10C98: + bufpush(0x10CD8); + break; + case 0x10C99: + bufpush(0x10CD9); + break; + case 0x10C9A: + bufpush(0x10CDA); + break; + case 0x10C9B: + bufpush(0x10CDB); + break; + case 0x10C9C: + bufpush(0x10CDC); + break; + case 0x10C9D: + bufpush(0x10CDD); + break; + case 0x10C9E: + bufpush(0x10CDE); + break; + case 0x10C9F: + bufpush(0x10CDF); + break; + case 0x10CA0: + bufpush(0x10CE0); + break; + case 0x10CA1: + bufpush(0x10CE1); + break; + case 0x10CA2: + bufpush(0x10CE2); + break; + case 0x10CA3: + bufpush(0x10CE3); + break; + case 0x10CA4: + bufpush(0x10CE4); + break; + case 0x10CA5: + bufpush(0x10CE5); + break; + case 0x10CA6: + bufpush(0x10CE6); + break; + case 0x10CA7: + bufpush(0x10CE7); + break; + case 0x10CA8: + bufpush(0x10CE8); + break; + case 0x10CA9: + bufpush(0x10CE9); + break; + case 0x10CAA: + bufpush(0x10CEA); + break; + case 0x10CAB: + bufpush(0x10CEB); + break; + case 0x10CAC: + bufpush(0x10CEC); + break; + case 0x10CAD: + bufpush(0x10CED); + break; + case 0x10CAE: + bufpush(0x10CEE); + break; + case 0x10CAF: + bufpush(0x10CEF); + break; + case 0x10CB0: + bufpush(0x10CF0); + break; + case 0x10CB1: + bufpush(0x10CF1); + break; + case 0x10CB2: + bufpush(0x10CF2); + break; + case 0x118A0: + bufpush(0x118C0); + break; + case 0x118A1: + bufpush(0x118C1); + break; + case 0x118A2: + bufpush(0x118C2); + break; + case 0x118A3: + bufpush(0x118C3); + break; + case 0x118A4: + bufpush(0x118C4); + break; + case 0x118A5: + bufpush(0x118C5); + break; + case 0x118A6: + bufpush(0x118C6); + break; + case 0x118A7: + bufpush(0x118C7); + break; + case 0x118A8: + bufpush(0x118C8); + break; + case 0x118A9: + bufpush(0x118C9); + break; + case 0x118AA: + bufpush(0x118CA); + break; + case 0x118AB: + bufpush(0x118CB); + break; + case 0x118AC: + bufpush(0x118CC); + break; + case 0x118AD: + bufpush(0x118CD); + break; + case 0x118AE: + bufpush(0x118CE); + break; + case 0x118AF: + bufpush(0x118CF); + break; + case 0x118B0: + bufpush(0x118D0); + break; + case 0x118B1: + bufpush(0x118D1); + break; + case 0x118B2: + bufpush(0x118D2); + break; + case 0x118B3: + bufpush(0x118D3); + break; + case 0x118B4: + bufpush(0x118D4); + break; + case 0x118B5: + bufpush(0x118D5); + break; + case 0x118B6: + bufpush(0x118D6); + break; + case 0x118B7: + bufpush(0x118D7); + break; + case 0x118B8: + bufpush(0x118D8); + break; + case 0x118B9: + bufpush(0x118D9); + break; + case 0x118BA: + bufpush(0x118DA); + break; + case 0x118BB: + bufpush(0x118DB); + break; + case 0x118BC: + bufpush(0x118DC); + break; + case 0x118BD: + bufpush(0x118DD); + break; + case 0x118BE: + bufpush(0x118DE); + break; + case 0x118BF: + bufpush(0x118DF); + break; + case 0x1E900: + bufpush(0x1E922); + break; + case 0x1E901: + bufpush(0x1E923); + break; + case 0x1E902: + bufpush(0x1E924); + break; + case 0x1E903: + bufpush(0x1E925); + break; + case 0x1E904: + bufpush(0x1E926); + break; + case 0x1E905: + bufpush(0x1E927); + break; + case 0x1E906: + bufpush(0x1E928); + break; + case 0x1E907: + bufpush(0x1E929); + break; + case 0x1E908: + bufpush(0x1E92A); + break; + case 0x1E909: + bufpush(0x1E92B); + break; + case 0x1E90A: + bufpush(0x1E92C); + break; + case 0x1E90B: + bufpush(0x1E92D); + break; + case 0x1E90C: + bufpush(0x1E92E); + break; + case 0x1E90D: + bufpush(0x1E92F); + break; + case 0x1E90E: + bufpush(0x1E930); + break; + case 0x1E90F: + bufpush(0x1E931); + break; + case 0x1E910: + bufpush(0x1E932); + break; + case 0x1E911: + bufpush(0x1E933); + break; + case 0x1E912: + bufpush(0x1E934); + break; + case 0x1E913: + bufpush(0x1E935); + break; + case 0x1E914: + bufpush(0x1E936); + break; + case 0x1E915: + bufpush(0x1E937); + break; + case 0x1E916: + bufpush(0x1E938); + break; + case 0x1E917: + bufpush(0x1E939); + break; + case 0x1E918: + bufpush(0x1E93A); + break; + case 0x1E919: + bufpush(0x1E93B); + break; + case 0x1E91A: + bufpush(0x1E93C); + break; + case 0x1E91B: + bufpush(0x1E93D); + break; + case 0x1E91C: + bufpush(0x1E93E); + break; + case 0x1E91D: + bufpush(0x1E93F); + break; + case 0x1E91E: + bufpush(0x1E940); + break; + case 0x1E91F: + bufpush(0x1E941); + break; + case 0x1E920: + bufpush(0x1E942); + break; + case 0x1E921: + bufpush(0x1E943); + break; + default: + bufpush(c); + } diff --git a/Sources/libcmark_gfm/cmark.c b/Sources/libcmark_gfm/cmark.c new file mode 100644 index 0000000..f6b4cdf --- /dev/null +++ b/Sources/libcmark_gfm/cmark.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include "registry.h" +#include "node.h" +#include "houdini.h" +#include "cmark.h" +#include "buffer.h" + +cmark_node_type CMARK_NODE_LAST_BLOCK = CMARK_NODE_FOOTNOTE_DEFINITION; +cmark_node_type CMARK_NODE_LAST_INLINE = CMARK_NODE_FOOTNOTE_REFERENCE; + +int cmark_version() { return CMARK_VERSION; } + +const char *cmark_version_string() { return CMARK_VERSION_STRING; } + +static void *xcalloc(size_t nmem, size_t size) { + void *ptr = calloc(nmem, size); + if (!ptr) { + fprintf(stderr, "[cmark] calloc returned null pointer, aborting\n"); + abort(); + } + return ptr; +} + +static void *xrealloc(void *ptr, size_t size) { + void *new_ptr = realloc(ptr, size); + if (!new_ptr) { + fprintf(stderr, "[cmark] realloc returned null pointer, aborting\n"); + abort(); + } + return new_ptr; +} + +static void xfree(void *ptr) { + free(ptr); +} + +cmark_mem CMARK_DEFAULT_MEM_ALLOCATOR = {xcalloc, xrealloc, xfree}; + +cmark_mem *cmark_get_default_mem_allocator() { + return &CMARK_DEFAULT_MEM_ALLOCATOR; +} + +char *cmark_markdown_to_html(const char *text, size_t len, int options) { + cmark_node *doc; + char *result; + + doc = cmark_parse_document(text, len, options); + + result = cmark_render_html(doc, options, NULL); + cmark_node_free(doc); + + return result; +} diff --git a/Sources/libcmark_gfm/cmark_ctype.c b/Sources/libcmark_gfm/cmark_ctype.c new file mode 100644 index 0000000..c0c4d5b --- /dev/null +++ b/Sources/libcmark_gfm/cmark_ctype.c @@ -0,0 +1,44 @@ +#include + +#include "cmark_ctype.h" + +/** 1 = space, 2 = punct, 3 = digit, 4 = alpha, 0 = other + */ +static const uint8_t cmark_ctype_class[256] = { + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, + /* 1 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 2 */ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + /* 3 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, + /* 4 */ 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + /* 5 */ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, + /* 6 */ 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + /* 7 */ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 9 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* a */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* b */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* c */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* d */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* e */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +/** + * Returns 1 if c is a "whitespace" character as defined by the spec. + */ +int cmark_isspace(char c) { return cmark_ctype_class[(uint8_t)c] == 1; } + +/** + * Returns 1 if c is an ascii punctuation character. + */ +int cmark_ispunct(char c) { return cmark_ctype_class[(uint8_t)c] == 2; } + +int cmark_isalnum(char c) { + uint8_t result; + result = cmark_ctype_class[(uint8_t)c]; + return (result == 3 || result == 4); +} + +int cmark_isdigit(char c) { return cmark_ctype_class[(uint8_t)c] == 3; } + +int cmark_isalpha(char c) { return cmark_ctype_class[(uint8_t)c] == 4; } diff --git a/Sources/libcmark_gfm/commonmark.c b/Sources/libcmark_gfm/commonmark.c new file mode 100644 index 0000000..c0ba7ae --- /dev/null +++ b/Sources/libcmark_gfm/commonmark.c @@ -0,0 +1,508 @@ +#include +#include +#include +#include +#include + +#include "config.h" +#include "cmark.h" +#include "node.h" +#include "buffer.h" +#include "utf8.h" +#include "scanners.h" +#include "render.h" +#include "syntax_extension.h" + +#define OUT(s, wrap, escaping) renderer->out(renderer, node, s, wrap, escaping) +#define LIT(s) renderer->out(renderer, node, s, false, LITERAL) +#define CR() renderer->cr(renderer) +#define BLANKLINE() renderer->blankline(renderer) +#define ENCODED_SIZE 20 +#define LISTMARKER_SIZE 20 + +// Functions to convert cmark_nodes to commonmark strings. + +static CMARK_INLINE void outc(cmark_renderer *renderer, cmark_node *node, + cmark_escaping escape, + int32_t c, unsigned char nextc) { + bool needs_escaping = false; + bool follows_digit = + renderer->buffer->size > 0 && + cmark_isdigit(renderer->buffer->ptr[renderer->buffer->size - 1]); + char encoded[ENCODED_SIZE]; + + needs_escaping = + c < 0x80 && escape != LITERAL && + ((escape == NORMAL && + (c == '*' || c == '_' || c == '[' || c == ']' || c == '#' || c == '<' || + c == '>' || c == '\\' || c == '`' || c == '!' || + (c == '&' && cmark_isalpha(nextc)) || (c == '!' && nextc == '[') || + (renderer->begin_content && (c == '-' || c == '+' || c == '=') && + // begin_content doesn't get set to false til we've passed digits + // at the beginning of line, so... + !follows_digit) || + (renderer->begin_content && (c == '.' || c == ')') && follows_digit && + (nextc == 0 || cmark_isspace(nextc))))) || + (escape == URL && + (c == '`' || c == '<' || c == '>' || cmark_isspace((char)c) || c == '\\' || + c == ')' || c == '(')) || + (escape == TITLE && + (c == '`' || c == '<' || c == '>' || c == '"' || c == '\\'))); + + if (needs_escaping) { + if (cmark_isspace((char)c)) { + // use percent encoding for spaces + snprintf(encoded, ENCODED_SIZE, "%%%2x", c); + cmark_strbuf_puts(renderer->buffer, encoded); + renderer->column += 3; + } else { + cmark_render_ascii(renderer, "\\"); + cmark_render_code_point(renderer, c); + } + } else { + cmark_render_code_point(renderer, c); + } +} + +static int longest_backtick_sequence(const char *code) { + int longest = 0; + int current = 0; + size_t i = 0; + size_t code_len = strlen(code); + while (i <= code_len) { + if (code[i] == '`') { + current++; + } else { + if (current > longest) { + longest = current; + } + current = 0; + } + i++; + } + return longest; +} + +static int shortest_unused_backtick_sequence(const char *code) { + // note: if the shortest sequence is >= 32, this returns 32 + // so as not to overflow the bit array. + uint32_t used = 1; + int current = 0; + size_t i = 0; + size_t code_len = strlen(code); + while (i <= code_len) { + if (code[i] == '`') { + current++; + } else { + if (current > 0 && current < 32) { + used |= (1U << current); + } + current = 0; + } + i++; + } + // return number of first bit that is 0: + i = 0; + while (i < 32 && used & 1) { + used = used >> 1; + i++; + } + return (int)i; +} + +static bool is_autolink(cmark_node *node) { + cmark_chunk *title; + cmark_chunk *url; + cmark_node *link_text; + char *realurl; + int realurllen; + + if (node->type != CMARK_NODE_LINK) { + return false; + } + + url = &node->as.link.url; + if (url->len == 0 || scan_scheme(url, 0) == 0) { + return false; + } + + title = &node->as.link.title; + // if it has a title, we can't treat it as an autolink: + if (title->len > 0) { + return false; + } + + link_text = node->first_child; + if (link_text == NULL) { + return false; + } + cmark_consolidate_text_nodes(link_text); + realurl = (char *)url->data; + realurllen = url->len; + if (strncmp(realurl, "mailto:", 7) == 0) { + realurl += 7; + realurllen -= 7; + } + return (realurllen == link_text->as.literal.len && + strncmp(realurl, (char *)link_text->as.literal.data, + link_text->as.literal.len) == 0); +} + +// if node is a block node, returns node. +// otherwise returns first block-level node that is an ancestor of node. +// if there is no block-level ancestor, returns NULL. +static cmark_node *get_containing_block(cmark_node *node) { + while (node) { + if (CMARK_NODE_BLOCK_P(node)) { + return node; + } else { + node = node->parent; + } + } + return NULL; +} + +static int S_render_node(cmark_renderer *renderer, cmark_node *node, + cmark_event_type ev_type, int options) { + cmark_node *tmp; + int list_number; + cmark_delim_type list_delim; + int numticks; + int i; + bool entering = (ev_type == CMARK_EVENT_ENTER); + const char *info, *code, *title; + size_t info_len, code_len; + char listmarker[LISTMARKER_SIZE]; + char *emph_delim; + bool first_in_list_item; + bufsize_t marker_width; + bool allow_wrap = renderer->width > 0 && !(CMARK_OPT_NOBREAKS & options) && + !(CMARK_OPT_HARDBREAKS & options); + + // Don't adjust tight list status til we've started the list. + // Otherwise we loose the blank line between a paragraph and + // a following list. + if (!(node->type == CMARK_NODE_ITEM && node->prev == NULL && entering)) { + tmp = get_containing_block(node); + renderer->in_tight_list_item = + tmp && // tmp might be NULL if there is no containing block + ((tmp->type == CMARK_NODE_ITEM && + cmark_node_get_list_tight(tmp->parent)) || + (tmp && tmp->parent && tmp->parent->type == CMARK_NODE_ITEM && + cmark_node_get_list_tight(tmp->parent->parent))); + } + + if (node->extension && node->extension->commonmark_render_func) { + node->extension->commonmark_render_func(node->extension, renderer, node, ev_type, options); + return 1; + } + + switch (node->type) { + case CMARK_NODE_DOCUMENT: + break; + + case CMARK_NODE_BLOCK_QUOTE: + if (entering) { + LIT("> "); + renderer->begin_content = true; + cmark_strbuf_puts(renderer->prefix, "> "); + } else { + cmark_strbuf_truncate(renderer->prefix, renderer->prefix->size - 2); + BLANKLINE(); + } + break; + + case CMARK_NODE_LIST: + if (!entering && node->next && (node->next->type == CMARK_NODE_CODE_BLOCK || + node->next->type == CMARK_NODE_LIST)) { + // this ensures that a following indented code block or list will be + // inteprereted correctly. + CR(); + LIT(""); + BLANKLINE(); + } + break; + + case CMARK_NODE_ITEM: + if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) { + marker_width = 4; + } else { + list_number = cmark_node_get_list_start(node->parent); + list_delim = cmark_node_get_list_delim(node->parent); + tmp = node; + while (tmp->prev) { + tmp = tmp->prev; + list_number += 1; + } + // we ensure a width of at least 4 so + // we get nice transition from single digits + // to double + snprintf(listmarker, LISTMARKER_SIZE, "%d%s%s", list_number, + list_delim == CMARK_PAREN_DELIM ? ")" : ".", + list_number < 10 ? " " : " "); + marker_width = (bufsize_t)strlen(listmarker); + } + if (entering) { + if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) { + LIT(" - "); + renderer->begin_content = true; + } else { + LIT(listmarker); + renderer->begin_content = true; + } + for (i = marker_width; i--;) { + cmark_strbuf_putc(renderer->prefix, ' '); + } + } else { + cmark_strbuf_truncate(renderer->prefix, + renderer->prefix->size - marker_width); + CR(); + } + break; + + case CMARK_NODE_HEADING: + if (entering) { + for (i = cmark_node_get_heading_level(node); i > 0; i--) { + LIT("#"); + } + LIT(" "); + renderer->begin_content = true; + renderer->no_linebreaks = true; + } else { + renderer->no_linebreaks = false; + BLANKLINE(); + } + break; + + case CMARK_NODE_CODE_BLOCK: + first_in_list_item = node->prev == NULL && node->parent && + node->parent->type == CMARK_NODE_ITEM; + + if (!first_in_list_item) { + BLANKLINE(); + } + info = cmark_node_get_fence_info(node); + info_len = strlen(info); + code = cmark_node_get_literal(node); + code_len = strlen(code); + // use indented form if no info, and code doesn't + // begin or end with a blank line, and code isn't + // first thing in a list item + if (info_len == 0 && (code_len > 2 && !cmark_isspace(code[0]) && + !(cmark_isspace(code[code_len - 1]) && + cmark_isspace(code[code_len - 2]))) && + !first_in_list_item) { + LIT(" "); + cmark_strbuf_puts(renderer->prefix, " "); + OUT(cmark_node_get_literal(node), false, LITERAL); + cmark_strbuf_truncate(renderer->prefix, renderer->prefix->size - 4); + } else { + numticks = longest_backtick_sequence(code) + 1; + if (numticks < 3) { + numticks = 3; + } + for (i = 0; i < numticks; i++) { + LIT("`"); + } + LIT(" "); + OUT(info, false, LITERAL); + CR(); + OUT(cmark_node_get_literal(node), false, LITERAL); + CR(); + for (i = 0; i < numticks; i++) { + LIT("`"); + } + } + BLANKLINE(); + break; + + case CMARK_NODE_HTML_BLOCK: + BLANKLINE(); + OUT(cmark_node_get_literal(node), false, LITERAL); + BLANKLINE(); + break; + + case CMARK_NODE_CUSTOM_BLOCK: + BLANKLINE(); + OUT(entering ? cmark_node_get_on_enter(node) : cmark_node_get_on_exit(node), + false, LITERAL); + BLANKLINE(); + break; + + case CMARK_NODE_THEMATIC_BREAK: + BLANKLINE(); + LIT("-----"); + BLANKLINE(); + break; + + case CMARK_NODE_PARAGRAPH: + if (!entering) { + BLANKLINE(); + } + break; + + case CMARK_NODE_TEXT: + OUT(cmark_node_get_literal(node), allow_wrap, NORMAL); + break; + + case CMARK_NODE_LINEBREAK: + if (!(CMARK_OPT_HARDBREAKS & options)) { + LIT(" "); + } + CR(); + break; + + case CMARK_NODE_SOFTBREAK: + if (CMARK_OPT_HARDBREAKS & options) { + LIT(" "); + CR(); + } else if (!renderer->no_linebreaks && renderer->width == 0 && + !(CMARK_OPT_HARDBREAKS & options) && + !(CMARK_OPT_NOBREAKS & options)) { + CR(); + } else { + OUT(" ", allow_wrap, LITERAL); + } + break; + + case CMARK_NODE_CODE: + code = cmark_node_get_literal(node); + code_len = strlen(code); + numticks = shortest_unused_backtick_sequence(code); + for (i = 0; i < numticks; i++) { + LIT("`"); + } + if (code_len == 0 || code[0] == '`') { + LIT(" "); + } + OUT(cmark_node_get_literal(node), allow_wrap, LITERAL); + if (code_len == 0 || code[code_len - 1] == '`') { + LIT(" "); + } + for (i = 0; i < numticks; i++) { + LIT("`"); + } + break; + + case CMARK_NODE_HTML_INLINE: + OUT(cmark_node_get_literal(node), false, LITERAL); + break; + + case CMARK_NODE_CUSTOM_INLINE: + OUT(entering ? cmark_node_get_on_enter(node) : cmark_node_get_on_exit(node), + false, LITERAL); + break; + + case CMARK_NODE_STRONG: + if (entering) { + LIT("**"); + } else { + LIT("**"); + } + break; + + case CMARK_NODE_EMPH: + // If we have EMPH(EMPH(x)), we need to use *_x_* + // because **x** is STRONG(x): + if (node->parent && node->parent->type == CMARK_NODE_EMPH && + node->next == NULL && node->prev == NULL) { + emph_delim = "_"; + } else { + emph_delim = "*"; + } + if (entering) { + LIT(emph_delim); + } else { + LIT(emph_delim); + } + break; + + case CMARK_NODE_LINK: + if (is_autolink(node)) { + if (entering) { + LIT("<"); + if (strncmp(cmark_node_get_url(node), "mailto:", 7) == 0) { + LIT((const char *)cmark_node_get_url(node) + 7); + } else { + LIT((const char *)cmark_node_get_url(node)); + } + LIT(">"); + // return signal to skip contents of node... + return 0; + } + } else { + if (entering) { + LIT("["); + } else { + LIT("]("); + OUT(cmark_node_get_url(node), false, URL); + title = cmark_node_get_title(node); + if (strlen(title) > 0) { + LIT(" \""); + OUT(title, false, TITLE); + LIT("\""); + } + LIT(")"); + } + } + break; + + case CMARK_NODE_IMAGE: + if (entering) { + LIT("!["); + } else { + LIT("]("); + OUT(cmark_node_get_url(node), false, URL); + title = cmark_node_get_title(node); + if (strlen(title) > 0) { + OUT(" \"", allow_wrap, LITERAL); + OUT(title, false, TITLE); + LIT("\""); + } + LIT(")"); + } + break; + + case CMARK_NODE_FOOTNOTE_REFERENCE: + if (entering) { + LIT("[^"); + OUT(cmark_chunk_to_cstr(renderer->mem, &node->as.literal), false, LITERAL); + LIT("]"); + } + break; + + case CMARK_NODE_FOOTNOTE_DEFINITION: + if (entering) { + renderer->footnote_ix += 1; + LIT("[^"); + char n[32]; + snprintf(n, sizeof(n), "%d", renderer->footnote_ix); + OUT(n, false, LITERAL); + LIT("]:\n"); + + cmark_strbuf_puts(renderer->prefix, " "); + } else { + cmark_strbuf_truncate(renderer->prefix, renderer->prefix->size - 4); + } + break; + + default: + assert(false); + break; + } + + return 1; +} + +char *cmark_render_commonmark(cmark_node *root, int options, int width) { + return cmark_render_commonmark_with_mem(root, options, width, cmark_node_mem(root)); +} + +char *cmark_render_commonmark_with_mem(cmark_node *root, int options, int width, cmark_mem *mem) { + if (options & CMARK_OPT_HARDBREAKS) { + // disable breaking on width, since it has + // a different meaning with OPT_HARDBREAKS + width = 0; + } + return cmark_render(mem, root, options, width, outc, S_render_node); +} diff --git a/Sources/libcmark_gfm/core-extensions.c b/Sources/libcmark_gfm/core-extensions.c new file mode 100644 index 0000000..4659ab1 --- /dev/null +++ b/Sources/libcmark_gfm/core-extensions.c @@ -0,0 +1,25 @@ +#include "core-extensions.h" +#include "autolink.h" +#include "strikethrough.h" +#include "table.h" +#include "tagfilter.h" +#include "registry.h" +#include "plugin.h" + +static int core_extensions_registration(cmark_plugin *plugin) { + cmark_plugin_register_syntax_extension(plugin, create_table_extension()); + cmark_plugin_register_syntax_extension(plugin, + create_strikethrough_extension()); + cmark_plugin_register_syntax_extension(plugin, create_autolink_extension()); + cmark_plugin_register_syntax_extension(plugin, create_tagfilter_extension()); + return 1; +} + +void core_extensions_ensure_registered(void) { + static int registered = 0; + + if (!registered) { + cmark_register_plugin(core_extensions_registration); + registered = 1; + } +} diff --git a/Sources/libcmark_gfm/entities.inc b/Sources/libcmark_gfm/entities.inc new file mode 100755 index 0000000..ec3d2a9 --- /dev/null +++ b/Sources/libcmark_gfm/entities.inc @@ -0,0 +1,2138 @@ +/* Autogenerated by tools/make_headers_inc.py */ + +struct cmark_entity_node { + unsigned char *entity; + unsigned char bytes[8]; +}; + +#define CMARK_ENTITY_MIN_LENGTH 2 +#define CMARK_ENTITY_MAX_LENGTH 31 +#define CMARK_NUM_ENTITIES 2125 + +static const struct cmark_entity_node cmark_entities[] = { +{(unsigned char*)"AElig", {195, 134, 0}}, +{(unsigned char*)"AMP", {38, 0}}, +{(unsigned char*)"Aacute", {195, 129, 0}}, +{(unsigned char*)"Abreve", {196, 130, 0}}, +{(unsigned char*)"Acirc", {195, 130, 0}}, +{(unsigned char*)"Acy", {208, 144, 0}}, +{(unsigned char*)"Afr", {240, 157, 148, 132, 0}}, +{(unsigned char*)"Agrave", {195, 128, 0}}, +{(unsigned char*)"Alpha", {206, 145, 0}}, +{(unsigned char*)"Amacr", {196, 128, 0}}, +{(unsigned char*)"And", {226, 169, 147, 0}}, +{(unsigned char*)"Aogon", {196, 132, 0}}, +{(unsigned char*)"Aopf", {240, 157, 148, 184, 0}}, +{(unsigned char*)"ApplyFunction", {226, 129, 161, 0}}, +{(unsigned char*)"Aring", {195, 133, 0}}, +{(unsigned char*)"Ascr", {240, 157, 146, 156, 0}}, +{(unsigned char*)"Assign", {226, 137, 148, 0}}, +{(unsigned char*)"Atilde", {195, 131, 0}}, +{(unsigned char*)"Auml", {195, 132, 0}}, +{(unsigned char*)"Backslash", {226, 136, 150, 0}}, +{(unsigned char*)"Barv", {226, 171, 167, 0}}, +{(unsigned char*)"Barwed", {226, 140, 134, 0}}, +{(unsigned char*)"Bcy", {208, 145, 0}}, +{(unsigned char*)"Because", {226, 136, 181, 0}}, +{(unsigned char*)"Bernoullis", {226, 132, 172, 0}}, +{(unsigned char*)"Beta", {206, 146, 0}}, +{(unsigned char*)"Bfr", {240, 157, 148, 133, 0}}, +{(unsigned char*)"Bopf", {240, 157, 148, 185, 0}}, +{(unsigned char*)"Breve", {203, 152, 0}}, +{(unsigned char*)"Bscr", {226, 132, 172, 0}}, +{(unsigned char*)"Bumpeq", {226, 137, 142, 0}}, +{(unsigned char*)"CHcy", {208, 167, 0}}, +{(unsigned char*)"COPY", {194, 169, 0}}, +{(unsigned char*)"Cacute", {196, 134, 0}}, +{(unsigned char*)"Cap", {226, 139, 146, 0}}, +{(unsigned char*)"CapitalDifferentialD", {226, 133, 133, 0}}, +{(unsigned char*)"Cayleys", {226, 132, 173, 0}}, +{(unsigned char*)"Ccaron", {196, 140, 0}}, +{(unsigned char*)"Ccedil", {195, 135, 0}}, +{(unsigned char*)"Ccirc", {196, 136, 0}}, +{(unsigned char*)"Cconint", {226, 136, 176, 0}}, +{(unsigned char*)"Cdot", {196, 138, 0}}, +{(unsigned char*)"Cedilla", {194, 184, 0}}, +{(unsigned char*)"CenterDot", {194, 183, 0}}, +{(unsigned char*)"Cfr", {226, 132, 173, 0}}, +{(unsigned char*)"Chi", {206, 167, 0}}, +{(unsigned char*)"CircleDot", {226, 138, 153, 0}}, +{(unsigned char*)"CircleMinus", {226, 138, 150, 0}}, +{(unsigned char*)"CirclePlus", {226, 138, 149, 0}}, +{(unsigned char*)"CircleTimes", {226, 138, 151, 0}}, +{(unsigned char*)"ClockwiseContourIntegral", {226, 136, 178, 0}}, +{(unsigned char*)"CloseCurlyDoubleQuote", {226, 128, 157, 0}}, +{(unsigned char*)"CloseCurlyQuote", {226, 128, 153, 0}}, +{(unsigned char*)"Colon", {226, 136, 183, 0}}, +{(unsigned char*)"Colone", {226, 169, 180, 0}}, +{(unsigned char*)"Congruent", {226, 137, 161, 0}}, +{(unsigned char*)"Conint", {226, 136, 175, 0}}, +{(unsigned char*)"ContourIntegral", {226, 136, 174, 0}}, +{(unsigned char*)"Copf", {226, 132, 130, 0}}, +{(unsigned char*)"Coproduct", {226, 136, 144, 0}}, +{(unsigned char*)"CounterClockwiseContourIntegral", {226, 136, 179, 0}}, +{(unsigned char*)"Cross", {226, 168, 175, 0}}, +{(unsigned char*)"Cscr", {240, 157, 146, 158, 0}}, +{(unsigned char*)"Cup", {226, 139, 147, 0}}, +{(unsigned char*)"CupCap", {226, 137, 141, 0}}, +{(unsigned char*)"DD", {226, 133, 133, 0}}, +{(unsigned char*)"DDotrahd", {226, 164, 145, 0}}, +{(unsigned char*)"DJcy", {208, 130, 0}}, +{(unsigned char*)"DScy", {208, 133, 0}}, +{(unsigned char*)"DZcy", {208, 143, 0}}, +{(unsigned char*)"Dagger", {226, 128, 161, 0}}, +{(unsigned char*)"Darr", {226, 134, 161, 0}}, +{(unsigned char*)"Dashv", {226, 171, 164, 0}}, +{(unsigned char*)"Dcaron", {196, 142, 0}}, +{(unsigned char*)"Dcy", {208, 148, 0}}, +{(unsigned char*)"Del", {226, 136, 135, 0}}, +{(unsigned char*)"Delta", {206, 148, 0}}, +{(unsigned char*)"Dfr", {240, 157, 148, 135, 0}}, +{(unsigned char*)"DiacriticalAcute", {194, 180, 0}}, +{(unsigned char*)"DiacriticalDot", {203, 153, 0}}, +{(unsigned char*)"DiacriticalDoubleAcute", {203, 157, 0}}, +{(unsigned char*)"DiacriticalGrave", {96, 0}}, +{(unsigned char*)"DiacriticalTilde", {203, 156, 0}}, +{(unsigned char*)"Diamond", {226, 139, 132, 0}}, +{(unsigned char*)"DifferentialD", {226, 133, 134, 0}}, +{(unsigned char*)"Dopf", {240, 157, 148, 187, 0}}, +{(unsigned char*)"Dot", {194, 168, 0}}, +{(unsigned char*)"DotDot", {226, 131, 156, 0}}, +{(unsigned char*)"DotEqual", {226, 137, 144, 0}}, +{(unsigned char*)"DoubleContourIntegral", {226, 136, 175, 0}}, +{(unsigned char*)"DoubleDot", {194, 168, 0}}, +{(unsigned char*)"DoubleDownArrow", {226, 135, 147, 0}}, +{(unsigned char*)"DoubleLeftArrow", {226, 135, 144, 0}}, +{(unsigned char*)"DoubleLeftRightArrow", {226, 135, 148, 0}}, +{(unsigned char*)"DoubleLeftTee", {226, 171, 164, 0}}, +{(unsigned char*)"DoubleLongLeftArrow", {226, 159, 184, 0}}, +{(unsigned char*)"DoubleLongLeftRightArrow", {226, 159, 186, 0}}, +{(unsigned char*)"DoubleLongRightArrow", {226, 159, 185, 0}}, +{(unsigned char*)"DoubleRightArrow", {226, 135, 146, 0}}, +{(unsigned char*)"DoubleRightTee", {226, 138, 168, 0}}, +{(unsigned char*)"DoubleUpArrow", {226, 135, 145, 0}}, +{(unsigned char*)"DoubleUpDownArrow", {226, 135, 149, 0}}, +{(unsigned char*)"DoubleVerticalBar", {226, 136, 165, 0}}, +{(unsigned char*)"DownArrow", {226, 134, 147, 0}}, +{(unsigned char*)"DownArrowBar", {226, 164, 147, 0}}, +{(unsigned char*)"DownArrowUpArrow", {226, 135, 181, 0}}, +{(unsigned char*)"DownBreve", {204, 145, 0}}, +{(unsigned char*)"DownLeftRightVector", {226, 165, 144, 0}}, +{(unsigned char*)"DownLeftTeeVector", {226, 165, 158, 0}}, +{(unsigned char*)"DownLeftVector", {226, 134, 189, 0}}, +{(unsigned char*)"DownLeftVectorBar", {226, 165, 150, 0}}, +{(unsigned char*)"DownRightTeeVector", {226, 165, 159, 0}}, +{(unsigned char*)"DownRightVector", {226, 135, 129, 0}}, +{(unsigned char*)"DownRightVectorBar", {226, 165, 151, 0}}, +{(unsigned char*)"DownTee", {226, 138, 164, 0}}, +{(unsigned char*)"DownTeeArrow", {226, 134, 167, 0}}, +{(unsigned char*)"Downarrow", {226, 135, 147, 0}}, +{(unsigned char*)"Dscr", {240, 157, 146, 159, 0}}, +{(unsigned char*)"Dstrok", {196, 144, 0}}, +{(unsigned char*)"ENG", {197, 138, 0}}, +{(unsigned char*)"ETH", {195, 144, 0}}, +{(unsigned char*)"Eacute", {195, 137, 0}}, +{(unsigned char*)"Ecaron", {196, 154, 0}}, +{(unsigned char*)"Ecirc", {195, 138, 0}}, +{(unsigned char*)"Ecy", {208, 173, 0}}, +{(unsigned char*)"Edot", {196, 150, 0}}, +{(unsigned char*)"Efr", {240, 157, 148, 136, 0}}, +{(unsigned char*)"Egrave", {195, 136, 0}}, +{(unsigned char*)"Element", {226, 136, 136, 0}}, +{(unsigned char*)"Emacr", {196, 146, 0}}, +{(unsigned char*)"EmptySmallSquare", {226, 151, 187, 0}}, +{(unsigned char*)"EmptyVerySmallSquare", {226, 150, 171, 0}}, +{(unsigned char*)"Eogon", {196, 152, 0}}, +{(unsigned char*)"Eopf", {240, 157, 148, 188, 0}}, +{(unsigned char*)"Epsilon", {206, 149, 0}}, +{(unsigned char*)"Equal", {226, 169, 181, 0}}, +{(unsigned char*)"EqualTilde", {226, 137, 130, 0}}, +{(unsigned char*)"Equilibrium", {226, 135, 140, 0}}, +{(unsigned char*)"Escr", {226, 132, 176, 0}}, +{(unsigned char*)"Esim", {226, 169, 179, 0}}, +{(unsigned char*)"Eta", {206, 151, 0}}, +{(unsigned char*)"Euml", {195, 139, 0}}, +{(unsigned char*)"Exists", {226, 136, 131, 0}}, +{(unsigned char*)"ExponentialE", {226, 133, 135, 0}}, +{(unsigned char*)"Fcy", {208, 164, 0}}, +{(unsigned char*)"Ffr", {240, 157, 148, 137, 0}}, +{(unsigned char*)"FilledSmallSquare", {226, 151, 188, 0}}, +{(unsigned char*)"FilledVerySmallSquare", {226, 150, 170, 0}}, +{(unsigned char*)"Fopf", {240, 157, 148, 189, 0}}, +{(unsigned char*)"ForAll", {226, 136, 128, 0}}, +{(unsigned char*)"Fouriertrf", {226, 132, 177, 0}}, +{(unsigned char*)"Fscr", {226, 132, 177, 0}}, +{(unsigned char*)"GJcy", {208, 131, 0}}, +{(unsigned char*)"GT", {62, 0}}, +{(unsigned char*)"Gamma", {206, 147, 0}}, +{(unsigned char*)"Gammad", {207, 156, 0}}, +{(unsigned char*)"Gbreve", {196, 158, 0}}, +{(unsigned char*)"Gcedil", {196, 162, 0}}, +{(unsigned char*)"Gcirc", {196, 156, 0}}, +{(unsigned char*)"Gcy", {208, 147, 0}}, +{(unsigned char*)"Gdot", {196, 160, 0}}, +{(unsigned char*)"Gfr", {240, 157, 148, 138, 0}}, +{(unsigned char*)"Gg", {226, 139, 153, 0}}, +{(unsigned char*)"Gopf", {240, 157, 148, 190, 0}}, +{(unsigned char*)"GreaterEqual", {226, 137, 165, 0}}, +{(unsigned char*)"GreaterEqualLess", {226, 139, 155, 0}}, +{(unsigned char*)"GreaterFullEqual", {226, 137, 167, 0}}, +{(unsigned char*)"GreaterGreater", {226, 170, 162, 0}}, +{(unsigned char*)"GreaterLess", {226, 137, 183, 0}}, +{(unsigned char*)"GreaterSlantEqual", {226, 169, 190, 0}}, +{(unsigned char*)"GreaterTilde", {226, 137, 179, 0}}, +{(unsigned char*)"Gscr", {240, 157, 146, 162, 0}}, +{(unsigned char*)"Gt", {226, 137, 171, 0}}, +{(unsigned char*)"HARDcy", {208, 170, 0}}, +{(unsigned char*)"Hacek", {203, 135, 0}}, +{(unsigned char*)"Hat", {94, 0}}, +{(unsigned char*)"Hcirc", {196, 164, 0}}, +{(unsigned char*)"Hfr", {226, 132, 140, 0}}, +{(unsigned char*)"HilbertSpace", {226, 132, 139, 0}}, +{(unsigned char*)"Hopf", {226, 132, 141, 0}}, +{(unsigned char*)"HorizontalLine", {226, 148, 128, 0}}, +{(unsigned char*)"Hscr", {226, 132, 139, 0}}, +{(unsigned char*)"Hstrok", {196, 166, 0}}, +{(unsigned char*)"HumpDownHump", {226, 137, 142, 0}}, +{(unsigned char*)"HumpEqual", {226, 137, 143, 0}}, +{(unsigned char*)"IEcy", {208, 149, 0}}, +{(unsigned char*)"IJlig", {196, 178, 0}}, +{(unsigned char*)"IOcy", {208, 129, 0}}, +{(unsigned char*)"Iacute", {195, 141, 0}}, +{(unsigned char*)"Icirc", {195, 142, 0}}, +{(unsigned char*)"Icy", {208, 152, 0}}, +{(unsigned char*)"Idot", {196, 176, 0}}, +{(unsigned char*)"Ifr", {226, 132, 145, 0}}, +{(unsigned char*)"Igrave", {195, 140, 0}}, +{(unsigned char*)"Im", {226, 132, 145, 0}}, +{(unsigned char*)"Imacr", {196, 170, 0}}, +{(unsigned char*)"ImaginaryI", {226, 133, 136, 0}}, +{(unsigned char*)"Implies", {226, 135, 146, 0}}, +{(unsigned char*)"Int", {226, 136, 172, 0}}, +{(unsigned char*)"Integral", {226, 136, 171, 0}}, +{(unsigned char*)"Intersection", {226, 139, 130, 0}}, +{(unsigned char*)"InvisibleComma", {226, 129, 163, 0}}, +{(unsigned char*)"InvisibleTimes", {226, 129, 162, 0}}, +{(unsigned char*)"Iogon", {196, 174, 0}}, +{(unsigned char*)"Iopf", {240, 157, 149, 128, 0}}, +{(unsigned char*)"Iota", {206, 153, 0}}, +{(unsigned char*)"Iscr", {226, 132, 144, 0}}, +{(unsigned char*)"Itilde", {196, 168, 0}}, +{(unsigned char*)"Iukcy", {208, 134, 0}}, +{(unsigned char*)"Iuml", {195, 143, 0}}, +{(unsigned char*)"Jcirc", {196, 180, 0}}, +{(unsigned char*)"Jcy", {208, 153, 0}}, +{(unsigned char*)"Jfr", {240, 157, 148, 141, 0}}, +{(unsigned char*)"Jopf", {240, 157, 149, 129, 0}}, +{(unsigned char*)"Jscr", {240, 157, 146, 165, 0}}, +{(unsigned char*)"Jsercy", {208, 136, 0}}, +{(unsigned char*)"Jukcy", {208, 132, 0}}, +{(unsigned char*)"KHcy", {208, 165, 0}}, +{(unsigned char*)"KJcy", {208, 140, 0}}, +{(unsigned char*)"Kappa", {206, 154, 0}}, +{(unsigned char*)"Kcedil", {196, 182, 0}}, +{(unsigned char*)"Kcy", {208, 154, 0}}, +{(unsigned char*)"Kfr", {240, 157, 148, 142, 0}}, +{(unsigned char*)"Kopf", {240, 157, 149, 130, 0}}, +{(unsigned char*)"Kscr", {240, 157, 146, 166, 0}}, +{(unsigned char*)"LJcy", {208, 137, 0}}, +{(unsigned char*)"LT", {60, 0}}, +{(unsigned char*)"Lacute", {196, 185, 0}}, +{(unsigned char*)"Lambda", {206, 155, 0}}, +{(unsigned char*)"Lang", {226, 159, 170, 0}}, +{(unsigned char*)"Laplacetrf", {226, 132, 146, 0}}, +{(unsigned char*)"Larr", {226, 134, 158, 0}}, +{(unsigned char*)"Lcaron", {196, 189, 0}}, +{(unsigned char*)"Lcedil", {196, 187, 0}}, +{(unsigned char*)"Lcy", {208, 155, 0}}, +{(unsigned char*)"LeftAngleBracket", {226, 159, 168, 0}}, +{(unsigned char*)"LeftArrow", {226, 134, 144, 0}}, +{(unsigned char*)"LeftArrowBar", {226, 135, 164, 0}}, +{(unsigned char*)"LeftArrowRightArrow", {226, 135, 134, 0}}, +{(unsigned char*)"LeftCeiling", {226, 140, 136, 0}}, +{(unsigned char*)"LeftDoubleBracket", {226, 159, 166, 0}}, +{(unsigned char*)"LeftDownTeeVector", {226, 165, 161, 0}}, +{(unsigned char*)"LeftDownVector", {226, 135, 131, 0}}, +{(unsigned char*)"LeftDownVectorBar", {226, 165, 153, 0}}, +{(unsigned char*)"LeftFloor", {226, 140, 138, 0}}, +{(unsigned char*)"LeftRightArrow", {226, 134, 148, 0}}, +{(unsigned char*)"LeftRightVector", {226, 165, 142, 0}}, +{(unsigned char*)"LeftTee", {226, 138, 163, 0}}, +{(unsigned char*)"LeftTeeArrow", {226, 134, 164, 0}}, +{(unsigned char*)"LeftTeeVector", {226, 165, 154, 0}}, +{(unsigned char*)"LeftTriangle", {226, 138, 178, 0}}, +{(unsigned char*)"LeftTriangleBar", {226, 167, 143, 0}}, +{(unsigned char*)"LeftTriangleEqual", {226, 138, 180, 0}}, +{(unsigned char*)"LeftUpDownVector", {226, 165, 145, 0}}, +{(unsigned char*)"LeftUpTeeVector", {226, 165, 160, 0}}, +{(unsigned char*)"LeftUpVector", {226, 134, 191, 0}}, +{(unsigned char*)"LeftUpVectorBar", {226, 165, 152, 0}}, +{(unsigned char*)"LeftVector", {226, 134, 188, 0}}, +{(unsigned char*)"LeftVectorBar", {226, 165, 146, 0}}, +{(unsigned char*)"Leftarrow", {226, 135, 144, 0}}, +{(unsigned char*)"Leftrightarrow", {226, 135, 148, 0}}, +{(unsigned char*)"LessEqualGreater", {226, 139, 154, 0}}, +{(unsigned char*)"LessFullEqual", {226, 137, 166, 0}}, +{(unsigned char*)"LessGreater", {226, 137, 182, 0}}, +{(unsigned char*)"LessLess", {226, 170, 161, 0}}, +{(unsigned char*)"LessSlantEqual", {226, 169, 189, 0}}, +{(unsigned char*)"LessTilde", {226, 137, 178, 0}}, +{(unsigned char*)"Lfr", {240, 157, 148, 143, 0}}, +{(unsigned char*)"Ll", {226, 139, 152, 0}}, +{(unsigned char*)"Lleftarrow", {226, 135, 154, 0}}, +{(unsigned char*)"Lmidot", {196, 191, 0}}, +{(unsigned char*)"LongLeftArrow", {226, 159, 181, 0}}, +{(unsigned char*)"LongLeftRightArrow", {226, 159, 183, 0}}, +{(unsigned char*)"LongRightArrow", {226, 159, 182, 0}}, +{(unsigned char*)"Longleftarrow", {226, 159, 184, 0}}, +{(unsigned char*)"Longleftrightarrow", {226, 159, 186, 0}}, +{(unsigned char*)"Longrightarrow", {226, 159, 185, 0}}, +{(unsigned char*)"Lopf", {240, 157, 149, 131, 0}}, +{(unsigned char*)"LowerLeftArrow", {226, 134, 153, 0}}, +{(unsigned char*)"LowerRightArrow", {226, 134, 152, 0}}, +{(unsigned char*)"Lscr", {226, 132, 146, 0}}, +{(unsigned char*)"Lsh", {226, 134, 176, 0}}, +{(unsigned char*)"Lstrok", {197, 129, 0}}, +{(unsigned char*)"Lt", {226, 137, 170, 0}}, +{(unsigned char*)"Map", {226, 164, 133, 0}}, +{(unsigned char*)"Mcy", {208, 156, 0}}, +{(unsigned char*)"MediumSpace", {226, 129, 159, 0}}, +{(unsigned char*)"Mellintrf", {226, 132, 179, 0}}, +{(unsigned char*)"Mfr", {240, 157, 148, 144, 0}}, +{(unsigned char*)"MinusPlus", {226, 136, 147, 0}}, +{(unsigned char*)"Mopf", {240, 157, 149, 132, 0}}, +{(unsigned char*)"Mscr", {226, 132, 179, 0}}, +{(unsigned char*)"Mu", {206, 156, 0}}, +{(unsigned char*)"NJcy", {208, 138, 0}}, +{(unsigned char*)"Nacute", {197, 131, 0}}, +{(unsigned char*)"Ncaron", {197, 135, 0}}, +{(unsigned char*)"Ncedil", {197, 133, 0}}, +{(unsigned char*)"Ncy", {208, 157, 0}}, +{(unsigned char*)"NegativeMediumSpace", {226, 128, 139, 0}}, +{(unsigned char*)"NegativeThickSpace", {226, 128, 139, 0}}, +{(unsigned char*)"NegativeThinSpace", {226, 128, 139, 0}}, +{(unsigned char*)"NegativeVeryThinSpace", {226, 128, 139, 0}}, +{(unsigned char*)"NestedGreaterGreater", {226, 137, 171, 0}}, +{(unsigned char*)"NestedLessLess", {226, 137, 170, 0}}, +{(unsigned char*)"NewLine", {10, 0}}, +{(unsigned char*)"Nfr", {240, 157, 148, 145, 0}}, +{(unsigned char*)"NoBreak", {226, 129, 160, 0}}, +{(unsigned char*)"NonBreakingSpace", {194, 160, 0}}, +{(unsigned char*)"Nopf", {226, 132, 149, 0}}, +{(unsigned char*)"Not", {226, 171, 172, 0}}, +{(unsigned char*)"NotCongruent", {226, 137, 162, 0}}, +{(unsigned char*)"NotCupCap", {226, 137, 173, 0}}, +{(unsigned char*)"NotDoubleVerticalBar", {226, 136, 166, 0}}, +{(unsigned char*)"NotElement", {226, 136, 137, 0}}, +{(unsigned char*)"NotEqual", {226, 137, 160, 0}}, +{(unsigned char*)"NotEqualTilde", {226, 137, 130, 204, 184, 0}}, +{(unsigned char*)"NotExists", {226, 136, 132, 0}}, +{(unsigned char*)"NotGreater", {226, 137, 175, 0}}, +{(unsigned char*)"NotGreaterEqual", {226, 137, 177, 0}}, +{(unsigned char*)"NotGreaterFullEqual", {226, 137, 167, 204, 184, 0}}, +{(unsigned char*)"NotGreaterGreater", {226, 137, 171, 204, 184, 0}}, +{(unsigned char*)"NotGreaterLess", {226, 137, 185, 0}}, +{(unsigned char*)"NotGreaterSlantEqual", {226, 169, 190, 204, 184, 0}}, +{(unsigned char*)"NotGreaterTilde", {226, 137, 181, 0}}, +{(unsigned char*)"NotHumpDownHump", {226, 137, 142, 204, 184, 0}}, +{(unsigned char*)"NotHumpEqual", {226, 137, 143, 204, 184, 0}}, +{(unsigned char*)"NotLeftTriangle", {226, 139, 170, 0}}, +{(unsigned char*)"NotLeftTriangleBar", {226, 167, 143, 204, 184, 0}}, +{(unsigned char*)"NotLeftTriangleEqual", {226, 139, 172, 0}}, +{(unsigned char*)"NotLess", {226, 137, 174, 0}}, +{(unsigned char*)"NotLessEqual", {226, 137, 176, 0}}, +{(unsigned char*)"NotLessGreater", {226, 137, 184, 0}}, +{(unsigned char*)"NotLessLess", {226, 137, 170, 204, 184, 0}}, +{(unsigned char*)"NotLessSlantEqual", {226, 169, 189, 204, 184, 0}}, +{(unsigned char*)"NotLessTilde", {226, 137, 180, 0}}, +{(unsigned char*)"NotNestedGreaterGreater", {226, 170, 162, 204, 184, 0}}, +{(unsigned char*)"NotNestedLessLess", {226, 170, 161, 204, 184, 0}}, +{(unsigned char*)"NotPrecedes", {226, 138, 128, 0}}, +{(unsigned char*)"NotPrecedesEqual", {226, 170, 175, 204, 184, 0}}, +{(unsigned char*)"NotPrecedesSlantEqual", {226, 139, 160, 0}}, +{(unsigned char*)"NotReverseElement", {226, 136, 140, 0}}, +{(unsigned char*)"NotRightTriangle", {226, 139, 171, 0}}, +{(unsigned char*)"NotRightTriangleBar", {226, 167, 144, 204, 184, 0}}, +{(unsigned char*)"NotRightTriangleEqual", {226, 139, 173, 0}}, +{(unsigned char*)"NotSquareSubset", {226, 138, 143, 204, 184, 0}}, +{(unsigned char*)"NotSquareSubsetEqual", {226, 139, 162, 0}}, +{(unsigned char*)"NotSquareSuperset", {226, 138, 144, 204, 184, 0}}, +{(unsigned char*)"NotSquareSupersetEqual", {226, 139, 163, 0}}, +{(unsigned char*)"NotSubset", {226, 138, 130, 226, 131, 146, 0}}, +{(unsigned char*)"NotSubsetEqual", {226, 138, 136, 0}}, +{(unsigned char*)"NotSucceeds", {226, 138, 129, 0}}, +{(unsigned char*)"NotSucceedsEqual", {226, 170, 176, 204, 184, 0}}, +{(unsigned char*)"NotSucceedsSlantEqual", {226, 139, 161, 0}}, +{(unsigned char*)"NotSucceedsTilde", {226, 137, 191, 204, 184, 0}}, +{(unsigned char*)"NotSuperset", {226, 138, 131, 226, 131, 146, 0}}, +{(unsigned char*)"NotSupersetEqual", {226, 138, 137, 0}}, +{(unsigned char*)"NotTilde", {226, 137, 129, 0}}, +{(unsigned char*)"NotTildeEqual", {226, 137, 132, 0}}, +{(unsigned char*)"NotTildeFullEqual", {226, 137, 135, 0}}, +{(unsigned char*)"NotTildeTilde", {226, 137, 137, 0}}, +{(unsigned char*)"NotVerticalBar", {226, 136, 164, 0}}, +{(unsigned char*)"Nscr", {240, 157, 146, 169, 0}}, +{(unsigned char*)"Ntilde", {195, 145, 0}}, +{(unsigned char*)"Nu", {206, 157, 0}}, +{(unsigned char*)"OElig", {197, 146, 0}}, +{(unsigned char*)"Oacute", {195, 147, 0}}, +{(unsigned char*)"Ocirc", {195, 148, 0}}, +{(unsigned char*)"Ocy", {208, 158, 0}}, +{(unsigned char*)"Odblac", {197, 144, 0}}, +{(unsigned char*)"Ofr", {240, 157, 148, 146, 0}}, +{(unsigned char*)"Ograve", {195, 146, 0}}, +{(unsigned char*)"Omacr", {197, 140, 0}}, +{(unsigned char*)"Omega", {206, 169, 0}}, +{(unsigned char*)"Omicron", {206, 159, 0}}, +{(unsigned char*)"Oopf", {240, 157, 149, 134, 0}}, +{(unsigned char*)"OpenCurlyDoubleQuote", {226, 128, 156, 0}}, +{(unsigned char*)"OpenCurlyQuote", {226, 128, 152, 0}}, +{(unsigned char*)"Or", {226, 169, 148, 0}}, +{(unsigned char*)"Oscr", {240, 157, 146, 170, 0}}, +{(unsigned char*)"Oslash", {195, 152, 0}}, +{(unsigned char*)"Otilde", {195, 149, 0}}, +{(unsigned char*)"Otimes", {226, 168, 183, 0}}, +{(unsigned char*)"Ouml", {195, 150, 0}}, +{(unsigned char*)"OverBar", {226, 128, 190, 0}}, +{(unsigned char*)"OverBrace", {226, 143, 158, 0}}, +{(unsigned char*)"OverBracket", {226, 142, 180, 0}}, +{(unsigned char*)"OverParenthesis", {226, 143, 156, 0}}, +{(unsigned char*)"PartialD", {226, 136, 130, 0}}, +{(unsigned char*)"Pcy", {208, 159, 0}}, +{(unsigned char*)"Pfr", {240, 157, 148, 147, 0}}, +{(unsigned char*)"Phi", {206, 166, 0}}, +{(unsigned char*)"Pi", {206, 160, 0}}, +{(unsigned char*)"PlusMinus", {194, 177, 0}}, +{(unsigned char*)"Poincareplane", {226, 132, 140, 0}}, +{(unsigned char*)"Popf", {226, 132, 153, 0}}, +{(unsigned char*)"Pr", {226, 170, 187, 0}}, +{(unsigned char*)"Precedes", {226, 137, 186, 0}}, +{(unsigned char*)"PrecedesEqual", {226, 170, 175, 0}}, +{(unsigned char*)"PrecedesSlantEqual", {226, 137, 188, 0}}, +{(unsigned char*)"PrecedesTilde", {226, 137, 190, 0}}, +{(unsigned char*)"Prime", {226, 128, 179, 0}}, +{(unsigned char*)"Product", {226, 136, 143, 0}}, +{(unsigned char*)"Proportion", {226, 136, 183, 0}}, +{(unsigned char*)"Proportional", {226, 136, 157, 0}}, +{(unsigned char*)"Pscr", {240, 157, 146, 171, 0}}, +{(unsigned char*)"Psi", {206, 168, 0}}, +{(unsigned char*)"QUOT", {34, 0}}, +{(unsigned char*)"Qfr", {240, 157, 148, 148, 0}}, +{(unsigned char*)"Qopf", {226, 132, 154, 0}}, +{(unsigned char*)"Qscr", {240, 157, 146, 172, 0}}, +{(unsigned char*)"RBarr", {226, 164, 144, 0}}, +{(unsigned char*)"REG", {194, 174, 0}}, +{(unsigned char*)"Racute", {197, 148, 0}}, +{(unsigned char*)"Rang", {226, 159, 171, 0}}, +{(unsigned char*)"Rarr", {226, 134, 160, 0}}, +{(unsigned char*)"Rarrtl", {226, 164, 150, 0}}, +{(unsigned char*)"Rcaron", {197, 152, 0}}, +{(unsigned char*)"Rcedil", {197, 150, 0}}, +{(unsigned char*)"Rcy", {208, 160, 0}}, +{(unsigned char*)"Re", {226, 132, 156, 0}}, +{(unsigned char*)"ReverseElement", {226, 136, 139, 0}}, +{(unsigned char*)"ReverseEquilibrium", {226, 135, 139, 0}}, +{(unsigned char*)"ReverseUpEquilibrium", {226, 165, 175, 0}}, +{(unsigned char*)"Rfr", {226, 132, 156, 0}}, +{(unsigned char*)"Rho", {206, 161, 0}}, +{(unsigned char*)"RightAngleBracket", {226, 159, 169, 0}}, +{(unsigned char*)"RightArrow", {226, 134, 146, 0}}, +{(unsigned char*)"RightArrowBar", {226, 135, 165, 0}}, +{(unsigned char*)"RightArrowLeftArrow", {226, 135, 132, 0}}, +{(unsigned char*)"RightCeiling", {226, 140, 137, 0}}, +{(unsigned char*)"RightDoubleBracket", {226, 159, 167, 0}}, +{(unsigned char*)"RightDownTeeVector", {226, 165, 157, 0}}, +{(unsigned char*)"RightDownVector", {226, 135, 130, 0}}, +{(unsigned char*)"RightDownVectorBar", {226, 165, 149, 0}}, +{(unsigned char*)"RightFloor", {226, 140, 139, 0}}, +{(unsigned char*)"RightTee", {226, 138, 162, 0}}, +{(unsigned char*)"RightTeeArrow", {226, 134, 166, 0}}, +{(unsigned char*)"RightTeeVector", {226, 165, 155, 0}}, +{(unsigned char*)"RightTriangle", {226, 138, 179, 0}}, +{(unsigned char*)"RightTriangleBar", {226, 167, 144, 0}}, +{(unsigned char*)"RightTriangleEqual", {226, 138, 181, 0}}, +{(unsigned char*)"RightUpDownVector", {226, 165, 143, 0}}, +{(unsigned char*)"RightUpTeeVector", {226, 165, 156, 0}}, +{(unsigned char*)"RightUpVector", {226, 134, 190, 0}}, +{(unsigned char*)"RightUpVectorBar", {226, 165, 148, 0}}, +{(unsigned char*)"RightVector", {226, 135, 128, 0}}, +{(unsigned char*)"RightVectorBar", {226, 165, 147, 0}}, +{(unsigned char*)"Rightarrow", {226, 135, 146, 0}}, +{(unsigned char*)"Ropf", {226, 132, 157, 0}}, +{(unsigned char*)"RoundImplies", {226, 165, 176, 0}}, +{(unsigned char*)"Rrightarrow", {226, 135, 155, 0}}, +{(unsigned char*)"Rscr", {226, 132, 155, 0}}, +{(unsigned char*)"Rsh", {226, 134, 177, 0}}, +{(unsigned char*)"RuleDelayed", {226, 167, 180, 0}}, +{(unsigned char*)"SHCHcy", {208, 169, 0}}, +{(unsigned char*)"SHcy", {208, 168, 0}}, +{(unsigned char*)"SOFTcy", {208, 172, 0}}, +{(unsigned char*)"Sacute", {197, 154, 0}}, +{(unsigned char*)"Sc", {226, 170, 188, 0}}, +{(unsigned char*)"Scaron", {197, 160, 0}}, +{(unsigned char*)"Scedil", {197, 158, 0}}, +{(unsigned char*)"Scirc", {197, 156, 0}}, +{(unsigned char*)"Scy", {208, 161, 0}}, +{(unsigned char*)"Sfr", {240, 157, 148, 150, 0}}, +{(unsigned char*)"ShortDownArrow", {226, 134, 147, 0}}, +{(unsigned char*)"ShortLeftArrow", {226, 134, 144, 0}}, +{(unsigned char*)"ShortRightArrow", {226, 134, 146, 0}}, +{(unsigned char*)"ShortUpArrow", {226, 134, 145, 0}}, +{(unsigned char*)"Sigma", {206, 163, 0}}, +{(unsigned char*)"SmallCircle", {226, 136, 152, 0}}, +{(unsigned char*)"Sopf", {240, 157, 149, 138, 0}}, +{(unsigned char*)"Sqrt", {226, 136, 154, 0}}, +{(unsigned char*)"Square", {226, 150, 161, 0}}, +{(unsigned char*)"SquareIntersection", {226, 138, 147, 0}}, +{(unsigned char*)"SquareSubset", {226, 138, 143, 0}}, +{(unsigned char*)"SquareSubsetEqual", {226, 138, 145, 0}}, +{(unsigned char*)"SquareSuperset", {226, 138, 144, 0}}, +{(unsigned char*)"SquareSupersetEqual", {226, 138, 146, 0}}, +{(unsigned char*)"SquareUnion", {226, 138, 148, 0}}, +{(unsigned char*)"Sscr", {240, 157, 146, 174, 0}}, +{(unsigned char*)"Star", {226, 139, 134, 0}}, +{(unsigned char*)"Sub", {226, 139, 144, 0}}, +{(unsigned char*)"Subset", {226, 139, 144, 0}}, +{(unsigned char*)"SubsetEqual", {226, 138, 134, 0}}, +{(unsigned char*)"Succeeds", {226, 137, 187, 0}}, +{(unsigned char*)"SucceedsEqual", {226, 170, 176, 0}}, +{(unsigned char*)"SucceedsSlantEqual", {226, 137, 189, 0}}, +{(unsigned char*)"SucceedsTilde", {226, 137, 191, 0}}, +{(unsigned char*)"SuchThat", {226, 136, 139, 0}}, +{(unsigned char*)"Sum", {226, 136, 145, 0}}, +{(unsigned char*)"Sup", {226, 139, 145, 0}}, +{(unsigned char*)"Superset", {226, 138, 131, 0}}, +{(unsigned char*)"SupersetEqual", {226, 138, 135, 0}}, +{(unsigned char*)"Supset", {226, 139, 145, 0}}, +{(unsigned char*)"THORN", {195, 158, 0}}, +{(unsigned char*)"TRADE", {226, 132, 162, 0}}, +{(unsigned char*)"TSHcy", {208, 139, 0}}, +{(unsigned char*)"TScy", {208, 166, 0}}, +{(unsigned char*)"Tab", {9, 0}}, +{(unsigned char*)"Tau", {206, 164, 0}}, +{(unsigned char*)"Tcaron", {197, 164, 0}}, +{(unsigned char*)"Tcedil", {197, 162, 0}}, +{(unsigned char*)"Tcy", {208, 162, 0}}, +{(unsigned char*)"Tfr", {240, 157, 148, 151, 0}}, +{(unsigned char*)"Therefore", {226, 136, 180, 0}}, +{(unsigned char*)"Theta", {206, 152, 0}}, +{(unsigned char*)"ThickSpace", {226, 129, 159, 226, 128, 138, 0}}, +{(unsigned char*)"ThinSpace", {226, 128, 137, 0}}, +{(unsigned char*)"Tilde", {226, 136, 188, 0}}, +{(unsigned char*)"TildeEqual", {226, 137, 131, 0}}, +{(unsigned char*)"TildeFullEqual", {226, 137, 133, 0}}, +{(unsigned char*)"TildeTilde", {226, 137, 136, 0}}, +{(unsigned char*)"Topf", {240, 157, 149, 139, 0}}, +{(unsigned char*)"TripleDot", {226, 131, 155, 0}}, +{(unsigned char*)"Tscr", {240, 157, 146, 175, 0}}, +{(unsigned char*)"Tstrok", {197, 166, 0}}, +{(unsigned char*)"Uacute", {195, 154, 0}}, +{(unsigned char*)"Uarr", {226, 134, 159, 0}}, +{(unsigned char*)"Uarrocir", {226, 165, 137, 0}}, +{(unsigned char*)"Ubrcy", {208, 142, 0}}, +{(unsigned char*)"Ubreve", {197, 172, 0}}, +{(unsigned char*)"Ucirc", {195, 155, 0}}, +{(unsigned char*)"Ucy", {208, 163, 0}}, +{(unsigned char*)"Udblac", {197, 176, 0}}, +{(unsigned char*)"Ufr", {240, 157, 148, 152, 0}}, +{(unsigned char*)"Ugrave", {195, 153, 0}}, +{(unsigned char*)"Umacr", {197, 170, 0}}, +{(unsigned char*)"UnderBar", {95, 0}}, +{(unsigned char*)"UnderBrace", {226, 143, 159, 0}}, +{(unsigned char*)"UnderBracket", {226, 142, 181, 0}}, +{(unsigned char*)"UnderParenthesis", {226, 143, 157, 0}}, +{(unsigned char*)"Union", {226, 139, 131, 0}}, +{(unsigned char*)"UnionPlus", {226, 138, 142, 0}}, +{(unsigned char*)"Uogon", {197, 178, 0}}, +{(unsigned char*)"Uopf", {240, 157, 149, 140, 0}}, +{(unsigned char*)"UpArrow", {226, 134, 145, 0}}, +{(unsigned char*)"UpArrowBar", {226, 164, 146, 0}}, +{(unsigned char*)"UpArrowDownArrow", {226, 135, 133, 0}}, +{(unsigned char*)"UpDownArrow", {226, 134, 149, 0}}, +{(unsigned char*)"UpEquilibrium", {226, 165, 174, 0}}, +{(unsigned char*)"UpTee", {226, 138, 165, 0}}, +{(unsigned char*)"UpTeeArrow", {226, 134, 165, 0}}, +{(unsigned char*)"Uparrow", {226, 135, 145, 0}}, +{(unsigned char*)"Updownarrow", {226, 135, 149, 0}}, +{(unsigned char*)"UpperLeftArrow", {226, 134, 150, 0}}, +{(unsigned char*)"UpperRightArrow", {226, 134, 151, 0}}, +{(unsigned char*)"Upsi", {207, 146, 0}}, +{(unsigned char*)"Upsilon", {206, 165, 0}}, +{(unsigned char*)"Uring", {197, 174, 0}}, +{(unsigned char*)"Uscr", {240, 157, 146, 176, 0}}, +{(unsigned char*)"Utilde", {197, 168, 0}}, +{(unsigned char*)"Uuml", {195, 156, 0}}, +{(unsigned char*)"VDash", {226, 138, 171, 0}}, +{(unsigned char*)"Vbar", {226, 171, 171, 0}}, +{(unsigned char*)"Vcy", {208, 146, 0}}, +{(unsigned char*)"Vdash", {226, 138, 169, 0}}, +{(unsigned char*)"Vdashl", {226, 171, 166, 0}}, +{(unsigned char*)"Vee", {226, 139, 129, 0}}, +{(unsigned char*)"Verbar", {226, 128, 150, 0}}, +{(unsigned char*)"Vert", {226, 128, 150, 0}}, +{(unsigned char*)"VerticalBar", {226, 136, 163, 0}}, +{(unsigned char*)"VerticalLine", {124, 0}}, +{(unsigned char*)"VerticalSeparator", {226, 157, 152, 0}}, +{(unsigned char*)"VerticalTilde", {226, 137, 128, 0}}, +{(unsigned char*)"VeryThinSpace", {226, 128, 138, 0}}, +{(unsigned char*)"Vfr", {240, 157, 148, 153, 0}}, +{(unsigned char*)"Vopf", {240, 157, 149, 141, 0}}, +{(unsigned char*)"Vscr", {240, 157, 146, 177, 0}}, +{(unsigned char*)"Vvdash", {226, 138, 170, 0}}, +{(unsigned char*)"Wcirc", {197, 180, 0}}, +{(unsigned char*)"Wedge", {226, 139, 128, 0}}, +{(unsigned char*)"Wfr", {240, 157, 148, 154, 0}}, +{(unsigned char*)"Wopf", {240, 157, 149, 142, 0}}, +{(unsigned char*)"Wscr", {240, 157, 146, 178, 0}}, +{(unsigned char*)"Xfr", {240, 157, 148, 155, 0}}, +{(unsigned char*)"Xi", {206, 158, 0}}, +{(unsigned char*)"Xopf", {240, 157, 149, 143, 0}}, +{(unsigned char*)"Xscr", {240, 157, 146, 179, 0}}, +{(unsigned char*)"YAcy", {208, 175, 0}}, +{(unsigned char*)"YIcy", {208, 135, 0}}, +{(unsigned char*)"YUcy", {208, 174, 0}}, +{(unsigned char*)"Yacute", {195, 157, 0}}, +{(unsigned char*)"Ycirc", {197, 182, 0}}, +{(unsigned char*)"Ycy", {208, 171, 0}}, +{(unsigned char*)"Yfr", {240, 157, 148, 156, 0}}, +{(unsigned char*)"Yopf", {240, 157, 149, 144, 0}}, +{(unsigned char*)"Yscr", {240, 157, 146, 180, 0}}, +{(unsigned char*)"Yuml", {197, 184, 0}}, +{(unsigned char*)"ZHcy", {208, 150, 0}}, +{(unsigned char*)"Zacute", {197, 185, 0}}, +{(unsigned char*)"Zcaron", {197, 189, 0}}, +{(unsigned char*)"Zcy", {208, 151, 0}}, +{(unsigned char*)"Zdot", {197, 187, 0}}, +{(unsigned char*)"ZeroWidthSpace", {226, 128, 139, 0}}, +{(unsigned char*)"Zeta", {206, 150, 0}}, +{(unsigned char*)"Zfr", {226, 132, 168, 0}}, +{(unsigned char*)"Zopf", {226, 132, 164, 0}}, +{(unsigned char*)"Zscr", {240, 157, 146, 181, 0}}, +{(unsigned char*)"aacute", {195, 161, 0}}, +{(unsigned char*)"abreve", {196, 131, 0}}, +{(unsigned char*)"ac", {226, 136, 190, 0}}, +{(unsigned char*)"acE", {226, 136, 190, 204, 179, 0}}, +{(unsigned char*)"acd", {226, 136, 191, 0}}, +{(unsigned char*)"acirc", {195, 162, 0}}, +{(unsigned char*)"acute", {194, 180, 0}}, +{(unsigned char*)"acy", {208, 176, 0}}, +{(unsigned char*)"aelig", {195, 166, 0}}, +{(unsigned char*)"af", {226, 129, 161, 0}}, +{(unsigned char*)"afr", {240, 157, 148, 158, 0}}, +{(unsigned char*)"agrave", {195, 160, 0}}, +{(unsigned char*)"alefsym", {226, 132, 181, 0}}, +{(unsigned char*)"aleph", {226, 132, 181, 0}}, +{(unsigned char*)"alpha", {206, 177, 0}}, +{(unsigned char*)"amacr", {196, 129, 0}}, +{(unsigned char*)"amalg", {226, 168, 191, 0}}, +{(unsigned char*)"amp", {38, 0}}, +{(unsigned char*)"and", {226, 136, 167, 0}}, +{(unsigned char*)"andand", {226, 169, 149, 0}}, +{(unsigned char*)"andd", {226, 169, 156, 0}}, +{(unsigned char*)"andslope", {226, 169, 152, 0}}, +{(unsigned char*)"andv", {226, 169, 154, 0}}, +{(unsigned char*)"ang", {226, 136, 160, 0}}, +{(unsigned char*)"ange", {226, 166, 164, 0}}, +{(unsigned char*)"angle", {226, 136, 160, 0}}, +{(unsigned char*)"angmsd", {226, 136, 161, 0}}, +{(unsigned char*)"angmsdaa", {226, 166, 168, 0}}, +{(unsigned char*)"angmsdab", {226, 166, 169, 0}}, +{(unsigned char*)"angmsdac", {226, 166, 170, 0}}, +{(unsigned char*)"angmsdad", {226, 166, 171, 0}}, +{(unsigned char*)"angmsdae", {226, 166, 172, 0}}, +{(unsigned char*)"angmsdaf", {226, 166, 173, 0}}, +{(unsigned char*)"angmsdag", {226, 166, 174, 0}}, +{(unsigned char*)"angmsdah", {226, 166, 175, 0}}, +{(unsigned char*)"angrt", {226, 136, 159, 0}}, +{(unsigned char*)"angrtvb", {226, 138, 190, 0}}, +{(unsigned char*)"angrtvbd", {226, 166, 157, 0}}, +{(unsigned char*)"angsph", {226, 136, 162, 0}}, +{(unsigned char*)"angst", {195, 133, 0}}, +{(unsigned char*)"angzarr", {226, 141, 188, 0}}, +{(unsigned char*)"aogon", {196, 133, 0}}, +{(unsigned char*)"aopf", {240, 157, 149, 146, 0}}, +{(unsigned char*)"ap", {226, 137, 136, 0}}, +{(unsigned char*)"apE", {226, 169, 176, 0}}, +{(unsigned char*)"apacir", {226, 169, 175, 0}}, +{(unsigned char*)"ape", {226, 137, 138, 0}}, +{(unsigned char*)"apid", {226, 137, 139, 0}}, +{(unsigned char*)"apos", {39, 0}}, +{(unsigned char*)"approx", {226, 137, 136, 0}}, +{(unsigned char*)"approxeq", {226, 137, 138, 0}}, +{(unsigned char*)"aring", {195, 165, 0}}, +{(unsigned char*)"ascr", {240, 157, 146, 182, 0}}, +{(unsigned char*)"ast", {42, 0}}, +{(unsigned char*)"asymp", {226, 137, 136, 0}}, +{(unsigned char*)"asympeq", {226, 137, 141, 0}}, +{(unsigned char*)"atilde", {195, 163, 0}}, +{(unsigned char*)"auml", {195, 164, 0}}, +{(unsigned char*)"awconint", {226, 136, 179, 0}}, +{(unsigned char*)"awint", {226, 168, 145, 0}}, +{(unsigned char*)"bNot", {226, 171, 173, 0}}, +{(unsigned char*)"backcong", {226, 137, 140, 0}}, +{(unsigned char*)"backepsilon", {207, 182, 0}}, +{(unsigned char*)"backprime", {226, 128, 181, 0}}, +{(unsigned char*)"backsim", {226, 136, 189, 0}}, +{(unsigned char*)"backsimeq", {226, 139, 141, 0}}, +{(unsigned char*)"barvee", {226, 138, 189, 0}}, +{(unsigned char*)"barwed", {226, 140, 133, 0}}, +{(unsigned char*)"barwedge", {226, 140, 133, 0}}, +{(unsigned char*)"bbrk", {226, 142, 181, 0}}, +{(unsigned char*)"bbrktbrk", {226, 142, 182, 0}}, +{(unsigned char*)"bcong", {226, 137, 140, 0}}, +{(unsigned char*)"bcy", {208, 177, 0}}, +{(unsigned char*)"bdquo", {226, 128, 158, 0}}, +{(unsigned char*)"becaus", {226, 136, 181, 0}}, +{(unsigned char*)"because", {226, 136, 181, 0}}, +{(unsigned char*)"bemptyv", {226, 166, 176, 0}}, +{(unsigned char*)"bepsi", {207, 182, 0}}, +{(unsigned char*)"bernou", {226, 132, 172, 0}}, +{(unsigned char*)"beta", {206, 178, 0}}, +{(unsigned char*)"beth", {226, 132, 182, 0}}, +{(unsigned char*)"between", {226, 137, 172, 0}}, +{(unsigned char*)"bfr", {240, 157, 148, 159, 0}}, +{(unsigned char*)"bigcap", {226, 139, 130, 0}}, +{(unsigned char*)"bigcirc", {226, 151, 175, 0}}, +{(unsigned char*)"bigcup", {226, 139, 131, 0}}, +{(unsigned char*)"bigodot", {226, 168, 128, 0}}, +{(unsigned char*)"bigoplus", {226, 168, 129, 0}}, +{(unsigned char*)"bigotimes", {226, 168, 130, 0}}, +{(unsigned char*)"bigsqcup", {226, 168, 134, 0}}, +{(unsigned char*)"bigstar", {226, 152, 133, 0}}, +{(unsigned char*)"bigtriangledown", {226, 150, 189, 0}}, +{(unsigned char*)"bigtriangleup", {226, 150, 179, 0}}, +{(unsigned char*)"biguplus", {226, 168, 132, 0}}, +{(unsigned char*)"bigvee", {226, 139, 129, 0}}, +{(unsigned char*)"bigwedge", {226, 139, 128, 0}}, +{(unsigned char*)"bkarow", {226, 164, 141, 0}}, +{(unsigned char*)"blacklozenge", {226, 167, 171, 0}}, +{(unsigned char*)"blacksquare", {226, 150, 170, 0}}, +{(unsigned char*)"blacktriangle", {226, 150, 180, 0}}, +{(unsigned char*)"blacktriangledown", {226, 150, 190, 0}}, +{(unsigned char*)"blacktriangleleft", {226, 151, 130, 0}}, +{(unsigned char*)"blacktriangleright", {226, 150, 184, 0}}, +{(unsigned char*)"blank", {226, 144, 163, 0}}, +{(unsigned char*)"blk12", {226, 150, 146, 0}}, +{(unsigned char*)"blk14", {226, 150, 145, 0}}, +{(unsigned char*)"blk34", {226, 150, 147, 0}}, +{(unsigned char*)"block", {226, 150, 136, 0}}, +{(unsigned char*)"bne", {61, 226, 131, 165, 0}}, +{(unsigned char*)"bnequiv", {226, 137, 161, 226, 131, 165, 0}}, +{(unsigned char*)"bnot", {226, 140, 144, 0}}, +{(unsigned char*)"bopf", {240, 157, 149, 147, 0}}, +{(unsigned char*)"bot", {226, 138, 165, 0}}, +{(unsigned char*)"bottom", {226, 138, 165, 0}}, +{(unsigned char*)"bowtie", {226, 139, 136, 0}}, +{(unsigned char*)"boxDL", {226, 149, 151, 0}}, +{(unsigned char*)"boxDR", {226, 149, 148, 0}}, +{(unsigned char*)"boxDl", {226, 149, 150, 0}}, +{(unsigned char*)"boxDr", {226, 149, 147, 0}}, +{(unsigned char*)"boxH", {226, 149, 144, 0}}, +{(unsigned char*)"boxHD", {226, 149, 166, 0}}, +{(unsigned char*)"boxHU", {226, 149, 169, 0}}, +{(unsigned char*)"boxHd", {226, 149, 164, 0}}, +{(unsigned char*)"boxHu", {226, 149, 167, 0}}, +{(unsigned char*)"boxUL", {226, 149, 157, 0}}, +{(unsigned char*)"boxUR", {226, 149, 154, 0}}, +{(unsigned char*)"boxUl", {226, 149, 156, 0}}, +{(unsigned char*)"boxUr", {226, 149, 153, 0}}, +{(unsigned char*)"boxV", {226, 149, 145, 0}}, +{(unsigned char*)"boxVH", {226, 149, 172, 0}}, +{(unsigned char*)"boxVL", {226, 149, 163, 0}}, +{(unsigned char*)"boxVR", {226, 149, 160, 0}}, +{(unsigned char*)"boxVh", {226, 149, 171, 0}}, +{(unsigned char*)"boxVl", {226, 149, 162, 0}}, +{(unsigned char*)"boxVr", {226, 149, 159, 0}}, +{(unsigned char*)"boxbox", {226, 167, 137, 0}}, +{(unsigned char*)"boxdL", {226, 149, 149, 0}}, +{(unsigned char*)"boxdR", {226, 149, 146, 0}}, +{(unsigned char*)"boxdl", {226, 148, 144, 0}}, +{(unsigned char*)"boxdr", {226, 148, 140, 0}}, +{(unsigned char*)"boxh", {226, 148, 128, 0}}, +{(unsigned char*)"boxhD", {226, 149, 165, 0}}, +{(unsigned char*)"boxhU", {226, 149, 168, 0}}, +{(unsigned char*)"boxhd", {226, 148, 172, 0}}, +{(unsigned char*)"boxhu", {226, 148, 180, 0}}, +{(unsigned char*)"boxminus", {226, 138, 159, 0}}, +{(unsigned char*)"boxplus", {226, 138, 158, 0}}, +{(unsigned char*)"boxtimes", {226, 138, 160, 0}}, +{(unsigned char*)"boxuL", {226, 149, 155, 0}}, +{(unsigned char*)"boxuR", {226, 149, 152, 0}}, +{(unsigned char*)"boxul", {226, 148, 152, 0}}, +{(unsigned char*)"boxur", {226, 148, 148, 0}}, +{(unsigned char*)"boxv", {226, 148, 130, 0}}, +{(unsigned char*)"boxvH", {226, 149, 170, 0}}, +{(unsigned char*)"boxvL", {226, 149, 161, 0}}, +{(unsigned char*)"boxvR", {226, 149, 158, 0}}, +{(unsigned char*)"boxvh", {226, 148, 188, 0}}, +{(unsigned char*)"boxvl", {226, 148, 164, 0}}, +{(unsigned char*)"boxvr", {226, 148, 156, 0}}, +{(unsigned char*)"bprime", {226, 128, 181, 0}}, +{(unsigned char*)"breve", {203, 152, 0}}, +{(unsigned char*)"brvbar", {194, 166, 0}}, +{(unsigned char*)"bscr", {240, 157, 146, 183, 0}}, +{(unsigned char*)"bsemi", {226, 129, 143, 0}}, +{(unsigned char*)"bsim", {226, 136, 189, 0}}, +{(unsigned char*)"bsime", {226, 139, 141, 0}}, +{(unsigned char*)"bsol", {92, 0}}, +{(unsigned char*)"bsolb", {226, 167, 133, 0}}, +{(unsigned char*)"bsolhsub", {226, 159, 136, 0}}, +{(unsigned char*)"bull", {226, 128, 162, 0}}, +{(unsigned char*)"bullet", {226, 128, 162, 0}}, +{(unsigned char*)"bump", {226, 137, 142, 0}}, +{(unsigned char*)"bumpE", {226, 170, 174, 0}}, +{(unsigned char*)"bumpe", {226, 137, 143, 0}}, +{(unsigned char*)"bumpeq", {226, 137, 143, 0}}, +{(unsigned char*)"cacute", {196, 135, 0}}, +{(unsigned char*)"cap", {226, 136, 169, 0}}, +{(unsigned char*)"capand", {226, 169, 132, 0}}, +{(unsigned char*)"capbrcup", {226, 169, 137, 0}}, +{(unsigned char*)"capcap", {226, 169, 139, 0}}, +{(unsigned char*)"capcup", {226, 169, 135, 0}}, +{(unsigned char*)"capdot", {226, 169, 128, 0}}, +{(unsigned char*)"caps", {226, 136, 169, 239, 184, 128, 0}}, +{(unsigned char*)"caret", {226, 129, 129, 0}}, +{(unsigned char*)"caron", {203, 135, 0}}, +{(unsigned char*)"ccaps", {226, 169, 141, 0}}, +{(unsigned char*)"ccaron", {196, 141, 0}}, +{(unsigned char*)"ccedil", {195, 167, 0}}, +{(unsigned char*)"ccirc", {196, 137, 0}}, +{(unsigned char*)"ccups", {226, 169, 140, 0}}, +{(unsigned char*)"ccupssm", {226, 169, 144, 0}}, +{(unsigned char*)"cdot", {196, 139, 0}}, +{(unsigned char*)"cedil", {194, 184, 0}}, +{(unsigned char*)"cemptyv", {226, 166, 178, 0}}, +{(unsigned char*)"cent", {194, 162, 0}}, +{(unsigned char*)"centerdot", {194, 183, 0}}, +{(unsigned char*)"cfr", {240, 157, 148, 160, 0}}, +{(unsigned char*)"chcy", {209, 135, 0}}, +{(unsigned char*)"check", {226, 156, 147, 0}}, +{(unsigned char*)"checkmark", {226, 156, 147, 0}}, +{(unsigned char*)"chi", {207, 135, 0}}, +{(unsigned char*)"cir", {226, 151, 139, 0}}, +{(unsigned char*)"cirE", {226, 167, 131, 0}}, +{(unsigned char*)"circ", {203, 134, 0}}, +{(unsigned char*)"circeq", {226, 137, 151, 0}}, +{(unsigned char*)"circlearrowleft", {226, 134, 186, 0}}, +{(unsigned char*)"circlearrowright", {226, 134, 187, 0}}, +{(unsigned char*)"circledR", {194, 174, 0}}, +{(unsigned char*)"circledS", {226, 147, 136, 0}}, +{(unsigned char*)"circledast", {226, 138, 155, 0}}, +{(unsigned char*)"circledcirc", {226, 138, 154, 0}}, +{(unsigned char*)"circleddash", {226, 138, 157, 0}}, +{(unsigned char*)"cire", {226, 137, 151, 0}}, +{(unsigned char*)"cirfnint", {226, 168, 144, 0}}, +{(unsigned char*)"cirmid", {226, 171, 175, 0}}, +{(unsigned char*)"cirscir", {226, 167, 130, 0}}, +{(unsigned char*)"clubs", {226, 153, 163, 0}}, +{(unsigned char*)"clubsuit", {226, 153, 163, 0}}, +{(unsigned char*)"colon", {58, 0}}, +{(unsigned char*)"colone", {226, 137, 148, 0}}, +{(unsigned char*)"coloneq", {226, 137, 148, 0}}, +{(unsigned char*)"comma", {44, 0}}, +{(unsigned char*)"commat", {64, 0}}, +{(unsigned char*)"comp", {226, 136, 129, 0}}, +{(unsigned char*)"compfn", {226, 136, 152, 0}}, +{(unsigned char*)"complement", {226, 136, 129, 0}}, +{(unsigned char*)"complexes", {226, 132, 130, 0}}, +{(unsigned char*)"cong", {226, 137, 133, 0}}, +{(unsigned char*)"congdot", {226, 169, 173, 0}}, +{(unsigned char*)"conint", {226, 136, 174, 0}}, +{(unsigned char*)"copf", {240, 157, 149, 148, 0}}, +{(unsigned char*)"coprod", {226, 136, 144, 0}}, +{(unsigned char*)"copy", {194, 169, 0}}, +{(unsigned char*)"copysr", {226, 132, 151, 0}}, +{(unsigned char*)"crarr", {226, 134, 181, 0}}, +{(unsigned char*)"cross", {226, 156, 151, 0}}, +{(unsigned char*)"cscr", {240, 157, 146, 184, 0}}, +{(unsigned char*)"csub", {226, 171, 143, 0}}, +{(unsigned char*)"csube", {226, 171, 145, 0}}, +{(unsigned char*)"csup", {226, 171, 144, 0}}, +{(unsigned char*)"csupe", {226, 171, 146, 0}}, +{(unsigned char*)"ctdot", {226, 139, 175, 0}}, +{(unsigned char*)"cudarrl", {226, 164, 184, 0}}, +{(unsigned char*)"cudarrr", {226, 164, 181, 0}}, +{(unsigned char*)"cuepr", {226, 139, 158, 0}}, +{(unsigned char*)"cuesc", {226, 139, 159, 0}}, +{(unsigned char*)"cularr", {226, 134, 182, 0}}, +{(unsigned char*)"cularrp", {226, 164, 189, 0}}, +{(unsigned char*)"cup", {226, 136, 170, 0}}, +{(unsigned char*)"cupbrcap", {226, 169, 136, 0}}, +{(unsigned char*)"cupcap", {226, 169, 134, 0}}, +{(unsigned char*)"cupcup", {226, 169, 138, 0}}, +{(unsigned char*)"cupdot", {226, 138, 141, 0}}, +{(unsigned char*)"cupor", {226, 169, 133, 0}}, +{(unsigned char*)"cups", {226, 136, 170, 239, 184, 128, 0}}, +{(unsigned char*)"curarr", {226, 134, 183, 0}}, +{(unsigned char*)"curarrm", {226, 164, 188, 0}}, +{(unsigned char*)"curlyeqprec", {226, 139, 158, 0}}, +{(unsigned char*)"curlyeqsucc", {226, 139, 159, 0}}, +{(unsigned char*)"curlyvee", {226, 139, 142, 0}}, +{(unsigned char*)"curlywedge", {226, 139, 143, 0}}, +{(unsigned char*)"curren", {194, 164, 0}}, +{(unsigned char*)"curvearrowleft", {226, 134, 182, 0}}, +{(unsigned char*)"curvearrowright", {226, 134, 183, 0}}, +{(unsigned char*)"cuvee", {226, 139, 142, 0}}, +{(unsigned char*)"cuwed", {226, 139, 143, 0}}, +{(unsigned char*)"cwconint", {226, 136, 178, 0}}, +{(unsigned char*)"cwint", {226, 136, 177, 0}}, +{(unsigned char*)"cylcty", {226, 140, 173, 0}}, +{(unsigned char*)"dArr", {226, 135, 147, 0}}, +{(unsigned char*)"dHar", {226, 165, 165, 0}}, +{(unsigned char*)"dagger", {226, 128, 160, 0}}, +{(unsigned char*)"daleth", {226, 132, 184, 0}}, +{(unsigned char*)"darr", {226, 134, 147, 0}}, +{(unsigned char*)"dash", {226, 128, 144, 0}}, +{(unsigned char*)"dashv", {226, 138, 163, 0}}, +{(unsigned char*)"dbkarow", {226, 164, 143, 0}}, +{(unsigned char*)"dblac", {203, 157, 0}}, +{(unsigned char*)"dcaron", {196, 143, 0}}, +{(unsigned char*)"dcy", {208, 180, 0}}, +{(unsigned char*)"dd", {226, 133, 134, 0}}, +{(unsigned char*)"ddagger", {226, 128, 161, 0}}, +{(unsigned char*)"ddarr", {226, 135, 138, 0}}, +{(unsigned char*)"ddotseq", {226, 169, 183, 0}}, +{(unsigned char*)"deg", {194, 176, 0}}, +{(unsigned char*)"delta", {206, 180, 0}}, +{(unsigned char*)"demptyv", {226, 166, 177, 0}}, +{(unsigned char*)"dfisht", {226, 165, 191, 0}}, +{(unsigned char*)"dfr", {240, 157, 148, 161, 0}}, +{(unsigned char*)"dharl", {226, 135, 131, 0}}, +{(unsigned char*)"dharr", {226, 135, 130, 0}}, +{(unsigned char*)"diam", {226, 139, 132, 0}}, +{(unsigned char*)"diamond", {226, 139, 132, 0}}, +{(unsigned char*)"diamondsuit", {226, 153, 166, 0}}, +{(unsigned char*)"diams", {226, 153, 166, 0}}, +{(unsigned char*)"die", {194, 168, 0}}, +{(unsigned char*)"digamma", {207, 157, 0}}, +{(unsigned char*)"disin", {226, 139, 178, 0}}, +{(unsigned char*)"div", {195, 183, 0}}, +{(unsigned char*)"divide", {195, 183, 0}}, +{(unsigned char*)"divideontimes", {226, 139, 135, 0}}, +{(unsigned char*)"divonx", {226, 139, 135, 0}}, +{(unsigned char*)"djcy", {209, 146, 0}}, +{(unsigned char*)"dlcorn", {226, 140, 158, 0}}, +{(unsigned char*)"dlcrop", {226, 140, 141, 0}}, +{(unsigned char*)"dollar", {36, 0}}, +{(unsigned char*)"dopf", {240, 157, 149, 149, 0}}, +{(unsigned char*)"dot", {203, 153, 0}}, +{(unsigned char*)"doteq", {226, 137, 144, 0}}, +{(unsigned char*)"doteqdot", {226, 137, 145, 0}}, +{(unsigned char*)"dotminus", {226, 136, 184, 0}}, +{(unsigned char*)"dotplus", {226, 136, 148, 0}}, +{(unsigned char*)"dotsquare", {226, 138, 161, 0}}, +{(unsigned char*)"doublebarwedge", {226, 140, 134, 0}}, +{(unsigned char*)"downarrow", {226, 134, 147, 0}}, +{(unsigned char*)"downdownarrows", {226, 135, 138, 0}}, +{(unsigned char*)"downharpoonleft", {226, 135, 131, 0}}, +{(unsigned char*)"downharpoonright", {226, 135, 130, 0}}, +{(unsigned char*)"drbkarow", {226, 164, 144, 0}}, +{(unsigned char*)"drcorn", {226, 140, 159, 0}}, +{(unsigned char*)"drcrop", {226, 140, 140, 0}}, +{(unsigned char*)"dscr", {240, 157, 146, 185, 0}}, +{(unsigned char*)"dscy", {209, 149, 0}}, +{(unsigned char*)"dsol", {226, 167, 182, 0}}, +{(unsigned char*)"dstrok", {196, 145, 0}}, +{(unsigned char*)"dtdot", {226, 139, 177, 0}}, +{(unsigned char*)"dtri", {226, 150, 191, 0}}, +{(unsigned char*)"dtrif", {226, 150, 190, 0}}, +{(unsigned char*)"duarr", {226, 135, 181, 0}}, +{(unsigned char*)"duhar", {226, 165, 175, 0}}, +{(unsigned char*)"dwangle", {226, 166, 166, 0}}, +{(unsigned char*)"dzcy", {209, 159, 0}}, +{(unsigned char*)"dzigrarr", {226, 159, 191, 0}}, +{(unsigned char*)"eDDot", {226, 169, 183, 0}}, +{(unsigned char*)"eDot", {226, 137, 145, 0}}, +{(unsigned char*)"eacute", {195, 169, 0}}, +{(unsigned char*)"easter", {226, 169, 174, 0}}, +{(unsigned char*)"ecaron", {196, 155, 0}}, +{(unsigned char*)"ecir", {226, 137, 150, 0}}, +{(unsigned char*)"ecirc", {195, 170, 0}}, +{(unsigned char*)"ecolon", {226, 137, 149, 0}}, +{(unsigned char*)"ecy", {209, 141, 0}}, +{(unsigned char*)"edot", {196, 151, 0}}, +{(unsigned char*)"ee", {226, 133, 135, 0}}, +{(unsigned char*)"efDot", {226, 137, 146, 0}}, +{(unsigned char*)"efr", {240, 157, 148, 162, 0}}, +{(unsigned char*)"eg", {226, 170, 154, 0}}, +{(unsigned char*)"egrave", {195, 168, 0}}, +{(unsigned char*)"egs", {226, 170, 150, 0}}, +{(unsigned char*)"egsdot", {226, 170, 152, 0}}, +{(unsigned char*)"el", {226, 170, 153, 0}}, +{(unsigned char*)"elinters", {226, 143, 167, 0}}, +{(unsigned char*)"ell", {226, 132, 147, 0}}, +{(unsigned char*)"els", {226, 170, 149, 0}}, +{(unsigned char*)"elsdot", {226, 170, 151, 0}}, +{(unsigned char*)"emacr", {196, 147, 0}}, +{(unsigned char*)"empty", {226, 136, 133, 0}}, +{(unsigned char*)"emptyset", {226, 136, 133, 0}}, +{(unsigned char*)"emptyv", {226, 136, 133, 0}}, +{(unsigned char*)"emsp", {226, 128, 131, 0}}, +{(unsigned char*)"emsp13", {226, 128, 132, 0}}, +{(unsigned char*)"emsp14", {226, 128, 133, 0}}, +{(unsigned char*)"eng", {197, 139, 0}}, +{(unsigned char*)"ensp", {226, 128, 130, 0}}, +{(unsigned char*)"eogon", {196, 153, 0}}, +{(unsigned char*)"eopf", {240, 157, 149, 150, 0}}, +{(unsigned char*)"epar", {226, 139, 149, 0}}, +{(unsigned char*)"eparsl", {226, 167, 163, 0}}, +{(unsigned char*)"eplus", {226, 169, 177, 0}}, +{(unsigned char*)"epsi", {206, 181, 0}}, +{(unsigned char*)"epsilon", {206, 181, 0}}, +{(unsigned char*)"epsiv", {207, 181, 0}}, +{(unsigned char*)"eqcirc", {226, 137, 150, 0}}, +{(unsigned char*)"eqcolon", {226, 137, 149, 0}}, +{(unsigned char*)"eqsim", {226, 137, 130, 0}}, +{(unsigned char*)"eqslantgtr", {226, 170, 150, 0}}, +{(unsigned char*)"eqslantless", {226, 170, 149, 0}}, +{(unsigned char*)"equals", {61, 0}}, +{(unsigned char*)"equest", {226, 137, 159, 0}}, +{(unsigned char*)"equiv", {226, 137, 161, 0}}, +{(unsigned char*)"equivDD", {226, 169, 184, 0}}, +{(unsigned char*)"eqvparsl", {226, 167, 165, 0}}, +{(unsigned char*)"erDot", {226, 137, 147, 0}}, +{(unsigned char*)"erarr", {226, 165, 177, 0}}, +{(unsigned char*)"escr", {226, 132, 175, 0}}, +{(unsigned char*)"esdot", {226, 137, 144, 0}}, +{(unsigned char*)"esim", {226, 137, 130, 0}}, +{(unsigned char*)"eta", {206, 183, 0}}, +{(unsigned char*)"eth", {195, 176, 0}}, +{(unsigned char*)"euml", {195, 171, 0}}, +{(unsigned char*)"euro", {226, 130, 172, 0}}, +{(unsigned char*)"excl", {33, 0}}, +{(unsigned char*)"exist", {226, 136, 131, 0}}, +{(unsigned char*)"expectation", {226, 132, 176, 0}}, +{(unsigned char*)"exponentiale", {226, 133, 135, 0}}, +{(unsigned char*)"fallingdotseq", {226, 137, 146, 0}}, +{(unsigned char*)"fcy", {209, 132, 0}}, +{(unsigned char*)"female", {226, 153, 128, 0}}, +{(unsigned char*)"ffilig", {239, 172, 131, 0}}, +{(unsigned char*)"fflig", {239, 172, 128, 0}}, +{(unsigned char*)"ffllig", {239, 172, 132, 0}}, +{(unsigned char*)"ffr", {240, 157, 148, 163, 0}}, +{(unsigned char*)"filig", {239, 172, 129, 0}}, +{(unsigned char*)"fjlig", {102, 106, 0}}, +{(unsigned char*)"flat", {226, 153, 173, 0}}, +{(unsigned char*)"fllig", {239, 172, 130, 0}}, +{(unsigned char*)"fltns", {226, 150, 177, 0}}, +{(unsigned char*)"fnof", {198, 146, 0}}, +{(unsigned char*)"fopf", {240, 157, 149, 151, 0}}, +{(unsigned char*)"forall", {226, 136, 128, 0}}, +{(unsigned char*)"fork", {226, 139, 148, 0}}, +{(unsigned char*)"forkv", {226, 171, 153, 0}}, +{(unsigned char*)"fpartint", {226, 168, 141, 0}}, +{(unsigned char*)"frac12", {194, 189, 0}}, +{(unsigned char*)"frac13", {226, 133, 147, 0}}, +{(unsigned char*)"frac14", {194, 188, 0}}, +{(unsigned char*)"frac15", {226, 133, 149, 0}}, +{(unsigned char*)"frac16", {226, 133, 153, 0}}, +{(unsigned char*)"frac18", {226, 133, 155, 0}}, +{(unsigned char*)"frac23", {226, 133, 148, 0}}, +{(unsigned char*)"frac25", {226, 133, 150, 0}}, +{(unsigned char*)"frac34", {194, 190, 0}}, +{(unsigned char*)"frac35", {226, 133, 151, 0}}, +{(unsigned char*)"frac38", {226, 133, 156, 0}}, +{(unsigned char*)"frac45", {226, 133, 152, 0}}, +{(unsigned char*)"frac56", {226, 133, 154, 0}}, +{(unsigned char*)"frac58", {226, 133, 157, 0}}, +{(unsigned char*)"frac78", {226, 133, 158, 0}}, +{(unsigned char*)"frasl", {226, 129, 132, 0}}, +{(unsigned char*)"frown", {226, 140, 162, 0}}, +{(unsigned char*)"fscr", {240, 157, 146, 187, 0}}, +{(unsigned char*)"gE", {226, 137, 167, 0}}, +{(unsigned char*)"gEl", {226, 170, 140, 0}}, +{(unsigned char*)"gacute", {199, 181, 0}}, +{(unsigned char*)"gamma", {206, 179, 0}}, +{(unsigned char*)"gammad", {207, 157, 0}}, +{(unsigned char*)"gap", {226, 170, 134, 0}}, +{(unsigned char*)"gbreve", {196, 159, 0}}, +{(unsigned char*)"gcirc", {196, 157, 0}}, +{(unsigned char*)"gcy", {208, 179, 0}}, +{(unsigned char*)"gdot", {196, 161, 0}}, +{(unsigned char*)"ge", {226, 137, 165, 0}}, +{(unsigned char*)"gel", {226, 139, 155, 0}}, +{(unsigned char*)"geq", {226, 137, 165, 0}}, +{(unsigned char*)"geqq", {226, 137, 167, 0}}, +{(unsigned char*)"geqslant", {226, 169, 190, 0}}, +{(unsigned char*)"ges", {226, 169, 190, 0}}, +{(unsigned char*)"gescc", {226, 170, 169, 0}}, +{(unsigned char*)"gesdot", {226, 170, 128, 0}}, +{(unsigned char*)"gesdoto", {226, 170, 130, 0}}, +{(unsigned char*)"gesdotol", {226, 170, 132, 0}}, +{(unsigned char*)"gesl", {226, 139, 155, 239, 184, 128, 0}}, +{(unsigned char*)"gesles", {226, 170, 148, 0}}, +{(unsigned char*)"gfr", {240, 157, 148, 164, 0}}, +{(unsigned char*)"gg", {226, 137, 171, 0}}, +{(unsigned char*)"ggg", {226, 139, 153, 0}}, +{(unsigned char*)"gimel", {226, 132, 183, 0}}, +{(unsigned char*)"gjcy", {209, 147, 0}}, +{(unsigned char*)"gl", {226, 137, 183, 0}}, +{(unsigned char*)"glE", {226, 170, 146, 0}}, +{(unsigned char*)"gla", {226, 170, 165, 0}}, +{(unsigned char*)"glj", {226, 170, 164, 0}}, +{(unsigned char*)"gnE", {226, 137, 169, 0}}, +{(unsigned char*)"gnap", {226, 170, 138, 0}}, +{(unsigned char*)"gnapprox", {226, 170, 138, 0}}, +{(unsigned char*)"gne", {226, 170, 136, 0}}, +{(unsigned char*)"gneq", {226, 170, 136, 0}}, +{(unsigned char*)"gneqq", {226, 137, 169, 0}}, +{(unsigned char*)"gnsim", {226, 139, 167, 0}}, +{(unsigned char*)"gopf", {240, 157, 149, 152, 0}}, +{(unsigned char*)"grave", {96, 0}}, +{(unsigned char*)"gscr", {226, 132, 138, 0}}, +{(unsigned char*)"gsim", {226, 137, 179, 0}}, +{(unsigned char*)"gsime", {226, 170, 142, 0}}, +{(unsigned char*)"gsiml", {226, 170, 144, 0}}, +{(unsigned char*)"gt", {62, 0}}, +{(unsigned char*)"gtcc", {226, 170, 167, 0}}, +{(unsigned char*)"gtcir", {226, 169, 186, 0}}, +{(unsigned char*)"gtdot", {226, 139, 151, 0}}, +{(unsigned char*)"gtlPar", {226, 166, 149, 0}}, +{(unsigned char*)"gtquest", {226, 169, 188, 0}}, +{(unsigned char*)"gtrapprox", {226, 170, 134, 0}}, +{(unsigned char*)"gtrarr", {226, 165, 184, 0}}, +{(unsigned char*)"gtrdot", {226, 139, 151, 0}}, +{(unsigned char*)"gtreqless", {226, 139, 155, 0}}, +{(unsigned char*)"gtreqqless", {226, 170, 140, 0}}, +{(unsigned char*)"gtrless", {226, 137, 183, 0}}, +{(unsigned char*)"gtrsim", {226, 137, 179, 0}}, +{(unsigned char*)"gvertneqq", {226, 137, 169, 239, 184, 128, 0}}, +{(unsigned char*)"gvnE", {226, 137, 169, 239, 184, 128, 0}}, +{(unsigned char*)"hArr", {226, 135, 148, 0}}, +{(unsigned char*)"hairsp", {226, 128, 138, 0}}, +{(unsigned char*)"half", {194, 189, 0}}, +{(unsigned char*)"hamilt", {226, 132, 139, 0}}, +{(unsigned char*)"hardcy", {209, 138, 0}}, +{(unsigned char*)"harr", {226, 134, 148, 0}}, +{(unsigned char*)"harrcir", {226, 165, 136, 0}}, +{(unsigned char*)"harrw", {226, 134, 173, 0}}, +{(unsigned char*)"hbar", {226, 132, 143, 0}}, +{(unsigned char*)"hcirc", {196, 165, 0}}, +{(unsigned char*)"hearts", {226, 153, 165, 0}}, +{(unsigned char*)"heartsuit", {226, 153, 165, 0}}, +{(unsigned char*)"hellip", {226, 128, 166, 0}}, +{(unsigned char*)"hercon", {226, 138, 185, 0}}, +{(unsigned char*)"hfr", {240, 157, 148, 165, 0}}, +{(unsigned char*)"hksearow", {226, 164, 165, 0}}, +{(unsigned char*)"hkswarow", {226, 164, 166, 0}}, +{(unsigned char*)"hoarr", {226, 135, 191, 0}}, +{(unsigned char*)"homtht", {226, 136, 187, 0}}, +{(unsigned char*)"hookleftarrow", {226, 134, 169, 0}}, +{(unsigned char*)"hookrightarrow", {226, 134, 170, 0}}, +{(unsigned char*)"hopf", {240, 157, 149, 153, 0}}, +{(unsigned char*)"horbar", {226, 128, 149, 0}}, +{(unsigned char*)"hscr", {240, 157, 146, 189, 0}}, +{(unsigned char*)"hslash", {226, 132, 143, 0}}, +{(unsigned char*)"hstrok", {196, 167, 0}}, +{(unsigned char*)"hybull", {226, 129, 131, 0}}, +{(unsigned char*)"hyphen", {226, 128, 144, 0}}, +{(unsigned char*)"iacute", {195, 173, 0}}, +{(unsigned char*)"ic", {226, 129, 163, 0}}, +{(unsigned char*)"icirc", {195, 174, 0}}, +{(unsigned char*)"icy", {208, 184, 0}}, +{(unsigned char*)"iecy", {208, 181, 0}}, +{(unsigned char*)"iexcl", {194, 161, 0}}, +{(unsigned char*)"iff", {226, 135, 148, 0}}, +{(unsigned char*)"ifr", {240, 157, 148, 166, 0}}, +{(unsigned char*)"igrave", {195, 172, 0}}, +{(unsigned char*)"ii", {226, 133, 136, 0}}, +{(unsigned char*)"iiiint", {226, 168, 140, 0}}, +{(unsigned char*)"iiint", {226, 136, 173, 0}}, +{(unsigned char*)"iinfin", {226, 167, 156, 0}}, +{(unsigned char*)"iiota", {226, 132, 169, 0}}, +{(unsigned char*)"ijlig", {196, 179, 0}}, +{(unsigned char*)"imacr", {196, 171, 0}}, +{(unsigned char*)"image", {226, 132, 145, 0}}, +{(unsigned char*)"imagline", {226, 132, 144, 0}}, +{(unsigned char*)"imagpart", {226, 132, 145, 0}}, +{(unsigned char*)"imath", {196, 177, 0}}, +{(unsigned char*)"imof", {226, 138, 183, 0}}, +{(unsigned char*)"imped", {198, 181, 0}}, +{(unsigned char*)"in", {226, 136, 136, 0}}, +{(unsigned char*)"incare", {226, 132, 133, 0}}, +{(unsigned char*)"infin", {226, 136, 158, 0}}, +{(unsigned char*)"infintie", {226, 167, 157, 0}}, +{(unsigned char*)"inodot", {196, 177, 0}}, +{(unsigned char*)"int", {226, 136, 171, 0}}, +{(unsigned char*)"intcal", {226, 138, 186, 0}}, +{(unsigned char*)"integers", {226, 132, 164, 0}}, +{(unsigned char*)"intercal", {226, 138, 186, 0}}, +{(unsigned char*)"intlarhk", {226, 168, 151, 0}}, +{(unsigned char*)"intprod", {226, 168, 188, 0}}, +{(unsigned char*)"iocy", {209, 145, 0}}, +{(unsigned char*)"iogon", {196, 175, 0}}, +{(unsigned char*)"iopf", {240, 157, 149, 154, 0}}, +{(unsigned char*)"iota", {206, 185, 0}}, +{(unsigned char*)"iprod", {226, 168, 188, 0}}, +{(unsigned char*)"iquest", {194, 191, 0}}, +{(unsigned char*)"iscr", {240, 157, 146, 190, 0}}, +{(unsigned char*)"isin", {226, 136, 136, 0}}, +{(unsigned char*)"isinE", {226, 139, 185, 0}}, +{(unsigned char*)"isindot", {226, 139, 181, 0}}, +{(unsigned char*)"isins", {226, 139, 180, 0}}, +{(unsigned char*)"isinsv", {226, 139, 179, 0}}, +{(unsigned char*)"isinv", {226, 136, 136, 0}}, +{(unsigned char*)"it", {226, 129, 162, 0}}, +{(unsigned char*)"itilde", {196, 169, 0}}, +{(unsigned char*)"iukcy", {209, 150, 0}}, +{(unsigned char*)"iuml", {195, 175, 0}}, +{(unsigned char*)"jcirc", {196, 181, 0}}, +{(unsigned char*)"jcy", {208, 185, 0}}, +{(unsigned char*)"jfr", {240, 157, 148, 167, 0}}, +{(unsigned char*)"jmath", {200, 183, 0}}, +{(unsigned char*)"jopf", {240, 157, 149, 155, 0}}, +{(unsigned char*)"jscr", {240, 157, 146, 191, 0}}, +{(unsigned char*)"jsercy", {209, 152, 0}}, +{(unsigned char*)"jukcy", {209, 148, 0}}, +{(unsigned char*)"kappa", {206, 186, 0}}, +{(unsigned char*)"kappav", {207, 176, 0}}, +{(unsigned char*)"kcedil", {196, 183, 0}}, +{(unsigned char*)"kcy", {208, 186, 0}}, +{(unsigned char*)"kfr", {240, 157, 148, 168, 0}}, +{(unsigned char*)"kgreen", {196, 184, 0}}, +{(unsigned char*)"khcy", {209, 133, 0}}, +{(unsigned char*)"kjcy", {209, 156, 0}}, +{(unsigned char*)"kopf", {240, 157, 149, 156, 0}}, +{(unsigned char*)"kscr", {240, 157, 147, 128, 0}}, +{(unsigned char*)"lAarr", {226, 135, 154, 0}}, +{(unsigned char*)"lArr", {226, 135, 144, 0}}, +{(unsigned char*)"lAtail", {226, 164, 155, 0}}, +{(unsigned char*)"lBarr", {226, 164, 142, 0}}, +{(unsigned char*)"lE", {226, 137, 166, 0}}, +{(unsigned char*)"lEg", {226, 170, 139, 0}}, +{(unsigned char*)"lHar", {226, 165, 162, 0}}, +{(unsigned char*)"lacute", {196, 186, 0}}, +{(unsigned char*)"laemptyv", {226, 166, 180, 0}}, +{(unsigned char*)"lagran", {226, 132, 146, 0}}, +{(unsigned char*)"lambda", {206, 187, 0}}, +{(unsigned char*)"lang", {226, 159, 168, 0}}, +{(unsigned char*)"langd", {226, 166, 145, 0}}, +{(unsigned char*)"langle", {226, 159, 168, 0}}, +{(unsigned char*)"lap", {226, 170, 133, 0}}, +{(unsigned char*)"laquo", {194, 171, 0}}, +{(unsigned char*)"larr", {226, 134, 144, 0}}, +{(unsigned char*)"larrb", {226, 135, 164, 0}}, +{(unsigned char*)"larrbfs", {226, 164, 159, 0}}, +{(unsigned char*)"larrfs", {226, 164, 157, 0}}, +{(unsigned char*)"larrhk", {226, 134, 169, 0}}, +{(unsigned char*)"larrlp", {226, 134, 171, 0}}, +{(unsigned char*)"larrpl", {226, 164, 185, 0}}, +{(unsigned char*)"larrsim", {226, 165, 179, 0}}, +{(unsigned char*)"larrtl", {226, 134, 162, 0}}, +{(unsigned char*)"lat", {226, 170, 171, 0}}, +{(unsigned char*)"latail", {226, 164, 153, 0}}, +{(unsigned char*)"late", {226, 170, 173, 0}}, +{(unsigned char*)"lates", {226, 170, 173, 239, 184, 128, 0}}, +{(unsigned char*)"lbarr", {226, 164, 140, 0}}, +{(unsigned char*)"lbbrk", {226, 157, 178, 0}}, +{(unsigned char*)"lbrace", {123, 0}}, +{(unsigned char*)"lbrack", {91, 0}}, +{(unsigned char*)"lbrke", {226, 166, 139, 0}}, +{(unsigned char*)"lbrksld", {226, 166, 143, 0}}, +{(unsigned char*)"lbrkslu", {226, 166, 141, 0}}, +{(unsigned char*)"lcaron", {196, 190, 0}}, +{(unsigned char*)"lcedil", {196, 188, 0}}, +{(unsigned char*)"lceil", {226, 140, 136, 0}}, +{(unsigned char*)"lcub", {123, 0}}, +{(unsigned char*)"lcy", {208, 187, 0}}, +{(unsigned char*)"ldca", {226, 164, 182, 0}}, +{(unsigned char*)"ldquo", {226, 128, 156, 0}}, +{(unsigned char*)"ldquor", {226, 128, 158, 0}}, +{(unsigned char*)"ldrdhar", {226, 165, 167, 0}}, +{(unsigned char*)"ldrushar", {226, 165, 139, 0}}, +{(unsigned char*)"ldsh", {226, 134, 178, 0}}, +{(unsigned char*)"le", {226, 137, 164, 0}}, +{(unsigned char*)"leftarrow", {226, 134, 144, 0}}, +{(unsigned char*)"leftarrowtail", {226, 134, 162, 0}}, +{(unsigned char*)"leftharpoondown", {226, 134, 189, 0}}, +{(unsigned char*)"leftharpoonup", {226, 134, 188, 0}}, +{(unsigned char*)"leftleftarrows", {226, 135, 135, 0}}, +{(unsigned char*)"leftrightarrow", {226, 134, 148, 0}}, +{(unsigned char*)"leftrightarrows", {226, 135, 134, 0}}, +{(unsigned char*)"leftrightharpoons", {226, 135, 139, 0}}, +{(unsigned char*)"leftrightsquigarrow", {226, 134, 173, 0}}, +{(unsigned char*)"leftthreetimes", {226, 139, 139, 0}}, +{(unsigned char*)"leg", {226, 139, 154, 0}}, +{(unsigned char*)"leq", {226, 137, 164, 0}}, +{(unsigned char*)"leqq", {226, 137, 166, 0}}, +{(unsigned char*)"leqslant", {226, 169, 189, 0}}, +{(unsigned char*)"les", {226, 169, 189, 0}}, +{(unsigned char*)"lescc", {226, 170, 168, 0}}, +{(unsigned char*)"lesdot", {226, 169, 191, 0}}, +{(unsigned char*)"lesdoto", {226, 170, 129, 0}}, +{(unsigned char*)"lesdotor", {226, 170, 131, 0}}, +{(unsigned char*)"lesg", {226, 139, 154, 239, 184, 128, 0}}, +{(unsigned char*)"lesges", {226, 170, 147, 0}}, +{(unsigned char*)"lessapprox", {226, 170, 133, 0}}, +{(unsigned char*)"lessdot", {226, 139, 150, 0}}, +{(unsigned char*)"lesseqgtr", {226, 139, 154, 0}}, +{(unsigned char*)"lesseqqgtr", {226, 170, 139, 0}}, +{(unsigned char*)"lessgtr", {226, 137, 182, 0}}, +{(unsigned char*)"lesssim", {226, 137, 178, 0}}, +{(unsigned char*)"lfisht", {226, 165, 188, 0}}, +{(unsigned char*)"lfloor", {226, 140, 138, 0}}, +{(unsigned char*)"lfr", {240, 157, 148, 169, 0}}, +{(unsigned char*)"lg", {226, 137, 182, 0}}, +{(unsigned char*)"lgE", {226, 170, 145, 0}}, +{(unsigned char*)"lhard", {226, 134, 189, 0}}, +{(unsigned char*)"lharu", {226, 134, 188, 0}}, +{(unsigned char*)"lharul", {226, 165, 170, 0}}, +{(unsigned char*)"lhblk", {226, 150, 132, 0}}, +{(unsigned char*)"ljcy", {209, 153, 0}}, +{(unsigned char*)"ll", {226, 137, 170, 0}}, +{(unsigned char*)"llarr", {226, 135, 135, 0}}, +{(unsigned char*)"llcorner", {226, 140, 158, 0}}, +{(unsigned char*)"llhard", {226, 165, 171, 0}}, +{(unsigned char*)"lltri", {226, 151, 186, 0}}, +{(unsigned char*)"lmidot", {197, 128, 0}}, +{(unsigned char*)"lmoust", {226, 142, 176, 0}}, +{(unsigned char*)"lmoustache", {226, 142, 176, 0}}, +{(unsigned char*)"lnE", {226, 137, 168, 0}}, +{(unsigned char*)"lnap", {226, 170, 137, 0}}, +{(unsigned char*)"lnapprox", {226, 170, 137, 0}}, +{(unsigned char*)"lne", {226, 170, 135, 0}}, +{(unsigned char*)"lneq", {226, 170, 135, 0}}, +{(unsigned char*)"lneqq", {226, 137, 168, 0}}, +{(unsigned char*)"lnsim", {226, 139, 166, 0}}, +{(unsigned char*)"loang", {226, 159, 172, 0}}, +{(unsigned char*)"loarr", {226, 135, 189, 0}}, +{(unsigned char*)"lobrk", {226, 159, 166, 0}}, +{(unsigned char*)"longleftarrow", {226, 159, 181, 0}}, +{(unsigned char*)"longleftrightarrow", {226, 159, 183, 0}}, +{(unsigned char*)"longmapsto", {226, 159, 188, 0}}, +{(unsigned char*)"longrightarrow", {226, 159, 182, 0}}, +{(unsigned char*)"looparrowleft", {226, 134, 171, 0}}, +{(unsigned char*)"looparrowright", {226, 134, 172, 0}}, +{(unsigned char*)"lopar", {226, 166, 133, 0}}, +{(unsigned char*)"lopf", {240, 157, 149, 157, 0}}, +{(unsigned char*)"loplus", {226, 168, 173, 0}}, +{(unsigned char*)"lotimes", {226, 168, 180, 0}}, +{(unsigned char*)"lowast", {226, 136, 151, 0}}, +{(unsigned char*)"lowbar", {95, 0}}, +{(unsigned char*)"loz", {226, 151, 138, 0}}, +{(unsigned char*)"lozenge", {226, 151, 138, 0}}, +{(unsigned char*)"lozf", {226, 167, 171, 0}}, +{(unsigned char*)"lpar", {40, 0}}, +{(unsigned char*)"lparlt", {226, 166, 147, 0}}, +{(unsigned char*)"lrarr", {226, 135, 134, 0}}, +{(unsigned char*)"lrcorner", {226, 140, 159, 0}}, +{(unsigned char*)"lrhar", {226, 135, 139, 0}}, +{(unsigned char*)"lrhard", {226, 165, 173, 0}}, +{(unsigned char*)"lrm", {226, 128, 142, 0}}, +{(unsigned char*)"lrtri", {226, 138, 191, 0}}, +{(unsigned char*)"lsaquo", {226, 128, 185, 0}}, +{(unsigned char*)"lscr", {240, 157, 147, 129, 0}}, +{(unsigned char*)"lsh", {226, 134, 176, 0}}, +{(unsigned char*)"lsim", {226, 137, 178, 0}}, +{(unsigned char*)"lsime", {226, 170, 141, 0}}, +{(unsigned char*)"lsimg", {226, 170, 143, 0}}, +{(unsigned char*)"lsqb", {91, 0}}, +{(unsigned char*)"lsquo", {226, 128, 152, 0}}, +{(unsigned char*)"lsquor", {226, 128, 154, 0}}, +{(unsigned char*)"lstrok", {197, 130, 0}}, +{(unsigned char*)"lt", {60, 0}}, +{(unsigned char*)"ltcc", {226, 170, 166, 0}}, +{(unsigned char*)"ltcir", {226, 169, 185, 0}}, +{(unsigned char*)"ltdot", {226, 139, 150, 0}}, +{(unsigned char*)"lthree", {226, 139, 139, 0}}, +{(unsigned char*)"ltimes", {226, 139, 137, 0}}, +{(unsigned char*)"ltlarr", {226, 165, 182, 0}}, +{(unsigned char*)"ltquest", {226, 169, 187, 0}}, +{(unsigned char*)"ltrPar", {226, 166, 150, 0}}, +{(unsigned char*)"ltri", {226, 151, 131, 0}}, +{(unsigned char*)"ltrie", {226, 138, 180, 0}}, +{(unsigned char*)"ltrif", {226, 151, 130, 0}}, +{(unsigned char*)"lurdshar", {226, 165, 138, 0}}, +{(unsigned char*)"luruhar", {226, 165, 166, 0}}, +{(unsigned char*)"lvertneqq", {226, 137, 168, 239, 184, 128, 0}}, +{(unsigned char*)"lvnE", {226, 137, 168, 239, 184, 128, 0}}, +{(unsigned char*)"mDDot", {226, 136, 186, 0}}, +{(unsigned char*)"macr", {194, 175, 0}}, +{(unsigned char*)"male", {226, 153, 130, 0}}, +{(unsigned char*)"malt", {226, 156, 160, 0}}, +{(unsigned char*)"maltese", {226, 156, 160, 0}}, +{(unsigned char*)"map", {226, 134, 166, 0}}, +{(unsigned char*)"mapsto", {226, 134, 166, 0}}, +{(unsigned char*)"mapstodown", {226, 134, 167, 0}}, +{(unsigned char*)"mapstoleft", {226, 134, 164, 0}}, +{(unsigned char*)"mapstoup", {226, 134, 165, 0}}, +{(unsigned char*)"marker", {226, 150, 174, 0}}, +{(unsigned char*)"mcomma", {226, 168, 169, 0}}, +{(unsigned char*)"mcy", {208, 188, 0}}, +{(unsigned char*)"mdash", {226, 128, 148, 0}}, +{(unsigned char*)"measuredangle", {226, 136, 161, 0}}, +{(unsigned char*)"mfr", {240, 157, 148, 170, 0}}, +{(unsigned char*)"mho", {226, 132, 167, 0}}, +{(unsigned char*)"micro", {194, 181, 0}}, +{(unsigned char*)"mid", {226, 136, 163, 0}}, +{(unsigned char*)"midast", {42, 0}}, +{(unsigned char*)"midcir", {226, 171, 176, 0}}, +{(unsigned char*)"middot", {194, 183, 0}}, +{(unsigned char*)"minus", {226, 136, 146, 0}}, +{(unsigned char*)"minusb", {226, 138, 159, 0}}, +{(unsigned char*)"minusd", {226, 136, 184, 0}}, +{(unsigned char*)"minusdu", {226, 168, 170, 0}}, +{(unsigned char*)"mlcp", {226, 171, 155, 0}}, +{(unsigned char*)"mldr", {226, 128, 166, 0}}, +{(unsigned char*)"mnplus", {226, 136, 147, 0}}, +{(unsigned char*)"models", {226, 138, 167, 0}}, +{(unsigned char*)"mopf", {240, 157, 149, 158, 0}}, +{(unsigned char*)"mp", {226, 136, 147, 0}}, +{(unsigned char*)"mscr", {240, 157, 147, 130, 0}}, +{(unsigned char*)"mstpos", {226, 136, 190, 0}}, +{(unsigned char*)"mu", {206, 188, 0}}, +{(unsigned char*)"multimap", {226, 138, 184, 0}}, +{(unsigned char*)"mumap", {226, 138, 184, 0}}, +{(unsigned char*)"nGg", {226, 139, 153, 204, 184, 0}}, +{(unsigned char*)"nGt", {226, 137, 171, 226, 131, 146, 0}}, +{(unsigned char*)"nGtv", {226, 137, 171, 204, 184, 0}}, +{(unsigned char*)"nLeftarrow", {226, 135, 141, 0}}, +{(unsigned char*)"nLeftrightarrow", {226, 135, 142, 0}}, +{(unsigned char*)"nLl", {226, 139, 152, 204, 184, 0}}, +{(unsigned char*)"nLt", {226, 137, 170, 226, 131, 146, 0}}, +{(unsigned char*)"nLtv", {226, 137, 170, 204, 184, 0}}, +{(unsigned char*)"nRightarrow", {226, 135, 143, 0}}, +{(unsigned char*)"nVDash", {226, 138, 175, 0}}, +{(unsigned char*)"nVdash", {226, 138, 174, 0}}, +{(unsigned char*)"nabla", {226, 136, 135, 0}}, +{(unsigned char*)"nacute", {197, 132, 0}}, +{(unsigned char*)"nang", {226, 136, 160, 226, 131, 146, 0}}, +{(unsigned char*)"nap", {226, 137, 137, 0}}, +{(unsigned char*)"napE", {226, 169, 176, 204, 184, 0}}, +{(unsigned char*)"napid", {226, 137, 139, 204, 184, 0}}, +{(unsigned char*)"napos", {197, 137, 0}}, +{(unsigned char*)"napprox", {226, 137, 137, 0}}, +{(unsigned char*)"natur", {226, 153, 174, 0}}, +{(unsigned char*)"natural", {226, 153, 174, 0}}, +{(unsigned char*)"naturals", {226, 132, 149, 0}}, +{(unsigned char*)"nbsp", {194, 160, 0}}, +{(unsigned char*)"nbump", {226, 137, 142, 204, 184, 0}}, +{(unsigned char*)"nbumpe", {226, 137, 143, 204, 184, 0}}, +{(unsigned char*)"ncap", {226, 169, 131, 0}}, +{(unsigned char*)"ncaron", {197, 136, 0}}, +{(unsigned char*)"ncedil", {197, 134, 0}}, +{(unsigned char*)"ncong", {226, 137, 135, 0}}, +{(unsigned char*)"ncongdot", {226, 169, 173, 204, 184, 0}}, +{(unsigned char*)"ncup", {226, 169, 130, 0}}, +{(unsigned char*)"ncy", {208, 189, 0}}, +{(unsigned char*)"ndash", {226, 128, 147, 0}}, +{(unsigned char*)"ne", {226, 137, 160, 0}}, +{(unsigned char*)"neArr", {226, 135, 151, 0}}, +{(unsigned char*)"nearhk", {226, 164, 164, 0}}, +{(unsigned char*)"nearr", {226, 134, 151, 0}}, +{(unsigned char*)"nearrow", {226, 134, 151, 0}}, +{(unsigned char*)"nedot", {226, 137, 144, 204, 184, 0}}, +{(unsigned char*)"nequiv", {226, 137, 162, 0}}, +{(unsigned char*)"nesear", {226, 164, 168, 0}}, +{(unsigned char*)"nesim", {226, 137, 130, 204, 184, 0}}, +{(unsigned char*)"nexist", {226, 136, 132, 0}}, +{(unsigned char*)"nexists", {226, 136, 132, 0}}, +{(unsigned char*)"nfr", {240, 157, 148, 171, 0}}, +{(unsigned char*)"ngE", {226, 137, 167, 204, 184, 0}}, +{(unsigned char*)"nge", {226, 137, 177, 0}}, +{(unsigned char*)"ngeq", {226, 137, 177, 0}}, +{(unsigned char*)"ngeqq", {226, 137, 167, 204, 184, 0}}, +{(unsigned char*)"ngeqslant", {226, 169, 190, 204, 184, 0}}, +{(unsigned char*)"nges", {226, 169, 190, 204, 184, 0}}, +{(unsigned char*)"ngsim", {226, 137, 181, 0}}, +{(unsigned char*)"ngt", {226, 137, 175, 0}}, +{(unsigned char*)"ngtr", {226, 137, 175, 0}}, +{(unsigned char*)"nhArr", {226, 135, 142, 0}}, +{(unsigned char*)"nharr", {226, 134, 174, 0}}, +{(unsigned char*)"nhpar", {226, 171, 178, 0}}, +{(unsigned char*)"ni", {226, 136, 139, 0}}, +{(unsigned char*)"nis", {226, 139, 188, 0}}, +{(unsigned char*)"nisd", {226, 139, 186, 0}}, +{(unsigned char*)"niv", {226, 136, 139, 0}}, +{(unsigned char*)"njcy", {209, 154, 0}}, +{(unsigned char*)"nlArr", {226, 135, 141, 0}}, +{(unsigned char*)"nlE", {226, 137, 166, 204, 184, 0}}, +{(unsigned char*)"nlarr", {226, 134, 154, 0}}, +{(unsigned char*)"nldr", {226, 128, 165, 0}}, +{(unsigned char*)"nle", {226, 137, 176, 0}}, +{(unsigned char*)"nleftarrow", {226, 134, 154, 0}}, +{(unsigned char*)"nleftrightarrow", {226, 134, 174, 0}}, +{(unsigned char*)"nleq", {226, 137, 176, 0}}, +{(unsigned char*)"nleqq", {226, 137, 166, 204, 184, 0}}, +{(unsigned char*)"nleqslant", {226, 169, 189, 204, 184, 0}}, +{(unsigned char*)"nles", {226, 169, 189, 204, 184, 0}}, +{(unsigned char*)"nless", {226, 137, 174, 0}}, +{(unsigned char*)"nlsim", {226, 137, 180, 0}}, +{(unsigned char*)"nlt", {226, 137, 174, 0}}, +{(unsigned char*)"nltri", {226, 139, 170, 0}}, +{(unsigned char*)"nltrie", {226, 139, 172, 0}}, +{(unsigned char*)"nmid", {226, 136, 164, 0}}, +{(unsigned char*)"nopf", {240, 157, 149, 159, 0}}, +{(unsigned char*)"not", {194, 172, 0}}, +{(unsigned char*)"notin", {226, 136, 137, 0}}, +{(unsigned char*)"notinE", {226, 139, 185, 204, 184, 0}}, +{(unsigned char*)"notindot", {226, 139, 181, 204, 184, 0}}, +{(unsigned char*)"notinva", {226, 136, 137, 0}}, +{(unsigned char*)"notinvb", {226, 139, 183, 0}}, +{(unsigned char*)"notinvc", {226, 139, 182, 0}}, +{(unsigned char*)"notni", {226, 136, 140, 0}}, +{(unsigned char*)"notniva", {226, 136, 140, 0}}, +{(unsigned char*)"notnivb", {226, 139, 190, 0}}, +{(unsigned char*)"notnivc", {226, 139, 189, 0}}, +{(unsigned char*)"npar", {226, 136, 166, 0}}, +{(unsigned char*)"nparallel", {226, 136, 166, 0}}, +{(unsigned char*)"nparsl", {226, 171, 189, 226, 131, 165, 0}}, +{(unsigned char*)"npart", {226, 136, 130, 204, 184, 0}}, +{(unsigned char*)"npolint", {226, 168, 148, 0}}, +{(unsigned char*)"npr", {226, 138, 128, 0}}, +{(unsigned char*)"nprcue", {226, 139, 160, 0}}, +{(unsigned char*)"npre", {226, 170, 175, 204, 184, 0}}, +{(unsigned char*)"nprec", {226, 138, 128, 0}}, +{(unsigned char*)"npreceq", {226, 170, 175, 204, 184, 0}}, +{(unsigned char*)"nrArr", {226, 135, 143, 0}}, +{(unsigned char*)"nrarr", {226, 134, 155, 0}}, +{(unsigned char*)"nrarrc", {226, 164, 179, 204, 184, 0}}, +{(unsigned char*)"nrarrw", {226, 134, 157, 204, 184, 0}}, +{(unsigned char*)"nrightarrow", {226, 134, 155, 0}}, +{(unsigned char*)"nrtri", {226, 139, 171, 0}}, +{(unsigned char*)"nrtrie", {226, 139, 173, 0}}, +{(unsigned char*)"nsc", {226, 138, 129, 0}}, +{(unsigned char*)"nsccue", {226, 139, 161, 0}}, +{(unsigned char*)"nsce", {226, 170, 176, 204, 184, 0}}, +{(unsigned char*)"nscr", {240, 157, 147, 131, 0}}, +{(unsigned char*)"nshortmid", {226, 136, 164, 0}}, +{(unsigned char*)"nshortparallel", {226, 136, 166, 0}}, +{(unsigned char*)"nsim", {226, 137, 129, 0}}, +{(unsigned char*)"nsime", {226, 137, 132, 0}}, +{(unsigned char*)"nsimeq", {226, 137, 132, 0}}, +{(unsigned char*)"nsmid", {226, 136, 164, 0}}, +{(unsigned char*)"nspar", {226, 136, 166, 0}}, +{(unsigned char*)"nsqsube", {226, 139, 162, 0}}, +{(unsigned char*)"nsqsupe", {226, 139, 163, 0}}, +{(unsigned char*)"nsub", {226, 138, 132, 0}}, +{(unsigned char*)"nsubE", {226, 171, 133, 204, 184, 0}}, +{(unsigned char*)"nsube", {226, 138, 136, 0}}, +{(unsigned char*)"nsubset", {226, 138, 130, 226, 131, 146, 0}}, +{(unsigned char*)"nsubseteq", {226, 138, 136, 0}}, +{(unsigned char*)"nsubseteqq", {226, 171, 133, 204, 184, 0}}, +{(unsigned char*)"nsucc", {226, 138, 129, 0}}, +{(unsigned char*)"nsucceq", {226, 170, 176, 204, 184, 0}}, +{(unsigned char*)"nsup", {226, 138, 133, 0}}, +{(unsigned char*)"nsupE", {226, 171, 134, 204, 184, 0}}, +{(unsigned char*)"nsupe", {226, 138, 137, 0}}, +{(unsigned char*)"nsupset", {226, 138, 131, 226, 131, 146, 0}}, +{(unsigned char*)"nsupseteq", {226, 138, 137, 0}}, +{(unsigned char*)"nsupseteqq", {226, 171, 134, 204, 184, 0}}, +{(unsigned char*)"ntgl", {226, 137, 185, 0}}, +{(unsigned char*)"ntilde", {195, 177, 0}}, +{(unsigned char*)"ntlg", {226, 137, 184, 0}}, +{(unsigned char*)"ntriangleleft", {226, 139, 170, 0}}, +{(unsigned char*)"ntrianglelefteq", {226, 139, 172, 0}}, +{(unsigned char*)"ntriangleright", {226, 139, 171, 0}}, +{(unsigned char*)"ntrianglerighteq", {226, 139, 173, 0}}, +{(unsigned char*)"nu", {206, 189, 0}}, +{(unsigned char*)"num", {35, 0}}, +{(unsigned char*)"numero", {226, 132, 150, 0}}, +{(unsigned char*)"numsp", {226, 128, 135, 0}}, +{(unsigned char*)"nvDash", {226, 138, 173, 0}}, +{(unsigned char*)"nvHarr", {226, 164, 132, 0}}, +{(unsigned char*)"nvap", {226, 137, 141, 226, 131, 146, 0}}, +{(unsigned char*)"nvdash", {226, 138, 172, 0}}, +{(unsigned char*)"nvge", {226, 137, 165, 226, 131, 146, 0}}, +{(unsigned char*)"nvgt", {62, 226, 131, 146, 0}}, +{(unsigned char*)"nvinfin", {226, 167, 158, 0}}, +{(unsigned char*)"nvlArr", {226, 164, 130, 0}}, +{(unsigned char*)"nvle", {226, 137, 164, 226, 131, 146, 0}}, +{(unsigned char*)"nvlt", {60, 226, 131, 146, 0}}, +{(unsigned char*)"nvltrie", {226, 138, 180, 226, 131, 146, 0}}, +{(unsigned char*)"nvrArr", {226, 164, 131, 0}}, +{(unsigned char*)"nvrtrie", {226, 138, 181, 226, 131, 146, 0}}, +{(unsigned char*)"nvsim", {226, 136, 188, 226, 131, 146, 0}}, +{(unsigned char*)"nwArr", {226, 135, 150, 0}}, +{(unsigned char*)"nwarhk", {226, 164, 163, 0}}, +{(unsigned char*)"nwarr", {226, 134, 150, 0}}, +{(unsigned char*)"nwarrow", {226, 134, 150, 0}}, +{(unsigned char*)"nwnear", {226, 164, 167, 0}}, +{(unsigned char*)"oS", {226, 147, 136, 0}}, +{(unsigned char*)"oacute", {195, 179, 0}}, +{(unsigned char*)"oast", {226, 138, 155, 0}}, +{(unsigned char*)"ocir", {226, 138, 154, 0}}, +{(unsigned char*)"ocirc", {195, 180, 0}}, +{(unsigned char*)"ocy", {208, 190, 0}}, +{(unsigned char*)"odash", {226, 138, 157, 0}}, +{(unsigned char*)"odblac", {197, 145, 0}}, +{(unsigned char*)"odiv", {226, 168, 184, 0}}, +{(unsigned char*)"odot", {226, 138, 153, 0}}, +{(unsigned char*)"odsold", {226, 166, 188, 0}}, +{(unsigned char*)"oelig", {197, 147, 0}}, +{(unsigned char*)"ofcir", {226, 166, 191, 0}}, +{(unsigned char*)"ofr", {240, 157, 148, 172, 0}}, +{(unsigned char*)"ogon", {203, 155, 0}}, +{(unsigned char*)"ograve", {195, 178, 0}}, +{(unsigned char*)"ogt", {226, 167, 129, 0}}, +{(unsigned char*)"ohbar", {226, 166, 181, 0}}, +{(unsigned char*)"ohm", {206, 169, 0}}, +{(unsigned char*)"oint", {226, 136, 174, 0}}, +{(unsigned char*)"olarr", {226, 134, 186, 0}}, +{(unsigned char*)"olcir", {226, 166, 190, 0}}, +{(unsigned char*)"olcross", {226, 166, 187, 0}}, +{(unsigned char*)"oline", {226, 128, 190, 0}}, +{(unsigned char*)"olt", {226, 167, 128, 0}}, +{(unsigned char*)"omacr", {197, 141, 0}}, +{(unsigned char*)"omega", {207, 137, 0}}, +{(unsigned char*)"omicron", {206, 191, 0}}, +{(unsigned char*)"omid", {226, 166, 182, 0}}, +{(unsigned char*)"ominus", {226, 138, 150, 0}}, +{(unsigned char*)"oopf", {240, 157, 149, 160, 0}}, +{(unsigned char*)"opar", {226, 166, 183, 0}}, +{(unsigned char*)"operp", {226, 166, 185, 0}}, +{(unsigned char*)"oplus", {226, 138, 149, 0}}, +{(unsigned char*)"or", {226, 136, 168, 0}}, +{(unsigned char*)"orarr", {226, 134, 187, 0}}, +{(unsigned char*)"ord", {226, 169, 157, 0}}, +{(unsigned char*)"order", {226, 132, 180, 0}}, +{(unsigned char*)"orderof", {226, 132, 180, 0}}, +{(unsigned char*)"ordf", {194, 170, 0}}, +{(unsigned char*)"ordm", {194, 186, 0}}, +{(unsigned char*)"origof", {226, 138, 182, 0}}, +{(unsigned char*)"oror", {226, 169, 150, 0}}, +{(unsigned char*)"orslope", {226, 169, 151, 0}}, +{(unsigned char*)"orv", {226, 169, 155, 0}}, +{(unsigned char*)"oscr", {226, 132, 180, 0}}, +{(unsigned char*)"oslash", {195, 184, 0}}, +{(unsigned char*)"osol", {226, 138, 152, 0}}, +{(unsigned char*)"otilde", {195, 181, 0}}, +{(unsigned char*)"otimes", {226, 138, 151, 0}}, +{(unsigned char*)"otimesas", {226, 168, 182, 0}}, +{(unsigned char*)"ouml", {195, 182, 0}}, +{(unsigned char*)"ovbar", {226, 140, 189, 0}}, +{(unsigned char*)"par", {226, 136, 165, 0}}, +{(unsigned char*)"para", {194, 182, 0}}, +{(unsigned char*)"parallel", {226, 136, 165, 0}}, +{(unsigned char*)"parsim", {226, 171, 179, 0}}, +{(unsigned char*)"parsl", {226, 171, 189, 0}}, +{(unsigned char*)"part", {226, 136, 130, 0}}, +{(unsigned char*)"pcy", {208, 191, 0}}, +{(unsigned char*)"percnt", {37, 0}}, +{(unsigned char*)"period", {46, 0}}, +{(unsigned char*)"permil", {226, 128, 176, 0}}, +{(unsigned char*)"perp", {226, 138, 165, 0}}, +{(unsigned char*)"pertenk", {226, 128, 177, 0}}, +{(unsigned char*)"pfr", {240, 157, 148, 173, 0}}, +{(unsigned char*)"phi", {207, 134, 0}}, +{(unsigned char*)"phiv", {207, 149, 0}}, +{(unsigned char*)"phmmat", {226, 132, 179, 0}}, +{(unsigned char*)"phone", {226, 152, 142, 0}}, +{(unsigned char*)"pi", {207, 128, 0}}, +{(unsigned char*)"pitchfork", {226, 139, 148, 0}}, +{(unsigned char*)"piv", {207, 150, 0}}, +{(unsigned char*)"planck", {226, 132, 143, 0}}, +{(unsigned char*)"planckh", {226, 132, 142, 0}}, +{(unsigned char*)"plankv", {226, 132, 143, 0}}, +{(unsigned char*)"plus", {43, 0}}, +{(unsigned char*)"plusacir", {226, 168, 163, 0}}, +{(unsigned char*)"plusb", {226, 138, 158, 0}}, +{(unsigned char*)"pluscir", {226, 168, 162, 0}}, +{(unsigned char*)"plusdo", {226, 136, 148, 0}}, +{(unsigned char*)"plusdu", {226, 168, 165, 0}}, +{(unsigned char*)"pluse", {226, 169, 178, 0}}, +{(unsigned char*)"plusmn", {194, 177, 0}}, +{(unsigned char*)"plussim", {226, 168, 166, 0}}, +{(unsigned char*)"plustwo", {226, 168, 167, 0}}, +{(unsigned char*)"pm", {194, 177, 0}}, +{(unsigned char*)"pointint", {226, 168, 149, 0}}, +{(unsigned char*)"popf", {240, 157, 149, 161, 0}}, +{(unsigned char*)"pound", {194, 163, 0}}, +{(unsigned char*)"pr", {226, 137, 186, 0}}, +{(unsigned char*)"prE", {226, 170, 179, 0}}, +{(unsigned char*)"prap", {226, 170, 183, 0}}, +{(unsigned char*)"prcue", {226, 137, 188, 0}}, +{(unsigned char*)"pre", {226, 170, 175, 0}}, +{(unsigned char*)"prec", {226, 137, 186, 0}}, +{(unsigned char*)"precapprox", {226, 170, 183, 0}}, +{(unsigned char*)"preccurlyeq", {226, 137, 188, 0}}, +{(unsigned char*)"preceq", {226, 170, 175, 0}}, +{(unsigned char*)"precnapprox", {226, 170, 185, 0}}, +{(unsigned char*)"precneqq", {226, 170, 181, 0}}, +{(unsigned char*)"precnsim", {226, 139, 168, 0}}, +{(unsigned char*)"precsim", {226, 137, 190, 0}}, +{(unsigned char*)"prime", {226, 128, 178, 0}}, +{(unsigned char*)"primes", {226, 132, 153, 0}}, +{(unsigned char*)"prnE", {226, 170, 181, 0}}, +{(unsigned char*)"prnap", {226, 170, 185, 0}}, +{(unsigned char*)"prnsim", {226, 139, 168, 0}}, +{(unsigned char*)"prod", {226, 136, 143, 0}}, +{(unsigned char*)"profalar", {226, 140, 174, 0}}, +{(unsigned char*)"profline", {226, 140, 146, 0}}, +{(unsigned char*)"profsurf", {226, 140, 147, 0}}, +{(unsigned char*)"prop", {226, 136, 157, 0}}, +{(unsigned char*)"propto", {226, 136, 157, 0}}, +{(unsigned char*)"prsim", {226, 137, 190, 0}}, +{(unsigned char*)"prurel", {226, 138, 176, 0}}, +{(unsigned char*)"pscr", {240, 157, 147, 133, 0}}, +{(unsigned char*)"psi", {207, 136, 0}}, +{(unsigned char*)"puncsp", {226, 128, 136, 0}}, +{(unsigned char*)"qfr", {240, 157, 148, 174, 0}}, +{(unsigned char*)"qint", {226, 168, 140, 0}}, +{(unsigned char*)"qopf", {240, 157, 149, 162, 0}}, +{(unsigned char*)"qprime", {226, 129, 151, 0}}, +{(unsigned char*)"qscr", {240, 157, 147, 134, 0}}, +{(unsigned char*)"quaternions", {226, 132, 141, 0}}, +{(unsigned char*)"quatint", {226, 168, 150, 0}}, +{(unsigned char*)"quest", {63, 0}}, +{(unsigned char*)"questeq", {226, 137, 159, 0}}, +{(unsigned char*)"quot", {34, 0}}, +{(unsigned char*)"rAarr", {226, 135, 155, 0}}, +{(unsigned char*)"rArr", {226, 135, 146, 0}}, +{(unsigned char*)"rAtail", {226, 164, 156, 0}}, +{(unsigned char*)"rBarr", {226, 164, 143, 0}}, +{(unsigned char*)"rHar", {226, 165, 164, 0}}, +{(unsigned char*)"race", {226, 136, 189, 204, 177, 0}}, +{(unsigned char*)"racute", {197, 149, 0}}, +{(unsigned char*)"radic", {226, 136, 154, 0}}, +{(unsigned char*)"raemptyv", {226, 166, 179, 0}}, +{(unsigned char*)"rang", {226, 159, 169, 0}}, +{(unsigned char*)"rangd", {226, 166, 146, 0}}, +{(unsigned char*)"range", {226, 166, 165, 0}}, +{(unsigned char*)"rangle", {226, 159, 169, 0}}, +{(unsigned char*)"raquo", {194, 187, 0}}, +{(unsigned char*)"rarr", {226, 134, 146, 0}}, +{(unsigned char*)"rarrap", {226, 165, 181, 0}}, +{(unsigned char*)"rarrb", {226, 135, 165, 0}}, +{(unsigned char*)"rarrbfs", {226, 164, 160, 0}}, +{(unsigned char*)"rarrc", {226, 164, 179, 0}}, +{(unsigned char*)"rarrfs", {226, 164, 158, 0}}, +{(unsigned char*)"rarrhk", {226, 134, 170, 0}}, +{(unsigned char*)"rarrlp", {226, 134, 172, 0}}, +{(unsigned char*)"rarrpl", {226, 165, 133, 0}}, +{(unsigned char*)"rarrsim", {226, 165, 180, 0}}, +{(unsigned char*)"rarrtl", {226, 134, 163, 0}}, +{(unsigned char*)"rarrw", {226, 134, 157, 0}}, +{(unsigned char*)"ratail", {226, 164, 154, 0}}, +{(unsigned char*)"ratio", {226, 136, 182, 0}}, +{(unsigned char*)"rationals", {226, 132, 154, 0}}, +{(unsigned char*)"rbarr", {226, 164, 141, 0}}, +{(unsigned char*)"rbbrk", {226, 157, 179, 0}}, +{(unsigned char*)"rbrace", {125, 0}}, +{(unsigned char*)"rbrack", {93, 0}}, +{(unsigned char*)"rbrke", {226, 166, 140, 0}}, +{(unsigned char*)"rbrksld", {226, 166, 142, 0}}, +{(unsigned char*)"rbrkslu", {226, 166, 144, 0}}, +{(unsigned char*)"rcaron", {197, 153, 0}}, +{(unsigned char*)"rcedil", {197, 151, 0}}, +{(unsigned char*)"rceil", {226, 140, 137, 0}}, +{(unsigned char*)"rcub", {125, 0}}, +{(unsigned char*)"rcy", {209, 128, 0}}, +{(unsigned char*)"rdca", {226, 164, 183, 0}}, +{(unsigned char*)"rdldhar", {226, 165, 169, 0}}, +{(unsigned char*)"rdquo", {226, 128, 157, 0}}, +{(unsigned char*)"rdquor", {226, 128, 157, 0}}, +{(unsigned char*)"rdsh", {226, 134, 179, 0}}, +{(unsigned char*)"real", {226, 132, 156, 0}}, +{(unsigned char*)"realine", {226, 132, 155, 0}}, +{(unsigned char*)"realpart", {226, 132, 156, 0}}, +{(unsigned char*)"reals", {226, 132, 157, 0}}, +{(unsigned char*)"rect", {226, 150, 173, 0}}, +{(unsigned char*)"reg", {194, 174, 0}}, +{(unsigned char*)"rfisht", {226, 165, 189, 0}}, +{(unsigned char*)"rfloor", {226, 140, 139, 0}}, +{(unsigned char*)"rfr", {240, 157, 148, 175, 0}}, +{(unsigned char*)"rhard", {226, 135, 129, 0}}, +{(unsigned char*)"rharu", {226, 135, 128, 0}}, +{(unsigned char*)"rharul", {226, 165, 172, 0}}, +{(unsigned char*)"rho", {207, 129, 0}}, +{(unsigned char*)"rhov", {207, 177, 0}}, +{(unsigned char*)"rightarrow", {226, 134, 146, 0}}, +{(unsigned char*)"rightarrowtail", {226, 134, 163, 0}}, +{(unsigned char*)"rightharpoondown", {226, 135, 129, 0}}, +{(unsigned char*)"rightharpoonup", {226, 135, 128, 0}}, +{(unsigned char*)"rightleftarrows", {226, 135, 132, 0}}, +{(unsigned char*)"rightleftharpoons", {226, 135, 140, 0}}, +{(unsigned char*)"rightrightarrows", {226, 135, 137, 0}}, +{(unsigned char*)"rightsquigarrow", {226, 134, 157, 0}}, +{(unsigned char*)"rightthreetimes", {226, 139, 140, 0}}, +{(unsigned char*)"ring", {203, 154, 0}}, +{(unsigned char*)"risingdotseq", {226, 137, 147, 0}}, +{(unsigned char*)"rlarr", {226, 135, 132, 0}}, +{(unsigned char*)"rlhar", {226, 135, 140, 0}}, +{(unsigned char*)"rlm", {226, 128, 143, 0}}, +{(unsigned char*)"rmoust", {226, 142, 177, 0}}, +{(unsigned char*)"rmoustache", {226, 142, 177, 0}}, +{(unsigned char*)"rnmid", {226, 171, 174, 0}}, +{(unsigned char*)"roang", {226, 159, 173, 0}}, +{(unsigned char*)"roarr", {226, 135, 190, 0}}, +{(unsigned char*)"robrk", {226, 159, 167, 0}}, +{(unsigned char*)"ropar", {226, 166, 134, 0}}, +{(unsigned char*)"ropf", {240, 157, 149, 163, 0}}, +{(unsigned char*)"roplus", {226, 168, 174, 0}}, +{(unsigned char*)"rotimes", {226, 168, 181, 0}}, +{(unsigned char*)"rpar", {41, 0}}, +{(unsigned char*)"rpargt", {226, 166, 148, 0}}, +{(unsigned char*)"rppolint", {226, 168, 146, 0}}, +{(unsigned char*)"rrarr", {226, 135, 137, 0}}, +{(unsigned char*)"rsaquo", {226, 128, 186, 0}}, +{(unsigned char*)"rscr", {240, 157, 147, 135, 0}}, +{(unsigned char*)"rsh", {226, 134, 177, 0}}, +{(unsigned char*)"rsqb", {93, 0}}, +{(unsigned char*)"rsquo", {226, 128, 153, 0}}, +{(unsigned char*)"rsquor", {226, 128, 153, 0}}, +{(unsigned char*)"rthree", {226, 139, 140, 0}}, +{(unsigned char*)"rtimes", {226, 139, 138, 0}}, +{(unsigned char*)"rtri", {226, 150, 185, 0}}, +{(unsigned char*)"rtrie", {226, 138, 181, 0}}, +{(unsigned char*)"rtrif", {226, 150, 184, 0}}, +{(unsigned char*)"rtriltri", {226, 167, 142, 0}}, +{(unsigned char*)"ruluhar", {226, 165, 168, 0}}, +{(unsigned char*)"rx", {226, 132, 158, 0}}, +{(unsigned char*)"sacute", {197, 155, 0}}, +{(unsigned char*)"sbquo", {226, 128, 154, 0}}, +{(unsigned char*)"sc", {226, 137, 187, 0}}, +{(unsigned char*)"scE", {226, 170, 180, 0}}, +{(unsigned char*)"scap", {226, 170, 184, 0}}, +{(unsigned char*)"scaron", {197, 161, 0}}, +{(unsigned char*)"sccue", {226, 137, 189, 0}}, +{(unsigned char*)"sce", {226, 170, 176, 0}}, +{(unsigned char*)"scedil", {197, 159, 0}}, +{(unsigned char*)"scirc", {197, 157, 0}}, +{(unsigned char*)"scnE", {226, 170, 182, 0}}, +{(unsigned char*)"scnap", {226, 170, 186, 0}}, +{(unsigned char*)"scnsim", {226, 139, 169, 0}}, +{(unsigned char*)"scpolint", {226, 168, 147, 0}}, +{(unsigned char*)"scsim", {226, 137, 191, 0}}, +{(unsigned char*)"scy", {209, 129, 0}}, +{(unsigned char*)"sdot", {226, 139, 133, 0}}, +{(unsigned char*)"sdotb", {226, 138, 161, 0}}, +{(unsigned char*)"sdote", {226, 169, 166, 0}}, +{(unsigned char*)"seArr", {226, 135, 152, 0}}, +{(unsigned char*)"searhk", {226, 164, 165, 0}}, +{(unsigned char*)"searr", {226, 134, 152, 0}}, +{(unsigned char*)"searrow", {226, 134, 152, 0}}, +{(unsigned char*)"sect", {194, 167, 0}}, +{(unsigned char*)"semi", {59, 0}}, +{(unsigned char*)"seswar", {226, 164, 169, 0}}, +{(unsigned char*)"setminus", {226, 136, 150, 0}}, +{(unsigned char*)"setmn", {226, 136, 150, 0}}, +{(unsigned char*)"sext", {226, 156, 182, 0}}, +{(unsigned char*)"sfr", {240, 157, 148, 176, 0}}, +{(unsigned char*)"sfrown", {226, 140, 162, 0}}, +{(unsigned char*)"sharp", {226, 153, 175, 0}}, +{(unsigned char*)"shchcy", {209, 137, 0}}, +{(unsigned char*)"shcy", {209, 136, 0}}, +{(unsigned char*)"shortmid", {226, 136, 163, 0}}, +{(unsigned char*)"shortparallel", {226, 136, 165, 0}}, +{(unsigned char*)"shy", {194, 173, 0}}, +{(unsigned char*)"sigma", {207, 131, 0}}, +{(unsigned char*)"sigmaf", {207, 130, 0}}, +{(unsigned char*)"sigmav", {207, 130, 0}}, +{(unsigned char*)"sim", {226, 136, 188, 0}}, +{(unsigned char*)"simdot", {226, 169, 170, 0}}, +{(unsigned char*)"sime", {226, 137, 131, 0}}, +{(unsigned char*)"simeq", {226, 137, 131, 0}}, +{(unsigned char*)"simg", {226, 170, 158, 0}}, +{(unsigned char*)"simgE", {226, 170, 160, 0}}, +{(unsigned char*)"siml", {226, 170, 157, 0}}, +{(unsigned char*)"simlE", {226, 170, 159, 0}}, +{(unsigned char*)"simne", {226, 137, 134, 0}}, +{(unsigned char*)"simplus", {226, 168, 164, 0}}, +{(unsigned char*)"simrarr", {226, 165, 178, 0}}, +{(unsigned char*)"slarr", {226, 134, 144, 0}}, +{(unsigned char*)"smallsetminus", {226, 136, 150, 0}}, +{(unsigned char*)"smashp", {226, 168, 179, 0}}, +{(unsigned char*)"smeparsl", {226, 167, 164, 0}}, +{(unsigned char*)"smid", {226, 136, 163, 0}}, +{(unsigned char*)"smile", {226, 140, 163, 0}}, +{(unsigned char*)"smt", {226, 170, 170, 0}}, +{(unsigned char*)"smte", {226, 170, 172, 0}}, +{(unsigned char*)"smtes", {226, 170, 172, 239, 184, 128, 0}}, +{(unsigned char*)"softcy", {209, 140, 0}}, +{(unsigned char*)"sol", {47, 0}}, +{(unsigned char*)"solb", {226, 167, 132, 0}}, +{(unsigned char*)"solbar", {226, 140, 191, 0}}, +{(unsigned char*)"sopf", {240, 157, 149, 164, 0}}, +{(unsigned char*)"spades", {226, 153, 160, 0}}, +{(unsigned char*)"spadesuit", {226, 153, 160, 0}}, +{(unsigned char*)"spar", {226, 136, 165, 0}}, +{(unsigned char*)"sqcap", {226, 138, 147, 0}}, +{(unsigned char*)"sqcaps", {226, 138, 147, 239, 184, 128, 0}}, +{(unsigned char*)"sqcup", {226, 138, 148, 0}}, +{(unsigned char*)"sqcups", {226, 138, 148, 239, 184, 128, 0}}, +{(unsigned char*)"sqsub", {226, 138, 143, 0}}, +{(unsigned char*)"sqsube", {226, 138, 145, 0}}, +{(unsigned char*)"sqsubset", {226, 138, 143, 0}}, +{(unsigned char*)"sqsubseteq", {226, 138, 145, 0}}, +{(unsigned char*)"sqsup", {226, 138, 144, 0}}, +{(unsigned char*)"sqsupe", {226, 138, 146, 0}}, +{(unsigned char*)"sqsupset", {226, 138, 144, 0}}, +{(unsigned char*)"sqsupseteq", {226, 138, 146, 0}}, +{(unsigned char*)"squ", {226, 150, 161, 0}}, +{(unsigned char*)"square", {226, 150, 161, 0}}, +{(unsigned char*)"squarf", {226, 150, 170, 0}}, +{(unsigned char*)"squf", {226, 150, 170, 0}}, +{(unsigned char*)"srarr", {226, 134, 146, 0}}, +{(unsigned char*)"sscr", {240, 157, 147, 136, 0}}, +{(unsigned char*)"ssetmn", {226, 136, 150, 0}}, +{(unsigned char*)"ssmile", {226, 140, 163, 0}}, +{(unsigned char*)"sstarf", {226, 139, 134, 0}}, +{(unsigned char*)"star", {226, 152, 134, 0}}, +{(unsigned char*)"starf", {226, 152, 133, 0}}, +{(unsigned char*)"straightepsilon", {207, 181, 0}}, +{(unsigned char*)"straightphi", {207, 149, 0}}, +{(unsigned char*)"strns", {194, 175, 0}}, +{(unsigned char*)"sub", {226, 138, 130, 0}}, +{(unsigned char*)"subE", {226, 171, 133, 0}}, +{(unsigned char*)"subdot", {226, 170, 189, 0}}, +{(unsigned char*)"sube", {226, 138, 134, 0}}, +{(unsigned char*)"subedot", {226, 171, 131, 0}}, +{(unsigned char*)"submult", {226, 171, 129, 0}}, +{(unsigned char*)"subnE", {226, 171, 139, 0}}, +{(unsigned char*)"subne", {226, 138, 138, 0}}, +{(unsigned char*)"subplus", {226, 170, 191, 0}}, +{(unsigned char*)"subrarr", {226, 165, 185, 0}}, +{(unsigned char*)"subset", {226, 138, 130, 0}}, +{(unsigned char*)"subseteq", {226, 138, 134, 0}}, +{(unsigned char*)"subseteqq", {226, 171, 133, 0}}, +{(unsigned char*)"subsetneq", {226, 138, 138, 0}}, +{(unsigned char*)"subsetneqq", {226, 171, 139, 0}}, +{(unsigned char*)"subsim", {226, 171, 135, 0}}, +{(unsigned char*)"subsub", {226, 171, 149, 0}}, +{(unsigned char*)"subsup", {226, 171, 147, 0}}, +{(unsigned char*)"succ", {226, 137, 187, 0}}, +{(unsigned char*)"succapprox", {226, 170, 184, 0}}, +{(unsigned char*)"succcurlyeq", {226, 137, 189, 0}}, +{(unsigned char*)"succeq", {226, 170, 176, 0}}, +{(unsigned char*)"succnapprox", {226, 170, 186, 0}}, +{(unsigned char*)"succneqq", {226, 170, 182, 0}}, +{(unsigned char*)"succnsim", {226, 139, 169, 0}}, +{(unsigned char*)"succsim", {226, 137, 191, 0}}, +{(unsigned char*)"sum", {226, 136, 145, 0}}, +{(unsigned char*)"sung", {226, 153, 170, 0}}, +{(unsigned char*)"sup", {226, 138, 131, 0}}, +{(unsigned char*)"sup1", {194, 185, 0}}, +{(unsigned char*)"sup2", {194, 178, 0}}, +{(unsigned char*)"sup3", {194, 179, 0}}, +{(unsigned char*)"supE", {226, 171, 134, 0}}, +{(unsigned char*)"supdot", {226, 170, 190, 0}}, +{(unsigned char*)"supdsub", {226, 171, 152, 0}}, +{(unsigned char*)"supe", {226, 138, 135, 0}}, +{(unsigned char*)"supedot", {226, 171, 132, 0}}, +{(unsigned char*)"suphsol", {226, 159, 137, 0}}, +{(unsigned char*)"suphsub", {226, 171, 151, 0}}, +{(unsigned char*)"suplarr", {226, 165, 187, 0}}, +{(unsigned char*)"supmult", {226, 171, 130, 0}}, +{(unsigned char*)"supnE", {226, 171, 140, 0}}, +{(unsigned char*)"supne", {226, 138, 139, 0}}, +{(unsigned char*)"supplus", {226, 171, 128, 0}}, +{(unsigned char*)"supset", {226, 138, 131, 0}}, +{(unsigned char*)"supseteq", {226, 138, 135, 0}}, +{(unsigned char*)"supseteqq", {226, 171, 134, 0}}, +{(unsigned char*)"supsetneq", {226, 138, 139, 0}}, +{(unsigned char*)"supsetneqq", {226, 171, 140, 0}}, +{(unsigned char*)"supsim", {226, 171, 136, 0}}, +{(unsigned char*)"supsub", {226, 171, 148, 0}}, +{(unsigned char*)"supsup", {226, 171, 150, 0}}, +{(unsigned char*)"swArr", {226, 135, 153, 0}}, +{(unsigned char*)"swarhk", {226, 164, 166, 0}}, +{(unsigned char*)"swarr", {226, 134, 153, 0}}, +{(unsigned char*)"swarrow", {226, 134, 153, 0}}, +{(unsigned char*)"swnwar", {226, 164, 170, 0}}, +{(unsigned char*)"szlig", {195, 159, 0}}, +{(unsigned char*)"target", {226, 140, 150, 0}}, +{(unsigned char*)"tau", {207, 132, 0}}, +{(unsigned char*)"tbrk", {226, 142, 180, 0}}, +{(unsigned char*)"tcaron", {197, 165, 0}}, +{(unsigned char*)"tcedil", {197, 163, 0}}, +{(unsigned char*)"tcy", {209, 130, 0}}, +{(unsigned char*)"tdot", {226, 131, 155, 0}}, +{(unsigned char*)"telrec", {226, 140, 149, 0}}, +{(unsigned char*)"tfr", {240, 157, 148, 177, 0}}, +{(unsigned char*)"there4", {226, 136, 180, 0}}, +{(unsigned char*)"therefore", {226, 136, 180, 0}}, +{(unsigned char*)"theta", {206, 184, 0}}, +{(unsigned char*)"thetasym", {207, 145, 0}}, +{(unsigned char*)"thetav", {207, 145, 0}}, +{(unsigned char*)"thickapprox", {226, 137, 136, 0}}, +{(unsigned char*)"thicksim", {226, 136, 188, 0}}, +{(unsigned char*)"thinsp", {226, 128, 137, 0}}, +{(unsigned char*)"thkap", {226, 137, 136, 0}}, +{(unsigned char*)"thksim", {226, 136, 188, 0}}, +{(unsigned char*)"thorn", {195, 190, 0}}, +{(unsigned char*)"tilde", {203, 156, 0}}, +{(unsigned char*)"times", {195, 151, 0}}, +{(unsigned char*)"timesb", {226, 138, 160, 0}}, +{(unsigned char*)"timesbar", {226, 168, 177, 0}}, +{(unsigned char*)"timesd", {226, 168, 176, 0}}, +{(unsigned char*)"tint", {226, 136, 173, 0}}, +{(unsigned char*)"toea", {226, 164, 168, 0}}, +{(unsigned char*)"top", {226, 138, 164, 0}}, +{(unsigned char*)"topbot", {226, 140, 182, 0}}, +{(unsigned char*)"topcir", {226, 171, 177, 0}}, +{(unsigned char*)"topf", {240, 157, 149, 165, 0}}, +{(unsigned char*)"topfork", {226, 171, 154, 0}}, +{(unsigned char*)"tosa", {226, 164, 169, 0}}, +{(unsigned char*)"tprime", {226, 128, 180, 0}}, +{(unsigned char*)"trade", {226, 132, 162, 0}}, +{(unsigned char*)"triangle", {226, 150, 181, 0}}, +{(unsigned char*)"triangledown", {226, 150, 191, 0}}, +{(unsigned char*)"triangleleft", {226, 151, 131, 0}}, +{(unsigned char*)"trianglelefteq", {226, 138, 180, 0}}, +{(unsigned char*)"triangleq", {226, 137, 156, 0}}, +{(unsigned char*)"triangleright", {226, 150, 185, 0}}, +{(unsigned char*)"trianglerighteq", {226, 138, 181, 0}}, +{(unsigned char*)"tridot", {226, 151, 172, 0}}, +{(unsigned char*)"trie", {226, 137, 156, 0}}, +{(unsigned char*)"triminus", {226, 168, 186, 0}}, +{(unsigned char*)"triplus", {226, 168, 185, 0}}, +{(unsigned char*)"trisb", {226, 167, 141, 0}}, +{(unsigned char*)"tritime", {226, 168, 187, 0}}, +{(unsigned char*)"trpezium", {226, 143, 162, 0}}, +{(unsigned char*)"tscr", {240, 157, 147, 137, 0}}, +{(unsigned char*)"tscy", {209, 134, 0}}, +{(unsigned char*)"tshcy", {209, 155, 0}}, +{(unsigned char*)"tstrok", {197, 167, 0}}, +{(unsigned char*)"twixt", {226, 137, 172, 0}}, +{(unsigned char*)"twoheadleftarrow", {226, 134, 158, 0}}, +{(unsigned char*)"twoheadrightarrow", {226, 134, 160, 0}}, +{(unsigned char*)"uArr", {226, 135, 145, 0}}, +{(unsigned char*)"uHar", {226, 165, 163, 0}}, +{(unsigned char*)"uacute", {195, 186, 0}}, +{(unsigned char*)"uarr", {226, 134, 145, 0}}, +{(unsigned char*)"ubrcy", {209, 158, 0}}, +{(unsigned char*)"ubreve", {197, 173, 0}}, +{(unsigned char*)"ucirc", {195, 187, 0}}, +{(unsigned char*)"ucy", {209, 131, 0}}, +{(unsigned char*)"udarr", {226, 135, 133, 0}}, +{(unsigned char*)"udblac", {197, 177, 0}}, +{(unsigned char*)"udhar", {226, 165, 174, 0}}, +{(unsigned char*)"ufisht", {226, 165, 190, 0}}, +{(unsigned char*)"ufr", {240, 157, 148, 178, 0}}, +{(unsigned char*)"ugrave", {195, 185, 0}}, +{(unsigned char*)"uharl", {226, 134, 191, 0}}, +{(unsigned char*)"uharr", {226, 134, 190, 0}}, +{(unsigned char*)"uhblk", {226, 150, 128, 0}}, +{(unsigned char*)"ulcorn", {226, 140, 156, 0}}, +{(unsigned char*)"ulcorner", {226, 140, 156, 0}}, +{(unsigned char*)"ulcrop", {226, 140, 143, 0}}, +{(unsigned char*)"ultri", {226, 151, 184, 0}}, +{(unsigned char*)"umacr", {197, 171, 0}}, +{(unsigned char*)"uml", {194, 168, 0}}, +{(unsigned char*)"uogon", {197, 179, 0}}, +{(unsigned char*)"uopf", {240, 157, 149, 166, 0}}, +{(unsigned char*)"uparrow", {226, 134, 145, 0}}, +{(unsigned char*)"updownarrow", {226, 134, 149, 0}}, +{(unsigned char*)"upharpoonleft", {226, 134, 191, 0}}, +{(unsigned char*)"upharpoonright", {226, 134, 190, 0}}, +{(unsigned char*)"uplus", {226, 138, 142, 0}}, +{(unsigned char*)"upsi", {207, 133, 0}}, +{(unsigned char*)"upsih", {207, 146, 0}}, +{(unsigned char*)"upsilon", {207, 133, 0}}, +{(unsigned char*)"upuparrows", {226, 135, 136, 0}}, +{(unsigned char*)"urcorn", {226, 140, 157, 0}}, +{(unsigned char*)"urcorner", {226, 140, 157, 0}}, +{(unsigned char*)"urcrop", {226, 140, 142, 0}}, +{(unsigned char*)"uring", {197, 175, 0}}, +{(unsigned char*)"urtri", {226, 151, 185, 0}}, +{(unsigned char*)"uscr", {240, 157, 147, 138, 0}}, +{(unsigned char*)"utdot", {226, 139, 176, 0}}, +{(unsigned char*)"utilde", {197, 169, 0}}, +{(unsigned char*)"utri", {226, 150, 181, 0}}, +{(unsigned char*)"utrif", {226, 150, 180, 0}}, +{(unsigned char*)"uuarr", {226, 135, 136, 0}}, +{(unsigned char*)"uuml", {195, 188, 0}}, +{(unsigned char*)"uwangle", {226, 166, 167, 0}}, +{(unsigned char*)"vArr", {226, 135, 149, 0}}, +{(unsigned char*)"vBar", {226, 171, 168, 0}}, +{(unsigned char*)"vBarv", {226, 171, 169, 0}}, +{(unsigned char*)"vDash", {226, 138, 168, 0}}, +{(unsigned char*)"vangrt", {226, 166, 156, 0}}, +{(unsigned char*)"varepsilon", {207, 181, 0}}, +{(unsigned char*)"varkappa", {207, 176, 0}}, +{(unsigned char*)"varnothing", {226, 136, 133, 0}}, +{(unsigned char*)"varphi", {207, 149, 0}}, +{(unsigned char*)"varpi", {207, 150, 0}}, +{(unsigned char*)"varpropto", {226, 136, 157, 0}}, +{(unsigned char*)"varr", {226, 134, 149, 0}}, +{(unsigned char*)"varrho", {207, 177, 0}}, +{(unsigned char*)"varsigma", {207, 130, 0}}, +{(unsigned char*)"varsubsetneq", {226, 138, 138, 239, 184, 128, 0}}, +{(unsigned char*)"varsubsetneqq", {226, 171, 139, 239, 184, 128, 0}}, +{(unsigned char*)"varsupsetneq", {226, 138, 139, 239, 184, 128, 0}}, +{(unsigned char*)"varsupsetneqq", {226, 171, 140, 239, 184, 128, 0}}, +{(unsigned char*)"vartheta", {207, 145, 0}}, +{(unsigned char*)"vartriangleleft", {226, 138, 178, 0}}, +{(unsigned char*)"vartriangleright", {226, 138, 179, 0}}, +{(unsigned char*)"vcy", {208, 178, 0}}, +{(unsigned char*)"vdash", {226, 138, 162, 0}}, +{(unsigned char*)"vee", {226, 136, 168, 0}}, +{(unsigned char*)"veebar", {226, 138, 187, 0}}, +{(unsigned char*)"veeeq", {226, 137, 154, 0}}, +{(unsigned char*)"vellip", {226, 139, 174, 0}}, +{(unsigned char*)"verbar", {124, 0}}, +{(unsigned char*)"vert", {124, 0}}, +{(unsigned char*)"vfr", {240, 157, 148, 179, 0}}, +{(unsigned char*)"vltri", {226, 138, 178, 0}}, +{(unsigned char*)"vnsub", {226, 138, 130, 226, 131, 146, 0}}, +{(unsigned char*)"vnsup", {226, 138, 131, 226, 131, 146, 0}}, +{(unsigned char*)"vopf", {240, 157, 149, 167, 0}}, +{(unsigned char*)"vprop", {226, 136, 157, 0}}, +{(unsigned char*)"vrtri", {226, 138, 179, 0}}, +{(unsigned char*)"vscr", {240, 157, 147, 139, 0}}, +{(unsigned char*)"vsubnE", {226, 171, 139, 239, 184, 128, 0}}, +{(unsigned char*)"vsubne", {226, 138, 138, 239, 184, 128, 0}}, +{(unsigned char*)"vsupnE", {226, 171, 140, 239, 184, 128, 0}}, +{(unsigned char*)"vsupne", {226, 138, 139, 239, 184, 128, 0}}, +{(unsigned char*)"vzigzag", {226, 166, 154, 0}}, +{(unsigned char*)"wcirc", {197, 181, 0}}, +{(unsigned char*)"wedbar", {226, 169, 159, 0}}, +{(unsigned char*)"wedge", {226, 136, 167, 0}}, +{(unsigned char*)"wedgeq", {226, 137, 153, 0}}, +{(unsigned char*)"weierp", {226, 132, 152, 0}}, +{(unsigned char*)"wfr", {240, 157, 148, 180, 0}}, +{(unsigned char*)"wopf", {240, 157, 149, 168, 0}}, +{(unsigned char*)"wp", {226, 132, 152, 0}}, +{(unsigned char*)"wr", {226, 137, 128, 0}}, +{(unsigned char*)"wreath", {226, 137, 128, 0}}, +{(unsigned char*)"wscr", {240, 157, 147, 140, 0}}, +{(unsigned char*)"xcap", {226, 139, 130, 0}}, +{(unsigned char*)"xcirc", {226, 151, 175, 0}}, +{(unsigned char*)"xcup", {226, 139, 131, 0}}, +{(unsigned char*)"xdtri", {226, 150, 189, 0}}, +{(unsigned char*)"xfr", {240, 157, 148, 181, 0}}, +{(unsigned char*)"xhArr", {226, 159, 186, 0}}, +{(unsigned char*)"xharr", {226, 159, 183, 0}}, +{(unsigned char*)"xi", {206, 190, 0}}, +{(unsigned char*)"xlArr", {226, 159, 184, 0}}, +{(unsigned char*)"xlarr", {226, 159, 181, 0}}, +{(unsigned char*)"xmap", {226, 159, 188, 0}}, +{(unsigned char*)"xnis", {226, 139, 187, 0}}, +{(unsigned char*)"xodot", {226, 168, 128, 0}}, +{(unsigned char*)"xopf", {240, 157, 149, 169, 0}}, +{(unsigned char*)"xoplus", {226, 168, 129, 0}}, +{(unsigned char*)"xotime", {226, 168, 130, 0}}, +{(unsigned char*)"xrArr", {226, 159, 185, 0}}, +{(unsigned char*)"xrarr", {226, 159, 182, 0}}, +{(unsigned char*)"xscr", {240, 157, 147, 141, 0}}, +{(unsigned char*)"xsqcup", {226, 168, 134, 0}}, +{(unsigned char*)"xuplus", {226, 168, 132, 0}}, +{(unsigned char*)"xutri", {226, 150, 179, 0}}, +{(unsigned char*)"xvee", {226, 139, 129, 0}}, +{(unsigned char*)"xwedge", {226, 139, 128, 0}}, +{(unsigned char*)"yacute", {195, 189, 0}}, +{(unsigned char*)"yacy", {209, 143, 0}}, +{(unsigned char*)"ycirc", {197, 183, 0}}, +{(unsigned char*)"ycy", {209, 139, 0}}, +{(unsigned char*)"yen", {194, 165, 0}}, +{(unsigned char*)"yfr", {240, 157, 148, 182, 0}}, +{(unsigned char*)"yicy", {209, 151, 0}}, +{(unsigned char*)"yopf", {240, 157, 149, 170, 0}}, +{(unsigned char*)"yscr", {240, 157, 147, 142, 0}}, +{(unsigned char*)"yucy", {209, 142, 0}}, +{(unsigned char*)"yuml", {195, 191, 0}}, +{(unsigned char*)"zacute", {197, 186, 0}}, +{(unsigned char*)"zcaron", {197, 190, 0}}, +{(unsigned char*)"zcy", {208, 183, 0}}, +{(unsigned char*)"zdot", {197, 188, 0}}, +{(unsigned char*)"zeetrf", {226, 132, 168, 0}}, +{(unsigned char*)"zeta", {206, 182, 0}}, +{(unsigned char*)"zfr", {240, 157, 148, 183, 0}}, +{(unsigned char*)"zhcy", {208, 182, 0}}, +{(unsigned char*)"zigrarr", {226, 135, 157, 0}}, +{(unsigned char*)"zopf", {240, 157, 149, 171, 0}}, +{(unsigned char*)"zscr", {240, 157, 147, 143, 0}}, +{(unsigned char*)"zwj", {226, 128, 141, 0}}, +{(unsigned char*)"zwnj", {226, 128, 140, 0}}, +}; diff --git a/Sources/libcmark_gfm/ext_scanners.c b/Sources/libcmark_gfm/ext_scanners.c new file mode 100644 index 0000000..7e0f5f2 --- /dev/null +++ b/Sources/libcmark_gfm/ext_scanners.c @@ -0,0 +1,941 @@ +/* Generated by re2c 0.15.3 */ +#include +#include "ext_scanners.h" + +bufsize_t _ext_scan_at(bufsize_t (*scanner)(const unsigned char *), + unsigned char *ptr, int len, bufsize_t offset) { + bufsize_t res; + + if (ptr == NULL || offset > len) { + return 0; + } else { + unsigned char lim = ptr[len]; + + ptr[len] = '\0'; + res = scanner(ptr + offset); + ptr[len] = lim; + } + + return res; +} + +bufsize_t _scan_table_start(const unsigned char *p) { + const unsigned char *marker = NULL; + const unsigned char *start = p; + + { + unsigned char yych; + static const unsigned char yybm[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }; + yych = *(marker = p); + if (yych <= '{') { + if (yych <= 0x1F) { + if (yych <= '\t') { + if (yych <= 0x08) + goto yy6; + goto yy3; + } else { + if (yych <= '\n') + goto yy2; + if (yych <= '\f') + goto yy3; + goto yy6; + } + } else { + if (yych <= '-') { + if (yych <= ' ') + goto yy3; + if (yych <= ',') + goto yy6; + goto yy5; + } else { + if (yych == ':') + goto yy4; + goto yy6; + } + } + } else { + if (yych <= 0xEC) { + if (yych <= 0xC1) { + if (yych <= '|') + goto yy3; + if (yych <= 0x7F) + goto yy6; + } else { + if (yych <= 0xDF) + goto yy7; + if (yych <= 0xE0) + goto yy9; + goto yy10; + } + } else { + if (yych <= 0xF0) { + if (yych <= 0xED) + goto yy14; + if (yych <= 0xEF) + goto yy10; + goto yy11; + } else { + if (yych <= 0xF3) + goto yy12; + if (yych <= 0xF4) + goto yy13; + } + } + } + yy2 : { return 0; } + yy3: + yych = *(marker = ++p); + if (yybm[0 + yych] & 128) { + goto yy22; + } + if (yych <= '\f') { + if (yych == '\t') + goto yy29; + if (yych <= '\n') + goto yy2; + goto yy29; + } else { + if (yych <= ' ') { + if (yych <= 0x1F) + goto yy2; + goto yy29; + } else { + if (yych == ':') + goto yy31; + goto yy2; + } + } + yy4: + yych = *(marker = ++p); + if (yybm[0 + yych] & 128) { + goto yy22; + } + goto yy2; + yy5: + yych = *(marker = ++p); + if (yybm[0 + yych] & 128) { + goto yy22; + } + if (yych <= ' ') { + if (yych <= 0x08) + goto yy2; + if (yych <= '\r') + goto yy16; + if (yych <= 0x1F) + goto yy2; + goto yy16; + } else { + if (yych <= ':') { + if (yych <= '9') + goto yy2; + goto yy15; + } else { + if (yych == '|') + goto yy16; + goto yy2; + } + } + yy6: + yych = *++p; + goto yy2; + yy7: + yych = *++p; + if (yych <= 0x7F) + goto yy8; + if (yych <= 0xBF) + goto yy6; + yy8: + p = marker; + goto yy2; + yy9: + yych = *++p; + if (yych <= 0x9F) + goto yy8; + if (yych <= 0xBF) + goto yy7; + goto yy8; + yy10: + yych = *++p; + if (yych <= 0x7F) + goto yy8; + if (yych <= 0xBF) + goto yy7; + goto yy8; + yy11: + yych = *++p; + if (yych <= 0x8F) + goto yy8; + if (yych <= 0xBF) + goto yy10; + goto yy8; + yy12: + yych = *++p; + if (yych <= 0x7F) + goto yy8; + if (yych <= 0xBF) + goto yy10; + goto yy8; + yy13: + yych = *++p; + if (yych <= 0x7F) + goto yy8; + if (yych <= 0x8F) + goto yy10; + goto yy8; + yy14: + yych = *++p; + if (yych <= 0x7F) + goto yy8; + if (yych <= 0x9F) + goto yy7; + goto yy8; + yy15: + ++p; + yych = *p; + yy16: + if (yybm[0 + yych] & 64) { + goto yy15; + } + if (yych <= '\r') { + if (yych <= 0x08) + goto yy8; + if (yych <= '\n') + goto yy20; + goto yy19; + } else { + if (yych != '|') + goto yy8; + } + yy17: + ++p; + yych = *p; + if (yych <= 0x1F) { + if (yych <= '\n') { + if (yych <= 0x08) + goto yy8; + if (yych <= '\t') + goto yy17; + goto yy20; + } else { + if (yych <= '\f') + goto yy17; + if (yych >= 0x0E) + goto yy8; + } + } else { + if (yych <= '-') { + if (yych <= ' ') + goto yy17; + if (yych <= ',') + goto yy8; + goto yy25; + } else { + if (yych == ':') + goto yy24; + goto yy8; + } + } + yy19: + yych = *++p; + if (yych != '\n') + goto yy8; + yy20: + ++p; + { return (bufsize_t)(p - start); } + yy22: + ++p; + yych = *p; + if (yybm[0 + yych] & 128) { + goto yy22; + } + if (yych <= 0x1F) { + if (yych <= '\n') { + if (yych <= 0x08) + goto yy8; + if (yych <= '\t') + goto yy15; + goto yy20; + } else { + if (yych <= '\f') + goto yy15; + if (yych <= '\r') + goto yy19; + goto yy8; + } + } else { + if (yych <= ':') { + if (yych <= ' ') + goto yy15; + if (yych <= '9') + goto yy8; + goto yy15; + } else { + if (yych == '|') + goto yy17; + goto yy8; + } + } + yy24: + ++p; + yych = *p; + if (yych != '-') + goto yy8; + yy25: + ++p; + yych = *p; + if (yych <= ' ') { + if (yych <= '\n') { + if (yych <= 0x08) + goto yy8; + if (yych >= '\n') + goto yy20; + } else { + if (yych <= '\f') + goto yy27; + if (yych <= '\r') + goto yy19; + if (yych <= 0x1F) + goto yy8; + } + } else { + if (yych <= '9') { + if (yych == '-') + goto yy25; + goto yy8; + } else { + if (yych <= ':') + goto yy27; + if (yych == '|') + goto yy17; + goto yy8; + } + } + yy27: + ++p; + yych = *p; + if (yych <= '\r') { + if (yych <= '\t') { + if (yych <= 0x08) + goto yy8; + goto yy27; + } else { + if (yych <= '\n') + goto yy20; + if (yych <= '\f') + goto yy27; + goto yy19; + } + } else { + if (yych <= ' ') { + if (yych <= 0x1F) + goto yy8; + goto yy27; + } else { + if (yych == '|') + goto yy17; + goto yy8; + } + } + yy29: + ++p; + yych = *p; + if (yybm[0 + yych] & 128) { + goto yy22; + } + if (yych <= '\f') { + if (yych == '\t') + goto yy29; + if (yych <= '\n') + goto yy8; + goto yy29; + } else { + if (yych <= ' ') { + if (yych <= 0x1F) + goto yy8; + goto yy29; + } else { + if (yych != ':') + goto yy8; + } + } + yy31: + ++p; + if (yybm[0 + (yych = *p)] & 128) { + goto yy22; + } + goto yy8; + } +} + +bufsize_t _scan_table_cell(const unsigned char *p) { + const unsigned char *marker = NULL; + const unsigned char *start = p; + + { + unsigned char yych; + static const unsigned char yybm[] = { + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 128, 128, 0, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 64, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 128, + 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + }; + yych = *(marker = p); + if (yych <= 0x7F) { + if (yych <= '\r') { + if (yych == '\n') + goto yy34; + if (yych <= '\f') + goto yy36; + goto yy45; + } else { + if (yych <= '\\') { + if (yych <= '[') + goto yy36; + goto yy35; + } else { + if (yych == '|') + goto yy45; + goto yy36; + } + } + } else { + if (yych <= 0xED) { + if (yych <= 0xDF) { + if (yych >= 0xC2) + goto yy37; + } else { + if (yych <= 0xE0) + goto yy39; + if (yych <= 0xEC) + goto yy40; + goto yy44; + } + } else { + if (yych <= 0xF0) { + if (yych <= 0xEF) + goto yy40; + goto yy41; + } else { + if (yych <= 0xF3) + goto yy42; + if (yych <= 0xF4) + goto yy43; + } + } + } + yy34 : { return (bufsize_t)(p - start); } + yy35: + yych = *(marker = ++p); + if (yych == '|') + goto yy49; + goto yy50; + yy36: + yych = *(marker = ++p); + goto yy50; + yy37: + yych = *++p; + if (yych <= 0x7F) + goto yy38; + if (yych <= 0xBF) + goto yy36; + yy38: + p = marker; + goto yy34; + yy39: + yych = *++p; + if (yych <= 0x9F) + goto yy38; + if (yych <= 0xBF) + goto yy37; + goto yy38; + yy40: + yych = *++p; + if (yych <= 0x7F) + goto yy38; + if (yych <= 0xBF) + goto yy37; + goto yy38; + yy41: + yych = *++p; + if (yych <= 0x8F) + goto yy38; + if (yych <= 0xBF) + goto yy40; + goto yy38; + yy42: + yych = *++p; + if (yych <= 0x7F) + goto yy38; + if (yych <= 0xBF) + goto yy40; + goto yy38; + yy43: + yych = *++p; + if (yych <= 0x7F) + goto yy38; + if (yych <= 0x8F) + goto yy40; + goto yy38; + yy44: + yych = *++p; + if (yych <= 0x7F) + goto yy38; + if (yych <= 0x9F) + goto yy37; + goto yy38; + yy45: + ++p; + { return 0; } + yy47: + marker = ++p; + yych = *p; + if (yybm[0 + yych] & 64) { + goto yy47; + } + if (yych <= 0xDF) { + if (yych <= '\f') { + if (yych == '\n') + goto yy34; + } else { + if (yych <= '\r') + goto yy34; + if (yych <= 0x7F) + goto yy49; + if (yych <= 0xC1) + goto yy34; + goto yy51; + } + } else { + if (yych <= 0xEF) { + if (yych <= 0xE0) + goto yy52; + if (yych == 0xED) + goto yy57; + goto yy53; + } else { + if (yych <= 0xF0) + goto yy54; + if (yych <= 0xF3) + goto yy55; + if (yych <= 0xF4) + goto yy56; + goto yy34; + } + } + yy49: + marker = ++p; + yych = *p; + yy50: + if (yybm[0 + yych] & 128) { + goto yy49; + } + if (yych <= 0xEC) { + if (yych <= 0xC1) { + if (yych <= '\r') + goto yy34; + if (yych <= '\\') + goto yy47; + goto yy34; + } else { + if (yych <= 0xDF) + goto yy51; + if (yych <= 0xE0) + goto yy52; + goto yy53; + } + } else { + if (yych <= 0xF0) { + if (yych <= 0xED) + goto yy57; + if (yych <= 0xEF) + goto yy53; + goto yy54; + } else { + if (yych <= 0xF3) + goto yy55; + if (yych <= 0xF4) + goto yy56; + goto yy34; + } + } + yy51: + ++p; + yych = *p; + if (yych <= 0x7F) + goto yy38; + if (yych <= 0xBF) + goto yy49; + goto yy38; + yy52: + ++p; + yych = *p; + if (yych <= 0x9F) + goto yy38; + if (yych <= 0xBF) + goto yy51; + goto yy38; + yy53: + ++p; + yych = *p; + if (yych <= 0x7F) + goto yy38; + if (yych <= 0xBF) + goto yy51; + goto yy38; + yy54: + ++p; + yych = *p; + if (yych <= 0x8F) + goto yy38; + if (yych <= 0xBF) + goto yy53; + goto yy38; + yy55: + ++p; + yych = *p; + if (yych <= 0x7F) + goto yy38; + if (yych <= 0xBF) + goto yy53; + goto yy38; + yy56: + ++p; + yych = *p; + if (yych <= 0x7F) + goto yy38; + if (yych <= 0x8F) + goto yy53; + goto yy38; + yy57: + ++p; + yych = *p; + if (yych <= 0x7F) + goto yy38; + if (yych <= 0x9F) + goto yy51; + goto yy38; + } +} + +bufsize_t _scan_table_cell_end(const unsigned char *p) { + const unsigned char *marker = NULL; + const unsigned char *start = p; + + { + unsigned char yych; + unsigned int yyaccept = 0; + static const unsigned char yybm[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 128, 128, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }; + yych = *(marker = p); + if (yych <= 0xDF) { + if (yych <= '{') { + if (yych != '\n') + goto yy63; + } else { + if (yych <= '|') + goto yy61; + if (yych <= 0x7F) + goto yy63; + if (yych >= 0xC2) + goto yy64; + } + } else { + if (yych <= 0xEF) { + if (yych <= 0xE0) + goto yy66; + if (yych == 0xED) + goto yy71; + goto yy67; + } else { + if (yych <= 0xF0) + goto yy68; + if (yych <= 0xF3) + goto yy69; + if (yych <= 0xF4) + goto yy70; + } + } + yy60 : { return 0; } + yy61: + yyaccept = 1; + yych = *(marker = ++p); + goto yy73; + yy62 : { return (bufsize_t)(p - start); } + yy63: + yych = *++p; + goto yy60; + yy64: + yych = *++p; + if (yych <= 0x7F) + goto yy65; + if (yych <= 0xBF) + goto yy63; + yy65: + p = marker; + if (yyaccept == 0) { + goto yy60; + } else { + goto yy62; + } + yy66: + yych = *++p; + if (yych <= 0x9F) + goto yy65; + if (yych <= 0xBF) + goto yy64; + goto yy65; + yy67: + yych = *++p; + if (yych <= 0x7F) + goto yy65; + if (yych <= 0xBF) + goto yy64; + goto yy65; + yy68: + yych = *++p; + if (yych <= 0x8F) + goto yy65; + if (yych <= 0xBF) + goto yy67; + goto yy65; + yy69: + yych = *++p; + if (yych <= 0x7F) + goto yy65; + if (yych <= 0xBF) + goto yy67; + goto yy65; + yy70: + yych = *++p; + if (yych <= 0x7F) + goto yy65; + if (yych <= 0x8F) + goto yy67; + goto yy65; + yy71: + yych = *++p; + if (yych <= 0x7F) + goto yy65; + if (yych <= 0x9F) + goto yy64; + goto yy65; + yy72: + yyaccept = 1; + marker = ++p; + yych = *p; + yy73: + if (yybm[0 + yych] & 128) { + goto yy72; + } + if (yych <= 0x08) + goto yy62; + if (yych <= '\n') + goto yy75; + if (yych >= 0x0E) + goto yy62; + yych = *++p; + if (yych != '\n') + goto yy65; + yy75: + ++p; + yych = *p; + goto yy62; + } +} + +bufsize_t _scan_table_row_end(const unsigned char *p) { + const unsigned char *marker = NULL; + const unsigned char *start = p; + + { + unsigned char yych; + static const unsigned char yybm[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 128, 128, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }; + yych = *(marker = p); + if (yych <= 0xC1) { + if (yych <= '\f') { + if (yych <= 0x08) + goto yy83; + if (yych == '\n') + goto yy81; + goto yy79; + } else { + if (yych <= 0x1F) { + if (yych <= '\r') + goto yy80; + goto yy83; + } else { + if (yych <= ' ') + goto yy79; + if (yych <= 0x7F) + goto yy83; + } + } + } else { + if (yych <= 0xED) { + if (yych <= 0xDF) + goto yy84; + if (yych <= 0xE0) + goto yy86; + if (yych <= 0xEC) + goto yy87; + goto yy91; + } else { + if (yych <= 0xF0) { + if (yych <= 0xEF) + goto yy87; + goto yy88; + } else { + if (yych <= 0xF3) + goto yy89; + if (yych <= 0xF4) + goto yy90; + } + } + } + yy78 : { return 0; } + yy79: + yych = *(marker = ++p); + if (yych <= 0x08) + goto yy78; + if (yych <= '\r') + goto yy94; + if (yych == ' ') + goto yy94; + goto yy78; + yy80: + yych = *++p; + if (yych != '\n') + goto yy78; + yy81: + ++p; + { return (bufsize_t)(p - start); } + yy83: + yych = *++p; + goto yy78; + yy84: + yych = *++p; + if (yych <= 0x7F) + goto yy85; + if (yych <= 0xBF) + goto yy83; + yy85: + p = marker; + goto yy78; + yy86: + yych = *++p; + if (yych <= 0x9F) + goto yy85; + if (yych <= 0xBF) + goto yy84; + goto yy85; + yy87: + yych = *++p; + if (yych <= 0x7F) + goto yy85; + if (yych <= 0xBF) + goto yy84; + goto yy85; + yy88: + yych = *++p; + if (yych <= 0x8F) + goto yy85; + if (yych <= 0xBF) + goto yy87; + goto yy85; + yy89: + yych = *++p; + if (yych <= 0x7F) + goto yy85; + if (yych <= 0xBF) + goto yy87; + goto yy85; + yy90: + yych = *++p; + if (yych <= 0x7F) + goto yy85; + if (yych <= 0x8F) + goto yy87; + goto yy85; + yy91: + yych = *++p; + if (yych <= 0x7F) + goto yy85; + if (yych <= 0x9F) + goto yy84; + goto yy85; + yy92: + yych = *++p; + if (yych == '\n') + goto yy81; + goto yy85; + yy93: + ++p; + yych = *p; + yy94: + if (yybm[0 + yych] & 128) { + goto yy93; + } + if (yych <= 0x08) + goto yy85; + if (yych <= '\n') + goto yy81; + if (yych <= '\r') + goto yy92; + goto yy85; + } +} diff --git a/Sources/libcmark_gfm/footnotes.c b/Sources/libcmark_gfm/footnotes.c new file mode 100644 index 0000000..ccd452c --- /dev/null +++ b/Sources/libcmark_gfm/footnotes.c @@ -0,0 +1,40 @@ +#include "cmark.h" +#include "parser.h" +#include "footnotes.h" +#include "inlines.h" +#include "chunk.h" + +static void footnote_free(cmark_map *map, cmark_map_entry *_ref) { + cmark_footnote *ref = (cmark_footnote *)_ref; + cmark_mem *mem = map->mem; + if (ref != NULL) { + mem->free(ref->entry.label); + if (ref->node) + cmark_node_free(ref->node); + mem->free(ref); + } +} + +void cmark_footnote_create(cmark_map *map, cmark_node *node) { + cmark_footnote *ref; + unsigned char *reflabel = normalize_map_label(map->mem, &node->as.literal); + + /* empty footnote name, or composed from only whitespace */ + if (reflabel == NULL) + return; + + assert(map->sorted == NULL); + + ref = (cmark_footnote *)map->mem->calloc(1, sizeof(*ref)); + ref->entry.label = reflabel; + ref->node = node; + ref->entry.age = map->size; + ref->entry.next = map->refs; + + map->refs = (cmark_map_entry *)ref; + map->size++; +} + +cmark_map *cmark_footnote_map_new(cmark_mem *mem) { + return cmark_map_new(mem, footnote_free); +} diff --git a/Sources/libcmark_gfm/houdini_href_e.c b/Sources/libcmark_gfm/houdini_href_e.c new file mode 100644 index 0000000..9152803 --- /dev/null +++ b/Sources/libcmark_gfm/houdini_href_e.c @@ -0,0 +1,100 @@ +#include +#include +#include + +#include "houdini.h" + +/* + * The following characters will not be escaped: + * + * -_.+!*'(),%#@?=;:/,+&$ alphanum + * + * Note that this character set is the addition of: + * + * - The characters which are safe to be in an URL + * - The characters which are *not* safe to be in + * an URL because they are RESERVED characters. + * + * We asume (lazily) that any RESERVED char that + * appears inside an URL is actually meant to + * have its native function (i.e. as an URL + * component/separator) and hence needs no escaping. + * + * There are two exceptions: the chacters & (amp) + * and ' (single quote) do not appear in the table. + * They are meant to appear in the URL as components, + * yet they require special HTML-entity escaping + * to generate valid HTML markup. + * + * All other characters will be escaped to %XX. + * + */ +static const char HREF_SAFE[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +int houdini_escape_href(cmark_strbuf *ob, const uint8_t *src, bufsize_t size) { + static const uint8_t hex_chars[] = "0123456789ABCDEF"; + bufsize_t i = 0, org; + uint8_t hex_str[3]; + + hex_str[0] = '%'; + + while (i < size) { + org = i; + while (i < size && HREF_SAFE[src[i]] != 0) + i++; + + if (likely(i > org)) + cmark_strbuf_put(ob, src + org, i - org); + + /* escaping */ + if (i >= size) + break; + + switch (src[i]) { + /* amp appears all the time in URLs, but needs + * HTML-entity escaping to be inside an href */ + case '&': + cmark_strbuf_puts(ob, "&"); + break; + + /* the single quote is a valid URL character + * according to the standard; it needs HTML + * entity escaping too */ + case '\'': + cmark_strbuf_puts(ob, "'"); + break; + +/* the space can be escaped to %20 or a plus + * sign. we're going with the generic escape + * for now. the plus thing is more commonly seen + * when building GET strings */ +#if 0 + case ' ': + cmark_strbuf_putc(ob, '+'); + break; +#endif + + /* every other character goes with a %XX escaping */ + default: + hex_str[1] = hex_chars[(src[i] >> 4) & 0xF]; + hex_str[2] = hex_chars[src[i] & 0xF]; + cmark_strbuf_put(ob, hex_str, 3); + } + + i++; + } + + return 1; +} diff --git a/Sources/libcmark_gfm/houdini_html_e.c b/Sources/libcmark_gfm/houdini_html_e.c new file mode 100644 index 0000000..da0b15c --- /dev/null +++ b/Sources/libcmark_gfm/houdini_html_e.c @@ -0,0 +1,66 @@ +#include +#include +#include + +#include "houdini.h" + +/** + * According to the OWASP rules: + * + * & --> & + * < --> < + * > --> > + * " --> " + * ' --> ' ' is not recommended + * / --> / forward slash is included as it helps end an HTML entity + * + */ +static const char HTML_ESCAPE_TABLE[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static const char *HTML_ESCAPES[] = {"", """, "&", "'", + "/", "<", ">"}; + +int houdini_escape_html0(cmark_strbuf *ob, const uint8_t *src, bufsize_t size, + int secure) { + bufsize_t i = 0, org, esc = 0; + + while (i < size) { + org = i; + while (i < size && (esc = HTML_ESCAPE_TABLE[src[i]]) == 0) + i++; + + if (i > org) + cmark_strbuf_put(ob, src + org, i - org); + + /* escaping */ + if (unlikely(i >= size)) + break; + + /* The forward slash and single quote are only escaped in secure mode */ + if ((src[i] == '/' || src[i] == '\'') && !secure) { + cmark_strbuf_putc(ob, src[i]); + } else { + cmark_strbuf_puts(ob, HTML_ESCAPES[esc]); + } + + i++; + } + + return 1; +} + +int houdini_escape_html(cmark_strbuf *ob, const uint8_t *src, bufsize_t size) { + return houdini_escape_html0(ob, src, size, 1); +} diff --git a/Sources/libcmark_gfm/houdini_html_u.c b/Sources/libcmark_gfm/houdini_html_u.c new file mode 100644 index 0000000..30d08aa --- /dev/null +++ b/Sources/libcmark_gfm/houdini_html_u.c @@ -0,0 +1,149 @@ +#include +#include +#include + +#include "buffer.h" +#include "houdini.h" +#include "utf8.h" +#include "entities.inc" + +/* Binary tree lookup code for entities added by JGM */ + +static const unsigned char *S_lookup(int i, int low, int hi, + const unsigned char *s, int len) { + int j; + int cmp = + strncmp((const char *)s, (const char *)cmark_entities[i].entity, len); + if (cmp == 0 && cmark_entities[i].entity[len] == 0) { + return (const unsigned char *)cmark_entities[i].bytes; + } else if (cmp <= 0 && i > low) { + j = i - ((i - low) / 2); + if (j == i) + j -= 1; + return S_lookup(j, low, i - 1, s, len); + } else if (cmp > 0 && i < hi) { + j = i + ((hi - i) / 2); + if (j == i) + j += 1; + return S_lookup(j, i + 1, hi, s, len); + } else { + return NULL; + } +} + +static const unsigned char *S_lookup_entity(const unsigned char *s, int len) { + return S_lookup(CMARK_NUM_ENTITIES / 2, 0, CMARK_NUM_ENTITIES - 1, s, len); +} + +bufsize_t houdini_unescape_ent(cmark_strbuf *ob, const uint8_t *src, + bufsize_t size) { + bufsize_t i = 0; + + if (size >= 3 && src[0] == '#') { + int codepoint = 0; + int num_digits = 0; + + if (_isdigit(src[1])) { + for (i = 1; i < size && _isdigit(src[i]); ++i) { + codepoint = (codepoint * 10) + (src[i] - '0'); + + if (codepoint >= 0x110000) { + // Keep counting digits but + // avoid integer overflow. + codepoint = 0x110000; + } + } + + num_digits = i - 1; + } + + else if (src[1] == 'x' || src[1] == 'X') { + for (i = 2; i < size && _isxdigit(src[i]); ++i) { + codepoint = (codepoint * 16) + ((src[i] | 32) % 39 - 9); + + if (codepoint >= 0x110000) { + // Keep counting digits but + // avoid integer overflow. + codepoint = 0x110000; + } + } + + num_digits = i - 2; + } + + if (num_digits >= 1 && num_digits <= 8 && i < size && src[i] == ';') { + if (codepoint == 0 || (codepoint >= 0xD800 && codepoint < 0xE000) || + codepoint >= 0x110000) { + codepoint = 0xFFFD; + } + cmark_utf8proc_encode_char(codepoint, ob); + return i + 1; + } + } + + else { + if (size > CMARK_ENTITY_MAX_LENGTH) + size = CMARK_ENTITY_MAX_LENGTH; + + for (i = CMARK_ENTITY_MIN_LENGTH; i < size; ++i) { + if (src[i] == ' ') + break; + + if (src[i] == ';') { + const unsigned char *entity = S_lookup_entity(src, i); + + if (entity != NULL) { + cmark_strbuf_puts(ob, (const char *)entity); + return i + 1; + } + + break; + } + } + } + + return 0; +} + +int houdini_unescape_html(cmark_strbuf *ob, const uint8_t *src, + bufsize_t size) { + bufsize_t i = 0, org, ent; + + while (i < size) { + org = i; + while (i < size && src[i] != '&') + i++; + + if (likely(i > org)) { + if (unlikely(org == 0)) { + if (i >= size) + return 0; + + cmark_strbuf_grow(ob, HOUDINI_UNESCAPED_SIZE(size)); + } + + cmark_strbuf_put(ob, src + org, i - org); + } + + /* escaping */ + if (i >= size) + break; + + i++; + + ent = houdini_unescape_ent(ob, src + i, size - i); + i += ent; + + /* not really an entity */ + if (ent == 0) + cmark_strbuf_putc(ob, '&'); + } + + return 1; +} + +void houdini_unescape_html_f(cmark_strbuf *ob, const uint8_t *src, + bufsize_t size) { + if (!houdini_unescape_html(ob, src, size)) + cmark_strbuf_put(ob, src, size); +} diff --git a/Sources/libcmark_gfm/html.c b/Sources/libcmark_gfm/html.c new file mode 100644 index 0000000..136f9e0 --- /dev/null +++ b/Sources/libcmark_gfm/html.c @@ -0,0 +1,457 @@ +#include +#include +#include +#include +#include "cmark_ctype.h" +#include "config.h" +#include "cmark.h" +#include "houdini.h" +#include "scanners.h" +#include "syntax_extension.h" +#include "html.h" +#include "render.h" + +// Functions to convert cmark_nodes to HTML strings. + +static void escape_html(cmark_strbuf *dest, const unsigned char *source, + bufsize_t length) { + houdini_escape_html0(dest, source, length, 0); +} + +static void filter_html_block(cmark_html_renderer *renderer, uint8_t *data, size_t len) { + cmark_strbuf *html = renderer->html; + cmark_llist *it; + cmark_syntax_extension *ext; + bool filtered; + uint8_t *match; + + while (len) { + match = (uint8_t *) memchr(data, '<', len); + if (!match) + break; + + if (match != data) { + cmark_strbuf_put(html, data, (bufsize_t)(match - data)); + len -= (match - data); + data = match; + } + + filtered = false; + for (it = renderer->filter_extensions; it; it = it->next) { + ext = ((cmark_syntax_extension *) it->data); + if (!ext->html_filter_func(ext, data, len)) { + filtered = true; + break; + } + } + + if (!filtered) { + cmark_strbuf_putc(html, '<'); + } else { + cmark_strbuf_puts(html, "<"); + } + + ++data; + --len; + } + + if (len) + cmark_strbuf_put(html, data, (bufsize_t)len); +} + +static bool S_put_footnote_backref(cmark_html_renderer *renderer, cmark_strbuf *html) { + if (renderer->written_footnote_ix >= renderer->footnote_ix) + return false; + renderer->written_footnote_ix = renderer->footnote_ix; + + cmark_strbuf_puts(html, "footnote_ix); + cmark_strbuf_puts(html, n); + cmark_strbuf_puts(html, "\" class=\"footnote-backref\">↩"); + + return true; +} + +static int S_render_node(cmark_html_renderer *renderer, cmark_node *node, + cmark_event_type ev_type, int options) { + cmark_node *parent; + cmark_node *grandparent; + cmark_strbuf *html = renderer->html; + cmark_llist *it; + cmark_syntax_extension *ext; + char start_heading[] = "plain == node) { // back at original node + renderer->plain = NULL; + } + + if (renderer->plain != NULL) { + switch (node->type) { + case CMARK_NODE_TEXT: + case CMARK_NODE_CODE: + case CMARK_NODE_HTML_INLINE: + escape_html(html, node->as.literal.data, node->as.literal.len); + break; + + case CMARK_NODE_LINEBREAK: + case CMARK_NODE_SOFTBREAK: + cmark_strbuf_putc(html, ' '); + break; + + default: + break; + } + return 1; + } + + if (node->extension && node->extension->html_render_func) { + node->extension->html_render_func(node->extension, renderer, node, ev_type, options); + return 1; + } + + switch (node->type) { + case CMARK_NODE_DOCUMENT: + break; + + case CMARK_NODE_BLOCK_QUOTE: + if (entering) { + cmark_html_render_cr(html); + cmark_strbuf_puts(html, "\n"); + } else { + cmark_html_render_cr(html); + cmark_strbuf_puts(html, "\n"); + } + break; + + case CMARK_NODE_LIST: { + cmark_list_type list_type = node->as.list.list_type; + int start = node->as.list.start; + + if (entering) { + cmark_html_render_cr(html); + if (list_type == CMARK_BULLET_LIST) { + cmark_strbuf_puts(html, "\n"); + } else if (start == 1) { + cmark_strbuf_puts(html, "\n"); + } else { + snprintf(buffer, BUFFER_SIZE, "
    \n"); + } + } else { + cmark_strbuf_puts(html, + list_type == CMARK_BULLET_LIST ? "\n" : "
\n"); + } + break; + } + + case CMARK_NODE_ITEM: + if (entering) { + cmark_html_render_cr(html); + cmark_strbuf_puts(html, "'); + } else { + cmark_strbuf_puts(html, "\n"); + } + break; + + case CMARK_NODE_HEADING: + if (entering) { + cmark_html_render_cr(html); + start_heading[2] = (char)('0' + node->as.heading.level); + cmark_strbuf_puts(html, start_heading); + cmark_html_render_sourcepos(node, html, options); + cmark_strbuf_putc(html, '>'); + } else { + end_heading[3] = (char)('0' + node->as.heading.level); + cmark_strbuf_puts(html, end_heading); + cmark_strbuf_puts(html, ">\n"); + } + break; + + case CMARK_NODE_CODE_BLOCK: + cmark_html_render_cr(html); + + if (node->as.code.info.len == 0) { + cmark_strbuf_puts(html, ""); + } else { + bufsize_t first_tag = 0; + while (first_tag < node->as.code.info.len && + !cmark_isspace(node->as.code.info.data[first_tag])) { + first_tag += 1; + } + + if (options & CMARK_OPT_GITHUB_PRE_LANG) { + cmark_strbuf_puts(html, "as.code.info.data, first_tag); + cmark_strbuf_puts(html, "\">"); + } else { + cmark_strbuf_puts(html, "as.code.info.data, first_tag); + cmark_strbuf_puts(html, "\">"); + } + } + + escape_html(html, node->as.code.literal.data, node->as.code.literal.len); + cmark_strbuf_puts(html, "\n"); + break; + + case CMARK_NODE_HTML_BLOCK: + cmark_html_render_cr(html); + if (options & CMARK_OPT_SAFE) { + cmark_strbuf_puts(html, ""); + } else if (renderer->filter_extensions) { + filter_html_block(renderer, node->as.literal.data, node->as.literal.len); + } else { + cmark_strbuf_put(html, node->as.literal.data, node->as.literal.len); + } + cmark_html_render_cr(html); + break; + + case CMARK_NODE_CUSTOM_BLOCK: + cmark_html_render_cr(html); + if (entering) { + cmark_strbuf_put(html, node->as.custom.on_enter.data, + node->as.custom.on_enter.len); + } else { + cmark_strbuf_put(html, node->as.custom.on_exit.data, + node->as.custom.on_exit.len); + } + cmark_html_render_cr(html); + break; + + case CMARK_NODE_THEMATIC_BREAK: + cmark_html_render_cr(html); + cmark_strbuf_puts(html, "\n"); + break; + + case CMARK_NODE_PARAGRAPH: + parent = cmark_node_parent(node); + grandparent = cmark_node_parent(parent); + if (grandparent != NULL && grandparent->type == CMARK_NODE_LIST) { + tight = grandparent->as.list.tight; + } else { + tight = false; + } + if (!tight) { + if (entering) { + cmark_html_render_cr(html); + cmark_strbuf_puts(html, "'); + } else { + if (parent->type == CMARK_NODE_FOOTNOTE_DEFINITION && node->next == NULL) { + cmark_strbuf_putc(html, ' '); + S_put_footnote_backref(renderer, html); + } + cmark_strbuf_puts(html, "

\n"); + } + } + break; + + case CMARK_NODE_TEXT: + escape_html(html, node->as.literal.data, node->as.literal.len); + break; + + case CMARK_NODE_LINEBREAK: + cmark_strbuf_puts(html, "
\n"); + break; + + case CMARK_NODE_SOFTBREAK: + if (options & CMARK_OPT_HARDBREAKS) { + cmark_strbuf_puts(html, "
\n"); + } else if (options & CMARK_OPT_NOBREAKS) { + cmark_strbuf_putc(html, ' '); + } else { + cmark_strbuf_putc(html, '\n'); + } + break; + + case CMARK_NODE_CODE: + cmark_strbuf_puts(html, ""); + escape_html(html, node->as.literal.data, node->as.literal.len); + cmark_strbuf_puts(html, ""); + break; + + case CMARK_NODE_HTML_INLINE: + if (options & CMARK_OPT_SAFE) { + cmark_strbuf_puts(html, ""); + } else { + filtered = false; + for (it = renderer->filter_extensions; it; it = it->next) { + ext = (cmark_syntax_extension *) it->data; + if (!ext->html_filter_func(ext, node->as.literal.data, node->as.literal.len)) { + filtered = true; + break; + } + } + if (!filtered) { + cmark_strbuf_put(html, node->as.literal.data, node->as.literal.len); + } else { + cmark_strbuf_puts(html, "<"); + cmark_strbuf_put(html, node->as.literal.data + 1, node->as.literal.len - 1); + } + } + break; + + case CMARK_NODE_CUSTOM_INLINE: + if (entering) { + cmark_strbuf_put(html, node->as.custom.on_enter.data, + node->as.custom.on_enter.len); + } else { + cmark_strbuf_put(html, node->as.custom.on_exit.data, + node->as.custom.on_exit.len); + } + break; + + case CMARK_NODE_STRONG: + if (entering) { + cmark_strbuf_puts(html, ""); + } else { + cmark_strbuf_puts(html, ""); + } + break; + + case CMARK_NODE_EMPH: + if (entering) { + cmark_strbuf_puts(html, ""); + } else { + cmark_strbuf_puts(html, ""); + } + break; + + case CMARK_NODE_LINK: + if (entering) { + cmark_strbuf_puts(html, "as.link.url, 0))) { + houdini_escape_href(html, node->as.link.url.data, + node->as.link.url.len); + } + if (node->as.link.title.len) { + cmark_strbuf_puts(html, "\" title=\""); + escape_html(html, node->as.link.title.data, node->as.link.title.len); + } + cmark_strbuf_puts(html, "\">"); + } else { + cmark_strbuf_puts(html, ""); + } + break; + + case CMARK_NODE_IMAGE: + if (entering) { + cmark_strbuf_puts(html, "as.link.url, 0))) { + houdini_escape_href(html, node->as.link.url.data, + node->as.link.url.len); + } + cmark_strbuf_puts(html, "\" alt=\""); + renderer->plain = node; + } else { + if (node->as.link.title.len) { + cmark_strbuf_puts(html, "\" title=\""); + escape_html(html, node->as.link.title.data, node->as.link.title.len); + } + + cmark_strbuf_puts(html, "\" />"); + } + break; + + case CMARK_NODE_FOOTNOTE_DEFINITION: + if (entering) { + if (renderer->footnote_ix == 0) { + cmark_strbuf_puts(html, "
\n
    \n"); + } + ++renderer->footnote_ix; + cmark_strbuf_puts(html, "
  1. footnote_ix); + cmark_strbuf_puts(html, n); + cmark_strbuf_puts(html, "\">\n"); + } else { + if (S_put_footnote_backref(renderer, html)) { + cmark_strbuf_putc(html, '\n'); + } + cmark_strbuf_puts(html, "
  2. \n"); + } + break; + + case CMARK_NODE_FOOTNOTE_REFERENCE: + if (entering) { + cmark_strbuf_puts(html, "as.literal.data, node->as.literal.len); + cmark_strbuf_puts(html, "\" id=\"fnref"); + cmark_strbuf_put(html, node->as.literal.data, node->as.literal.len); + cmark_strbuf_puts(html, "\">["); + cmark_strbuf_put(html, node->as.literal.data, node->as.literal.len); + cmark_strbuf_puts(html, "]"); + } + break; + + default: + assert(false); + break; + } + + return 1; +} + +char *cmark_render_html(cmark_node *root, int options, cmark_llist *extensions) { + return cmark_render_html_with_mem(root, options, extensions, cmark_node_mem(root)); +} + +char *cmark_render_html_with_mem(cmark_node *root, int options, cmark_llist *extensions, cmark_mem *mem) { + char *result; + cmark_strbuf html = CMARK_BUF_INIT(mem); + cmark_event_type ev_type; + cmark_node *cur; + cmark_html_renderer renderer = {&html, NULL, NULL, 0, 0, NULL}; + cmark_iter *iter = cmark_iter_new(root); + + for (; extensions; extensions = extensions->next) + if (((cmark_syntax_extension *) extensions->data)->html_filter_func) + renderer.filter_extensions = cmark_llist_append( + mem, + renderer.filter_extensions, + (cmark_syntax_extension *) extensions->data); + + while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) { + cur = cmark_iter_get_node(iter); + S_render_node(&renderer, cur, ev_type, options); + } + + if (renderer.footnote_ix) { + cmark_strbuf_puts(&html, "
\n
\n"); + } + + result = (char *)cmark_strbuf_detach(&html); + + cmark_llist_free(mem, renderer.filter_extensions); + + cmark_iter_free(iter); + return result; +} diff --git a/Sources/libcmark_gfm/include/autolink.h b/Sources/libcmark_gfm/include/autolink.h new file mode 100644 index 0000000..ee2ea2f --- /dev/null +++ b/Sources/libcmark_gfm/include/autolink.h @@ -0,0 +1,8 @@ +#ifndef AUTOLINK_H +#define AUTOLINK_H + +#include "core-extensions.h" + +cmark_syntax_extension *create_autolink_extension(void); + +#endif diff --git a/Sources/libcmark_gfm/include/buffer.h b/Sources/libcmark_gfm/include/buffer.h new file mode 100644 index 0000000..35af9c3 --- /dev/null +++ b/Sources/libcmark_gfm/include/buffer.h @@ -0,0 +1,116 @@ +#ifndef CMARK_BUFFER_H +#define CMARK_BUFFER_H + +#include +#include +#include +#include +#include +#include "config.h" +#include "cmark.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + cmark_mem *mem; + unsigned char *ptr; + bufsize_t asize, size; +} cmark_strbuf; + +extern unsigned char cmark_strbuf__initbuf[]; + +#define CMARK_BUF_INIT(mem) \ + { mem, cmark_strbuf__initbuf, 0, 0 } + +/** + * Initialize a cmark_strbuf structure. + * + * For the cases where CMARK_BUF_INIT cannot be used to do static + * initialization. + */ +CMARK_EXPORT +void cmark_strbuf_init(cmark_mem *mem, cmark_strbuf *buf, + bufsize_t initial_size); + +/** + * Grow the buffer to hold at least `target_size` bytes. + */ +CMARK_EXPORT +void cmark_strbuf_grow(cmark_strbuf *buf, bufsize_t target_size); + +CMARK_EXPORT +void cmark_strbuf_free(cmark_strbuf *buf); + +CMARK_EXPORT +void cmark_strbuf_swap(cmark_strbuf *buf_a, cmark_strbuf *buf_b); + +CMARK_EXPORT +bufsize_t cmark_strbuf_len(const cmark_strbuf *buf); + +CMARK_EXPORT +int cmark_strbuf_cmp(const cmark_strbuf *a, const cmark_strbuf *b); + +CMARK_EXPORT +unsigned char *cmark_strbuf_detach(cmark_strbuf *buf); + +CMARK_EXPORT +void cmark_strbuf_copy_cstr(char *data, bufsize_t datasize, + const cmark_strbuf *buf); + +static CMARK_INLINE const char *cmark_strbuf_cstr(const cmark_strbuf *buf) { + return (char *)buf->ptr; +} + +#define cmark_strbuf_at(buf, n) ((buf)->ptr[n]) + +CMARK_EXPORT +void cmark_strbuf_set(cmark_strbuf *buf, const unsigned char *data, + bufsize_t len); + +CMARK_EXPORT +void cmark_strbuf_sets(cmark_strbuf *buf, const char *string); + +CMARK_EXPORT +void cmark_strbuf_putc(cmark_strbuf *buf, int c); + +CMARK_EXPORT +void cmark_strbuf_put(cmark_strbuf *buf, const unsigned char *data, + bufsize_t len); + +CMARK_EXPORT +void cmark_strbuf_puts(cmark_strbuf *buf, const char *string); + +CMARK_EXPORT +void cmark_strbuf_clear(cmark_strbuf *buf); + +CMARK_EXPORT +bufsize_t cmark_strbuf_strchr(const cmark_strbuf *buf, int c, bufsize_t pos); + +CMARK_EXPORT +bufsize_t cmark_strbuf_strrchr(const cmark_strbuf *buf, int c, bufsize_t pos); + +CMARK_EXPORT +void cmark_strbuf_drop(cmark_strbuf *buf, bufsize_t n); + +CMARK_EXPORT +void cmark_strbuf_truncate(cmark_strbuf *buf, bufsize_t len); + +CMARK_EXPORT +void cmark_strbuf_rtrim(cmark_strbuf *buf); + +CMARK_EXPORT +void cmark_strbuf_trim(cmark_strbuf *buf); + +CMARK_EXPORT +void cmark_strbuf_normalize_whitespace(cmark_strbuf *s); + +CMARK_EXPORT +void cmark_strbuf_unescape(cmark_strbuf *s); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Sources/libcmark_gfm/include/chunk.h b/Sources/libcmark_gfm/include/chunk.h new file mode 100644 index 0000000..a9059d4 --- /dev/null +++ b/Sources/libcmark_gfm/include/chunk.h @@ -0,0 +1,136 @@ +#ifndef CMARK_CHUNK_H +#define CMARK_CHUNK_H + +#include +#include +#include +#include "cmark.h" +#include "buffer.h" +//#include +#include "cmark_ctype.h" + +#define CMARK_CHUNK_EMPTY \ + { NULL, 0, 0 } + +typedef struct cmark_chunk { + unsigned char *data; + bufsize_t len; + bufsize_t alloc; // also implies a NULL-terminated string +} cmark_chunk; + +static CMARK_INLINE void cmark_chunk_free(cmark_mem *mem, cmark_chunk *c) { + if (c->alloc) + mem->free(c->data); + + c->data = NULL; + c->alloc = 0; + c->len = 0; +} + +static CMARK_INLINE void cmark_chunk_ltrim(cmark_chunk *c) { + assert(!c->alloc); + + while (c->len && cmark_isspace(c->data[0])) { + c->data++; + c->len--; + } +} + +static CMARK_INLINE void cmark_chunk_rtrim(cmark_chunk *c) { + assert(!c->alloc); + + while (c->len > 0) { + if (!cmark_isspace(c->data[c->len - 1])) + break; + + c->len--; + } +} + +static CMARK_INLINE void cmark_chunk_trim(cmark_chunk *c) { + cmark_chunk_ltrim(c); + cmark_chunk_rtrim(c); +} + +static CMARK_INLINE bufsize_t cmark_chunk_strchr(cmark_chunk *ch, int c, + bufsize_t offset) { + const unsigned char *p = + (unsigned char *)memchr(ch->data + offset, c, ch->len - offset); + return p ? (bufsize_t)(p - ch->data) : ch->len; +} + +static CMARK_INLINE const char *cmark_chunk_to_cstr(cmark_mem *mem, + cmark_chunk *c) { + unsigned char *str; + + if (c->alloc) { + return (char *)c->data; + } + str = (unsigned char *)mem->calloc(c->len + 1, 1); + if (c->len > 0) { + memcpy(str, c->data, c->len); + } + str[c->len] = 0; + c->data = str; + c->alloc = 1; + + return (char *)str; +} + +static CMARK_INLINE void cmark_chunk_set_cstr(cmark_mem *mem, cmark_chunk *c, + const char *str) { + unsigned char *old = c->alloc ? c->data : NULL; + if (str == NULL) { + c->len = 0; + c->data = NULL; + c->alloc = 0; + } else { + c->len = (bufsize_t)strlen(str); + c->data = (unsigned char *)mem->calloc(c->len + 1, 1); + c->alloc = 1; + memcpy(c->data, str, c->len + 1); + } + if (old != NULL) { + mem->free(old); + } +} + +static CMARK_INLINE cmark_chunk cmark_chunk_literal(const char *data) { + bufsize_t len = data ? (bufsize_t)strlen(data) : 0; + cmark_chunk c = {(unsigned char *)data, len, 0}; + return c; +} + +static CMARK_INLINE cmark_chunk cmark_chunk_dup(const cmark_chunk *ch, + bufsize_t pos, bufsize_t len) { + cmark_chunk c = {ch->data + pos, len, 0}; + return c; +} + +static CMARK_INLINE cmark_chunk cmark_chunk_buf_detach(cmark_strbuf *buf) { + cmark_chunk c; + + c.len = buf->size; + c.data = cmark_strbuf_detach(buf); + c.alloc = 1; + + return c; +} + +/* trim_new variants are to be used when the source chunk may or may not be + * allocated; forces a newly allocated chunk. */ +static CMARK_INLINE cmark_chunk cmark_chunk_ltrim_new(cmark_mem *mem, cmark_chunk *c) { + cmark_chunk r = cmark_chunk_dup(c, 0, c->len); + cmark_chunk_ltrim(&r); + cmark_chunk_to_cstr(mem, &r); + return r; +} + +static CMARK_INLINE cmark_chunk cmark_chunk_rtrim_new(cmark_mem *mem, cmark_chunk *c) { + cmark_chunk r = cmark_chunk_dup(c, 0, c->len); + cmark_chunk_rtrim(&r); + cmark_chunk_to_cstr(mem, &r); + return r; +} + +#endif diff --git a/Sources/libcmark_gfm/include/cmark.h b/Sources/libcmark_gfm/include/cmark.h new file mode 100644 index 0000000..dd3e5ef --- /dev/null +++ b/Sources/libcmark_gfm/include/cmark.h @@ -0,0 +1,794 @@ +#ifndef CMARK_CMARK_H +#define CMARK_CMARK_H + +#include +#include +#include "cmark_export.h" +#include "cmark_version.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** # NAME + * + * **cmark-gfm** - CommonMark parsing, manipulating, and rendering + */ + +/** # DESCRIPTION + * + * ## Simple Interface + */ + +/** Convert 'text' (assumed to be a UTF-8 encoded string with length + * 'len') from CommonMark Markdown to HTML, returning a null-terminated, + * UTF-8-encoded string. It is the caller's responsibility + * to free the returned buffer. + */ +CMARK_EXPORT +char *cmark_markdown_to_html(const char *text, size_t len, int options); + +/** ## Node Structure + */ + +#define CMARK_NODE_TYPE_PRESENT (0x8000) +#define CMARK_NODE_TYPE_BLOCK (CMARK_NODE_TYPE_PRESENT | 0x0000) +#define CMARK_NODE_TYPE_INLINE (CMARK_NODE_TYPE_PRESENT | 0x4000) +#define CMARK_NODE_TYPE_MASK (0xc000) +#define CMARK_NODE_VALUE_MASK (0x3fff) + +typedef enum { + /* Error status */ + CMARK_NODE_NONE = 0x0000, + + /* Block */ + CMARK_NODE_DOCUMENT = CMARK_NODE_TYPE_BLOCK | 0x0001, + CMARK_NODE_BLOCK_QUOTE = CMARK_NODE_TYPE_BLOCK | 0x0002, + CMARK_NODE_LIST = CMARK_NODE_TYPE_BLOCK | 0x0003, + CMARK_NODE_ITEM = CMARK_NODE_TYPE_BLOCK | 0x0004, + CMARK_NODE_CODE_BLOCK = CMARK_NODE_TYPE_BLOCK | 0x0005, + CMARK_NODE_HTML_BLOCK = CMARK_NODE_TYPE_BLOCK | 0x0006, + CMARK_NODE_CUSTOM_BLOCK = CMARK_NODE_TYPE_BLOCK | 0x0007, + CMARK_NODE_PARAGRAPH = CMARK_NODE_TYPE_BLOCK | 0x0008, + CMARK_NODE_HEADING = CMARK_NODE_TYPE_BLOCK | 0x0009, + CMARK_NODE_THEMATIC_BREAK = CMARK_NODE_TYPE_BLOCK | 0x000a, + CMARK_NODE_FOOTNOTE_DEFINITION = CMARK_NODE_TYPE_BLOCK | 0x000b, + + /* Inline */ + CMARK_NODE_TEXT = CMARK_NODE_TYPE_INLINE | 0x0001, + CMARK_NODE_SOFTBREAK = CMARK_NODE_TYPE_INLINE | 0x0002, + CMARK_NODE_LINEBREAK = CMARK_NODE_TYPE_INLINE | 0x0003, + CMARK_NODE_CODE = CMARK_NODE_TYPE_INLINE | 0x0004, + CMARK_NODE_HTML_INLINE = CMARK_NODE_TYPE_INLINE | 0x0005, + CMARK_NODE_CUSTOM_INLINE = CMARK_NODE_TYPE_INLINE | 0x0006, + CMARK_NODE_EMPH = CMARK_NODE_TYPE_INLINE | 0x0007, + CMARK_NODE_STRONG = CMARK_NODE_TYPE_INLINE | 0x0008, + CMARK_NODE_LINK = CMARK_NODE_TYPE_INLINE | 0x0009, + CMARK_NODE_IMAGE = CMARK_NODE_TYPE_INLINE | 0x000a, + CMARK_NODE_FOOTNOTE_REFERENCE = CMARK_NODE_TYPE_INLINE | 0x000b, +} cmark_node_type; + +extern cmark_node_type CMARK_NODE_LAST_BLOCK; +extern cmark_node_type CMARK_NODE_LAST_INLINE; + +/* For backwards compatibility: */ +#define CMARK_NODE_HEADER CMARK_NODE_HEADING +#define CMARK_NODE_HRULE CMARK_NODE_THEMATIC_BREAK +#define CMARK_NODE_HTML CMARK_NODE_HTML_BLOCK +#define CMARK_NODE_INLINE_HTML CMARK_NODE_HTML_INLINE + +typedef enum { + CMARK_NO_LIST, + CMARK_BULLET_LIST, + CMARK_ORDERED_LIST +} cmark_list_type; + +typedef enum { + CMARK_NO_DELIM, + CMARK_PERIOD_DELIM, + CMARK_PAREN_DELIM +} cmark_delim_type; + +typedef struct cmark_node cmark_node; +typedef struct cmark_parser cmark_parser; +typedef struct cmark_iter cmark_iter; + +/** + * ## Custom memory allocator support + */ + +/** Defines the memory allocation functions to be used by CMark + * when parsing and allocating a document tree + */ +typedef struct cmark_mem { + void *(*calloc)(size_t, size_t); + void *(*realloc)(void *, size_t); + void (*free)(void *); +} cmark_mem; + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wstrict-prototypes" + +/** The default memory allocator; uses the system's calloc, + * realloc and free. + */ +CMARK_EXPORT +cmark_mem *cmark_get_default_mem_allocator(); + +/** An arena allocator; uses system calloc to allocate large + * slabs of memory. Memory in these slabs is not reused at all. + */ +CMARK_EXPORT +cmark_mem *cmark_get_arena_mem_allocator(); + +#pragma clang diagnostic pop + +/** Resets the arena allocator, quickly returning all used memory + * to the operating system. + */ +CMARK_EXPORT +void cmark_arena_reset(void); + +/** Callback for freeing user data with a 'cmark_mem' context. + */ +typedef void (*cmark_free_func) (cmark_mem *mem, void *user_data); + + +/* + * ## Basic data structures + * + * To keep dependencies to the strict minimum, libcmark implements + * its own versions of "classic" data structures. + */ + +/** + * ### Linked list + */ + +/** A generic singly linked list. + */ +typedef struct _cmark_llist +{ + struct _cmark_llist *next; + void *data; +} cmark_llist; + +/** Append an element to the linked list, return the possibly modified + * head of the list. + */ +CMARK_EXPORT +cmark_llist * cmark_llist_append (cmark_mem * mem, + cmark_llist * head, + void * data); + +/** Free the list starting with 'head', calling 'free_func' with the + * data pointer of each of its elements + */ +CMARK_EXPORT +void cmark_llist_free_full (cmark_mem * mem, + cmark_llist * head, + cmark_free_func free_func); + +/** Free the list starting with 'head' + */ +CMARK_EXPORT +void cmark_llist_free (cmark_mem * mem, + cmark_llist * head); + +/** + * ## Creating and Destroying Nodes + */ + +/** Creates a new node of type 'type'. Note that the node may have + * other required properties, which it is the caller's responsibility + * to assign. + */ +CMARK_EXPORT cmark_node *cmark_node_new(cmark_node_type type); + +/** Same as `cmark_node_new`, but explicitly listing the memory + * allocator used to allocate the node. Note: be sure to use the same + * allocator for every node in a tree, or bad things can happen. + */ +CMARK_EXPORT cmark_node *cmark_node_new_with_mem(cmark_node_type type, + cmark_mem *mem); + +/** Frees the memory allocated for a node and any children. + */ +CMARK_EXPORT void cmark_node_free(cmark_node *node); + +/** + * ## Tree Traversal + */ + +/** Returns the next node in the sequence after 'node', or NULL if + * there is none. + */ +CMARK_EXPORT cmark_node *cmark_node_next(cmark_node *node); + +/** Returns the previous node in the sequence after 'node', or NULL if + * there is none. + */ +CMARK_EXPORT cmark_node *cmark_node_previous(cmark_node *node); + +/** Returns the parent of 'node', or NULL if there is none. + */ +CMARK_EXPORT cmark_node *cmark_node_parent(cmark_node *node); + +/** Returns the first child of 'node', or NULL if 'node' has no children. + */ +CMARK_EXPORT cmark_node *cmark_node_first_child(cmark_node *node); + +/** Returns the last child of 'node', or NULL if 'node' has no children. + */ +CMARK_EXPORT cmark_node *cmark_node_last_child(cmark_node *node); + +/** + * ## Iterator + * + * An iterator will walk through a tree of nodes, starting from a root + * node, returning one node at a time, together with information about + * whether the node is being entered or exited. The iterator will + * first descend to a child node, if there is one. When there is no + * child, the iterator will go to the next sibling. When there is no + * next sibling, the iterator will return to the parent (but with + * a 'cmark_event_type' of `CMARK_EVENT_EXIT`). The iterator will + * return `CMARK_EVENT_DONE` when it reaches the root node again. + * One natural application is an HTML renderer, where an `ENTER` event + * outputs an open tag and an `EXIT` event outputs a close tag. + * An iterator might also be used to transform an AST in some systematic + * way, for example, turning all level-3 headings into regular paragraphs. + * + * void + * usage_example(cmark_node *root) { + * cmark_event_type ev_type; + * cmark_iter *iter = cmark_iter_new(root); + * + * while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) { + * cmark_node *cur = cmark_iter_get_node(iter); + * // Do something with `cur` and `ev_type` + * } + * + * cmark_iter_free(iter); + * } + * + * Iterators will never return `EXIT` events for leaf nodes, which are nodes + * of type: + * + * * CMARK_NODE_HTML_BLOCK + * * CMARK_NODE_THEMATIC_BREAK + * * CMARK_NODE_CODE_BLOCK + * * CMARK_NODE_TEXT + * * CMARK_NODE_SOFTBREAK + * * CMARK_NODE_LINEBREAK + * * CMARK_NODE_CODE + * * CMARK_NODE_HTML_INLINE + * + * Nodes must only be modified after an `EXIT` event, or an `ENTER` event for + * leaf nodes. + */ + +typedef enum { + CMARK_EVENT_NONE, + CMARK_EVENT_DONE, + CMARK_EVENT_ENTER, + CMARK_EVENT_EXIT +} cmark_event_type; + +/** Creates a new iterator starting at 'root'. The current node and event + * type are undefined until 'cmark_iter_next' is called for the first time. + * The memory allocated for the iterator should be released using + * 'cmark_iter_free' when it is no longer needed. + */ +CMARK_EXPORT +cmark_iter *cmark_iter_new(cmark_node *root); + +/** Frees the memory allocated for an iterator. + */ +CMARK_EXPORT +void cmark_iter_free(cmark_iter *iter); + +/** Advances to the next node and returns the event type (`CMARK_EVENT_ENTER`, + * `CMARK_EVENT_EXIT` or `CMARK_EVENT_DONE`). + */ +CMARK_EXPORT +cmark_event_type cmark_iter_next(cmark_iter *iter); + +/** Returns the current node. + */ +CMARK_EXPORT +cmark_node *cmark_iter_get_node(cmark_iter *iter); + +/** Returns the current event type. + */ +CMARK_EXPORT +cmark_event_type cmark_iter_get_event_type(cmark_iter *iter); + +/** Returns the root node. + */ +CMARK_EXPORT +cmark_node *cmark_iter_get_root(cmark_iter *iter); + +/** Resets the iterator so that the current node is 'current' and + * the event type is 'event_type'. The new current node must be a + * descendant of the root node or the root node itself. + */ +CMARK_EXPORT +void cmark_iter_reset(cmark_iter *iter, cmark_node *current, + cmark_event_type event_type); + +/** + * ## Accessors + */ + +/** Returns the user data of 'node'. + */ +CMARK_EXPORT void *cmark_node_get_user_data(cmark_node *node); + +/** Sets arbitrary user data for 'node'. Returns 1 on success, + * 0 on failure. + */ +CMARK_EXPORT int cmark_node_set_user_data(cmark_node *node, void *user_data); + +/** Set free function for user data */ +CMARK_EXPORT +int cmark_node_set_user_data_free_func(cmark_node *node, + cmark_free_func free_func); + +/** Returns the type of 'node', or `CMARK_NODE_NONE` on error. + */ +CMARK_EXPORT cmark_node_type cmark_node_get_type(cmark_node *node); + +/** Like 'cmark_node_get_type', but returns a string representation + of the type, or `""`. + */ +CMARK_EXPORT +const char *cmark_node_get_type_string(cmark_node *node); + +/** Returns the string contents of 'node', or an empty + string if none is set. Returns NULL if called on a + node that does not have string content. + */ +CMARK_EXPORT const char *cmark_node_get_literal(cmark_node *node); + +/** Sets the string contents of 'node'. Returns 1 on success, + * 0 on failure. + */ +CMARK_EXPORT int cmark_node_set_literal(cmark_node *node, const char *content); + +/** Returns the heading level of 'node', or 0 if 'node' is not a heading. + */ +CMARK_EXPORT int cmark_node_get_heading_level(cmark_node *node); + +/* For backwards compatibility */ +#define cmark_node_get_header_level cmark_node_get_heading_level +#define cmark_node_set_header_level cmark_node_set_heading_level + +/** Sets the heading level of 'node', returning 1 on success and 0 on error. + */ +CMARK_EXPORT int cmark_node_set_heading_level(cmark_node *node, int level); + +/** Returns the list type of 'node', or `CMARK_NO_LIST` if 'node' + * is not a list. + */ +CMARK_EXPORT cmark_list_type cmark_node_get_list_type(cmark_node *node); + +/** Sets the list type of 'node', returning 1 on success and 0 on error. + */ +CMARK_EXPORT int cmark_node_set_list_type(cmark_node *node, + cmark_list_type type); + +/** Returns the list delimiter type of 'node', or `CMARK_NO_DELIM` if 'node' + * is not a list. + */ +CMARK_EXPORT cmark_delim_type cmark_node_get_list_delim(cmark_node *node); + +/** Sets the list delimiter type of 'node', returning 1 on success and 0 + * on error. + */ +CMARK_EXPORT int cmark_node_set_list_delim(cmark_node *node, + cmark_delim_type delim); + +/** Returns starting number of 'node', if it is an ordered list, otherwise 0. + */ +CMARK_EXPORT int cmark_node_get_list_start(cmark_node *node); + +/** Sets starting number of 'node', if it is an ordered list. Returns 1 + * on success, 0 on failure. + */ +CMARK_EXPORT int cmark_node_set_list_start(cmark_node *node, int start); + +/** Returns 1 if 'node' is a tight list, 0 otherwise. + */ +CMARK_EXPORT int cmark_node_get_list_tight(cmark_node *node); + +/** Sets the "tightness" of a list. Returns 1 on success, 0 on failure. + */ +CMARK_EXPORT int cmark_node_set_list_tight(cmark_node *node, int tight); + +/** Returns the info string from a fenced code block. + */ +CMARK_EXPORT const char *cmark_node_get_fence_info(cmark_node *node); + +/** Sets the info string in a fenced code block, returning 1 on + * success and 0 on failure. + */ +CMARK_EXPORT int cmark_node_set_fence_info(cmark_node *node, const char *info); + +/** Sets code blocks fencing details + */ +CMARK_EXPORT int cmark_node_set_fenced(cmark_node * node, int fenced, + int length, int offset, char character); + +/** Returns code blocks fencing details + */ +CMARK_EXPORT int cmark_node_get_fenced(cmark_node *node, int *length, int *offset, char *character); + +/** Returns the URL of a link or image 'node', or an empty string + if no URL is set. Returns NULL if called on a node that is + not a link or image. + */ +CMARK_EXPORT const char *cmark_node_get_url(cmark_node *node); + +/** Sets the URL of a link or image 'node'. Returns 1 on success, + * 0 on failure. + */ +CMARK_EXPORT int cmark_node_set_url(cmark_node *node, const char *url); + +/** Returns the title of a link or image 'node', or an empty + string if no title is set. Returns NULL if called on a node + that is not a link or image. + */ +CMARK_EXPORT const char *cmark_node_get_title(cmark_node *node); + +/** Sets the title of a link or image 'node'. Returns 1 on success, + * 0 on failure. + */ +CMARK_EXPORT int cmark_node_set_title(cmark_node *node, const char *title); + +/** Returns the literal "on enter" text for a custom 'node', or + an empty string if no on_enter is set. Returns NULL if called + on a non-custom node. + */ +CMARK_EXPORT const char *cmark_node_get_on_enter(cmark_node *node); + +/** Sets the literal text to render "on enter" for a custom 'node'. + Any children of the node will be rendered after this text. + Returns 1 on success 0 on failure. + */ +CMARK_EXPORT int cmark_node_set_on_enter(cmark_node *node, + const char *on_enter); + +/** Returns the literal "on exit" text for a custom 'node', or + an empty string if no on_exit is set. Returns NULL if + called on a non-custom node. + */ +CMARK_EXPORT const char *cmark_node_get_on_exit(cmark_node *node); + +/** Sets the literal text to render "on exit" for a custom 'node'. + Any children of the node will be rendered before this text. + Returns 1 on success 0 on failure. + */ +CMARK_EXPORT int cmark_node_set_on_exit(cmark_node *node, const char *on_exit); + +/** Returns the line on which 'node' begins. + */ +CMARK_EXPORT int cmark_node_get_start_line(cmark_node *node); + +/** Returns the column at which 'node' begins. + */ +CMARK_EXPORT int cmark_node_get_start_column(cmark_node *node); + +/** Returns the line on which 'node' ends. + */ +CMARK_EXPORT int cmark_node_get_end_line(cmark_node *node); + +/** Returns the column at which 'node' ends. + */ +CMARK_EXPORT int cmark_node_get_end_column(cmark_node *node); + +/** + * ## Tree Manipulation + */ + +/** Unlinks a 'node', removing it from the tree, but not freeing its + * memory. (Use 'cmark_node_free' for that.) + */ +CMARK_EXPORT void cmark_node_unlink(cmark_node *node); + +/** Inserts 'sibling' before 'node'. Returns 1 on success, 0 on failure. + */ +CMARK_EXPORT int cmark_node_insert_before(cmark_node *node, + cmark_node *sibling); + +/** Inserts 'sibling' after 'node'. Returns 1 on success, 0 on failure. + */ +CMARK_EXPORT int cmark_node_insert_after(cmark_node *node, cmark_node *sibling); + +/** Replaces 'oldnode' with 'newnode' and unlinks 'oldnode' (but does + * not free its memory). + * Returns 1 on success, 0 on failure. + */ +CMARK_EXPORT int cmark_node_replace(cmark_node *oldnode, cmark_node *newnode); + +/** Adds 'child' to the beginning of the children of 'node'. + * Returns 1 on success, 0 on failure. + */ +CMARK_EXPORT int cmark_node_prepend_child(cmark_node *node, cmark_node *child); + +/** Adds 'child' to the end of the children of 'node'. + * Returns 1 on success, 0 on failure. + */ +CMARK_EXPORT int cmark_node_append_child(cmark_node *node, cmark_node *child); + +/** Consolidates adjacent text nodes. + */ +CMARK_EXPORT void cmark_consolidate_text_nodes(cmark_node *root); + +/** Ensures a node and all its children own their own chunk memory. + */ +CMARK_EXPORT void cmark_node_own(cmark_node *root); + +/** + * ## Parsing + * + * Simple interface: + * + * cmark_node *document = cmark_parse_document("Hello *world*", 13, + * CMARK_OPT_DEFAULT); + * + * Streaming interface: + * + * cmark_parser *parser = cmark_parser_new(CMARK_OPT_DEFAULT); + * FILE *fp = fopen("myfile.md", "rb"); + * while ((bytes = fread(buffer, 1, sizeof(buffer), fp)) > 0) { + * cmark_parser_feed(parser, buffer, bytes); + * if (bytes < sizeof(buffer)) { + * break; + * } + * } + * document = cmark_parser_finish(parser); + * cmark_parser_free(parser); + */ + +/** Creates a new parser object. + */ +CMARK_EXPORT +cmark_parser *cmark_parser_new(int options); + +/** Creates a new parser object with the given memory allocator + */ +CMARK_EXPORT +cmark_parser *cmark_parser_new_with_mem(int options, cmark_mem *mem); + +/** Frees memory allocated for a parser object. + */ +CMARK_EXPORT +void cmark_parser_free(cmark_parser *parser); + +/** Feeds a string of length 'len' to 'parser'. + */ +CMARK_EXPORT +void cmark_parser_feed(cmark_parser *parser, const char *buffer, size_t len); + +/** Finish parsing and return a pointer to a tree of nodes. + */ +CMARK_EXPORT +cmark_node *cmark_parser_finish(cmark_parser *parser); + +/** Parse a CommonMark document in 'buffer' of length 'len'. + * Returns a pointer to a tree of nodes. The memory allocated for + * the node tree should be released using 'cmark_node_free' + * when it is no longer needed. + */ +CMARK_EXPORT +cmark_node *cmark_parse_document(const char *buffer, size_t len, int options); + +/** Parse a CommonMark document in file 'f', returning a pointer to + * a tree of nodes. The memory allocated for the node tree should be + * released using 'cmark_node_free' when it is no longer needed. + */ +CMARK_EXPORT +cmark_node *cmark_parse_file(FILE *f, int options); + +/** + * ## Rendering + */ + +/** Render a 'node' tree as XML. It is the caller's responsibility + * to free the returned buffer. + */ +CMARK_EXPORT +char *cmark_render_xml(cmark_node *root, int options); + +/** As for 'cmark_render_xml', but specifying the allocator to use for + * the resulting string. + */ +CMARK_EXPORT +char *cmark_render_xml_with_mem(cmark_node *root, int options, cmark_mem *mem); + +/** Render a 'node' tree as an HTML fragment. It is up to the user + * to add an appropriate header and footer. It is the caller's + * responsibility to free the returned buffer. + */ +CMARK_EXPORT +char *cmark_render_html(cmark_node *root, int options, cmark_llist *extensions); + +/** As for 'cmark_render_html', but specifying the allocator to use for + * the resulting string. + */ +CMARK_EXPORT +char *cmark_render_html_with_mem(cmark_node *root, int options, cmark_llist *extensions, cmark_mem *mem); + +/** Render a 'node' tree as a groff man page, without the header. + * It is the caller's responsibility to free the returned buffer. + */ +CMARK_EXPORT +char *cmark_render_man(cmark_node *root, int options, int width); + +/** As for 'cmark_render_man', but specifying the allocator to use for + * the resulting string. + */ +CMARK_EXPORT +char *cmark_render_man_with_mem(cmark_node *root, int options, int width, cmark_mem *mem); + +/** Render a 'node' tree as a commonmark document. + * It is the caller's responsibility to free the returned buffer. + */ +CMARK_EXPORT +char *cmark_render_commonmark(cmark_node *root, int options, int width); + +/** As for 'cmark_render_commonmark', but specifying the allocator to use for + * the resulting string. + */ +CMARK_EXPORT +char *cmark_render_commonmark_with_mem(cmark_node *root, int options, int width, cmark_mem *mem); + +/** Render a 'node' tree as a plain text document. + * It is the caller's responsibility to free the returned buffer. + */ +CMARK_EXPORT +char *cmark_render_plaintext(cmark_node *root, int options, int width); + +/** As for 'cmark_render_plaintext', but specifying the allocator to use for + * the resulting string. + */ +CMARK_EXPORT +char *cmark_render_plaintext_with_mem(cmark_node *root, int options, int width, cmark_mem *mem); + +/** Render a 'node' tree as a LaTeX document. + * It is the caller's responsibility to free the returned buffer. + */ +CMARK_EXPORT +char *cmark_render_latex(cmark_node *root, int options, int width); + +/** As for 'cmark_render_latex', but specifying the allocator to use for + * the resulting string. + */ +CMARK_EXPORT +char *cmark_render_latex_with_mem(cmark_node *root, int options, int width, cmark_mem *mem); + +/** + * ## Options + */ + +/** Default options. + */ +#define CMARK_OPT_DEFAULT 0 + +/** + * ### Options affecting rendering + */ + +/** Include a `data-sourcepos` attribute on all block elements. + */ +#define CMARK_OPT_SOURCEPOS (1 << 1) + +/** Render `softbreak` elements as hard line breaks. + */ +#define CMARK_OPT_HARDBREAKS (1 << 2) + +/** Suppress raw HTML and unsafe links (`javascript:`, `vbscript:`, + * `file:`, and `data:`, except for `image/png`, `image/gif`, + * `image/jpeg`, or `image/webp` mime types). Raw HTML is replaced + * by a placeholder HTML comment. Unsafe links are replaced by + * empty strings. + */ +#define CMARK_OPT_SAFE (1 << 3) + +/** Render `softbreak` elements as spaces. + */ +#define CMARK_OPT_NOBREAKS (1 << 4) + +/** + * ### Options affecting parsing + */ + +/** Legacy option (no effect). + */ +#define CMARK_OPT_NORMALIZE (1 << 8) + +/** Validate UTF-8 in the input before parsing, replacing illegal + * sequences with the replacement character U+FFFD. + */ +#define CMARK_OPT_VALIDATE_UTF8 (1 << 9) + +/** Convert straight quotes to curly, --- to em dashes, -- to en dashes. + */ +#define CMARK_OPT_SMART (1 << 10) + +/** Use GitHub-style
 tags for code blocks instead of 
.
+ */
+#define CMARK_OPT_GITHUB_PRE_LANG (1 << 11)
+
+/** Be liberal in interpreting inline HTML tags.
+ */
+#define CMARK_OPT_LIBERAL_HTML_TAG (1 << 12)
+
+/** Parse footnotes.
+ */
+#define CMARK_OPT_FOOTNOTES (1 << 13)
+
+/**
+ * ## Version information
+ */
+
+/** The library version as integer for runtime checks. Also available as
+ * macro CMARK_VERSION for compile time checks.
+ *
+ * * Bits 16-23 contain the major version.
+ * * Bits 8-15 contain the minor version.
+ * * Bits 0-7 contain the patchlevel.
+ *
+ * In hexadecimal format, the number 0x010203 represents version 1.2.3.
+ */
+CMARK_EXPORT
+int cmark_version(void);
+
+/** The library version string for runtime checks. Also available as
+ * macro CMARK_VERSION_STRING for compile time checks.
+ */
+CMARK_EXPORT
+const char *cmark_version_string(void);
+
+/** # AUTHORS
+ *
+ * John MacFarlane, Vicent Marti,  Kārlis Gaņģis, Nick Wellnhofer.
+ */
+
+#ifndef CMARK_NO_SHORT_NAMES
+#define NODE_DOCUMENT CMARK_NODE_DOCUMENT
+#define NODE_BLOCK_QUOTE CMARK_NODE_BLOCK_QUOTE
+#define NODE_LIST CMARK_NODE_LIST
+#define NODE_ITEM CMARK_NODE_ITEM
+#define NODE_CODE_BLOCK CMARK_NODE_CODE_BLOCK
+#define NODE_HTML_BLOCK CMARK_NODE_HTML_BLOCK
+#define NODE_CUSTOM_BLOCK CMARK_NODE_CUSTOM_BLOCK
+#define NODE_PARAGRAPH CMARK_NODE_PARAGRAPH
+#define NODE_HEADING CMARK_NODE_HEADING
+#define NODE_HEADER CMARK_NODE_HEADER
+#define NODE_THEMATIC_BREAK CMARK_NODE_THEMATIC_BREAK
+#define NODE_HRULE CMARK_NODE_HRULE
+#define NODE_TEXT CMARK_NODE_TEXT
+#define NODE_SOFTBREAK CMARK_NODE_SOFTBREAK
+#define NODE_LINEBREAK CMARK_NODE_LINEBREAK
+#define NODE_CODE CMARK_NODE_CODE
+#define NODE_HTML_INLINE CMARK_NODE_HTML_INLINE
+#define NODE_CUSTOM_INLINE CMARK_NODE_CUSTOM_INLINE
+#define NODE_EMPH CMARK_NODE_EMPH
+#define NODE_STRONG CMARK_NODE_STRONG
+#define NODE_LINK CMARK_NODE_LINK
+#define NODE_IMAGE CMARK_NODE_IMAGE
+#define BULLET_LIST CMARK_BULLET_LIST
+#define ORDERED_LIST CMARK_ORDERED_LIST
+#define PERIOD_DELIM CMARK_PERIOD_DELIM
+#define PAREN_DELIM CMARK_PAREN_DELIM
+#endif
+
+typedef int32_t bufsize_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Sources/libcmark_gfm/include/cmark_ctype.h b/Sources/libcmark_gfm/include/cmark_ctype.h
new file mode 100644
index 0000000..4b90940
--- /dev/null
+++ b/Sources/libcmark_gfm/include/cmark_ctype.h
@@ -0,0 +1,33 @@
+#ifndef CMARK_CMARK_CTYPE_H
+#define CMARK_CMARK_CTYPE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "cmark_export.h"
+
+/** Locale-independent versions of functions from ctype.h.
+ * We want cmark to behave the same no matter what the system locale.
+ */
+
+CMARK_EXPORT
+int cmark_isspace(char c);
+
+CMARK_EXPORT
+int cmark_ispunct(char c);
+
+CMARK_EXPORT
+int cmark_isalnum(char c);
+
+CMARK_EXPORT
+int cmark_isdigit(char c);
+
+CMARK_EXPORT
+int cmark_isalpha(char c);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Sources/libcmark_gfm/include/cmark_export.h b/Sources/libcmark_gfm/include/cmark_export.h
new file mode 100644
index 0000000..cbf02d5
--- /dev/null
+++ b/Sources/libcmark_gfm/include/cmark_export.h
@@ -0,0 +1,42 @@
+
+#ifndef CMARK_EXPORT_H
+#define CMARK_EXPORT_H
+
+#ifdef CMARK_STATIC_DEFINE
+#  define CMARK_EXPORT
+#  define CMARK_NO_EXPORT
+#else
+#  ifndef CMARK_EXPORT
+#    ifdef libcmark_gfm_EXPORTS
+        /* We are building this library */
+#      define CMARK_EXPORT __attribute__((visibility("default")))
+#    else
+        /* We are using this library */
+#      define CMARK_EXPORT __attribute__((visibility("default")))
+#    endif
+#  endif
+
+#  ifndef CMARK_NO_EXPORT
+#    define CMARK_NO_EXPORT __attribute__((visibility("hidden")))
+#  endif
+#endif
+
+#ifndef CMARK_DEPRECATED
+#  define CMARK_DEPRECATED __attribute__ ((__deprecated__))
+#endif
+
+#ifndef CMARK_DEPRECATED_EXPORT
+#  define CMARK_DEPRECATED_EXPORT CMARK_EXPORT CMARK_DEPRECATED
+#endif
+
+#ifndef CMARK_DEPRECATED_NO_EXPORT
+#  define CMARK_DEPRECATED_NO_EXPORT CMARK_NO_EXPORT CMARK_DEPRECATED
+#endif
+
+#if 0 /* DEFINE_NO_DEPRECATED */
+#  ifndef CMARK_NO_DEPRECATED
+#    define CMARK_NO_DEPRECATED
+#  endif
+#endif
+
+#endif
diff --git a/Sources/libcmark_gfm/include/cmark_extension_api.h b/Sources/libcmark_gfm/include/cmark_extension_api.h
new file mode 100644
index 0000000..57ff229
--- /dev/null
+++ b/Sources/libcmark_gfm/include/cmark_extension_api.h
@@ -0,0 +1,719 @@
+#ifndef CMARK_CMARK_EXTENSION_API_H
+#define CMARK_CMARK_EXTENSION_API_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "cmark.h"
+
+struct cmark_renderer;
+struct cmark_html_renderer;
+struct cmark_chunk;
+
+/**
+ * ## Extension Support
+ *
+ * While the "core" of libcmark is strictly compliant with the
+ * specification, an API is provided for extension writers to
+ * hook into the parsing process.
+ *
+ * It should be noted that the cmark_node API already offers
+ * room for customization, with methods offered to traverse and
+ * modify the AST, and even define custom blocks.
+ * When the desired customization is achievable in an error-proof
+ * way using that API, it should be the preferred method.
+ *
+ * The following API requires a more in-depth understanding
+ * of libcmark's parsing strategy, which is exposed
+ * [here](http://spec.commonmark.org/0.24/#appendix-a-parsing-strategy).
+ *
+ * It should be used when "a posteriori" modification of the AST
+ * proves to be too difficult / impossible to implement correctly.
+ *
+ * It can also serve as an intermediary step before extending
+ * the specification, as an extension implemented using this API
+ * will be trivially integrated in the core if it proves to be
+ * desirable.
+ */
+
+typedef struct cmark_plugin cmark_plugin;
+
+/** A syntax extension that can be attached to a cmark_parser
+ * with cmark_parser_attach_syntax_extension().
+ *
+ * Extension writers should assign functions matching
+ * the signature of the following 'virtual methods' to
+ * implement new functionality.
+ *
+ * Their calling order and expected behaviour match the procedure outlined
+ * at :
+ *
+ * During step 1, cmark will call the function provided through
+ * 'cmark_syntax_extension_set_match_block_func' when it
+ * iterates over an open block created by this extension,
+ * to determine  whether it could contain the new line.
+ * If no function was provided, cmark will close the block.
+ *
+ * During step 2, if and only if the new line doesn't match any
+ * of the standard syntax rules, cmark will call the function
+ * provided through 'cmark_syntax_extension_set_open_block_func'
+ * to let the extension determine whether that new line matches
+ * one of its syntax rules.
+ * It is the responsibility of the parser to create and add the
+ * new block with cmark_parser_make_block and cmark_parser_add_child.
+ * If no function was provided is NULL, the extension will have
+ * no effect at all on the final block structure of the AST.
+ *
+ * #### Inline parsing phase hooks
+ *
+ * For each character provided by the extension through
+ * 'cmark_syntax_extension_set_special_inline_chars',
+ * the function provided by the extension through
+ * 'cmark_syntax_extension_set_match_inline_func'
+ * will get called, it is the responsibility of the extension
+ * to scan the characters located at the current inline parsing offset
+ * with the cmark_inline_parser API.
+ *
+ * Depending on the type of the extension, it can either:
+ *
+ * * Scan forward, determine that the syntax matches and return
+ *   a newly-created inline node with the appropriate type.
+ *   This is the technique that would be used if inline code
+ *   (with backticks) was implemented as an extension.
+ * * Scan only the character(s) that its syntax rules require
+ *   for opening and closing nodes, push a delimiter on the
+ *   delimiter stack, and return a simple text node with its
+ *   contents set to the character(s) consumed.
+ *   This is the technique that would be used if emphasis
+ *   inlines were implemented as an extension.
+ *
+ * When an extension has pushed delimiters on the stack,
+ * the function provided through
+ * 'cmark_syntax_extension_set_inline_from_delim_func'
+ * will get called in a latter phase,
+ * when the inline parser has matched opener and closer delimiters
+ * created by the extension together.
+ *
+ * It is then the responsibility of the extension to modify
+ * and populate the opener inline text node, and to remove
+ * the necessary delimiters from the delimiter stack.
+ *
+ * Finally, the extension should return NULL if its scan didn't
+ * match its syntax rules.
+ *
+ * The extension can store whatever private data it might need
+ * with 'cmark_syntax_extension_set_private',
+ * and optionally define a free function for this data.
+ */
+typedef struct cmark_syntax_extension cmark_syntax_extension;
+
+typedef struct subject cmark_inline_parser;
+
+/** Exposed raw for now */
+
+typedef struct delimiter {
+  struct delimiter *previous;
+  struct delimiter *next;
+  cmark_node *inl_text;
+  bufsize_t length;
+  unsigned char delim_char;
+  int can_open;
+  int can_close;
+} delimiter;
+
+/**
+ * ### Plugin API.
+ *
+ * Extensions should be distributed as dynamic libraries,
+ * with a single exported function named after the distributed
+ * filename.
+ *
+ * When discovering extensions (see cmark_init), cmark will
+ * try to load a symbol named "init_{{filename}}" in all the
+ * dynamic libraries it encounters.
+ *
+ * For example, given a dynamic library named myextension.so
+ * (or myextension.dll), cmark will try to load the symbol
+ * named "init_myextension". This means that the filename
+ * must lend itself to forming a valid C identifier, with
+ * the notable exception of dashes, which will be translated
+ * to underscores, which means cmark will look for a function
+ * named "init_my_extension" if it encounters a dynamic library
+ * named "my-extension.so".
+ *
+ * See the 'cmark_plugin_init_func' typedef for the exact prototype
+ * this function should follow.
+ *
+ * For now the extensibility of cmark is not complete, as
+ * it only offers API to hook into the block parsing phase
+ * ().
+ *
+ * See 'cmark_plugin_register_syntax_extension' for more information.
+ */
+
+/** The prototype plugins' init function should follow.
+ */
+typedef int (*cmark_plugin_init_func)(cmark_plugin *plugin);
+
+/** Register a syntax 'extension' with the 'plugin', it will be made
+ * available as an extension and, if attached to a cmark_parser
+ * with 'cmark_parser_attach_syntax_extension', it will contribute
+ * to the block parsing process.
+ *
+ * See the documentation for 'cmark_syntax_extension' for information
+ * on how to implement one.
+ *
+ * This function will typically be called from the init function
+ * of external modules.
+ *
+ * This takes ownership of 'extension', one should not call
+ * 'cmark_syntax_extension_free' on a registered extension.
+ */
+CMARK_EXPORT
+int cmark_plugin_register_syntax_extension(cmark_plugin *plugin,
+                                            cmark_syntax_extension *extension);
+
+/** This will search for the syntax extension named 'name' among the
+ *  registered syntax extensions.
+ *
+ *  It can then be attached to a cmark_parser
+ *  with the cmark_parser_attach_syntax_extension method.
+ */
+CMARK_EXPORT
+cmark_syntax_extension *cmark_find_syntax_extension(const char *name);
+
+/** Should create and add a new open block to 'parent_container' if
+ * 'input' matches a syntax rule for that block type. It is allowed
+ * to modify the type of 'parent_container'.
+ *
+ * Should return the newly created block if there is one, or
+ * 'parent_container' if its type was modified, or NULL.
+ */
+typedef cmark_node * (*cmark_open_block_func) (cmark_syntax_extension *extension,
+                                       int indented,
+                                       cmark_parser *parser,
+                                       cmark_node *parent_container,
+                                       unsigned char *input,
+                                       int len);
+
+typedef cmark_node *(*cmark_match_inline_func)(cmark_syntax_extension *extension,
+                                       cmark_parser *parser,
+                                       cmark_node *parent,
+                                       unsigned char character,
+                                       cmark_inline_parser *inline_parser);
+
+typedef delimiter *(*cmark_inline_from_delim_func)(cmark_syntax_extension *extension,
+                                           cmark_parser *parser,
+                                           cmark_inline_parser *inline_parser,
+                                           delimiter *opener,
+                                           delimiter *closer);
+
+/** Should return 'true' if 'input' can be contained in 'container',
+ *  'false' otherwise.
+ */
+typedef int (*cmark_match_block_func)        (cmark_syntax_extension *extension,
+                                       cmark_parser *parser,
+                                       unsigned char *input,
+                                       int len,
+                                       cmark_node *container);
+
+typedef const char *(*cmark_get_type_string_func) (cmark_syntax_extension *extension,
+                                                   cmark_node *node);
+
+typedef int (*cmark_can_contain_func) (cmark_syntax_extension *extension,
+                                       cmark_node *node,
+                                       cmark_node_type child);
+
+typedef int (*cmark_contains_inlines_func) (cmark_syntax_extension *extension,
+                                            cmark_node *node);
+
+typedef void (*cmark_common_render_func) (cmark_syntax_extension *extension,
+                                          struct cmark_renderer *renderer,
+                                          cmark_node *node,
+                                          cmark_event_type ev_type,
+                                          int options);
+
+typedef int (*cmark_commonmark_escape_func) (cmark_syntax_extension *extension,
+                                              cmark_node *node,
+                                              int c);
+
+typedef void (*cmark_html_render_func) (cmark_syntax_extension *extension,
+                                        struct cmark_html_renderer *renderer,
+                                        cmark_node *node,
+                                        cmark_event_type ev_type,
+                                        int options);
+
+typedef int (*cmark_html_filter_func) (cmark_syntax_extension *extension,
+                                       const unsigned char *tag,
+                                       size_t tag_len);
+
+typedef cmark_node *(*cmark_postprocess_func) (cmark_syntax_extension *extension,
+                                               cmark_parser *parser,
+                                               cmark_node *root);
+
+typedef int (*cmark_ispunct_func) (char c);
+
+typedef void (*cmark_opaque_free_func) (cmark_syntax_extension *extension,
+                                        cmark_mem *mem,
+                                        cmark_node *node);
+
+/** Free a cmark_syntax_extension.
+ */
+CMARK_EXPORT
+void cmark_syntax_extension_free               (cmark_mem *mem, cmark_syntax_extension *extension);
+
+/** Return a newly-constructed cmark_syntax_extension, named 'name'.
+ */
+CMARK_EXPORT
+cmark_syntax_extension *cmark_syntax_extension_new (const char *name);
+
+CMARK_EXPORT
+cmark_node_type cmark_syntax_extension_add_node(int is_inline);
+
+CMARK_EXPORT
+void cmark_syntax_extension_set_emphasis(cmark_syntax_extension *extension, int emphasis);
+
+/** See the documentation for 'cmark_syntax_extension'
+ */
+CMARK_EXPORT
+void cmark_syntax_extension_set_open_block_func(cmark_syntax_extension *extension,
+                                                cmark_open_block_func func);
+
+/** See the documentation for 'cmark_syntax_extension'
+ */
+CMARK_EXPORT
+void cmark_syntax_extension_set_match_block_func(cmark_syntax_extension *extension,
+                                                 cmark_match_block_func func);
+
+/** See the documentation for 'cmark_syntax_extension'
+ */
+CMARK_EXPORT
+void cmark_syntax_extension_set_match_inline_func(cmark_syntax_extension *extension,
+                                                  cmark_match_inline_func func);
+
+/** See the documentation for 'cmark_syntax_extension'
+ */
+CMARK_EXPORT
+void cmark_syntax_extension_set_inline_from_delim_func(cmark_syntax_extension *extension,
+                                                       cmark_inline_from_delim_func func);
+
+/** See the documentation for 'cmark_syntax_extension'
+ */
+CMARK_EXPORT
+void cmark_syntax_extension_set_special_inline_chars(cmark_syntax_extension *extension,
+                                                     cmark_llist *special_chars);
+
+/** See the documentation for 'cmark_syntax_extension'
+ */
+CMARK_EXPORT
+void cmark_syntax_extension_set_get_type_string_func(cmark_syntax_extension *extension,
+                                                     cmark_get_type_string_func func);
+
+/** See the documentation for 'cmark_syntax_extension'
+ */
+CMARK_EXPORT
+void cmark_syntax_extension_set_can_contain_func(cmark_syntax_extension *extension,
+                                                 cmark_can_contain_func func);
+
+/** See the documentation for 'cmark_syntax_extension'
+ */
+CMARK_EXPORT
+void cmark_syntax_extension_set_contains_inlines_func(cmark_syntax_extension *extension,
+                                                      cmark_contains_inlines_func func);
+
+/** See the documentation for 'cmark_syntax_extension'
+ */
+CMARK_EXPORT
+void cmark_syntax_extension_set_commonmark_render_func(cmark_syntax_extension *extension,
+                                                       cmark_common_render_func func);
+
+/** See the documentation for 'cmark_syntax_extension'
+ */
+CMARK_EXPORT
+void cmark_syntax_extension_set_plaintext_render_func(cmark_syntax_extension *extension,
+                                                      cmark_common_render_func func);
+
+/** See the documentation for 'cmark_syntax_extension'
+ */
+CMARK_EXPORT
+void cmark_syntax_extension_set_latex_render_func(cmark_syntax_extension *extension,
+                                                  cmark_common_render_func func);
+
+/** See the documentation for 'cmark_syntax_extension'
+ */
+CMARK_EXPORT
+void cmark_syntax_extension_set_man_render_func(cmark_syntax_extension *extension,
+                                                cmark_common_render_func func);
+
+/** See the documentation for 'cmark_syntax_extension'
+ */
+CMARK_EXPORT
+void cmark_syntax_extension_set_html_render_func(cmark_syntax_extension *extension,
+                                                 cmark_html_render_func func);
+
+/** See the documentation for 'cmark_syntax_extension'
+ */
+CMARK_EXPORT
+void cmark_syntax_extension_set_html_filter_func(cmark_syntax_extension *extension,
+                                                 cmark_html_filter_func func);
+
+/** See the documentation for 'cmark_syntax_extension'
+ */
+CMARK_EXPORT
+void cmark_syntax_extension_set_commonmark_escape_func(cmark_syntax_extension *extension,
+                                                       cmark_commonmark_escape_func func);
+
+/** See the documentation for 'cmark_syntax_extension'
+ */
+CMARK_EXPORT
+void cmark_syntax_extension_set_private(cmark_syntax_extension *extension,
+                                        void *priv,
+                                        cmark_free_func free_func);
+
+/** See the documentation for 'cmark_syntax_extension'
+ */
+CMARK_EXPORT
+void *cmark_syntax_extension_get_private(cmark_syntax_extension *extension);
+
+/** See the documentation for 'cmark_syntax_extension'
+ */
+CMARK_EXPORT
+void cmark_syntax_extension_set_postprocess_func(cmark_syntax_extension *extension,
+                                                 cmark_postprocess_func func);
+
+/** See the documentation for 'cmark_syntax_extension'
+ */
+CMARK_EXPORT
+void cmark_syntax_extension_set_opaque_free_func(cmark_syntax_extension *extension,
+                                                 cmark_opaque_free_func func);
+
+/** See the documentation for 'cmark_syntax_extension'
+ */
+CMARK_EXPORT
+void cmark_parser_set_backslash_ispunct_func(cmark_parser *parser,
+                                             cmark_ispunct_func func);
+
+/** Return the index of the line currently being parsed, starting with 1.
+ */
+CMARK_EXPORT
+int cmark_parser_get_line_number(cmark_parser *parser);
+
+/** Return the offset in bytes in the line being processed.
+ *
+ * Example:
+ *
+ * ### foo
+ *
+ * Here, offset will first be 0, then 5 (the index of the 'f' character).
+ */
+CMARK_EXPORT
+int cmark_parser_get_offset(cmark_parser *parser);
+
+/**
+ * Return the offset in 'columns' in the line being processed.
+ *
+ * This value may differ from the value returned by
+ * cmark_parser_get_offset() in that it accounts for tabs,
+ * and as such should not be used as an index in the current line's
+ * buffer.
+ *
+ * Example:
+ *
+ * cmark_parser_advance_offset() can be called to advance the
+ * offset by a number of columns, instead of a number of bytes.
+ *
+ * In that case, if offset falls "in the middle" of a tab
+ * character, 'column' and offset will differ.
+ *
+ * ```
+ * foo                 \t bar
+ * ^                   ^^
+ * offset (0)          20
+ * ```
+ *
+ * If cmark_parser_advance_offset is called here with 'columns'
+ * set to 'true' and 'offset' set to 22, cmark_parser_get_offset()
+ * will return 20, whereas cmark_parser_get_column() will return
+ * 22.
+ *
+ * Additionally, as tabs expand to the next multiple of 4 column,
+ * cmark_parser_has_partially_consumed_tab() will now return
+ * 'true'.
+ */
+CMARK_EXPORT
+int cmark_parser_get_column(cmark_parser *parser);
+
+/** Return the absolute index in bytes of the first nonspace
+ * character coming after the offset as returned by
+ * cmark_parser_get_offset() in the line currently being processed.
+ *
+ * Example:
+ *
+ * ```
+ *   foo        bar            baz  \n
+ * ^               ^           ^
+ * 0            offset (16) first_nonspace (28)
+ * ```
+ */
+CMARK_EXPORT
+int cmark_parser_get_first_nonspace(cmark_parser *parser);
+
+/** Return the absolute index of the first nonspace column coming after 'offset'
+ * in the line currently being processed, counting tabs as multiple
+ * columns as appropriate.
+ *
+ * See the documentation for cmark_parser_get_first_nonspace() and
+ * cmark_parser_get_column() for more information.
+ */
+CMARK_EXPORT
+int cmark_parser_get_first_nonspace_column(cmark_parser *parser);
+
+/** Return the difference between the values returned by
+ * cmark_parser_get_first_nonspace_column() and
+ * cmark_parser_get_column().
+ *
+ * This is not a byte offset, as it can count one tab as multiple
+ * characters.
+ */
+CMARK_EXPORT
+int cmark_parser_get_indent(cmark_parser *parser);
+
+/** Return 'true' if the line currently being processed has been entirely
+ * consumed, 'false' otherwise.
+ *
+ * Example:
+ *
+ * ```
+ *   foo        bar            baz  \n
+ * ^
+ * offset
+ * ```
+ *
+ * This function will return 'false' here.
+ *
+ * ```
+ *   foo        bar            baz  \n
+ *                 ^
+ *              offset
+ * ```
+ * This function will still return 'false'.
+ *
+ * ```
+ *   foo        bar            baz  \n
+ *                                ^
+ *                             offset
+ * ```
+ *
+ * At this point, this function will now return 'true'.
+ */
+CMARK_EXPORT
+int cmark_parser_is_blank(cmark_parser *parser);
+
+/** Return 'true' if the value returned by cmark_parser_get_offset()
+ * is 'inside' an expanded tab.
+ *
+ * See the documentation for cmark_parser_get_column() for more
+ * information.
+ */
+CMARK_EXPORT
+int cmark_parser_has_partially_consumed_tab(cmark_parser *parser);
+
+/** Return the length in bytes of the previously processed line, excluding potential
+ * newline (\n) and carriage return (\r) trailing characters.
+ */
+CMARK_EXPORT
+int cmark_parser_get_last_line_length(cmark_parser *parser);
+
+/** Add a child to 'parent' during the parsing process.
+ *
+ * If 'parent' isn't the kind of node that can accept this child,
+ * this function will back up till it hits a node that can, closing
+ * blocks as appropriate.
+ */
+CMARK_EXPORT
+cmark_node*cmark_parser_add_child(cmark_parser *parser,
+                                  cmark_node *parent,
+                                  cmark_node_type block_type,
+                                  int start_column);
+
+/** Advance the 'offset' of the parser in the current line.
+ *
+ * See the documentation of cmark_parser_get_offset() and
+ * cmark_parser_get_column() for more information.
+ */
+CMARK_EXPORT
+void cmark_parser_advance_offset(cmark_parser *parser,
+                                 const char *input,
+                                 int count,
+                                 int columns);
+
+
+CMARK_EXPORT
+void cmark_parser_feed_reentrant(cmark_parser *parser, const char *buffer, size_t len);
+
+/** Attach the syntax 'extension' to the 'parser', to provide extra syntax
+ *  rules.
+ *  See the documentation for cmark_syntax_extension for more information.
+ *
+ *  Returns 'true' if the 'extension' was successfully attached,
+ *  'false' otherwise.
+ */
+CMARK_EXPORT
+int cmark_parser_attach_syntax_extension(cmark_parser *parser, cmark_syntax_extension *extension);
+
+/** Change the type of 'node'.
+ *
+ * Return 0 if the type could be changed, 1 otherwise.
+ */
+CMARK_EXPORT int cmark_node_set_type(cmark_node *node, cmark_node_type type);
+
+/** Return the string content for all types of 'node'.
+ *  The pointer stays valid as long as 'node' isn't freed.
+ */
+CMARK_EXPORT const char *cmark_node_get_string_content(cmark_node *node);
+
+/** Set the string 'content' for all types of 'node'.
+ *  Copies 'content'.
+ */
+CMARK_EXPORT int cmark_node_set_string_content(cmark_node *node, const char *content);
+
+/** Get the syntax extension responsible for the creation of 'node'.
+ *  Return NULL if 'node' was created because it matched standard syntax rules.
+ */
+CMARK_EXPORT cmark_syntax_extension *cmark_node_get_syntax_extension(cmark_node *node);
+
+/** Set the syntax extension responsible for creating 'node'.
+ */
+CMARK_EXPORT int cmark_node_set_syntax_extension(cmark_node *node,
+                                                  cmark_syntax_extension *extension);
+
+/**
+ * ## Inline syntax extension helpers
+ *
+ * The inline parsing process is described in detail at
+ * 
+ */
+
+/** Should return 'true' if the predicate matches 'c', 'false' otherwise
+ */
+typedef int (*cmark_inline_predicate)(int c);
+
+/** Advance the current inline parsing offset */
+CMARK_EXPORT
+void cmark_inline_parser_advance_offset(cmark_inline_parser *parser);
+
+/** Get the current inline parsing offset */
+CMARK_EXPORT
+int cmark_inline_parser_get_offset(cmark_inline_parser *parser);
+
+/** Set the offset in bytes in the chunk being processed by the given inline parser.
+ */
+CMARK_EXPORT
+void cmark_inline_parser_set_offset(cmark_inline_parser *parser, int offset);
+
+/** Gets the cmark_chunk being operated on by the given inline parser.
+ * Use cmark_inline_parser_get_offset to get our current position in the chunk.
+ */
+CMARK_EXPORT
+struct cmark_chunk *cmark_inline_parser_get_chunk(cmark_inline_parser *parser);
+
+/** Returns 1 if the inline parser is currently in a bracket; pass 1 for 'image'
+ * if you want to know about an image-type bracket, 0 for link-type. */
+CMARK_EXPORT
+int cmark_inline_parser_in_bracket(cmark_inline_parser *parser, int image);
+
+/** Remove the last n characters from the last child of the given node.
+ * This only works where all n characters are in the single last child, and the last
+ * child is CMARK_NODE_TEXT.
+ */
+CMARK_EXPORT
+void cmark_node_unput(cmark_node *node, int n);
+
+
+/** Get the character located at the current inline parsing offset
+ */
+CMARK_EXPORT
+unsigned char cmark_inline_parser_peek_char(cmark_inline_parser *parser);
+
+/** Get the character located 'pos' bytes in the current line.
+ */
+CMARK_EXPORT
+unsigned char cmark_inline_parser_peek_at(cmark_inline_parser *parser, int pos);
+
+/** Whether the inline parser has reached the end of the current line
+ */
+CMARK_EXPORT
+int cmark_inline_parser_is_eof(cmark_inline_parser *parser);
+
+/** Get the characters located after the current inline parsing offset
+ * while 'pred' matches. Free after usage.
+ */
+CMARK_EXPORT
+char *cmark_inline_parser_take_while(cmark_inline_parser *parser, cmark_inline_predicate pred);
+
+/** Push a delimiter on the delimiter stack.
+ * See < for
+ * more information on the parameters
+ */
+CMARK_EXPORT
+void cmark_inline_parser_push_delimiter(cmark_inline_parser *parser,
+                                  unsigned char c,
+                                  int can_open,
+                                  int can_close,
+                                  cmark_node *inl_text);
+
+/** Remove 'delim' from the delimiter stack
+ */
+CMARK_EXPORT
+void cmark_inline_parser_remove_delimiter(cmark_inline_parser *parser, delimiter *delim);
+
+CMARK_EXPORT
+delimiter *cmark_inline_parser_get_last_delimiter(cmark_inline_parser *parser);
+
+CMARK_EXPORT
+int cmark_inline_parser_get_line(cmark_inline_parser *parser);
+
+CMARK_EXPORT
+int cmark_inline_parser_get_column(cmark_inline_parser *parser);
+
+/** Convenience function to scan a given delimiter.
+ *
+ * 'left_flanking' and 'right_flanking' will be set to true if they
+ * respectively precede and follow a non-space, non-punctuation
+ * character.
+ *
+ * Additionally, 'punct_before' and 'punct_after' will respectively be set
+ * if the preceding or following character is a punctuation character.
+ *
+ * Note that 'left_flanking' and 'right_flanking' can both be 'true'.
+ *
+ * Returns the number of delimiters encountered, in the limit
+ * of 'max_delims', and advances the inline parsing offset.
+ */
+CMARK_EXPORT
+int cmark_inline_parser_scan_delimiters(cmark_inline_parser *parser,
+                                  int max_delims,
+                                  unsigned char c,
+                                  int *left_flanking,
+                                  int *right_flanking,
+                                  int *punct_before,
+                                  int *punct_after);
+
+CMARK_EXPORT
+void cmark_manage_extensions_special_characters(cmark_parser *parser, int add);
+
+CMARK_EXPORT
+cmark_llist *cmark_parser_get_syntax_extensions(cmark_parser *parser);
+
+CMARK_EXPORT
+void cmark_arena_push(void);
+
+CMARK_EXPORT
+int cmark_arena_pop(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Sources/libcmark_gfm/include/cmark_version.h b/Sources/libcmark_gfm/include/cmark_version.h
new file mode 100644
index 0000000..e652669
--- /dev/null
+++ b/Sources/libcmark_gfm/include/cmark_version.h
@@ -0,0 +1,8 @@
+#ifndef CMARK_VERSION_H
+#define CMARK_VERSION_H
+
+#define CMARK_VERSION ((0 << 24) | (28 << 16) | (3 << 8) | 11)
+#define CMARK_VERSION_STRING "0.28.3.gfm.11"
+#define CMARK_GFM_VERSION 11
+
+#endif
diff --git a/Sources/libcmark_gfm/include/cmarkextensions_export.h b/Sources/libcmark_gfm/include/cmarkextensions_export.h
new file mode 100644
index 0000000..f646aa8
--- /dev/null
+++ b/Sources/libcmark_gfm/include/cmarkextensions_export.h
@@ -0,0 +1,42 @@
+
+#ifndef CMARKEXTENSIONS_EXPORT_H
+#define CMARKEXTENSIONS_EXPORT_H
+
+#ifdef CMARKEXTENSIONS_STATIC_DEFINE
+#  define CMARKEXTENSIONS_EXPORT
+#  define CMARKEXTENSIONS_NO_EXPORT
+#else
+#  ifndef CMARKEXTENSIONS_EXPORT
+#    ifdef libcmark_gfmextensions_EXPORTS
+        /* We are building this library */
+#      define CMARKEXTENSIONS_EXPORT __attribute__((visibility("default")))
+#    else
+        /* We are using this library */
+#      define CMARKEXTENSIONS_EXPORT __attribute__((visibility("default")))
+#    endif
+#  endif
+
+#  ifndef CMARKEXTENSIONS_NO_EXPORT
+#    define CMARKEXTENSIONS_NO_EXPORT __attribute__((visibility("hidden")))
+#  endif
+#endif
+
+#ifndef CMARKEXTENSIONS_DEPRECATED
+#  define CMARKEXTENSIONS_DEPRECATED __attribute__ ((__deprecated__))
+#endif
+
+#ifndef CMARKEXTENSIONS_DEPRECATED_EXPORT
+#  define CMARKEXTENSIONS_DEPRECATED_EXPORT CMARKEXTENSIONS_EXPORT CMARKEXTENSIONS_DEPRECATED
+#endif
+
+#ifndef CMARKEXTENSIONS_DEPRECATED_NO_EXPORT
+#  define CMARKEXTENSIONS_DEPRECATED_NO_EXPORT CMARKEXTENSIONS_NO_EXPORT CMARKEXTENSIONS_DEPRECATED
+#endif
+
+#if 0 /* DEFINE_NO_DEPRECATED */
+#  ifndef CMARKEXTENSIONS_NO_DEPRECATED
+#    define CMARKEXTENSIONS_NO_DEPRECATED
+#  endif
+#endif
+
+#endif
diff --git a/Sources/libcmark_gfm/include/config.h b/Sources/libcmark_gfm/include/config.h
new file mode 100644
index 0000000..d38c7c7
--- /dev/null
+++ b/Sources/libcmark_gfm/include/config.h
@@ -0,0 +1,76 @@
+#ifndef CMARK_CONFIG_H
+#define CMARK_CONFIG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define HAVE_STDBOOL_H
+
+#ifdef HAVE_STDBOOL_H
+  #include 
+#elif !defined(__cplusplus)
+  typedef char bool;
+#endif
+
+#define HAVE___BUILTIN_EXPECT
+
+#define HAVE___ATTRIBUTE__
+
+#ifdef HAVE___ATTRIBUTE__
+  #define CMARK_ATTRIBUTE(list) __attribute__ (list)
+#else
+  #define CMARK_ATTRIBUTE(list)
+#endif
+
+#ifndef CMARK_INLINE
+  #if defined(_MSC_VER) && !defined(__cplusplus)
+    #define CMARK_INLINE __inline
+  #else
+    #define CMARK_INLINE inline
+  #endif
+#endif
+
+/* snprintf and vsnprintf fallbacks for MSVC before 2015,
+   due to Valentin Milea http://stackoverflow.com/questions/2915672/
+*/
+
+#if defined(_MSC_VER) && _MSC_VER < 1900
+
+#include 
+#include 
+
+#define snprintf c99_snprintf
+#define vsnprintf c99_vsnprintf
+
+CMARK_INLINE int c99_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap)
+{
+    int count = -1;
+
+    if (size != 0)
+        count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
+    if (count == -1)
+        count = _vscprintf(format, ap);
+
+    return count;
+}
+
+CMARK_INLINE int c99_snprintf(char *outBuf, size_t size, const char *format, ...)
+{
+    int count;
+    va_list ap;
+
+    va_start(ap, format);
+    count = c99_vsnprintf(outBuf, size, format, ap);
+    va_end(ap);
+
+    return count;
+}
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Sources/libcmark_gfm/include/core-extensions.h b/Sources/libcmark_gfm/include/core-extensions.h
new file mode 100644
index 0000000..a9fd0cb
--- /dev/null
+++ b/Sources/libcmark_gfm/include/core-extensions.h
@@ -0,0 +1,25 @@
+#ifndef CORE_EXTENSIONS_H
+#define CORE_EXTENSIONS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "cmark_extension_api.h"
+#include "cmarkextensions_export.h"
+#include 
+
+CMARKEXTENSIONS_EXPORT
+void core_extensions_ensure_registered(void);
+
+CMARKEXTENSIONS_EXPORT
+uint16_t cmarkextensions_get_table_columns(cmark_node *node);
+
+CMARKEXTENSIONS_EXPORT
+uint8_t *cmarkextensions_get_table_alignments(cmark_node *node);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Sources/libcmark_gfm/include/ext_scanners.h b/Sources/libcmark_gfm/include/ext_scanners.h
new file mode 100644
index 0000000..53584d8
--- /dev/null
+++ b/Sources/libcmark_gfm/include/ext_scanners.h
@@ -0,0 +1,22 @@
+#include "chunk.h"
+#include "cmark.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+bufsize_t _ext_scan_at(bufsize_t (*scanner)(const unsigned char *),
+                       unsigned char *ptr, int len, bufsize_t offset);
+bufsize_t _scan_table_start(const unsigned char *p);
+bufsize_t _scan_table_cell(const unsigned char *p);
+bufsize_t _scan_table_cell_end(const unsigned char *p);
+bufsize_t _scan_table_row_end(const unsigned char *p);
+
+#define scan_table_start(c, l, n) _ext_scan_at(&_scan_table_start, c, l, n)
+#define scan_table_cell(c, l, n) _ext_scan_at(&_scan_table_cell, c, l, n)
+#define scan_table_cell_end(c, l, n) _ext_scan_at(&_scan_table_cell_end, c, l, n)
+#define scan_table_row_end(c, l, n) _ext_scan_at(&_scan_table_row_end, c, l, n)
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/Sources/libcmark_gfm/include/footnotes.h b/Sources/libcmark_gfm/include/footnotes.h
new file mode 100644
index 0000000..43dd64f
--- /dev/null
+++ b/Sources/libcmark_gfm/include/footnotes.h
@@ -0,0 +1,25 @@
+#ifndef CMARK_FOOTNOTES_H
+#define CMARK_FOOTNOTES_H
+
+#include "map.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct cmark_footnote {
+  cmark_map_entry entry;
+  cmark_node *node;
+  unsigned int ix;
+};
+
+typedef struct cmark_footnote cmark_footnote;
+
+void cmark_footnote_create(cmark_map *map, cmark_node *node);
+cmark_map *cmark_footnote_map_new(cmark_mem *mem);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Sources/libcmark_gfm/include/houdini.h b/Sources/libcmark_gfm/include/houdini.h
new file mode 100644
index 0000000..7852c3a
--- /dev/null
+++ b/Sources/libcmark_gfm/include/houdini.h
@@ -0,0 +1,57 @@
+#ifndef CMARK_HOUDINI_H
+#define CMARK_HOUDINI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include 
+#include "config.h"
+#include "buffer.h"
+
+#ifdef HAVE___BUILTIN_EXPECT
+#define likely(x) __builtin_expect((x), 1)
+#define unlikely(x) __builtin_expect((x), 0)
+#else
+#define likely(x) (x)
+#define unlikely(x) (x)
+#endif
+
+#ifdef HOUDINI_USE_LOCALE
+#define _isxdigit(c) isxdigit(c)
+#define _isdigit(c) isdigit(c)
+#else
+/*
+ * Helper _isdigit methods -- do not trust the current locale
+ * */
+#define _isxdigit(c) (strchr("0123456789ABCDEFabcdef", (c)) != NULL)
+#define _isdigit(c) ((c) >= '0' && (c) <= '9')
+#endif
+
+#define HOUDINI_ESCAPED_SIZE(x) (((x)*12) / 10)
+#define HOUDINI_UNESCAPED_SIZE(x) (x)
+
+CMARK_EXPORT
+bufsize_t houdini_unescape_ent(cmark_strbuf *ob, const uint8_t *src,
+                                      bufsize_t size);
+CMARK_EXPORT
+int houdini_escape_html(cmark_strbuf *ob, const uint8_t *src,
+                               bufsize_t size);
+CMARK_EXPORT
+int houdini_escape_html0(cmark_strbuf *ob, const uint8_t *src,
+                                bufsize_t size, int secure);
+CMARK_EXPORT
+int houdini_unescape_html(cmark_strbuf *ob, const uint8_t *src,
+                                 bufsize_t size);
+CMARK_EXPORT
+void houdini_unescape_html_f(cmark_strbuf *ob, const uint8_t *src,
+                                    bufsize_t size);
+CMARK_EXPORT
+int houdini_escape_href(cmark_strbuf *ob, const uint8_t *src,
+                               bufsize_t size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Sources/libcmark_gfm/include/html.h b/Sources/libcmark_gfm/include/html.h
new file mode 100644
index 0000000..aeba7bc
--- /dev/null
+++ b/Sources/libcmark_gfm/include/html.h
@@ -0,0 +1,27 @@
+#ifndef CMARK_HTML_H
+#define CMARK_HTML_H
+
+#include "buffer.h"
+#include "node.h"
+
+CMARK_INLINE
+static void cmark_html_render_cr(cmark_strbuf *html) {
+  if (html->size && html->ptr[html->size - 1] != '\n')
+    cmark_strbuf_putc(html, '\n');
+}
+
+#define BUFFER_SIZE 100
+
+CMARK_INLINE 
+static void cmark_html_render_sourcepos(cmark_node *node, cmark_strbuf *html, int options) {
+  char buffer[BUFFER_SIZE];
+  if (CMARK_OPT_SOURCEPOS & options) {
+    snprintf(buffer, BUFFER_SIZE, " data-sourcepos=\"%d:%d-%d:%d\"",
+             cmark_node_get_start_line(node), cmark_node_get_start_column(node),
+             cmark_node_get_end_line(node), cmark_node_get_end_column(node));
+    cmark_strbuf_puts(html, buffer);
+  }
+}
+
+
+#endif
diff --git a/Sources/libcmark_gfm/include/inlines.h b/Sources/libcmark_gfm/include/inlines.h
new file mode 100644
index 0000000..8c8174c
--- /dev/null
+++ b/Sources/libcmark_gfm/include/inlines.h
@@ -0,0 +1,29 @@
+#ifndef CMARK_INLINES_H
+#define CMARK_INLINES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "references.h"
+
+cmark_chunk cmark_clean_url(cmark_mem *mem, cmark_chunk *url);
+cmark_chunk cmark_clean_title(cmark_mem *mem, cmark_chunk *title);
+
+CMARK_EXPORT
+void cmark_parse_inlines(cmark_parser *parser,
+                         cmark_node *parent,
+                         cmark_map *refmap,
+                         int options);
+
+bufsize_t cmark_parse_reference_inline(cmark_mem *mem, cmark_chunk *input,
+                                       cmark_map *refmap);
+
+void cmark_inlines_add_special_character(unsigned char c, bool emphasis);
+void cmark_inlines_remove_special_character(unsigned char c, bool emphasis);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Sources/libcmark_gfm/include/iterator.h b/Sources/libcmark_gfm/include/iterator.h
new file mode 100644
index 0000000..138f111
--- /dev/null
+++ b/Sources/libcmark_gfm/include/iterator.h
@@ -0,0 +1,27 @@
+#ifndef CMARK_ITERATOR_H
+#define CMARK_ITERATOR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "cmark.h"
+//#include 
+
+typedef struct {
+  cmark_event_type ev_type;
+  cmark_node *node;
+} cmark_iter_state;
+
+struct cmark_iter {
+  cmark_mem *mem;
+  cmark_node *root;
+  cmark_iter_state cur;
+  cmark_iter_state next;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Sources/libcmark_gfm/include/libcmark_gfm.h b/Sources/libcmark_gfm/include/libcmark_gfm.h
new file mode 100644
index 0000000..b2c2976
--- /dev/null
+++ b/Sources/libcmark_gfm/include/libcmark_gfm.h
@@ -0,0 +1,43 @@
+//
+//  libcmark_gfm.h
+//  libcmark_gfm
+//
+//  Created by Kris Baker on 12/23/17.
+//  Copyright © 2017 Kristopher Baker. All rights reserved.
+//
+
+#ifndef libcmark_gfm_h
+#define libcmark_gfm_h
+
+#include "autolink.h"
+#include "buffer.h"
+#include "chunk.h"
+#include "cmark.h"
+#include "cmark_ctype.h"
+#include "cmark_export.h"
+#include "cmark_extension_api.h"
+#include "cmark_version.h"
+#include "cmarkextensions_export.h"
+#include "config.h"
+#include "core-extensions.h"
+#include "ext_scanners.h"
+#include "footnotes.h"
+#include "houdini.h"
+#include "html.h"
+#include "inlines.h"
+#include "iterator.h"
+#include "map.h"
+#include "node.h"
+#include "parser.h"
+#include "plugin.h"
+#include "references.h"
+#include "registry.h"
+#include "render.h"
+#include "scanners.h"
+#include "strikethrough.h"
+#include "syntax_extension.h"
+#include "table.h"
+#include "tagfilter.h"
+#include "utf8.h"
+
+#endif /* libcmark_gfm_h */
diff --git a/Sources/libcmark_gfm/include/map.h b/Sources/libcmark_gfm/include/map.h
new file mode 100644
index 0000000..874f7bc
--- /dev/null
+++ b/Sources/libcmark_gfm/include/map.h
@@ -0,0 +1,42 @@
+#ifndef CMARK_MAP_H
+#define CMARK_MAP_H
+
+//#include 
+#include "chunk.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct cmark_map_entry {
+  struct cmark_map_entry *next;
+  unsigned char *label;
+  unsigned int age;
+};
+
+typedef struct cmark_map_entry cmark_map_entry;
+
+struct cmark_map;
+
+typedef void (*cmark_map_free_f)(struct cmark_map *, cmark_map_entry *);
+
+struct cmark_map {
+  cmark_mem *mem;
+  cmark_map_entry *refs;
+  cmark_map_entry **sorted;
+  unsigned int size;
+  cmark_map_free_f free;
+};
+
+typedef struct cmark_map cmark_map;
+
+unsigned char *normalize_map_label(cmark_mem *mem, cmark_chunk *ref);
+cmark_map *cmark_map_new(cmark_mem *mem, cmark_map_free_f free);
+void cmark_map_free(cmark_map *map);
+cmark_map_entry *cmark_map_lookup(cmark_map *map, cmark_chunk *label);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Sources/libcmark_gfm/include/node.h b/Sources/libcmark_gfm/include/node.h
new file mode 100644
index 0000000..1d8aa50
--- /dev/null
+++ b/Sources/libcmark_gfm/include/node.h
@@ -0,0 +1,116 @@
+#ifndef CMARK_NODE_H
+#define CMARK_NODE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include 
+#include 
+
+#include "cmark.h"
+#include "cmark_extension_api.h"
+#include "buffer.h"
+#include "chunk.h"
+
+typedef struct {
+  cmark_list_type list_type;
+  int marker_offset;
+  int padding;
+  int start;
+  cmark_delim_type delimiter;
+  unsigned char bullet_char;
+  bool tight;
+} cmark_list;
+
+typedef struct {
+  cmark_chunk info;
+  cmark_chunk literal;
+  uint8_t fence_length;
+  uint8_t fence_offset;
+  unsigned char fence_char;
+  int8_t fenced;
+} cmark_code;
+
+typedef struct {
+  int level;
+  bool setext;
+} cmark_heading;
+
+typedef struct {
+  cmark_chunk url;
+  cmark_chunk title;
+} cmark_link;
+
+typedef struct {
+  cmark_chunk on_enter;
+  cmark_chunk on_exit;
+} cmark_custom;
+
+enum cmark_node__internal_flags {
+  CMARK_NODE__OPEN = (1 << 0),
+  CMARK_NODE__LAST_LINE_BLANK = (1 << 1),
+};
+
+struct cmark_node {
+  cmark_strbuf content;
+
+  struct cmark_node *next;
+  struct cmark_node *prev;
+  struct cmark_node *parent;
+  struct cmark_node *first_child;
+  struct cmark_node *last_child;
+
+  void *user_data;
+  cmark_free_func user_data_free_func;
+
+  int start_line;
+  int start_column;
+  int end_line;
+  int end_column;
+  int internal_offset;
+  uint16_t type;
+  uint16_t flags;
+
+  cmark_syntax_extension *extension;
+
+  union {
+    cmark_chunk literal;
+    cmark_list list;
+    cmark_code code;
+    cmark_heading heading;
+    cmark_link link;
+    cmark_custom custom;
+    int html_block_type;
+    void *opaque;
+  } as;
+};
+
+static CMARK_INLINE cmark_mem *cmark_node_mem(cmark_node *node) {
+  return node->content.mem;
+}
+CMARK_EXPORT int cmark_node_check(cmark_node *node, FILE *out);
+
+static CMARK_INLINE bool CMARK_NODE_TYPE_BLOCK_P(cmark_node_type node_type) {
+	return (node_type & CMARK_NODE_TYPE_MASK) == CMARK_NODE_TYPE_BLOCK;
+}
+
+static CMARK_INLINE bool CMARK_NODE_BLOCK_P(cmark_node *node) {
+	return node != NULL && CMARK_NODE_TYPE_BLOCK_P((cmark_node_type) node->type);
+}
+
+static CMARK_INLINE bool CMARK_NODE_TYPE_INLINE_P(cmark_node_type node_type) {
+	return (node_type & CMARK_NODE_TYPE_MASK) == CMARK_NODE_TYPE_INLINE;
+}
+
+static CMARK_INLINE bool CMARK_NODE_INLINE_P(cmark_node *node) {
+	return node != NULL && CMARK_NODE_TYPE_INLINE_P((cmark_node_type) node->type);
+}
+
+CMARK_EXPORT bool cmark_node_can_contain_type(cmark_node *node, cmark_node_type child_type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Sources/libcmark_gfm/include/parser.h b/Sources/libcmark_gfm/include/parser.h
new file mode 100644
index 0000000..0011506
--- /dev/null
+++ b/Sources/libcmark_gfm/include/parser.h
@@ -0,0 +1,57 @@
+#ifndef CMARK_PARSER_H
+#define CMARK_PARSER_H
+
+#include 
+#include "node.h"
+#include "buffer.h"
+//#include 
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAX_LINK_LABEL_LENGTH 1000
+
+struct cmark_parser {
+  struct cmark_mem *mem;
+  /* A hashtable of urls in the current document for cross-references */
+  struct cmark_map *refmap;
+  /* The root node of the parser, always a CMARK_NODE_DOCUMENT */
+  struct cmark_node *root;
+  /* The last open block after a line is fully processed */
+  struct cmark_node *current;
+  /* See the documentation for cmark_parser_get_line_number() in cmark.h */
+  int line_number;
+  /* See the documentation for cmark_parser_get_offset() in cmark.h */
+  bufsize_t offset;
+  /* See the documentation for cmark_parser_get_column() in cmark.h */
+  bufsize_t column;
+  /* See the documentation for cmark_parser_get_first_nonspace() in cmark.h */
+  bufsize_t first_nonspace;
+  /* See the documentation for cmark_parser_get_first_nonspace_column() in cmark.h */
+  bufsize_t first_nonspace_column;
+  /* See the documentation for cmark_parser_get_indent() in cmark.h */
+  int indent;
+  /* See the documentation for cmark_parser_is_blank() in cmark.h */
+  bool blank;
+  /* See the documentation for cmark_parser_has_partially_consumed_tab() in cmark.h */
+  bool partially_consumed_tab;
+  /* Contains the currently processed line */
+  cmark_strbuf curline;
+  /* See the documentation for cmark_parser_get_last_line_length() in cmark.h */
+  bufsize_t last_line_length;
+  /* FIXME: not sure about the difference with curline */
+  cmark_strbuf linebuf;
+  /* Options set by the user, see the Options section in cmark.h */
+  int options;
+  bool last_buffer_ended_with_cr;
+  cmark_llist *syntax_extensions;
+  cmark_llist *inline_syntax_extensions;
+  cmark_ispunct_func backslash_ispunct;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Sources/libcmark_gfm/include/plugin.h b/Sources/libcmark_gfm/include/plugin.h
new file mode 100644
index 0000000..b9e9d29
--- /dev/null
+++ b/Sources/libcmark_gfm/include/plugin.h
@@ -0,0 +1,34 @@
+#ifndef CMARK_PLUGIN_H
+#define CMARK_PLUGIN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "cmark.h"
+#include "cmark_extension_api.h"
+
+/**
+ * cmark_plugin:
+ *
+ * A plugin structure, which should be filled by plugin's
+ * init functions.
+ */
+struct cmark_plugin {
+  cmark_llist *syntax_extensions;
+};
+
+cmark_llist *
+cmark_plugin_steal_syntax_extensions(cmark_plugin *plugin);
+
+cmark_plugin *
+cmark_plugin_new(void);
+
+void
+cmark_plugin_free(cmark_plugin *plugin);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Sources/libcmark_gfm/include/references.h b/Sources/libcmark_gfm/include/references.h
new file mode 100644
index 0000000..def944d
--- /dev/null
+++ b/Sources/libcmark_gfm/include/references.h
@@ -0,0 +1,26 @@
+#ifndef CMARK_REFERENCES_H
+#define CMARK_REFERENCES_H
+
+#include "map.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct cmark_reference {
+  cmark_map_entry entry;
+  cmark_chunk url;
+  cmark_chunk title;
+};
+
+typedef struct cmark_reference cmark_reference;
+
+void cmark_reference_create(cmark_map *map, cmark_chunk *label,
+                            cmark_chunk *url, cmark_chunk *title);
+cmark_map *cmark_reference_map_new(cmark_mem *mem);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Sources/libcmark_gfm/include/registry.h b/Sources/libcmark_gfm/include/registry.h
new file mode 100644
index 0000000..0f0fbae
--- /dev/null
+++ b/Sources/libcmark_gfm/include/registry.h
@@ -0,0 +1,24 @@
+#ifndef CMARK_REGISTRY_H
+#define CMARK_REGISTRY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "cmark.h"
+#include "plugin.h"
+
+CMARK_EXPORT
+void cmark_register_plugin(cmark_plugin_init_func reg_fn);
+
+CMARK_EXPORT
+void cmark_release_plugins(void);
+
+CMARK_EXPORT
+cmark_llist *cmark_list_syntax_extensions(cmark_mem *mem);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Sources/libcmark_gfm/include/render.h b/Sources/libcmark_gfm/include/render.h
new file mode 100644
index 0000000..8738dd5
--- /dev/null
+++ b/Sources/libcmark_gfm/include/render.h
@@ -0,0 +1,63 @@
+#ifndef CMARK_RENDER_H
+#define CMARK_RENDER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include 
+#include "buffer.h"
+#include "chunk.h"
+//#include 
+
+typedef enum { LITERAL, NORMAL, TITLE, URL } cmark_escaping;
+
+struct cmark_renderer {
+  cmark_mem *mem;
+  cmark_strbuf *buffer;
+  cmark_strbuf *prefix;
+  int column;
+  int width;
+  int need_cr;
+  bufsize_t last_breakable;
+  bool begin_line;
+  bool begin_content;
+  bool no_linebreaks;
+  bool in_tight_list_item;
+  void (*outc)(struct cmark_renderer *, cmark_node *, cmark_escaping, int32_t, unsigned char);
+  void (*cr)(struct cmark_renderer *);
+  void (*blankline)(struct cmark_renderer *);
+  void (*out)(struct cmark_renderer *, cmark_node *, const char *, bool, cmark_escaping);
+  unsigned int footnote_ix;
+};
+
+typedef struct cmark_renderer cmark_renderer;
+
+struct cmark_html_renderer {
+  cmark_strbuf *html;
+  cmark_node *plain;
+  cmark_llist *filter_extensions;
+  unsigned int footnote_ix;
+  unsigned int written_footnote_ix;
+  void *opaque;
+};
+
+typedef struct cmark_html_renderer cmark_html_renderer;
+
+void cmark_render_ascii(cmark_renderer *renderer, const char *s);
+
+void cmark_render_code_point(cmark_renderer *renderer, uint32_t c);
+
+char *cmark_render(cmark_mem *mem, cmark_node *root, int options, int width,
+                   void (*outc)(cmark_renderer *, cmark_node *,
+                                cmark_escaping, int32_t,
+                                unsigned char),
+                   int (*render_node)(cmark_renderer *renderer,
+                                      cmark_node *node,
+                                      cmark_event_type ev_type, int options));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Sources/libcmark_gfm/include/scanners.h b/Sources/libcmark_gfm/include/scanners.h
new file mode 100644
index 0000000..ffdbaeb
--- /dev/null
+++ b/Sources/libcmark_gfm/include/scanners.h
@@ -0,0 +1,64 @@
+#ifndef CMARK_SCANNERS_H
+#define CMARK_SCANNERS_H
+
+#include "cmark.h"
+#include "chunk.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+bufsize_t _scan_at(bufsize_t (*scanner)(const unsigned char *), cmark_chunk *c,
+                   bufsize_t offset);
+bufsize_t _scan_scheme(const unsigned char *p);
+bufsize_t _scan_autolink_uri(const unsigned char *p);
+bufsize_t _scan_autolink_email(const unsigned char *p);
+bufsize_t _scan_html_tag(const unsigned char *p);
+bufsize_t _scan_liberal_html_tag(const unsigned char *p);
+bufsize_t _scan_html_block_start(const unsigned char *p);
+bufsize_t _scan_html_block_start_7(const unsigned char *p);
+bufsize_t _scan_html_block_end_1(const unsigned char *p);
+bufsize_t _scan_html_block_end_2(const unsigned char *p);
+bufsize_t _scan_html_block_end_3(const unsigned char *p);
+bufsize_t _scan_html_block_end_4(const unsigned char *p);
+bufsize_t _scan_html_block_end_5(const unsigned char *p);
+bufsize_t _scan_link_title(const unsigned char *p);
+bufsize_t _scan_spacechars(const unsigned char *p);
+bufsize_t _scan_atx_heading_start(const unsigned char *p);
+bufsize_t _scan_setext_heading_line(const unsigned char *p);
+bufsize_t _scan_thematic_break(const unsigned char *p);
+bufsize_t _scan_open_code_fence(const unsigned char *p);
+bufsize_t _scan_close_code_fence(const unsigned char *p);
+bufsize_t _scan_entity(const unsigned char *p);
+bufsize_t _scan_dangerous_url(const unsigned char *p);
+bufsize_t _scan_footnote_definition(const unsigned char *p);
+
+#define scan_scheme(c, n) _scan_at(&_scan_scheme, c, n)
+#define scan_autolink_uri(c, n) _scan_at(&_scan_autolink_uri, c, n)
+#define scan_autolink_email(c, n) _scan_at(&_scan_autolink_email, c, n)
+#define scan_html_tag(c, n) _scan_at(&_scan_html_tag, c, n)
+#define scan_liberal_html_tag(c, n) _scan_at(&_scan_liberal_html_tag, c, n)
+#define scan_html_block_start(c, n) _scan_at(&_scan_html_block_start, c, n)
+#define scan_html_block_start_7(c, n) _scan_at(&_scan_html_block_start_7, c, n)
+#define scan_html_block_end_1(c, n) _scan_at(&_scan_html_block_end_1, c, n)
+#define scan_html_block_end_2(c, n) _scan_at(&_scan_html_block_end_2, c, n)
+#define scan_html_block_end_3(c, n) _scan_at(&_scan_html_block_end_3, c, n)
+#define scan_html_block_end_4(c, n) _scan_at(&_scan_html_block_end_4, c, n)
+#define scan_html_block_end_5(c, n) _scan_at(&_scan_html_block_end_5, c, n)
+#define scan_link_title(c, n) _scan_at(&_scan_link_title, c, n)
+#define scan_spacechars(c, n) _scan_at(&_scan_spacechars, c, n)
+#define scan_atx_heading_start(c, n) _scan_at(&_scan_atx_heading_start, c, n)
+#define scan_setext_heading_line(c, n)                                         \
+  _scan_at(&_scan_setext_heading_line, c, n)
+#define scan_thematic_break(c, n) _scan_at(&_scan_thematic_break, c, n)
+#define scan_open_code_fence(c, n) _scan_at(&_scan_open_code_fence, c, n)
+#define scan_close_code_fence(c, n) _scan_at(&_scan_close_code_fence, c, n)
+#define scan_entity(c, n) _scan_at(&_scan_entity, c, n)
+#define scan_dangerous_url(c, n) _scan_at(&_scan_dangerous_url, c, n)
+#define scan_footnote_definition(c, n) _scan_at(&_scan_footnote_definition, c, n)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Sources/libcmark_gfm/include/strikethrough.h b/Sources/libcmark_gfm/include/strikethrough.h
new file mode 100644
index 0000000..1c43f57
--- /dev/null
+++ b/Sources/libcmark_gfm/include/strikethrough.h
@@ -0,0 +1,9 @@
+#ifndef STRIKETHROUGH_H
+#define STRIKETHROUGH_H
+
+#include "core-extensions.h"
+
+extern cmark_node_type CMARK_NODE_STRIKETHROUGH;
+cmark_syntax_extension *create_strikethrough_extension(void);
+
+#endif
diff --git a/Sources/libcmark_gfm/include/syntax_extension.h b/Sources/libcmark_gfm/include/syntax_extension.h
new file mode 100644
index 0000000..f51f1f4
--- /dev/null
+++ b/Sources/libcmark_gfm/include/syntax_extension.h
@@ -0,0 +1,32 @@
+#ifndef CMARK_SYNTAX_EXTENSION_H
+#define CMARK_SYNTAX_EXTENSION_H
+
+#include "cmark.h"
+#include "cmark_extension_api.h"
+#include "config.h"
+
+struct cmark_syntax_extension {
+  cmark_match_block_func          last_block_matches;
+  cmark_open_block_func           try_opening_block;
+  cmark_match_inline_func         match_inline;
+  cmark_inline_from_delim_func    insert_inline_from_delim;
+  cmark_llist                   * special_inline_chars;
+  char                          * name;
+  void                          * priv;
+  bool                            emphasis;
+  cmark_free_func                 free_function;
+  cmark_get_type_string_func      get_type_string_func;
+  cmark_can_contain_func          can_contain_func;
+  cmark_contains_inlines_func     contains_inlines_func;
+  cmark_common_render_func        commonmark_render_func;
+  cmark_common_render_func        plaintext_render_func;
+  cmark_common_render_func        latex_render_func;
+  cmark_common_render_func        man_render_func;
+  cmark_html_render_func          html_render_func;
+  cmark_html_filter_func          html_filter_func;
+  cmark_postprocess_func          postprocess_func;
+  cmark_opaque_free_func          opaque_free_func;
+  cmark_commonmark_escape_func    commonmark_escape_func;
+};
+
+#endif
diff --git a/Sources/libcmark_gfm/include/table.h b/Sources/libcmark_gfm/include/table.h
new file mode 100644
index 0000000..ff630b2
--- /dev/null
+++ b/Sources/libcmark_gfm/include/table.h
@@ -0,0 +1,8 @@
+#ifndef TABLE_H
+#define TABLE_H
+
+#include "core-extensions.h"
+
+cmark_syntax_extension *create_table_extension(void);
+
+#endif
diff --git a/Sources/libcmark_gfm/include/tagfilter.h b/Sources/libcmark_gfm/include/tagfilter.h
new file mode 100644
index 0000000..4068b50
--- /dev/null
+++ b/Sources/libcmark_gfm/include/tagfilter.h
@@ -0,0 +1,8 @@
+#ifndef TAGFILTER_H
+#define TAGFILTER_H
+
+#include "core-extensions.h"
+
+cmark_syntax_extension *create_tagfilter_extension(void);
+
+#endif
diff --git a/Sources/libcmark_gfm/include/utf8.h b/Sources/libcmark_gfm/include/utf8.h
new file mode 100644
index 0000000..5e64344
--- /dev/null
+++ b/Sources/libcmark_gfm/include/utf8.h
@@ -0,0 +1,35 @@
+#ifndef CMARK_UTF8_H
+#define CMARK_UTF8_H
+
+#include 
+#include "buffer.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+CMARK_EXPORT
+void cmark_utf8proc_case_fold(cmark_strbuf *dest, const uint8_t *str,
+                              bufsize_t len);
+
+CMARK_EXPORT
+void cmark_utf8proc_encode_char(int32_t uc, cmark_strbuf *buf);
+
+CMARK_EXPORT
+int cmark_utf8proc_iterate(const uint8_t *str, bufsize_t str_len, int32_t *dst);
+
+CMARK_EXPORT
+void cmark_utf8proc_check(cmark_strbuf *dest, const uint8_t *line,
+                          bufsize_t size);
+
+CMARK_EXPORT
+int cmark_utf8proc_is_space(int32_t uc);
+
+CMARK_EXPORT
+int cmark_utf8proc_is_punctuation(int32_t uc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Sources/libcmark_gfm/inlines.c b/Sources/libcmark_gfm/inlines.c
new file mode 100644
index 0000000..7597392
--- /dev/null
+++ b/Sources/libcmark_gfm/inlines.c
@@ -0,0 +1,1594 @@
+#include 
+#include 
+#include 
+
+#include "cmark_ctype.h"
+#include "config.h"
+#include "node.h"
+#include "parser.h"
+#include "references.h"
+#include "cmark.h"
+#include "houdini.h"
+#include "utf8.h"
+#include "scanners.h"
+#include "inlines.h"
+#include "syntax_extension.h"
+
+static const char *EMDASH = "\xE2\x80\x94";
+static const char *ENDASH = "\xE2\x80\x93";
+static const char *ELLIPSES = "\xE2\x80\xA6";
+static const char *LEFTDOUBLEQUOTE = "\xE2\x80\x9C";
+static const char *RIGHTDOUBLEQUOTE = "\xE2\x80\x9D";
+static const char *LEFTSINGLEQUOTE = "\xE2\x80\x98";
+static const char *RIGHTSINGLEQUOTE = "\xE2\x80\x99";
+
+// Macros for creating various kinds of simple.
+#define make_str(subj, sc, ec, s) make_literal(subj, CMARK_NODE_TEXT, sc, ec, s)
+#define make_code(subj, sc, ec, s) make_literal(subj, CMARK_NODE_CODE, sc, ec, s)
+#define make_raw_html(subj, sc, ec, s) make_literal(subj, CMARK_NODE_HTML_INLINE, sc, ec, s)
+#define make_linebreak(mem) make_simple(mem, CMARK_NODE_LINEBREAK)
+#define make_softbreak(mem) make_simple(mem, CMARK_NODE_SOFTBREAK)
+#define make_emph(mem) make_simple(mem, CMARK_NODE_EMPH)
+#define make_strong(mem) make_simple(mem, CMARK_NODE_STRONG)
+
+#define MAXBACKTICKS 80
+
+typedef struct bracket {
+  struct bracket *previous;
+  struct delimiter *previous_delimiter;
+  cmark_node *inl_text;
+  bufsize_t position;
+  bool image;
+  bool active;
+  bool bracket_after;
+} bracket;
+
+typedef struct subject{
+  cmark_mem *mem;
+  cmark_chunk input;
+  int line;
+  bufsize_t pos;
+  int block_offset;
+  int column_offset;
+  cmark_map *refmap;
+  delimiter *last_delim;
+  bracket *last_bracket;
+  bufsize_t backticks[MAXBACKTICKS + 1];
+  bool scanned_for_backticks;
+} subject;
+
+// Extensions may populate this.
+static int8_t SKIP_CHARS[256];
+
+static CMARK_INLINE bool S_is_line_end_char(char c) {
+  return (c == '\n' || c == '\r');
+}
+
+static delimiter *S_insert_emph(subject *subj, delimiter *opener,
+                                delimiter *closer);
+
+static int parse_inline(cmark_parser *parser, subject *subj, cmark_node *parent, int options);
+
+static void subject_from_buf(cmark_mem *mem, int line_number, int block_offset, subject *e,
+                             cmark_chunk *buffer, cmark_map *refmap);
+static bufsize_t subject_find_special_char(subject *subj, int options);
+
+// Create an inline with a literal string value.
+static CMARK_INLINE cmark_node *make_literal(subject *subj, cmark_node_type t,
+                                             int start_column, int end_column,
+                                             cmark_chunk s) {
+  cmark_node *e = (cmark_node *)subj->mem->calloc(1, sizeof(*e));
+  cmark_strbuf_init(subj->mem, &e->content, 0);
+  e->type = (uint16_t)t;
+  e->as.literal = s;
+  e->start_line = e->end_line = subj->line;
+  // columns are 1 based.
+  e->start_column = start_column + 1 + subj->column_offset + subj->block_offset;
+  e->end_column = end_column + 1 + subj->column_offset + subj->block_offset;
+  return e;
+}
+
+// Create an inline with no value.
+static CMARK_INLINE cmark_node *make_simple(cmark_mem *mem, cmark_node_type t) {
+  cmark_node *e = (cmark_node *)mem->calloc(1, sizeof(*e));
+  cmark_strbuf_init(mem, &e->content, 0);
+  e->type = (uint16_t)t;
+  return e;
+}
+
+// Like make_str, but parses entities.
+static cmark_node *make_str_with_entities(subject *subj,
+                                          int start_column, int end_column,
+                                          cmark_chunk *content) {
+  cmark_strbuf unescaped = CMARK_BUF_INIT(subj->mem);
+
+  if (houdini_unescape_html(&unescaped, content->data, content->len)) {
+    return make_str(subj, start_column, end_column, cmark_chunk_buf_detach(&unescaped));
+  } else {
+    return make_str(subj, start_column, end_column, *content);
+  }
+}
+
+// Duplicate a chunk by creating a copy of the buffer not by reusing the
+// buffer like cmark_chunk_dup does.
+static cmark_chunk chunk_clone(cmark_mem *mem, cmark_chunk *src) {
+  cmark_chunk c;
+  bufsize_t len = src->len;
+
+  c.len = len;
+  c.data = (unsigned char *)mem->calloc(len + 1, 1);
+  c.alloc = 1;
+  if (len)
+    memcpy(c.data, src->data, len);
+  c.data[len] = '\0';
+
+  return c;
+}
+
+static cmark_chunk cmark_clean_autolink(cmark_mem *mem, cmark_chunk *url,
+                                        int is_email) {
+  cmark_strbuf buf = CMARK_BUF_INIT(mem);
+
+  cmark_chunk_trim(url);
+
+  if (url->len == 0) {
+    cmark_chunk result = CMARK_CHUNK_EMPTY;
+    return result;
+  }
+
+  if (is_email)
+    cmark_strbuf_puts(&buf, "mailto:");
+
+  houdini_unescape_html_f(&buf, url->data, url->len);
+  return cmark_chunk_buf_detach(&buf);
+}
+
+static CMARK_INLINE cmark_node *make_autolink(subject *subj,
+                                              int start_column, int end_column,
+                                              cmark_chunk url, int is_email) {
+  cmark_node *link = make_simple(subj->mem, CMARK_NODE_LINK);
+  link->as.link.url = cmark_clean_autolink(subj->mem, &url, is_email);
+  link->as.link.title = cmark_chunk_literal("");
+  link->start_line = link->end_line = subj->line;
+  link->start_column = start_column + 1;
+  link->end_column = end_column + 1;
+  cmark_node_append_child(link, make_str_with_entities(subj, start_column + 1, end_column - 1, &url));
+  return link;
+}
+
+static void subject_from_buf(cmark_mem *mem, int line_number, int block_offset, subject *e,
+                             cmark_chunk *chunk, cmark_map *refmap) {
+  int i;
+  e->mem = mem;
+  e->input = *chunk;
+  e->line = line_number;
+  e->pos = 0;
+  e->block_offset = block_offset;
+  e->column_offset = 0;
+  e->refmap = refmap;
+  e->last_delim = NULL;
+  e->last_bracket = NULL;
+  for (i = 0; i <= MAXBACKTICKS; i++) {
+    e->backticks[i] = 0;
+  }
+  e->scanned_for_backticks = false;
+}
+
+static CMARK_INLINE int isbacktick(int c) { return (c == '`'); }
+
+static CMARK_INLINE unsigned char peek_char_n(subject *subj, bufsize_t n) {
+  // NULL bytes should have been stripped out by now.  If they're
+  // present, it's a programming error:
+  assert(!(subj->pos + n < subj->input.len && subj->input.data[subj->pos + n] == 0));
+  return (subj->pos + n < subj->input.len) ? subj->input.data[subj->pos + n] : 0;
+}
+
+static CMARK_INLINE unsigned char peek_char(subject *subj) {
+  return peek_char_n(subj, 0);
+}
+
+static CMARK_INLINE unsigned char peek_at(subject *subj, bufsize_t pos) {
+  return subj->input.data[pos];
+}
+
+// Return true if there are more characters in the subject.
+static CMARK_INLINE int is_eof(subject *subj) {
+  return (subj->pos >= subj->input.len);
+}
+
+// Advance the subject.  Doesn't check for eof.
+#define advance(subj) (subj)->pos += 1
+
+static CMARK_INLINE bool skip_spaces(subject *subj) {
+  bool skipped = false;
+  while (peek_char(subj) == ' ' || peek_char(subj) == '\t') {
+    advance(subj);
+    skipped = true;
+  }
+  return skipped;
+}
+
+static CMARK_INLINE bool skip_line_end(subject *subj) {
+  bool seen_line_end_char = false;
+  if (peek_char(subj) == '\r') {
+    advance(subj);
+    seen_line_end_char = true;
+  }
+  if (peek_char(subj) == '\n') {
+    advance(subj);
+    seen_line_end_char = true;
+  }
+  return seen_line_end_char || is_eof(subj);
+}
+
+// Take characters while a predicate holds, and return a string.
+static CMARK_INLINE cmark_chunk take_while(subject *subj, int (*f)(int)) {
+  unsigned char c;
+  bufsize_t startpos = subj->pos;
+  bufsize_t len = 0;
+
+  while ((c = peek_char(subj)) && (*f)(c)) {
+    advance(subj);
+    len++;
+  }
+
+  return cmark_chunk_dup(&subj->input, startpos, len);
+}
+
+// Return the number of newlines in a given span of text in a subject.  If
+// the number is greater than zero, also return the number of characters
+// between the last newline and the end of the span in `since_newline`.
+static int count_newlines(subject *subj, bufsize_t from, bufsize_t len, int *since_newline) {
+  int nls = 0;
+  int since_nl = 0;
+
+  while (len--) {
+    if (subj->input.data[from++] == '\n') {
+      ++nls;
+      since_nl = 0;
+    } else {
+      ++since_nl;
+    }
+  }
+
+  if (!nls)
+    return 0;
+
+  *since_newline = since_nl;
+  return nls;
+}
+
+// Adjust `node`'s `end_line`, `end_column`, and `subj`'s `line` and
+// `column_offset` according to the number of newlines in a just-matched span
+// of text in `subj`.
+static void adjust_subj_node_newlines(subject *subj, cmark_node *node, int matchlen, int extra, int options) {
+  if (!(options & CMARK_OPT_SOURCEPOS)) {
+    return;
+  }
+
+  int since_newline;
+  int newlines = count_newlines(subj, subj->pos - matchlen - extra, matchlen, &since_newline);
+  if (newlines) {
+    subj->line += newlines;
+    node->end_line += newlines;
+    node->end_column = since_newline;
+    subj->column_offset = -subj->pos + since_newline + extra;
+  }
+}
+
+// Try to process a backtick code span that began with a
+// span of ticks of length openticklength length (already
+// parsed).  Return 0 if you don't find matching closing
+// backticks, otherwise return the position in the subject
+// after the closing backticks.
+static bufsize_t scan_to_closing_backticks(subject *subj,
+                                           bufsize_t openticklength) {
+
+  bool found = false;
+  if (openticklength > MAXBACKTICKS) {
+    // we limit backtick string length because of the array subj->backticks:
+    return 0;
+  }
+  if (subj->scanned_for_backticks &&
+      subj->backticks[openticklength] <= subj->pos) {
+    // return if we already know there's no closer
+    return 0;
+  }
+  while (!found) {
+    // read non backticks
+    unsigned char c;
+    while ((c = peek_char(subj)) && c != '`') {
+      advance(subj);
+    }
+    if (is_eof(subj)) {
+      break;
+    }
+    bufsize_t numticks = 0;
+    while (peek_char(subj) == '`') {
+      advance(subj);
+      numticks++;
+    }
+    // store position of ender
+    if (numticks <= MAXBACKTICKS) {
+      subj->backticks[numticks] = subj->pos - numticks;
+    }
+    if (numticks == openticklength) {
+      return (subj->pos);
+    }
+  }
+  // got through whole input without finding closer
+  subj->scanned_for_backticks = true;
+  return 0;
+}
+
+// Parse backtick code section or raw backticks, return an inline.
+// Assumes that the subject has a backtick at the current position.
+static cmark_node *handle_backticks(subject *subj, int options) {
+  cmark_chunk openticks = take_while(subj, isbacktick);
+  bufsize_t startpos = subj->pos;
+  bufsize_t endpos = scan_to_closing_backticks(subj, openticks.len);
+
+  if (endpos == 0) {      // not found
+    subj->pos = startpos; // rewind
+    return make_str(subj, subj->pos, subj->pos, openticks);
+  } else {
+    cmark_strbuf buf = CMARK_BUF_INIT(subj->mem);
+
+    cmark_strbuf_set(&buf, subj->input.data + startpos,
+                     endpos - startpos - openticks.len);
+    cmark_strbuf_trim(&buf);
+    cmark_strbuf_normalize_whitespace(&buf);
+
+    cmark_node *node = make_code(subj, startpos, endpos - openticks.len - 1, cmark_chunk_buf_detach(&buf));
+    adjust_subj_node_newlines(subj, node, endpos - startpos, openticks.len, options);
+    return node;
+  }
+}
+
+// Scan ***, **, or * and return number scanned, or 0.
+// Advances position.
+static int scan_delims(subject *subj, unsigned char c, bool *can_open,
+                       bool *can_close) {
+  int numdelims = 0;
+  bufsize_t before_char_pos, after_char_pos;
+  int32_t after_char = 0;
+  int32_t before_char = 0;
+  int len;
+  bool left_flanking, right_flanking;
+
+  if (subj->pos == 0) {
+    before_char = 10;
+  } else {
+    before_char_pos = subj->pos - 1;
+    // walk back to the beginning of the UTF_8 sequence:
+    while ((peek_at(subj, before_char_pos) >> 6 == 2 || SKIP_CHARS[peek_at(subj, before_char_pos)]) && before_char_pos > 0) {
+      before_char_pos -= 1;
+    }
+    len = cmark_utf8proc_iterate(subj->input.data + before_char_pos,
+                                 subj->pos - before_char_pos, &before_char);
+    if (len == -1 || (before_char < 256 && SKIP_CHARS[(unsigned char) before_char])) {
+      before_char = 10;
+    }
+  }
+
+  if (c == '\'' || c == '"') {
+    numdelims++;
+    advance(subj); // limit to 1 delim for quotes
+  } else {
+    while (peek_char(subj) == c) {
+      numdelims++;
+      advance(subj);
+    }
+  }
+
+  if (subj->pos == subj->input.len) {
+    after_char = 10;
+  } else {
+    after_char_pos = subj->pos;
+    while (SKIP_CHARS[peek_at(subj, after_char_pos)] && after_char_pos < subj->input.len) {
+      after_char_pos += 1;
+    }
+    len = cmark_utf8proc_iterate(subj->input.data + after_char_pos,
+                                 subj->input.len - after_char_pos, &after_char);
+    if (len == -1 || (after_char < 256 && SKIP_CHARS[(unsigned char) after_char])) {
+    after_char = 10;
+  }
+  }
+
+  left_flanking = numdelims > 0 && !cmark_utf8proc_is_space(after_char) &&
+                  (!cmark_utf8proc_is_punctuation(after_char) ||
+                   cmark_utf8proc_is_space(before_char) ||
+                   cmark_utf8proc_is_punctuation(before_char));
+  right_flanking = numdelims > 0 && !cmark_utf8proc_is_space(before_char) &&
+                   (!cmark_utf8proc_is_punctuation(before_char) ||
+                    cmark_utf8proc_is_space(after_char) ||
+                    cmark_utf8proc_is_punctuation(after_char));
+  if (c == '_') {
+    *can_open = left_flanking &&
+                (!right_flanking || cmark_utf8proc_is_punctuation(before_char));
+    *can_close = right_flanking &&
+                 (!left_flanking || cmark_utf8proc_is_punctuation(after_char));
+  } else if (c == '\'' || c == '"') {
+    *can_open = left_flanking && !right_flanking &&
+	         before_char != ']' && before_char != ')';
+    *can_close = right_flanking;
+  } else {
+    *can_open = left_flanking;
+    *can_close = right_flanking;
+  }
+  return numdelims;
+}
+
+/*
+static void print_delimiters(subject *subj)
+{
+        delimiter *delim;
+        delim = subj->last_delim;
+        while (delim != NULL) {
+                printf("Item at stack pos %p: %d %d %d next(%p) prev(%p)\n",
+                       (void*)delim, delim->delim_char,
+                       delim->can_open, delim->can_close,
+                       (void*)delim->next, (void*)delim->previous);
+                delim = delim->previous;
+        }
+}
+*/
+
+static void remove_delimiter(subject *subj, delimiter *delim) {
+  if (delim == NULL)
+    return;
+  if (delim->next == NULL) {
+    // end of list:
+    assert(delim == subj->last_delim);
+    subj->last_delim = delim->previous;
+  } else {
+    delim->next->previous = delim->previous;
+  }
+  if (delim->previous != NULL) {
+    delim->previous->next = delim->next;
+  }
+  subj->mem->free(delim);
+}
+
+static void pop_bracket(subject *subj) {
+  bracket *b;
+  if (subj->last_bracket == NULL)
+    return;
+  b = subj->last_bracket;
+  subj->last_bracket = subj->last_bracket->previous;
+  subj->mem->free(b);
+}
+
+static void push_delimiter(subject *subj, unsigned char c, bool can_open,
+                           bool can_close, cmark_node *inl_text) {
+  delimiter *delim = (delimiter *)subj->mem->calloc(1, sizeof(delimiter));
+  delim->delim_char = c;
+  delim->can_open = can_open;
+  delim->can_close = can_close;
+  delim->inl_text = inl_text;
+  delim->length = inl_text->as.literal.len;
+  delim->previous = subj->last_delim;
+  delim->next = NULL;
+  if (delim->previous != NULL) {
+    delim->previous->next = delim;
+  }
+  subj->last_delim = delim;
+}
+
+static void push_bracket(subject *subj, bool image, cmark_node *inl_text) {
+  bracket *b = (bracket *)subj->mem->calloc(1, sizeof(bracket));
+  if (subj->last_bracket != NULL) {
+    subj->last_bracket->bracket_after = true;
+  }
+  b->image = image;
+  b->active = true;
+  b->inl_text = inl_text;
+  b->previous = subj->last_bracket;
+  b->previous_delimiter = subj->last_delim;
+  b->position = subj->pos;
+  b->bracket_after = false;
+  subj->last_bracket = b;
+}
+
+// Assumes the subject has a c at the current position.
+static cmark_node *handle_delim(subject *subj, unsigned char c, bool smart) {
+  bufsize_t numdelims;
+  cmark_node *inl_text;
+  bool can_open, can_close;
+  cmark_chunk contents;
+
+  numdelims = scan_delims(subj, c, &can_open, &can_close);
+
+  if (c == '\'' && smart) {
+    contents = cmark_chunk_literal(RIGHTSINGLEQUOTE);
+  } else if (c == '"' && smart) {
+    contents =
+        cmark_chunk_literal(can_close ? RIGHTDOUBLEQUOTE : LEFTDOUBLEQUOTE);
+  } else {
+    contents = cmark_chunk_dup(&subj->input, subj->pos - numdelims, numdelims);
+  }
+
+  inl_text = make_str(subj, subj->pos - numdelims, subj->pos - 1, contents);
+
+  if ((can_open || can_close) && (!(c == '\'' || c == '"') || smart)) {
+    push_delimiter(subj, c, can_open, can_close, inl_text);
+  }
+
+  return inl_text;
+}
+
+// Assumes we have a hyphen at the current position.
+static cmark_node *handle_hyphen(subject *subj, bool smart) {
+  int startpos = subj->pos;
+
+  advance(subj);
+
+  if (!smart || peek_char(subj) != '-') {
+    return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal("-"));
+  }
+
+  while (smart && peek_char(subj) == '-') {
+    advance(subj);
+  }
+
+  int numhyphens = subj->pos - startpos;
+  int en_count = 0;
+  int em_count = 0;
+  int i;
+  cmark_strbuf buf = CMARK_BUF_INIT(subj->mem);
+
+  if (numhyphens % 3 == 0) { // if divisible by 3, use all em dashes
+    em_count = numhyphens / 3;
+  } else if (numhyphens % 2 == 0) { // if divisible by 2, use all en dashes
+    en_count = numhyphens / 2;
+  } else if (numhyphens % 3 == 2) { // use one en dash at end
+    en_count = 1;
+    em_count = (numhyphens - 2) / 3;
+  } else { // use two en dashes at the end
+    en_count = 2;
+    em_count = (numhyphens - 4) / 3;
+  }
+
+  for (i = em_count; i > 0; i--) {
+    cmark_strbuf_puts(&buf, EMDASH);
+  }
+
+  for (i = en_count; i > 0; i--) {
+    cmark_strbuf_puts(&buf, ENDASH);
+  }
+
+  return make_str(subj, startpos, subj->pos - 1, cmark_chunk_buf_detach(&buf));
+}
+
+// Assumes we have a period at the current position.
+static cmark_node *handle_period(subject *subj, bool smart) {
+  advance(subj);
+  if (smart && peek_char(subj) == '.') {
+    advance(subj);
+    if (peek_char(subj) == '.') {
+      advance(subj);
+      return make_str(subj, subj->pos - 3, subj->pos - 1, cmark_chunk_literal(ELLIPSES));
+    } else {
+      return make_str(subj, subj->pos - 2, subj->pos - 1, cmark_chunk_literal(".."));
+    }
+  } else {
+    return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal("."));
+  }
+}
+
+static cmark_syntax_extension *get_extension_for_special_char(cmark_parser *parser, unsigned char c) {
+  cmark_llist *tmp_ext;
+
+  for (tmp_ext = parser->inline_syntax_extensions; tmp_ext; tmp_ext=tmp_ext->next) {
+    cmark_syntax_extension *ext = (cmark_syntax_extension *) tmp_ext->data;
+    cmark_llist *tmp_char;
+    for (tmp_char = ext->special_inline_chars; tmp_char; tmp_char=tmp_char->next) {
+      unsigned char tmp_c = (unsigned char)(size_t)tmp_char->data;
+
+      if (tmp_c == c) {
+        return ext;
+      }
+    }
+  }
+
+  return NULL;
+}
+
+static void process_emphasis(cmark_parser *parser, subject *subj, delimiter *stack_bottom) {
+  delimiter *closer = subj->last_delim;
+  delimiter *opener;
+  delimiter *old_closer;
+  bool opener_found;
+  bool odd_match;
+  delimiter *openers_bottom[3][128];
+  int i;
+
+  // initialize openers_bottom:
+  memset(&openers_bottom, 0, sizeof(openers_bottom));
+  for (i=0; i < 3; i++) {
+    openers_bottom[i]['*'] = stack_bottom;
+    openers_bottom[i]['_'] = stack_bottom;
+    openers_bottom[i]['\''] = stack_bottom;
+    openers_bottom[i]['"'] = stack_bottom;
+  }
+
+  // move back to first relevant delim.
+  while (closer != NULL && closer->previous != stack_bottom) {
+    closer = closer->previous;
+  }
+
+  // now move forward, looking for closers, and handling each
+  while (closer != NULL) {
+    cmark_syntax_extension *extension = get_extension_for_special_char(parser, closer->delim_char);
+    if (closer->can_close) {
+      // Now look backwards for first matching opener:
+      opener = closer->previous;
+      opener_found = false;
+      odd_match = false;
+      while (opener != NULL && opener != stack_bottom &&
+             opener != openers_bottom[closer->length % 3][closer->delim_char]) {
+        if (opener->can_open && opener->delim_char == closer->delim_char) {
+          // interior closer of size 2 can't match opener of size 1
+          // or of size 1 can't match 2
+          odd_match = (closer->can_open || opener->can_close) &&
+                      ((opener->length + closer->length) % 3 == 0);
+          if (!odd_match) {
+            opener_found = true;
+            break;
+          }
+        }
+        opener = opener->previous;
+      }
+      old_closer = closer;
+
+      if (extension) {
+        if (opener_found)
+          closer = extension->insert_inline_from_delim(extension, parser, subj, opener, closer);
+        else
+          closer = closer->next;
+      } else if (closer->delim_char == '*' || closer->delim_char == '_') {
+        if (opener_found) {
+          closer = S_insert_emph(subj, opener, closer);
+        } else {
+          closer = closer->next;
+        }
+      } else if (closer->delim_char == '\'') {
+        cmark_chunk_free(subj->mem, &closer->inl_text->as.literal);
+        closer->inl_text->as.literal = cmark_chunk_literal(RIGHTSINGLEQUOTE);
+        if (opener_found) {
+          cmark_chunk_free(subj->mem, &opener->inl_text->as.literal);
+          opener->inl_text->as.literal = cmark_chunk_literal(LEFTSINGLEQUOTE);
+        }
+        closer = closer->next;
+      } else if (closer->delim_char == '"') {
+        cmark_chunk_free(subj->mem, &closer->inl_text->as.literal);
+        closer->inl_text->as.literal = cmark_chunk_literal(RIGHTDOUBLEQUOTE);
+        if (opener_found) {
+          cmark_chunk_free(subj->mem, &opener->inl_text->as.literal);
+          opener->inl_text->as.literal = cmark_chunk_literal(LEFTDOUBLEQUOTE);
+        }
+        closer = closer->next;
+      }
+      if (!opener_found) {
+        // set lower bound for future searches for openers
+        openers_bottom[old_closer->length % 3][old_closer->delim_char] =
+		old_closer->previous;
+        if (!old_closer->can_open) {
+          // we can remove a closer that can't be an
+          // opener, once we've seen there's no
+          // matching opener:
+          remove_delimiter(subj, old_closer);
+        }
+      }
+    } else {
+      closer = closer->next;
+    }
+  }
+  // free all delimiters in list until stack_bottom:
+  while (subj->last_delim != NULL && subj->last_delim != stack_bottom) {
+    remove_delimiter(subj, subj->last_delim);
+  }
+}
+
+static delimiter *S_insert_emph(subject *subj, delimiter *opener,
+                                delimiter *closer) {
+  delimiter *delim, *tmp_delim;
+  bufsize_t use_delims;
+  cmark_node *opener_inl = opener->inl_text;
+  cmark_node *closer_inl = closer->inl_text;
+  bufsize_t opener_num_chars = opener_inl->as.literal.len;
+  bufsize_t closer_num_chars = closer_inl->as.literal.len;
+  cmark_node *tmp, *tmpnext, *emph;
+
+  // calculate the actual number of characters used from this closer
+  use_delims = (closer_num_chars >= 2 && opener_num_chars >= 2) ? 2 : 1;
+
+  // remove used characters from associated inlines.
+  opener_num_chars -= use_delims;
+  closer_num_chars -= use_delims;
+  opener_inl->as.literal.len = opener_num_chars;
+  closer_inl->as.literal.len = closer_num_chars;
+
+  // free delimiters between opener and closer
+  delim = closer->previous;
+  while (delim != NULL && delim != opener) {
+    tmp_delim = delim->previous;
+    remove_delimiter(subj, delim);
+    delim = tmp_delim;
+  }
+
+  // create new emph or strong, and splice it in to our inlines
+  // between the opener and closer
+  emph = use_delims == 1 ? make_emph(subj->mem) : make_strong(subj->mem);
+
+  tmp = opener_inl->next;
+  while (tmp && tmp != closer_inl) {
+    tmpnext = tmp->next;
+    cmark_node_append_child(emph, tmp);
+    tmp = tmpnext;
+  }
+  cmark_node_insert_after(opener_inl, emph);
+
+  emph->start_line = emph->end_line = subj->line;
+  emph->start_column = opener_inl->start_column + subj->column_offset;
+  emph->end_column = closer_inl->end_column + subj->column_offset;
+
+  // if opener has 0 characters, remove it and its associated inline
+  if (opener_num_chars == 0) {
+    cmark_node_free(opener_inl);
+    remove_delimiter(subj, opener);
+  }
+
+  // if closer has 0 characters, remove it and its associated inline
+  if (closer_num_chars == 0) {
+    // remove empty closer inline
+    cmark_node_free(closer_inl);
+    // remove closer from list
+    tmp_delim = closer->next;
+    remove_delimiter(subj, closer);
+    closer = tmp_delim;
+  }
+
+  return closer;
+}
+
+// Parse backslash-escape or just a backslash, returning an inline.
+static cmark_node *handle_backslash(cmark_parser *parser, subject *subj) {
+  advance(subj);
+  unsigned char nextchar = peek_char(subj);
+  if ((parser->backslash_ispunct ? parser->backslash_ispunct : cmark_ispunct)(nextchar)) {
+    // only ascii symbols and newline can be escaped
+    advance(subj);
+    return make_str(subj, subj->pos - 2, subj->pos - 1, cmark_chunk_dup(&subj->input, subj->pos - 1, 1));
+  } else if (!is_eof(subj) && skip_line_end(subj)) {
+    return make_linebreak(subj->mem);
+  } else {
+    return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal("\\"));
+  }
+}
+
+// Parse an entity or a regular "&" string.
+// Assumes the subject has an '&' character at the current position.
+static cmark_node *handle_entity(subject *subj) {
+  cmark_strbuf ent = CMARK_BUF_INIT(subj->mem);
+  bufsize_t len;
+
+  advance(subj);
+
+  len = houdini_unescape_ent(&ent, subj->input.data + subj->pos,
+                             subj->input.len - subj->pos);
+
+  if (len == 0)
+    return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal("&"));
+
+  subj->pos += len;
+  return make_str(subj, subj->pos - 1 - len, subj->pos - 1, cmark_chunk_buf_detach(&ent));
+}
+
+// Clean a URL: remove surrounding whitespace, and remove \ that escape
+// punctuation.
+cmark_chunk cmark_clean_url(cmark_mem *mem, cmark_chunk *url) {
+  cmark_strbuf buf = CMARK_BUF_INIT(mem);
+
+  cmark_chunk_trim(url);
+
+  if (url->len == 0) {
+    cmark_chunk result = CMARK_CHUNK_EMPTY;
+    return result;
+  }
+
+  houdini_unescape_html_f(&buf, url->data, url->len);
+
+  cmark_strbuf_unescape(&buf);
+  return cmark_chunk_buf_detach(&buf);
+}
+
+cmark_chunk cmark_clean_title(cmark_mem *mem, cmark_chunk *title) {
+  cmark_strbuf buf = CMARK_BUF_INIT(mem);
+  unsigned char first, last;
+
+  if (title->len == 0) {
+    cmark_chunk result = CMARK_CHUNK_EMPTY;
+    return result;
+  }
+
+  first = title->data[0];
+  last = title->data[title->len - 1];
+
+  // remove surrounding quotes if any:
+  if ((first == '\'' && last == '\'') || (first == '(' && last == ')') ||
+      (first == '"' && last == '"')) {
+    houdini_unescape_html_f(&buf, title->data + 1, title->len - 2);
+  } else {
+    houdini_unescape_html_f(&buf, title->data, title->len);
+  }
+
+  cmark_strbuf_unescape(&buf);
+  return cmark_chunk_buf_detach(&buf);
+}
+
+// Parse an autolink or HTML tag.
+// Assumes the subject has a '<' character at the current position.
+static cmark_node *handle_pointy_brace(subject *subj, int options) {
+  bufsize_t matchlen = 0;
+  cmark_chunk contents;
+
+  advance(subj); // advance past first <
+
+  // first try to match a URL autolink
+  matchlen = scan_autolink_uri(&subj->input, subj->pos);
+  if (matchlen > 0) {
+    contents = cmark_chunk_dup(&subj->input, subj->pos, matchlen - 1);
+    subj->pos += matchlen;
+
+    return make_autolink(subj, subj->pos - 1 - matchlen, subj->pos - 1, contents, 0);
+  }
+
+  // next try to match an email autolink
+  matchlen = scan_autolink_email(&subj->input, subj->pos);
+  if (matchlen > 0) {
+    contents = cmark_chunk_dup(&subj->input, subj->pos, matchlen - 1);
+    subj->pos += matchlen;
+
+    return make_autolink(subj, subj->pos - 1 - matchlen, subj->pos - 1, contents, 1);
+  }
+
+  // finally, try to match an html tag
+  matchlen = scan_html_tag(&subj->input, subj->pos);
+  if (matchlen > 0) {
+    contents = cmark_chunk_dup(&subj->input, subj->pos - 1, matchlen + 1);
+    subj->pos += matchlen;
+    cmark_node *node = make_raw_html(subj, subj->pos - matchlen - 1, subj->pos - 1, contents);
+    adjust_subj_node_newlines(subj, node, matchlen, 1, options);
+    return node;
+  }
+
+  if (options & CMARK_OPT_LIBERAL_HTML_TAG) {
+    matchlen = scan_liberal_html_tag(&subj->input, subj->pos);
+    if (matchlen > 0) {
+      contents = cmark_chunk_dup(&subj->input, subj->pos - 1, matchlen + 1);
+      subj->pos += matchlen;
+      cmark_node *node = make_raw_html(subj, subj->pos - matchlen - 1, subj->pos - 1, contents);
+      adjust_subj_node_newlines(subj, node, matchlen, 1, options);
+      return node;
+    }
+  }
+
+  // if nothing matches, just return the opening <:
+  return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal("<"));
+}
+
+// Parse a link label.  Returns 1 if successful.
+// Note:  unescaped brackets are not allowed in labels.
+// The label begins with `[` and ends with the first `]` character
+// encountered.  Backticks in labels do not start code spans.
+static int link_label(subject *subj, cmark_chunk *raw_label) {
+  bufsize_t startpos = subj->pos;
+  int length = 0;
+  unsigned char c;
+
+  // advance past [
+  if (peek_char(subj) == '[') {
+    advance(subj);
+  } else {
+    return 0;
+  }
+
+  while ((c = peek_char(subj)) && c != '[' && c != ']') {
+    if (c == '\\') {
+      advance(subj);
+      length++;
+      if (cmark_ispunct(peek_char(subj))) {
+        advance(subj);
+        length++;
+      }
+    } else {
+      advance(subj);
+      length++;
+    }
+    if (length > MAX_LINK_LABEL_LENGTH) {
+      goto noMatch;
+    }
+  }
+
+  if (c == ']') { // match found
+    *raw_label =
+        cmark_chunk_dup(&subj->input, startpos + 1, subj->pos - (startpos + 1));
+    cmark_chunk_trim(raw_label);
+    advance(subj); // advance past ]
+    return 1;
+  }
+
+noMatch:
+  subj->pos = startpos; // rewind
+  return 0;
+}
+
+static bufsize_t manual_scan_link_url_2(cmark_chunk *input, bufsize_t offset,
+                                        cmark_chunk *output) {
+  bufsize_t i = offset;
+  size_t nb_p = 0;
+
+  while (i < input->len) {
+    if (input->data[i] == '\\' &&
+        i + 1 < input-> len &&
+        cmark_ispunct(input->data[i+1]))
+      i += 2;
+    else if (input->data[i] == '(') {
+      ++nb_p;
+      ++i;
+        if (nb_p > 32)
+          return -1;
+    } else if (input->data[i] == ')') {
+      if (nb_p == 0)
+        break;
+      --nb_p;
+      ++i;
+    } else if (cmark_isspace(input->data[i]))
+      break;
+    else
+      ++i;
+  }
+
+  if (i >= input->len)
+    return -1;
+
+  {
+    cmark_chunk result = {input->data + offset, i - offset, 0};
+    *output = result;
+  }
+  return i - offset;
+}
+
+static bufsize_t manual_scan_link_url(cmark_chunk *input, bufsize_t offset,
+                                      cmark_chunk *output) {
+  bufsize_t i = offset;
+
+  if (i < input->len && input->data[i] == '<') {
+    ++i;
+    while (i < input->len) {
+      if (input->data[i] == '>') {
+        ++i;
+        break;
+      } else if (input->data[i] == '\\')
+        i += 2;
+      else if (cmark_isspace(input->data[i]) || input->data[i] == '<')
+        return manual_scan_link_url_2(input, offset, output);
+      else
+        ++i;
+    }
+  } else {
+    return manual_scan_link_url_2(input, offset, output);
+  }
+
+  if (i >= input->len)
+    return -1;
+
+  {
+    cmark_chunk result = {input->data + offset + 1, i - 2 - offset, 0};
+    *output = result;
+  }
+  return i - offset;
+}
+
+// Return a link, an image, or a literal close bracket.
+static cmark_node *handle_close_bracket(cmark_parser *parser, subject *subj) {
+  bufsize_t initial_pos, after_link_text_pos;
+  bufsize_t endurl, starttitle, endtitle, endall;
+  bufsize_t sps, n;
+  cmark_reference *ref = NULL;
+  cmark_chunk url_chunk, title_chunk;
+  cmark_chunk url, title;
+  bracket *opener;
+  cmark_node *inl;
+  cmark_chunk raw_label;
+  int found_label;
+  cmark_node *tmp, *tmpnext;
+  bool is_image;
+
+  advance(subj); // advance past ]
+  initial_pos = subj->pos;
+
+  // get last [ or ![
+  opener = subj->last_bracket;
+
+  if (opener == NULL) {
+    return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal("]"));
+  }
+
+  if (!opener->active) {
+    // take delimiter off stack
+    pop_bracket(subj);
+    return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal("]"));
+  }
+
+  // If we got here, we matched a potential link/image text.
+  // Now we check to see if it's a link/image.
+  is_image = opener->image;
+
+  after_link_text_pos = subj->pos;
+
+  // First, look for an inline link.
+  if (peek_char(subj) == '(' &&
+      ((sps = scan_spacechars(&subj->input, subj->pos + 1)) > -1) &&
+      ((n = manual_scan_link_url(&subj->input, subj->pos + 1 + sps,
+                                 &url_chunk)) > -1)) {
+
+    // try to parse an explicit link:
+    endurl = subj->pos + 1 + sps + n;
+    starttitle = endurl + scan_spacechars(&subj->input, endurl);
+
+    // ensure there are spaces btw url and title
+    endtitle = (starttitle == endurl)
+                   ? starttitle
+                   : starttitle + scan_link_title(&subj->input, starttitle);
+
+    endall = endtitle + scan_spacechars(&subj->input, endtitle);
+
+    if (peek_at(subj, endall) == ')') {
+      subj->pos = endall + 1;
+
+      title_chunk =
+          cmark_chunk_dup(&subj->input, starttitle, endtitle - starttitle);
+      url = cmark_clean_url(subj->mem, &url_chunk);
+      title = cmark_clean_title(subj->mem, &title_chunk);
+      cmark_chunk_free(subj->mem, &url_chunk);
+      cmark_chunk_free(subj->mem, &title_chunk);
+      goto match;
+
+    } else {
+      // it could still be a shortcut reference link
+      subj->pos = after_link_text_pos;
+    }
+  }
+
+  // Next, look for a following [link label] that matches in refmap.
+  // skip spaces
+  raw_label = cmark_chunk_literal("");
+  found_label = link_label(subj, &raw_label);
+  if (!found_label) {
+    // If we have a shortcut reference link, back up
+    // to before the spacse we skipped.
+    subj->pos = initial_pos;
+  }
+
+  if ((!found_label || raw_label.len == 0) && !opener->bracket_after) {
+    cmark_chunk_free(subj->mem, &raw_label);
+    raw_label = cmark_chunk_dup(&subj->input, opener->position,
+                                initial_pos - opener->position - 1);
+    found_label = true;
+  }
+
+  if (found_label) {
+    ref = (cmark_reference *)cmark_map_lookup(subj->refmap, &raw_label);
+    cmark_chunk_free(subj->mem, &raw_label);
+  }
+
+  if (ref != NULL) { // found
+    url = chunk_clone(subj->mem, &ref->url);
+    title = chunk_clone(subj->mem, &ref->title);
+    goto match;
+  } else {
+    goto noMatch;
+  }
+
+noMatch:
+  // If we fall through to here, it means we didn't match a link.
+  // What if we're a footnote link?
+  if (parser->options & CMARK_OPT_FOOTNOTES &&
+      opener->inl_text->next &&
+      opener->inl_text->next->type == CMARK_NODE_TEXT &&
+      !opener->inl_text->next->next) {
+    cmark_chunk *literal = &opener->inl_text->next->as.literal;
+    if (literal->len > 1 && literal->data[0] == '^') {
+      inl = make_simple(subj->mem, CMARK_NODE_FOOTNOTE_REFERENCE);
+      inl->as.literal = cmark_chunk_dup(literal, 1, literal->len - 1);
+      inl->start_line = inl->end_line = subj->line;
+      inl->start_column = opener->inl_text->start_column;
+      inl->end_column = subj->pos + subj->column_offset + subj->block_offset;
+      cmark_node_insert_before(opener->inl_text, inl);
+      cmark_node_free(opener->inl_text->next);
+      cmark_node_free(opener->inl_text);
+      process_emphasis(parser, subj, opener->previous_delimiter);
+      pop_bracket(subj);
+      return NULL;
+    }
+  }
+
+  pop_bracket(subj); // remove this opener from delimiter list
+  subj->pos = initial_pos;
+  return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal("]"));
+
+match:
+  inl = make_simple(subj->mem, is_image ? CMARK_NODE_IMAGE : CMARK_NODE_LINK);
+  inl->as.link.url = url;
+  inl->as.link.title = title;
+  inl->start_line = inl->end_line = subj->line;
+  inl->start_column = opener->inl_text->start_column;
+  inl->end_column = subj->pos + subj->column_offset + subj->block_offset;
+  cmark_node_insert_before(opener->inl_text, inl);
+  // Add link text:
+  tmp = opener->inl_text->next;
+  while (tmp) {
+    tmpnext = tmp->next;
+    cmark_node_append_child(inl, tmp);
+    tmp = tmpnext;
+  }
+
+  // Free the bracket [:
+  cmark_node_free(opener->inl_text);
+
+  process_emphasis(parser, subj, opener->previous_delimiter);
+  pop_bracket(subj);
+
+  // Now, if we have a link, we also want to deactivate earlier link
+  // delimiters. (This code can be removed if we decide to allow links
+  // inside links.)
+  if (!is_image) {
+    opener = subj->last_bracket;
+    while (opener != NULL) {
+      if (!opener->image) {
+        if (!opener->active) {
+          break;
+        } else {
+          opener->active = false;
+        }
+      }
+      opener = opener->previous;
+    }
+  }
+
+  return NULL;
+}
+
+// Parse a hard or soft linebreak, returning an inline.
+// Assumes the subject has a cr or newline at the current position.
+static cmark_node *handle_newline(subject *subj) {
+  bufsize_t nlpos = subj->pos;
+  // skip over cr, crlf, or lf:
+  if (peek_at(subj, subj->pos) == '\r') {
+    advance(subj);
+  }
+  if (peek_at(subj, subj->pos) == '\n') {
+    advance(subj);
+  }
+  ++subj->line;
+  subj->column_offset = -subj->pos;
+  // skip spaces at beginning of line
+  skip_spaces(subj);
+  if (nlpos > 1 && peek_at(subj, nlpos - 1) == ' ' &&
+      peek_at(subj, nlpos - 2) == ' ') {
+    return make_linebreak(subj->mem);
+  } else {
+    return make_softbreak(subj->mem);
+  }
+}
+
+// "\r\n\\`&_*[]pos + 1;
+
+  while (n < subj->input.len) {
+    if (SPECIAL_CHARS[subj->input.data[n]])
+      return n;
+    if (options & CMARK_OPT_SMART && SMART_PUNCT_CHARS[subj->input.data[n]])
+      return n;
+    n++;
+  }
+
+  return subj->input.len;
+}
+
+void cmark_inlines_add_special_character(unsigned char c, bool emphasis) {
+  SPECIAL_CHARS[c] = 1;
+  if (emphasis)
+    SKIP_CHARS[c] = 1;
+}
+
+void cmark_inlines_remove_special_character(unsigned char c, bool emphasis) {
+  SPECIAL_CHARS[c] = 0;
+  if (emphasis)
+    SKIP_CHARS[c] = 0;
+}
+
+static cmark_node *try_extensions(cmark_parser *parser,
+                                  cmark_node *parent,
+                                  unsigned char c,
+                                  subject *subj) {
+  cmark_node *res = NULL;
+  cmark_llist *tmp;
+
+  for (tmp = parser->inline_syntax_extensions; tmp; tmp = tmp->next) {
+    cmark_syntax_extension *ext = (cmark_syntax_extension *) tmp->data;
+    res = ext->match_inline(ext, parser, parent, c, subj);
+
+    if (res)
+      break;
+  }
+
+  return res;
+}
+
+// Parse an inline, advancing subject, and add it as a child of parent.
+// Return 0 if no inline can be parsed, 1 otherwise.
+static int parse_inline(cmark_parser *parser, subject *subj, cmark_node *parent, int options) {
+  cmark_node *new_inl = NULL;
+  cmark_chunk contents;
+  unsigned char c;
+  bufsize_t startpos, endpos;
+  c = peek_char(subj);
+  if (c == 0) {
+    return 0;
+  }
+  switch (c) {
+  case '\r':
+  case '\n':
+    new_inl = handle_newline(subj);
+    break;
+  case '`':
+    new_inl = handle_backticks(subj, options);
+    break;
+  case '\\':
+    new_inl = handle_backslash(parser, subj);
+    break;
+  case '&':
+    new_inl = handle_entity(subj);
+    break;
+  case '<':
+    new_inl = handle_pointy_brace(subj, options);
+    break;
+  case '*':
+  case '_':
+  case '\'':
+  case '"':
+    new_inl = handle_delim(subj, c, (options & CMARK_OPT_SMART) != 0);
+    break;
+  case '-':
+    new_inl = handle_hyphen(subj, (options & CMARK_OPT_SMART) != 0);
+    break;
+  case '.':
+    new_inl = handle_period(subj, (options & CMARK_OPT_SMART) != 0);
+    break;
+  case '[':
+    advance(subj);
+    new_inl = make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal("["));
+    push_bracket(subj, false, new_inl);
+    break;
+  case ']':
+    new_inl = handle_close_bracket(parser, subj);
+    break;
+  case '!':
+    advance(subj);
+    if (peek_char(subj) == '[' && peek_char_n(subj, 1) != '^') {
+      advance(subj);
+      new_inl = make_str(subj, subj->pos - 2, subj->pos - 1, cmark_chunk_literal("!["));
+      push_bracket(subj, true, new_inl);
+    } else {
+      new_inl = make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal("!"));
+    }
+    break;
+  default:
+    new_inl = try_extensions(parser, parent, c, subj);
+    if (new_inl != NULL)
+      break;
+
+    endpos = subject_find_special_char(subj, options);
+    contents = cmark_chunk_dup(&subj->input, subj->pos, endpos - subj->pos);
+    startpos = subj->pos;
+    subj->pos = endpos;
+
+    // if we're at a newline, strip trailing spaces.
+    if (S_is_line_end_char(peek_char(subj))) {
+      cmark_chunk_rtrim(&contents);
+    }
+
+    new_inl = make_str(subj, startpos, endpos - 1, contents);
+  }
+  if (new_inl != NULL) {
+    cmark_node_append_child(parent, new_inl);
+  }
+
+  return 1;
+}
+
+// Parse inlines from parent's string_content, adding as children of parent.
+void cmark_parse_inlines(cmark_parser *parser,
+                         cmark_node *parent,
+                         cmark_map *refmap,
+                         int options) {
+  subject subj;
+  cmark_chunk content = {parent->content.ptr, parent->content.size, 0};
+  subject_from_buf(parser->mem, parent->start_line, parent->start_column - 1 + parent->internal_offset, &subj, &content, refmap);
+  cmark_chunk_rtrim(&subj.input);
+
+  while (!is_eof(&subj) && parse_inline(parser, &subj, parent, options))
+    ;
+
+  process_emphasis(parser, &subj, NULL);
+  // free bracket and delim stack
+  while (subj.last_delim) {
+    remove_delimiter(&subj, subj.last_delim);
+  }
+  while (subj.last_bracket) {
+    pop_bracket(&subj);
+  }
+}
+
+// Parse zero or more space characters, including at most one newline.
+static void spnl(subject *subj) {
+  skip_spaces(subj);
+  if (skip_line_end(subj)) {
+    skip_spaces(subj);
+  }
+}
+
+// Parse reference.  Assumes string begins with '[' character.
+// Modify refmap if a reference is encountered.
+// Return 0 if no reference found, otherwise position of subject
+// after reference is parsed.
+bufsize_t cmark_parse_reference_inline(cmark_mem *mem, cmark_chunk *input,
+                                       cmark_map *refmap) {
+  subject subj;
+
+  cmark_chunk lab;
+  cmark_chunk url;
+  cmark_chunk title;
+
+  bufsize_t matchlen = 0;
+  bufsize_t beforetitle;
+
+  subject_from_buf(mem, -1, 0, &subj, input, NULL);
+
+  // parse label:
+  if (!link_label(&subj, &lab) || lab.len == 0)
+    return 0;
+
+  // colon:
+  if (peek_char(&subj) == ':') {
+    advance(&subj);
+  } else {
+    return 0;
+  }
+
+  // parse link url:
+  spnl(&subj);
+  if ((matchlen = manual_scan_link_url(&subj.input, subj.pos, &url)) > -1 &&
+      url.len > 0) {
+    subj.pos += matchlen;
+  } else {
+    return 0;
+  }
+
+  // parse optional link_title
+  beforetitle = subj.pos;
+  spnl(&subj);
+  matchlen = scan_link_title(&subj.input, subj.pos);
+  if (matchlen) {
+    title = cmark_chunk_dup(&subj.input, subj.pos, matchlen);
+    subj.pos += matchlen;
+  } else {
+    subj.pos = beforetitle;
+    title = cmark_chunk_literal("");
+  }
+
+  // parse final spaces and newline:
+  skip_spaces(&subj);
+  if (!skip_line_end(&subj)) {
+    if (matchlen) { // try rewinding before title
+      subj.pos = beforetitle;
+      skip_spaces(&subj);
+      if (!skip_line_end(&subj)) {
+        return 0;
+      }
+    } else {
+      return 0;
+    }
+  }
+  // insert reference into refmap
+  cmark_reference_create(refmap, &lab, &url, &title);
+  return subj.pos;
+}
+
+unsigned char cmark_inline_parser_peek_char(cmark_inline_parser *parser) {
+  return peek_char(parser);
+}
+
+unsigned char cmark_inline_parser_peek_at(cmark_inline_parser *parser, bufsize_t pos) {
+  return peek_at(parser, pos);
+}
+
+int cmark_inline_parser_is_eof(cmark_inline_parser *parser) {
+  return is_eof(parser);
+}
+
+static char *
+my_strndup (const char *s, size_t n)
+{
+  char *result;
+  size_t len = strlen (s);
+
+  if (n < len)
+    len = n;
+
+  result = (char *) malloc (len + 1);
+  if (!result)
+    return 0;
+
+  result[len] = '\0';
+  return (char *) memcpy (result, s, len);
+}
+
+char *cmark_inline_parser_take_while(cmark_inline_parser *parser, cmark_inline_predicate pred) {
+  unsigned char c;
+  bufsize_t startpos = parser->pos;
+  bufsize_t len = 0;
+
+  while ((c = peek_char(parser)) && (*pred)(c)) {
+    advance(parser);
+    len++;
+  }
+
+  return my_strndup((const char *) parser->input.data + startpos, len);
+}
+
+void cmark_inline_parser_push_delimiter(cmark_inline_parser *parser,
+                                  unsigned char c,
+                                  int can_open,
+                                  int can_close,
+                                  cmark_node *inl_text) {
+  push_delimiter(parser, c, can_open != 0, can_close != 0, inl_text);
+}
+
+void cmark_inline_parser_remove_delimiter(cmark_inline_parser *parser, delimiter *delim) {
+  remove_delimiter(parser, delim);
+}
+
+int cmark_inline_parser_scan_delimiters(cmark_inline_parser *parser,
+                                  int max_delims,
+                                  unsigned char c,
+                                  int *left_flanking,
+                                  int *right_flanking,
+                                  int *punct_before,
+                                  int *punct_after) {
+  int numdelims = 0;
+  bufsize_t before_char_pos;
+  int32_t after_char = 0;
+  int32_t before_char = 0;
+  int len;
+  bool space_before, space_after;
+
+  if (parser->pos == 0) {
+    before_char = 10;
+  } else {
+    before_char_pos = parser->pos - 1;
+    // walk back to the beginning of the UTF_8 sequence:
+    while (peek_at(parser, before_char_pos) >> 6 == 2 && before_char_pos > 0) {
+      before_char_pos -= 1;
+    }
+    len = cmark_utf8proc_iterate(parser->input.data + before_char_pos,
+                                 parser->pos - before_char_pos, &before_char);
+    if (len == -1) {
+      before_char = 10;
+    }
+  }
+
+  while (peek_char(parser) == c && numdelims <= max_delims) {
+    numdelims++;
+    advance(parser);
+  }
+
+  len = cmark_utf8proc_iterate(parser->input.data + parser->pos,
+                               parser->input.len - parser->pos, &after_char);
+  if (len == -1) {
+    after_char = 10;
+  }
+
+  *punct_before = cmark_utf8proc_is_punctuation(before_char);
+  *punct_after = cmark_utf8proc_is_punctuation(after_char);
+  space_before = cmark_utf8proc_is_space(before_char) != 0;
+  space_after = cmark_utf8proc_is_space(after_char) != 0;
+
+  *left_flanking = numdelims > 0 && !cmark_utf8proc_is_space(after_char) &&
+                  !(*punct_after && !space_before && !*punct_before);
+  *right_flanking = numdelims > 0 && !cmark_utf8proc_is_space(before_char) &&
+                  !(*punct_before && !space_after && !*punct_after);
+
+  return numdelims;
+}
+
+void cmark_inline_parser_advance_offset(cmark_inline_parser *parser) {
+  advance(parser);
+}
+
+int cmark_inline_parser_get_offset(cmark_inline_parser *parser) {
+  return parser->pos;
+}
+
+void cmark_inline_parser_set_offset(cmark_inline_parser *parser, int offset) {
+  parser->pos = offset;
+}
+
+int cmark_inline_parser_get_column(cmark_inline_parser *parser) {
+  return parser->pos + 1 + parser->column_offset + parser->block_offset;
+}
+
+cmark_chunk *cmark_inline_parser_get_chunk(cmark_inline_parser *parser) {
+  return &parser->input;
+}
+
+int cmark_inline_parser_in_bracket(cmark_inline_parser *parser, int image) {
+  for (bracket *b = parser->last_bracket; b; b = b->previous)
+    if (b->active && b->image == (image != 0))
+      return 1;
+  return 0;
+}
+
+void cmark_node_unput(cmark_node *node, int n) {
+	node = node->last_child;
+	while (n > 0 && node && node->type == CMARK_NODE_TEXT) {
+		if (node->as.literal.len < n) {
+			n -= node->as.literal.len;
+			node->as.literal.len = 0;
+		} else {
+			node->as.literal.len -= n;
+			n = 0;
+		}
+		node = node->prev;
+	}
+}
+
+delimiter *cmark_inline_parser_get_last_delimiter(cmark_inline_parser *parser) {
+  return parser->last_delim;
+}
+
+int cmark_inline_parser_get_line(cmark_inline_parser *parser) {
+  return parser->line;
+}
diff --git a/Sources/libcmark_gfm/iterator.c b/Sources/libcmark_gfm/iterator.c
new file mode 100644
index 0000000..5557dff
--- /dev/null
+++ b/Sources/libcmark_gfm/iterator.c
@@ -0,0 +1,159 @@
+#include 
+#include 
+
+#include "config.h"
+#include "node.h"
+#include "cmark.h"
+#include "iterator.h"
+
+cmark_iter *cmark_iter_new(cmark_node *root) {
+  if (root == NULL) {
+    return NULL;
+  }
+  cmark_mem *mem = root->content.mem;
+  cmark_iter *iter = (cmark_iter *)mem->calloc(1, sizeof(cmark_iter));
+  iter->mem = mem;
+  iter->root = root;
+  iter->cur.ev_type = CMARK_EVENT_NONE;
+  iter->cur.node = NULL;
+  iter->next.ev_type = CMARK_EVENT_ENTER;
+  iter->next.node = root;
+  return iter;
+}
+
+void cmark_iter_free(cmark_iter *iter) { iter->mem->free(iter); }
+
+static bool S_is_leaf(cmark_node *node) {
+  switch (node->type) {
+  case CMARK_NODE_HTML_BLOCK:
+  case CMARK_NODE_THEMATIC_BREAK:
+  case CMARK_NODE_CODE_BLOCK:
+  case CMARK_NODE_TEXT:
+  case CMARK_NODE_SOFTBREAK:
+  case CMARK_NODE_LINEBREAK:
+  case CMARK_NODE_CODE:
+  case CMARK_NODE_HTML_INLINE:
+    return 1;
+  }
+  return 0;
+}
+
+cmark_event_type cmark_iter_next(cmark_iter *iter) {
+  cmark_event_type ev_type = iter->next.ev_type;
+  cmark_node *node = iter->next.node;
+
+  iter->cur.ev_type = ev_type;
+  iter->cur.node = node;
+
+  if (ev_type == CMARK_EVENT_DONE) {
+    return ev_type;
+  }
+
+  /* roll forward to next item, setting both fields */
+  if (ev_type == CMARK_EVENT_ENTER && !S_is_leaf(node)) {
+    if (node->first_child == NULL) {
+      /* stay on this node but exit */
+      iter->next.ev_type = CMARK_EVENT_EXIT;
+    } else {
+      iter->next.ev_type = CMARK_EVENT_ENTER;
+      iter->next.node = node->first_child;
+    }
+  } else if (node == iter->root) {
+    /* don't move past root */
+    iter->next.ev_type = CMARK_EVENT_DONE;
+    iter->next.node = NULL;
+  } else if (node->next) {
+    iter->next.ev_type = CMARK_EVENT_ENTER;
+    iter->next.node = node->next;
+  } else if (node->parent) {
+    iter->next.ev_type = CMARK_EVENT_EXIT;
+    iter->next.node = node->parent;
+  } else {
+    assert(false);
+    iter->next.ev_type = CMARK_EVENT_DONE;
+    iter->next.node = NULL;
+  }
+
+  return ev_type;
+}
+
+void cmark_iter_reset(cmark_iter *iter, cmark_node *current,
+                      cmark_event_type event_type) {
+  iter->next.ev_type = event_type;
+  iter->next.node = current;
+  cmark_iter_next(iter);
+}
+
+cmark_node *cmark_iter_get_node(cmark_iter *iter) { return iter->cur.node; }
+
+cmark_event_type cmark_iter_get_event_type(cmark_iter *iter) {
+  return iter->cur.ev_type;
+}
+
+cmark_node *cmark_iter_get_root(cmark_iter *iter) { return iter->root; }
+
+void cmark_consolidate_text_nodes(cmark_node *root) {
+  if (root == NULL) {
+    return;
+  }
+  cmark_iter *iter = cmark_iter_new(root);
+  cmark_strbuf buf = CMARK_BUF_INIT(iter->mem);
+  cmark_event_type ev_type;
+  cmark_node *cur, *tmp, *next;
+
+  while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {
+    cur = cmark_iter_get_node(iter);
+    if (ev_type == CMARK_EVENT_ENTER && cur->type == CMARK_NODE_TEXT &&
+        cur->next && cur->next->type == CMARK_NODE_TEXT) {
+      cmark_strbuf_clear(&buf);
+      cmark_strbuf_put(&buf, cur->as.literal.data, cur->as.literal.len);
+      tmp = cur->next;
+      while (tmp && tmp->type == CMARK_NODE_TEXT) {
+        cmark_iter_next(iter); // advance pointer
+        cmark_strbuf_put(&buf, tmp->as.literal.data, tmp->as.literal.len);
+        cur->end_column = tmp->end_column;
+        next = tmp->next;
+        cmark_node_free(tmp);
+        tmp = next;
+      }
+      cmark_chunk_free(iter->mem, &cur->as.literal);
+      cur->as.literal = cmark_chunk_buf_detach(&buf);
+    }
+  }
+
+  cmark_strbuf_free(&buf);
+  cmark_iter_free(iter);
+}
+
+void cmark_node_own(cmark_node *root) {
+  if (root == NULL) {
+    return;
+  }
+  cmark_iter *iter = cmark_iter_new(root);
+  cmark_event_type ev_type;
+  cmark_node *cur;
+
+  while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {
+    cur = cmark_iter_get_node(iter);
+    if (ev_type == CMARK_EVENT_ENTER) {
+      switch (cur->type) {
+      case CMARK_NODE_TEXT:
+      case CMARK_NODE_HTML_INLINE:
+      case CMARK_NODE_CODE:
+      case CMARK_NODE_HTML_BLOCK:
+        cmark_chunk_to_cstr(iter->mem, &cur->as.literal);
+        break;
+      case CMARK_NODE_LINK:
+        cmark_chunk_to_cstr(iter->mem, &cur->as.link.url);
+        cmark_chunk_to_cstr(iter->mem, &cur->as.link.title);
+        break;
+      case CMARK_NODE_CUSTOM_INLINE:
+        cmark_chunk_to_cstr(iter->mem, &cur->as.custom.on_enter);
+        cmark_chunk_to_cstr(iter->mem, &cur->as.custom.on_exit);
+        break;
+      }
+    }
+  }
+
+  cmark_iter_free(iter);
+}
diff --git a/Sources/libcmark_gfm/latex.c b/Sources/libcmark_gfm/latex.c
new file mode 100644
index 0000000..1767cee
--- /dev/null
+++ b/Sources/libcmark_gfm/latex.c
@@ -0,0 +1,466 @@
+#include 
+#include 
+#include 
+#include 
+
+#include "config.h"
+#include "cmark.h"
+#include "node.h"
+#include "buffer.h"
+#include "utf8.h"
+#include "scanners.h"
+#include "render.h"
+#include "syntax_extension.h"
+
+#define OUT(s, wrap, escaping) renderer->out(renderer, node, s, wrap, escaping)
+#define LIT(s) renderer->out(renderer, node, s, false, LITERAL)
+#define CR() renderer->cr(renderer)
+#define BLANKLINE() renderer->blankline(renderer)
+#define LIST_NUMBER_STRING_SIZE 20
+
+static CMARK_INLINE void outc(cmark_renderer *renderer, cmark_node *node,
+                              cmark_escaping escape,
+                              int32_t c, unsigned char nextc) {
+  if (escape == LITERAL) {
+    cmark_render_code_point(renderer, c);
+    return;
+  }
+
+  switch (c) {
+  case 123: // '{'
+  case 125: // '}'
+  case 35:  // '#'
+  case 37:  // '%'
+  case 38:  // '&'
+    cmark_render_ascii(renderer, "\\");
+    cmark_render_code_point(renderer, c);
+    break;
+  case 36: // '$'
+  case 95: // '_'
+    if (escape == NORMAL) {
+      cmark_render_ascii(renderer, "\\");
+    }
+    cmark_render_code_point(renderer, c);
+    break;
+  case 45:             // '-'
+    if (nextc == 45) { // prevent ligature
+      cmark_render_ascii(renderer, "-{}");
+    } else {
+      cmark_render_ascii(renderer, "-");
+    }
+    break;
+  case 126: // '~'
+    if (escape == NORMAL) {
+      cmark_render_ascii(renderer, "\\textasciitilde{}");
+    } else {
+      cmark_render_code_point(renderer, c);
+    }
+    break;
+  case 94: // '^'
+    cmark_render_ascii(renderer, "\\^{}");
+    break;
+  case 92: // '\\'
+    if (escape == URL) {
+      // / acts as path sep even on windows:
+      cmark_render_ascii(renderer, "/");
+    } else {
+      cmark_render_ascii(renderer, "\\textbackslash{}");
+    }
+    break;
+  case 124: // '|'
+    cmark_render_ascii(renderer, "\\textbar{}");
+    break;
+  case 60: // '<'
+    cmark_render_ascii(renderer, "\\textless{}");
+    break;
+  case 62: // '>'
+    cmark_render_ascii(renderer, "\\textgreater{}");
+    break;
+  case 91: // '['
+  case 93: // ']'
+    cmark_render_ascii(renderer, "{");
+    cmark_render_code_point(renderer, c);
+    cmark_render_ascii(renderer, "}");
+    break;
+  case 34: // '"'
+    cmark_render_ascii(renderer, "\\textquotedbl{}");
+    // requires \usepackage[T1]{fontenc}
+    break;
+  case 39: // '\''
+    cmark_render_ascii(renderer, "\\textquotesingle{}");
+    // requires \usepackage{textcomp}
+    break;
+  case 160: // nbsp
+    cmark_render_ascii(renderer, "~");
+    break;
+  case 8230: // hellip
+    cmark_render_ascii(renderer, "\\ldots{}");
+    break;
+  case 8216: // lsquo
+    if (escape == NORMAL) {
+      cmark_render_ascii(renderer, "`");
+    } else {
+      cmark_render_code_point(renderer, c);
+    }
+    break;
+  case 8217: // rsquo
+    if (escape == NORMAL) {
+      cmark_render_ascii(renderer, "\'");
+    } else {
+      cmark_render_code_point(renderer, c);
+    }
+    break;
+  case 8220: // ldquo
+    if (escape == NORMAL) {
+      cmark_render_ascii(renderer, "``");
+    } else {
+      cmark_render_code_point(renderer, c);
+    }
+    break;
+  case 8221: // rdquo
+    if (escape == NORMAL) {
+      cmark_render_ascii(renderer, "''");
+    } else {
+      cmark_render_code_point(renderer, c);
+    }
+    break;
+  case 8212: // emdash
+    if (escape == NORMAL) {
+      cmark_render_ascii(renderer, "---");
+    } else {
+      cmark_render_code_point(renderer, c);
+    }
+    break;
+  case 8211: // endash
+    if (escape == NORMAL) {
+      cmark_render_ascii(renderer, "--");
+    } else {
+      cmark_render_code_point(renderer, c);
+    }
+    break;
+  default:
+    cmark_render_code_point(renderer, c);
+  }
+}
+
+typedef enum {
+  NO_LINK,
+  URL_AUTOLINK,
+  EMAIL_AUTOLINK,
+  NORMAL_LINK,
+  INTERNAL_LINK
+} link_type;
+
+static link_type get_link_type(cmark_node *node) {
+  size_t title_len, url_len;
+  cmark_node *link_text;
+  char *realurl;
+  int realurllen;
+  bool isemail = false;
+
+  if (node->type != CMARK_NODE_LINK) {
+    return NO_LINK;
+  }
+
+  const char *url = cmark_node_get_url(node);
+  cmark_chunk url_chunk = cmark_chunk_literal(url);
+
+  if (url && *url == '#') {
+    return INTERNAL_LINK;
+  }
+
+  url_len = strlen(url);
+  if (url_len == 0 || scan_scheme(&url_chunk, 0) == 0) {
+    return NO_LINK;
+  }
+
+  const char *title = cmark_node_get_title(node);
+  title_len = strlen(title);
+  // if it has a title, we can't treat it as an autolink:
+  if (title_len == 0) {
+
+    link_text = node->first_child;
+    cmark_consolidate_text_nodes(link_text);
+
+    if (!link_text)
+      return NO_LINK;
+
+    realurl = (char *)url;
+    realurllen = (int)url_len;
+    if (strncmp(realurl, "mailto:", 7) == 0) {
+      realurl += 7;
+      realurllen -= 7;
+      isemail = true;
+    }
+    if (realurllen == link_text->as.literal.len &&
+        strncmp(realurl, (char *)link_text->as.literal.data,
+                link_text->as.literal.len) == 0) {
+      if (isemail) {
+        return EMAIL_AUTOLINK;
+      } else {
+        return URL_AUTOLINK;
+      }
+    }
+  }
+
+  return NORMAL_LINK;
+}
+
+static int S_get_enumlevel(cmark_node *node) {
+  int enumlevel = 0;
+  cmark_node *tmp = node;
+  while (tmp) {
+    if (tmp->type == CMARK_NODE_LIST &&
+        cmark_node_get_list_type(node) == CMARK_ORDERED_LIST) {
+      enumlevel++;
+    }
+    tmp = tmp->parent;
+  }
+  return enumlevel;
+}
+
+static int S_render_node(cmark_renderer *renderer, cmark_node *node,
+                         cmark_event_type ev_type, int options) {
+  int list_number;
+  int enumlevel;
+  char list_number_string[LIST_NUMBER_STRING_SIZE];
+  bool entering = (ev_type == CMARK_EVENT_ENTER);
+  cmark_list_type list_type;
+  bool allow_wrap = renderer->width > 0 && !(CMARK_OPT_NOBREAKS & options);
+
+  if (node->extension && node->extension->latex_render_func) {
+    node->extension->latex_render_func(node->extension, renderer, node, ev_type, options);
+    return 1;
+  }
+
+  switch (node->type) {
+  case CMARK_NODE_DOCUMENT:
+    break;
+
+  case CMARK_NODE_BLOCK_QUOTE:
+    if (entering) {
+      LIT("\\begin{quote}");
+      CR();
+    } else {
+      LIT("\\end{quote}");
+      BLANKLINE();
+    }
+    break;
+
+  case CMARK_NODE_LIST:
+    list_type = cmark_node_get_list_type(node);
+    if (entering) {
+      LIT("\\begin{");
+      LIT(list_type == CMARK_ORDERED_LIST ? "enumerate" : "itemize");
+      LIT("}");
+      CR();
+      list_number = cmark_node_get_list_start(node);
+      if (list_number > 1) {
+        enumlevel = S_get_enumlevel(node);
+        // latex normally supports only five levels
+        if (enumlevel >= 1 && enumlevel <= 5) {
+          snprintf(list_number_string, LIST_NUMBER_STRING_SIZE, "%d",
+                   list_number);
+          LIT("\\setcounter{enum");
+          switch (enumlevel) {
+          case 1: LIT("i"); break;
+          case 2: LIT("ii"); break;
+          case 3: LIT("iii"); break;
+          case 4: LIT("iv"); break;
+          case 5: LIT("v"); break;
+          default: LIT("i"); break;
+	  }
+          LIT("}{");
+          OUT(list_number_string, false, NORMAL);
+          LIT("}");
+        }
+        CR();
+      }
+    } else {
+      LIT("\\end{");
+      LIT(list_type == CMARK_ORDERED_LIST ? "enumerate" : "itemize");
+      LIT("}");
+      BLANKLINE();
+    }
+    break;
+
+  case CMARK_NODE_ITEM:
+    if (entering) {
+      LIT("\\item ");
+    } else {
+      CR();
+    }
+    break;
+
+  case CMARK_NODE_HEADING:
+    if (entering) {
+      switch (cmark_node_get_heading_level(node)) {
+      case 1:
+        LIT("\\section");
+        break;
+      case 2:
+        LIT("\\subsection");
+        break;
+      case 3:
+        LIT("\\subsubsection");
+        break;
+      case 4:
+        LIT("\\paragraph");
+        break;
+      case 5:
+        LIT("\\subparagraph");
+        break;
+      }
+      LIT("{");
+    } else {
+      LIT("}");
+      BLANKLINE();
+    }
+    break;
+
+  case CMARK_NODE_CODE_BLOCK:
+    CR();
+    LIT("\\begin{verbatim}");
+    CR();
+    OUT(cmark_node_get_literal(node), false, LITERAL);
+    CR();
+    LIT("\\end{verbatim}");
+    BLANKLINE();
+    break;
+
+  case CMARK_NODE_HTML_BLOCK:
+    break;
+
+  case CMARK_NODE_CUSTOM_BLOCK:
+    CR();
+    OUT(entering ? cmark_node_get_on_enter(node) : cmark_node_get_on_exit(node),
+        false, LITERAL);
+    CR();
+    break;
+
+  case CMARK_NODE_THEMATIC_BREAK:
+    BLANKLINE();
+    LIT("\\begin{center}\\rule{0.5\\linewidth}{\\linethickness}\\end{center}");
+    BLANKLINE();
+    break;
+
+  case CMARK_NODE_PARAGRAPH:
+    if (!entering) {
+      BLANKLINE();
+    }
+    break;
+
+  case CMARK_NODE_TEXT:
+    OUT(cmark_node_get_literal(node), allow_wrap, NORMAL);
+    break;
+
+  case CMARK_NODE_LINEBREAK:
+    LIT("\\\\");
+    CR();
+    break;
+
+  case CMARK_NODE_SOFTBREAK:
+    if (options & CMARK_OPT_HARDBREAKS) {
+      LIT("\\\\");
+      CR();
+    } else if (renderer->width == 0 && !(CMARK_OPT_NOBREAKS & options)) {
+      CR();
+    } else {
+      OUT(" ", allow_wrap, NORMAL);
+    }
+    break;
+
+  case CMARK_NODE_CODE:
+    LIT("\\texttt{");
+    OUT(cmark_node_get_literal(node), false, NORMAL);
+    LIT("}");
+    break;
+
+  case CMARK_NODE_HTML_INLINE:
+    break;
+
+  case CMARK_NODE_CUSTOM_INLINE:
+    OUT(entering ? cmark_node_get_on_enter(node) : cmark_node_get_on_exit(node),
+        false, LITERAL);
+    break;
+
+  case CMARK_NODE_STRONG:
+    if (entering) {
+      LIT("\\textbf{");
+    } else {
+      LIT("}");
+    }
+    break;
+
+  case CMARK_NODE_EMPH:
+    if (entering) {
+      LIT("\\emph{");
+    } else {
+      LIT("}");
+    }
+    break;
+
+  case CMARK_NODE_LINK:
+    if (entering) {
+      const char *url = cmark_node_get_url(node);
+      // requires \usepackage{hyperref}
+      switch (get_link_type(node)) {
+      case URL_AUTOLINK:
+        LIT("\\url{");
+        OUT(url, false, URL);
+        LIT("}");
+        return 0; // Don't process further nodes to avoid double-rendering artefacts
+      case EMAIL_AUTOLINK:
+        LIT("\\href{");
+        OUT(url, false, URL);
+        LIT("}\\nolinkurl{");
+        break;
+      case NORMAL_LINK:
+        LIT("\\href{");
+        OUT(url, false, URL);
+        LIT("}{");
+        break;
+      case INTERNAL_LINK:
+        LIT("\\protect\\hyperlink{");
+        OUT(url + 1, false, URL);
+        LIT("}{");
+        break;
+      case NO_LINK:
+        LIT("{"); // error?
+      }
+    } else {
+      LIT("}");
+    }
+
+    break;
+
+  case CMARK_NODE_IMAGE:
+    if (entering) {
+      LIT("\\protect\\includegraphics{");
+      // requires \include{graphicx}
+      OUT(cmark_node_get_url(node), false, URL);
+      LIT("}");
+      return 0;
+    }
+    break;
+
+  case CMARK_NODE_FOOTNOTE_DEFINITION:
+  case CMARK_NODE_FOOTNOTE_REFERENCE:
+    // TODO
+    break;
+
+  default:
+    assert(false);
+    break;
+  }
+
+  return 1;
+}
+
+char *cmark_render_latex(cmark_node *root, int options, int width) {
+  return cmark_render_latex_with_mem(root, options, width, cmark_node_mem(root));
+}
+
+char *cmark_render_latex_with_mem(cmark_node *root, int options, int width, cmark_mem *mem) {
+  return cmark_render(mem, root, options, width, outc, S_render_node);
+}
diff --git a/Sources/libcmark_gfm/linked_list.c b/Sources/libcmark_gfm/linked_list.c
new file mode 100644
index 0000000..f8bc604
--- /dev/null
+++ b/Sources/libcmark_gfm/linked_list.c
@@ -0,0 +1,37 @@
+#include 
+
+#include "cmark.h"
+
+cmark_llist *cmark_llist_append(cmark_mem *mem, cmark_llist *head, void *data) {
+  cmark_llist *tmp;
+  cmark_llist *new_node = (cmark_llist *) mem->calloc(1, sizeof(cmark_llist));
+
+  new_node->data = data;
+  new_node->next = NULL;
+
+  if (!head)
+    return new_node;
+
+  for (tmp = head; tmp->next; tmp=tmp->next);
+
+  tmp->next = new_node;
+
+  return head;
+}
+
+void cmark_llist_free_full(cmark_mem *mem, cmark_llist *head, cmark_free_func free_func) {
+  cmark_llist *tmp, *prev;
+
+  for (tmp = head; tmp;) {
+    if (free_func)
+      free_func(mem, tmp->data);
+
+    prev = tmp;
+    tmp = tmp->next;
+    mem->free(prev);
+  }
+}
+
+void cmark_llist_free(cmark_mem *mem, cmark_llist *head) {
+  cmark_llist_free_full(mem, head, NULL);
+}
diff --git a/Sources/libcmark_gfm/man.c b/Sources/libcmark_gfm/man.c
new file mode 100644
index 0000000..1e1a69d
--- /dev/null
+++ b/Sources/libcmark_gfm/man.c
@@ -0,0 +1,278 @@
+#include 
+#include 
+#include 
+#include 
+
+#include "config.h"
+#include "cmark.h"
+#include "node.h"
+#include "buffer.h"
+#include "utf8.h"
+#include "render.h"
+#include "syntax_extension.h"
+
+#define OUT(s, wrap, escaping) renderer->out(renderer, node, s, wrap, escaping)
+#define LIT(s) renderer->out(renderer, node, s, false, LITERAL)
+#define CR() renderer->cr(renderer)
+#define BLANKLINE() renderer->blankline(renderer)
+#define LIST_NUMBER_SIZE 20
+
+// Functions to convert cmark_nodes to groff man strings.
+static void S_outc(cmark_renderer *renderer, cmark_node *node, 
+                   cmark_escaping escape, int32_t c,
+                   unsigned char nextc) {
+  (void)(nextc);
+
+  if (escape == LITERAL) {
+    cmark_render_code_point(renderer, c);
+    return;
+  }
+
+  switch (c) {
+  case 46:
+    if (renderer->begin_line) {
+      cmark_render_ascii(renderer, "\\&.");
+    } else {
+      cmark_render_code_point(renderer, c);
+    }
+    break;
+  case 39:
+    if (renderer->begin_line) {
+      cmark_render_ascii(renderer, "\\&'");
+    } else {
+      cmark_render_code_point(renderer, c);
+    }
+    break;
+  case 45:
+    cmark_render_ascii(renderer, "\\-");
+    break;
+  case 92:
+    cmark_render_ascii(renderer, "\\e");
+    break;
+  case 8216: // left single quote
+    cmark_render_ascii(renderer, "\\[oq]");
+    break;
+  case 8217: // right single quote
+    cmark_render_ascii(renderer, "\\[cq]");
+    break;
+  case 8220: // left double quote
+    cmark_render_ascii(renderer, "\\[lq]");
+    break;
+  case 8221: // right double quote
+    cmark_render_ascii(renderer, "\\[rq]");
+    break;
+  case 8212: // em dash
+    cmark_render_ascii(renderer, "\\[em]");
+    break;
+  case 8211: // en dash
+    cmark_render_ascii(renderer, "\\[en]");
+    break;
+  default:
+    cmark_render_code_point(renderer, c);
+  }
+}
+
+static int S_render_node(cmark_renderer *renderer, cmark_node *node,
+                         cmark_event_type ev_type, int options) {
+  cmark_node *tmp;
+  int list_number;
+  bool entering = (ev_type == CMARK_EVENT_ENTER);
+  bool allow_wrap = renderer->width > 0 && !(CMARK_OPT_NOBREAKS & options);
+
+  if (node->extension && node->extension->man_render_func) {
+    node->extension->man_render_func(node->extension, renderer, node, ev_type, options);
+    return 1;
+  }
+
+  switch (node->type) {
+  case CMARK_NODE_DOCUMENT:
+    if (entering) {
+      /* Define a strikethrough macro */
+      /* Commenting out because this makes tests fail
+      LIT(".de ST");
+      CR();
+      LIT(".nr ww \\w'\\\\$1'");
+      CR();
+      LIT("\\Z@\\v'-.25m'\\l'\\\\n[ww]u'@\\\\$1");
+      CR();
+      LIT("..");
+      CR();
+      */
+    }
+    break;
+
+  case CMARK_NODE_BLOCK_QUOTE:
+    if (entering) {
+      CR();
+      LIT(".RS");
+      CR();
+    } else {
+      CR();
+      LIT(".RE");
+      CR();
+    }
+    break;
+
+  case CMARK_NODE_LIST:
+    break;
+
+  case CMARK_NODE_ITEM:
+    if (entering) {
+      CR();
+      LIT(".IP ");
+      if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {
+        LIT("\\[bu] 2");
+      } else {
+        list_number = cmark_node_get_list_start(node->parent);
+        tmp = node;
+        while (tmp->prev) {
+          tmp = tmp->prev;
+          list_number += 1;
+        }
+        char list_number_s[LIST_NUMBER_SIZE];
+        snprintf(list_number_s, LIST_NUMBER_SIZE, "\"%d.\" 4", list_number);
+        LIT(list_number_s);
+      }
+      CR();
+    } else {
+      CR();
+    }
+    break;
+
+  case CMARK_NODE_HEADING:
+    if (entering) {
+      CR();
+      LIT(cmark_node_get_heading_level(node) == 1 ? ".SH" : ".SS");
+      CR();
+    } else {
+      CR();
+    }
+    break;
+
+  case CMARK_NODE_CODE_BLOCK:
+    CR();
+    LIT(".IP\n.nf\n\\f[C]\n");
+    OUT(cmark_node_get_literal(node), false, NORMAL);
+    CR();
+    LIT("\\f[]\n.fi");
+    CR();
+    break;
+
+  case CMARK_NODE_HTML_BLOCK:
+    break;
+
+  case CMARK_NODE_CUSTOM_BLOCK:
+    CR();
+    OUT(entering ? cmark_node_get_on_enter(node) : cmark_node_get_on_exit(node),
+        false, LITERAL);
+    CR();
+    break;
+
+  case CMARK_NODE_THEMATIC_BREAK:
+    CR();
+    LIT(".PP\n  *  *  *  *  *");
+    CR();
+    break;
+
+  case CMARK_NODE_PARAGRAPH:
+    if (entering) {
+      // no blank line if first paragraph in list:
+      if (node->parent && node->parent->type == CMARK_NODE_ITEM &&
+          node->prev == NULL) {
+        // no blank line or .PP
+      } else {
+        CR();
+        LIT(".PP");
+        CR();
+      }
+    } else {
+      CR();
+    }
+    break;
+
+  case CMARK_NODE_TEXT:
+    OUT(cmark_node_get_literal(node), allow_wrap, NORMAL);
+    break;
+
+  case CMARK_NODE_LINEBREAK:
+    LIT(".PD 0\n.P\n.PD");
+    CR();
+    break;
+
+  case CMARK_NODE_SOFTBREAK:
+    if (options & CMARK_OPT_HARDBREAKS) {
+      LIT(".PD 0\n.P\n.PD");
+      CR();
+    } else if (renderer->width == 0 && !(CMARK_OPT_NOBREAKS & options)) {
+      CR();
+    } else {
+      OUT(" ", allow_wrap, LITERAL);
+    }
+    break;
+
+  case CMARK_NODE_CODE:
+    LIT("\\f[C]");
+    OUT(cmark_node_get_literal(node), allow_wrap, NORMAL);
+    LIT("\\f[]");
+    break;
+
+  case CMARK_NODE_HTML_INLINE:
+    break;
+
+  case CMARK_NODE_CUSTOM_INLINE:
+    OUT(entering ? cmark_node_get_on_enter(node) : cmark_node_get_on_exit(node),
+        false, LITERAL);
+    break;
+
+  case CMARK_NODE_STRONG:
+    if (entering) {
+      LIT("\\f[B]");
+    } else {
+      LIT("\\f[]");
+    }
+    break;
+
+  case CMARK_NODE_EMPH:
+    if (entering) {
+      LIT("\\f[I]");
+    } else {
+      LIT("\\f[]");
+    }
+    break;
+
+  case CMARK_NODE_LINK:
+    if (!entering) {
+      LIT(" (");
+      OUT(cmark_node_get_url(node), allow_wrap, URL);
+      LIT(")");
+    }
+    break;
+
+  case CMARK_NODE_IMAGE:
+    if (entering) {
+      LIT("[IMAGE: ");
+    } else {
+      LIT("]");
+    }
+    break;
+
+  case CMARK_NODE_FOOTNOTE_DEFINITION:
+  case CMARK_NODE_FOOTNOTE_REFERENCE:
+    // TODO
+    break;
+
+  default:
+    assert(false);
+    break;
+  }
+
+  return 1;
+}
+
+char *cmark_render_man(cmark_node *root, int options, int width) {
+  return cmark_render_man_with_mem(root, options, width, cmark_node_mem(root));
+}
+
+char *cmark_render_man_with_mem(cmark_node *root, int options, int width, cmark_mem *mem) {
+  return cmark_render(mem, root, options, width, S_outc, S_render_node);
+}
diff --git a/Sources/libcmark_gfm/map.c b/Sources/libcmark_gfm/map.c
new file mode 100644
index 0000000..9a418df
--- /dev/null
+++ b/Sources/libcmark_gfm/map.c
@@ -0,0 +1,122 @@
+#include "map.h"
+#include "utf8.h"
+#include "parser.h"
+
+// normalize map label:  collapse internal whitespace to single space,
+// remove leading/trailing whitespace, case fold
+// Return NULL if the label is actually empty (i.e. composed solely from
+// whitespace)
+unsigned char *normalize_map_label(cmark_mem *mem, cmark_chunk *ref) {
+  cmark_strbuf normalized = CMARK_BUF_INIT(mem);
+  unsigned char *result;
+
+  if (ref == NULL)
+    return NULL;
+
+  if (ref->len == 0)
+    return NULL;
+
+  cmark_utf8proc_case_fold(&normalized, ref->data, ref->len);
+  cmark_strbuf_trim(&normalized);
+  cmark_strbuf_normalize_whitespace(&normalized);
+
+  result = cmark_strbuf_detach(&normalized);
+  assert(result);
+
+  if (result[0] == '\0') {
+    mem->free(result);
+    return NULL;
+  }
+
+  return result;
+}
+
+static int
+labelcmp(const unsigned char *a, const unsigned char *b) {
+  return strcmp((const char *)a, (const char *)b);
+}
+
+static int
+refcmp(const void *p1, const void *p2) {
+  cmark_map_entry *r1 = *(cmark_map_entry **)p1;
+  cmark_map_entry *r2 = *(cmark_map_entry **)p2;
+  int res = labelcmp(r1->label, r2->label);
+  return res ? res : ((int)r1->age - (int)r2->age);
+}
+
+static int
+refsearch(const void *label, const void *p2) {
+  cmark_map_entry *ref = *(cmark_map_entry **)p2;
+  return labelcmp((const unsigned char *)label, ref->label);
+}
+
+static void sort_map(cmark_map *map) {
+  unsigned int i = 0, last = 0, size = map->size;
+  cmark_map_entry *r = map->refs, **sorted = NULL;
+
+  sorted = (cmark_map_entry **)map->mem->calloc(size, sizeof(cmark_map_entry *));
+  while (r) {
+    sorted[i++] = r;
+    r = r->next;
+  }
+
+  qsort(sorted, size, sizeof(cmark_map_entry *), refcmp);
+
+  for (i = 1; i < size; i++) {
+    if (labelcmp(sorted[i]->label, sorted[last]->label) != 0)
+      sorted[++last] = sorted[i];
+  }
+
+  map->sorted = sorted;
+  map->size = last + 1;
+}
+
+cmark_map_entry *cmark_map_lookup(cmark_map *map, cmark_chunk *label) {
+  cmark_map_entry **ref = NULL;
+  unsigned char *norm;
+
+  if (label->len < 1 || label->len > MAX_LINK_LABEL_LENGTH)
+    return NULL;
+
+  if (map == NULL || !map->size)
+    return NULL;
+
+  norm = normalize_map_label(map->mem, label);
+  if (norm == NULL)
+    return NULL;
+
+  if (!map->sorted)
+    sort_map(map);
+
+  ref = (cmark_map_entry **)bsearch(norm, map->sorted, map->size, sizeof(cmark_map_entry *), refsearch);
+  map->mem->free(norm);
+
+  if (!ref)
+    return NULL;
+
+  return ref[0];
+}
+
+void cmark_map_free(cmark_map *map) {
+  cmark_map_entry *ref;
+
+  if (map == NULL)
+    return;
+
+  ref = map->refs;
+  while (ref) {
+    cmark_map_entry *next = ref->next;
+    map->free(map, ref);
+    ref = next;
+  }
+
+  map->mem->free(map->sorted);
+  map->mem->free(map);
+}
+
+cmark_map *cmark_map_new(cmark_mem *mem, cmark_map_free_f free) {
+  cmark_map *map = (cmark_map *)mem->calloc(1, sizeof(cmark_map));
+  map->mem = mem;
+  map->free = free;
+  return map;
+}
diff --git a/Sources/libcmark_gfm/node.c b/Sources/libcmark_gfm/node.c
new file mode 100644
index 0000000..3f94834
--- /dev/null
+++ b/Sources/libcmark_gfm/node.c
@@ -0,0 +1,965 @@
+#include 
+#include 
+
+#include "config.h"
+#include "node.h"
+#include "syntax_extension.h"
+
+static void S_node_unlink(cmark_node *node);
+
+#define NODE_MEM(node) cmark_node_mem(node)
+
+bool cmark_node_can_contain_type(cmark_node *node, cmark_node_type child_type) {
+  if (child_type == CMARK_NODE_DOCUMENT) {
+      return false;
+    }
+
+  if (node->extension && node->extension->can_contain_func) {
+    return node->extension->can_contain_func(node->extension, node, child_type) != 0;
+  }
+
+  switch (node->type) {
+  case CMARK_NODE_DOCUMENT:
+  case CMARK_NODE_BLOCK_QUOTE:
+  case CMARK_NODE_FOOTNOTE_DEFINITION:
+  case CMARK_NODE_ITEM:
+    return CMARK_NODE_TYPE_BLOCK_P(child_type) && child_type != CMARK_NODE_ITEM;
+
+  case CMARK_NODE_LIST:
+    return child_type == CMARK_NODE_ITEM;
+
+  case CMARK_NODE_CUSTOM_BLOCK:
+    return true;
+
+  case CMARK_NODE_PARAGRAPH:
+  case CMARK_NODE_HEADING:
+  case CMARK_NODE_EMPH:
+  case CMARK_NODE_STRONG:
+  case CMARK_NODE_LINK:
+  case CMARK_NODE_IMAGE:
+  case CMARK_NODE_CUSTOM_INLINE:
+    return CMARK_NODE_TYPE_INLINE_P(child_type);
+
+  default:
+    break;
+  }
+
+  return false;
+}
+
+static bool S_can_contain(cmark_node *node, cmark_node *child) {
+  cmark_node *cur;
+
+  if (node == NULL || child == NULL) {
+    return false;
+  }
+  if (NODE_MEM(node) != NODE_MEM(child)) {
+    return 0;
+  }
+
+  // Verify that child is not an ancestor of node or equal to node.
+  cur = node;
+  do {
+    if (cur == child) {
+      return false;
+    }
+    cur = cur->parent;
+  } while (cur != NULL);
+
+  return cmark_node_can_contain_type(node, (cmark_node_type) child->type);
+}
+
+cmark_node *cmark_node_new_with_mem(cmark_node_type type, cmark_mem *mem) {
+  cmark_node *node = (cmark_node *)mem->calloc(1, sizeof(*node));
+  cmark_strbuf_init(mem, &node->content, 0);
+  node->type = (uint16_t)type;
+
+  switch (node->type) {
+  case CMARK_NODE_HEADING:
+    node->as.heading.level = 1;
+    break;
+
+  case CMARK_NODE_LIST: {
+    cmark_list *list = &node->as.list;
+    list->list_type = CMARK_BULLET_LIST;
+    list->start = 0;
+    list->tight = false;
+    break;
+  }
+
+  default:
+    break;
+  }
+
+  return node;
+}
+
+cmark_node *cmark_node_new(cmark_node_type type) {
+  extern cmark_mem CMARK_DEFAULT_MEM_ALLOCATOR;
+  return cmark_node_new_with_mem(type, &CMARK_DEFAULT_MEM_ALLOCATOR);
+}
+
+static void free_node_as(cmark_node *node) {
+  switch (node->type) {
+    case CMARK_NODE_CODE_BLOCK:
+    cmark_chunk_free(NODE_MEM(node), &node->as.code.info);
+    cmark_chunk_free(NODE_MEM(node), &node->as.code.literal);
+      break;
+    case CMARK_NODE_TEXT:
+    case CMARK_NODE_HTML_INLINE:
+    case CMARK_NODE_CODE:
+    case CMARK_NODE_HTML_BLOCK:
+    case CMARK_NODE_FOOTNOTE_REFERENCE:
+    case CMARK_NODE_FOOTNOTE_DEFINITION:
+    cmark_chunk_free(NODE_MEM(node), &node->as.literal);
+      break;
+    case CMARK_NODE_LINK:
+    case CMARK_NODE_IMAGE:
+    cmark_chunk_free(NODE_MEM(node), &node->as.link.url);
+    cmark_chunk_free(NODE_MEM(node), &node->as.link.title);
+      break;
+    case CMARK_NODE_CUSTOM_BLOCK:
+    case CMARK_NODE_CUSTOM_INLINE:
+    cmark_chunk_free(NODE_MEM(node), &node->as.custom.on_enter);
+    cmark_chunk_free(NODE_MEM(node), &node->as.custom.on_exit);
+      break;
+    default:
+      break;
+    }
+}
+
+// Free a cmark_node list and any children.
+static void S_free_nodes(cmark_node *e) {
+  cmark_node *next;
+  while (e != NULL) {
+    cmark_strbuf_free(&e->content);
+
+    if (e->user_data && e->user_data_free_func)
+      e->user_data_free_func(NODE_MEM(e), e->user_data);
+
+    if (e->as.opaque && e->extension && e->extension->opaque_free_func)
+      e->extension->opaque_free_func(e->extension, NODE_MEM(e), e);
+
+    free_node_as(e);
+
+    if (e->last_child) {
+      // Splice children into list
+      e->last_child->next = e->next;
+      e->next = e->first_child;
+    }
+    next = e->next;
+    NODE_MEM(e)->free(e);
+    e = next;
+  }
+}
+
+void cmark_node_free(cmark_node *node) {
+  S_node_unlink(node);
+  node->next = NULL;
+  S_free_nodes(node);
+}
+
+cmark_node_type cmark_node_get_type(cmark_node *node) {
+  if (node == NULL) {
+    return CMARK_NODE_NONE;
+  } else {
+    return (cmark_node_type)node->type;
+  }
+}
+
+int cmark_node_set_type(cmark_node * node, cmark_node_type type) {
+  cmark_node_type initial_type;
+
+  if (type == node->type)
+    return 1;
+
+  initial_type = (cmark_node_type) node->type;
+  node->type = (uint16_t)type;
+
+  if (!S_can_contain(node->parent, node)) {
+    node->type = (uint16_t)initial_type;
+    return 0;
+  }
+
+  /* We rollback the type to free the union members appropriately */
+  node->type = (uint16_t)initial_type;
+  free_node_as(node);
+
+  node->type = (uint16_t)type;
+
+  return 1;
+}
+
+const char *cmark_node_get_type_string(cmark_node *node) {
+  if (node == NULL) {
+    return "NONE";
+  }
+
+  if (node->extension && node->extension->get_type_string_func) {
+    return node->extension->get_type_string_func(node->extension, node);
+  }
+
+  switch (node->type) {
+  case CMARK_NODE_NONE:
+    return "none";
+  case CMARK_NODE_DOCUMENT:
+    return "document";
+  case CMARK_NODE_BLOCK_QUOTE:
+    return "block_quote";
+  case CMARK_NODE_LIST:
+    return "list";
+  case CMARK_NODE_ITEM:
+    return "item";
+  case CMARK_NODE_CODE_BLOCK:
+    return "code_block";
+  case CMARK_NODE_HTML_BLOCK:
+    return "html_block";
+  case CMARK_NODE_CUSTOM_BLOCK:
+    return "custom_block";
+  case CMARK_NODE_PARAGRAPH:
+    return "paragraph";
+  case CMARK_NODE_HEADING:
+    return "heading";
+  case CMARK_NODE_THEMATIC_BREAK:
+    return "thematic_break";
+  case CMARK_NODE_TEXT:
+    return "text";
+  case CMARK_NODE_SOFTBREAK:
+    return "softbreak";
+  case CMARK_NODE_LINEBREAK:
+    return "linebreak";
+  case CMARK_NODE_CODE:
+    return "code";
+  case CMARK_NODE_HTML_INLINE:
+    return "html_inline";
+  case CMARK_NODE_CUSTOM_INLINE:
+    return "custom_inline";
+  case CMARK_NODE_EMPH:
+    return "emph";
+  case CMARK_NODE_STRONG:
+    return "strong";
+  case CMARK_NODE_LINK:
+    return "link";
+  case CMARK_NODE_IMAGE:
+    return "image";
+  }
+
+  return "";
+}
+
+cmark_node *cmark_node_next(cmark_node *node) {
+  if (node == NULL) {
+    return NULL;
+  } else {
+    return node->next;
+  }
+}
+
+cmark_node *cmark_node_previous(cmark_node *node) {
+  if (node == NULL) {
+    return NULL;
+  } else {
+    return node->prev;
+  }
+}
+
+cmark_node *cmark_node_parent(cmark_node *node) {
+  if (node == NULL) {
+    return NULL;
+  } else {
+    return node->parent;
+  }
+}
+
+cmark_node *cmark_node_first_child(cmark_node *node) {
+  if (node == NULL) {
+    return NULL;
+  } else {
+    return node->first_child;
+  }
+}
+
+cmark_node *cmark_node_last_child(cmark_node *node) {
+  if (node == NULL) {
+    return NULL;
+  } else {
+    return node->last_child;
+  }
+}
+
+void *cmark_node_get_user_data(cmark_node *node) {
+  if (node == NULL) {
+    return NULL;
+  } else {
+    return node->user_data;
+  }
+}
+
+int cmark_node_set_user_data(cmark_node *node, void *user_data) {
+  if (node == NULL) {
+    return 0;
+  }
+  node->user_data = user_data;
+  return 1;
+}
+
+int cmark_node_set_user_data_free_func(cmark_node *node,
+                                        cmark_free_func free_func) {
+  if (node == NULL) {
+    return 0;
+  }
+  node->user_data_free_func = free_func;
+  return 1;
+}
+
+const char *cmark_node_get_literal(cmark_node *node) {
+  if (node == NULL) {
+    return NULL;
+  }
+
+  switch (node->type) {
+  case CMARK_NODE_HTML_BLOCK:
+  case CMARK_NODE_TEXT:
+  case CMARK_NODE_HTML_INLINE:
+  case CMARK_NODE_CODE:
+  case CMARK_NODE_FOOTNOTE_REFERENCE:
+    return cmark_chunk_to_cstr(NODE_MEM(node), &node->as.literal);
+
+  case CMARK_NODE_CODE_BLOCK:
+    return cmark_chunk_to_cstr(NODE_MEM(node), &node->as.code.literal);
+
+  default:
+    break;
+  }
+
+  return NULL;
+}
+
+int cmark_node_set_literal(cmark_node *node, const char *content) {
+  if (node == NULL) {
+    return 0;
+  }
+
+  switch (node->type) {
+  case CMARK_NODE_HTML_BLOCK:
+  case CMARK_NODE_TEXT:
+  case CMARK_NODE_HTML_INLINE:
+  case CMARK_NODE_CODE:
+  case CMARK_NODE_FOOTNOTE_REFERENCE:
+    cmark_chunk_set_cstr(NODE_MEM(node), &node->as.literal, content);
+    return 1;
+
+  case CMARK_NODE_CODE_BLOCK:
+    cmark_chunk_set_cstr(NODE_MEM(node), &node->as.code.literal, content);
+    return 1;
+
+  default:
+    break;
+  }
+
+  return 0;
+}
+
+const char *cmark_node_get_string_content(cmark_node *node) {
+  return (char *) node->content.ptr;
+}
+
+int cmark_node_set_string_content(cmark_node *node, const char *content) {
+  cmark_strbuf_sets(&node->content, content);
+  return true;
+}
+
+int cmark_node_get_heading_level(cmark_node *node) {
+  if (node == NULL) {
+    return 0;
+  }
+
+  switch (node->type) {
+  case CMARK_NODE_HEADING:
+    return node->as.heading.level;
+
+  default:
+    break;
+  }
+
+  return 0;
+}
+
+int cmark_node_set_heading_level(cmark_node *node, int level) {
+  if (node == NULL || level < 1 || level > 6) {
+    return 0;
+  }
+
+  switch (node->type) {
+  case CMARK_NODE_HEADING:
+    node->as.heading.level = level;
+    return 1;
+
+  default:
+    break;
+  }
+
+  return 0;
+}
+
+cmark_list_type cmark_node_get_list_type(cmark_node *node) {
+  if (node == NULL) {
+    return CMARK_NO_LIST;
+  }
+
+  if (node->type == CMARK_NODE_LIST) {
+    return node->as.list.list_type;
+  } else {
+    return CMARK_NO_LIST;
+  }
+}
+
+int cmark_node_set_list_type(cmark_node *node, cmark_list_type type) {
+  if (!(type == CMARK_BULLET_LIST || type == CMARK_ORDERED_LIST)) {
+    return 0;
+  }
+
+  if (node == NULL) {
+    return 0;
+  }
+
+  if (node->type == CMARK_NODE_LIST) {
+    node->as.list.list_type = type;
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+cmark_delim_type cmark_node_get_list_delim(cmark_node *node) {
+  if (node == NULL) {
+    return CMARK_NO_DELIM;
+  }
+
+  if (node->type == CMARK_NODE_LIST) {
+    return node->as.list.delimiter;
+  } else {
+    return CMARK_NO_DELIM;
+  }
+}
+
+int cmark_node_set_list_delim(cmark_node *node, cmark_delim_type delim) {
+  if (!(delim == CMARK_PERIOD_DELIM || delim == CMARK_PAREN_DELIM)) {
+    return 0;
+  }
+
+  if (node == NULL) {
+    return 0;
+  }
+
+  if (node->type == CMARK_NODE_LIST) {
+    node->as.list.delimiter = delim;
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+int cmark_node_get_list_start(cmark_node *node) {
+  if (node == NULL) {
+    return 0;
+  }
+
+  if (node->type == CMARK_NODE_LIST) {
+    return node->as.list.start;
+  } else {
+    return 0;
+  }
+}
+
+int cmark_node_set_list_start(cmark_node *node, int start) {
+  if (node == NULL || start < 0) {
+    return 0;
+  }
+
+  if (node->type == CMARK_NODE_LIST) {
+    node->as.list.start = start;
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+int cmark_node_get_list_tight(cmark_node *node) {
+  if (node == NULL) {
+    return 0;
+  }
+
+  if (node->type == CMARK_NODE_LIST) {
+    return node->as.list.tight;
+  } else {
+    return 0;
+  }
+}
+
+int cmark_node_set_list_tight(cmark_node *node, int tight) {
+  if (node == NULL) {
+    return 0;
+  }
+
+  if (node->type == CMARK_NODE_LIST) {
+    node->as.list.tight = tight == 1;
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+const char *cmark_node_get_fence_info(cmark_node *node) {
+  if (node == NULL) {
+    return NULL;
+  }
+
+  if (node->type == CMARK_NODE_CODE_BLOCK) {
+    return cmark_chunk_to_cstr(NODE_MEM(node), &node->as.code.info);
+  } else {
+    return NULL;
+  }
+}
+
+int cmark_node_set_fence_info(cmark_node *node, const char *info) {
+  if (node == NULL) {
+    return 0;
+  }
+
+  if (node->type == CMARK_NODE_CODE_BLOCK) {
+    cmark_chunk_set_cstr(NODE_MEM(node), &node->as.code.info, info);
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+int cmark_node_get_fenced(cmark_node *node, int *length, int *offset, char *character) {
+  if (node == NULL) {
+    return 0;
+  }
+
+  if (node->type == CMARK_NODE_CODE_BLOCK) {
+    *length = node->as.code.fence_length;
+    *offset = node->as.code.fence_offset;
+    *character = node->as.code.fence_char;
+    return node->as.code.fenced;
+  } else {
+    return 0;
+  }
+}
+
+int cmark_node_set_fenced(cmark_node * node, int fenced,
+    int length, int offset, char character) {
+  if (node == NULL) {
+    return 0;
+  }
+
+  if (node->type == CMARK_NODE_CODE_BLOCK) {
+    node->as.code.fenced = (int8_t)fenced;
+    node->as.code.fence_length = (uint8_t)length;
+    node->as.code.fence_offset = (uint8_t)offset;
+    node->as.code.fence_char = character;
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+const char *cmark_node_get_url(cmark_node *node) {
+  if (node == NULL) {
+    return NULL;
+  }
+
+  switch (node->type) {
+  case CMARK_NODE_LINK:
+  case CMARK_NODE_IMAGE:
+    return cmark_chunk_to_cstr(NODE_MEM(node), &node->as.link.url);
+  default:
+    break;
+  }
+
+  return NULL;
+}
+
+int cmark_node_set_url(cmark_node *node, const char *url) {
+  if (node == NULL) {
+    return 0;
+  }
+
+  switch (node->type) {
+  case CMARK_NODE_LINK:
+  case CMARK_NODE_IMAGE:
+    cmark_chunk_set_cstr(NODE_MEM(node), &node->as.link.url, url);
+    return 1;
+  default:
+    break;
+  }
+
+  return 0;
+}
+
+const char *cmark_node_get_title(cmark_node *node) {
+  if (node == NULL) {
+    return NULL;
+  }
+
+  switch (node->type) {
+  case CMARK_NODE_LINK:
+  case CMARK_NODE_IMAGE:
+    return cmark_chunk_to_cstr(NODE_MEM(node), &node->as.link.title);
+  default:
+    break;
+  }
+
+  return NULL;
+}
+
+int cmark_node_set_title(cmark_node *node, const char *title) {
+  if (node == NULL) {
+    return 0;
+  }
+
+  switch (node->type) {
+  case CMARK_NODE_LINK:
+  case CMARK_NODE_IMAGE:
+    cmark_chunk_set_cstr(NODE_MEM(node), &node->as.link.title, title);
+    return 1;
+  default:
+    break;
+  }
+
+  return 0;
+}
+
+const char *cmark_node_get_on_enter(cmark_node *node) {
+  if (node == NULL) {
+    return NULL;
+  }
+
+  switch (node->type) {
+  case CMARK_NODE_CUSTOM_INLINE:
+  case CMARK_NODE_CUSTOM_BLOCK:
+    return cmark_chunk_to_cstr(NODE_MEM(node), &node->as.custom.on_enter);
+  default:
+    break;
+  }
+
+  return NULL;
+}
+
+int cmark_node_set_on_enter(cmark_node *node, const char *on_enter) {
+  if (node == NULL) {
+    return 0;
+  }
+
+  switch (node->type) {
+  case CMARK_NODE_CUSTOM_INLINE:
+  case CMARK_NODE_CUSTOM_BLOCK:
+    cmark_chunk_set_cstr(NODE_MEM(node), &node->as.custom.on_enter, on_enter);
+    return 1;
+  default:
+    break;
+  }
+
+  return 0;
+}
+
+const char *cmark_node_get_on_exit(cmark_node *node) {
+  if (node == NULL) {
+    return NULL;
+  }
+
+  switch (node->type) {
+  case CMARK_NODE_CUSTOM_INLINE:
+  case CMARK_NODE_CUSTOM_BLOCK:
+    return cmark_chunk_to_cstr(NODE_MEM(node), &node->as.custom.on_exit);
+  default:
+    break;
+  }
+
+  return NULL;
+}
+
+int cmark_node_set_on_exit(cmark_node *node, const char *on_exit) {
+  if (node == NULL) {
+    return 0;
+  }
+
+  switch (node->type) {
+  case CMARK_NODE_CUSTOM_INLINE:
+  case CMARK_NODE_CUSTOM_BLOCK:
+    cmark_chunk_set_cstr(NODE_MEM(node), &node->as.custom.on_exit, on_exit);
+    return 1;
+  default:
+    break;
+  }
+
+  return 0;
+}
+
+cmark_syntax_extension *cmark_node_get_syntax_extension(cmark_node *node) {
+  if (node == NULL) {
+    return NULL;
+  }
+
+  return node->extension;
+}
+
+int cmark_node_set_syntax_extension(cmark_node *node, cmark_syntax_extension *extension) {
+  if (node == NULL) {
+    return 0;
+  }
+
+  node->extension = extension;
+  return 1;
+}
+
+int cmark_node_get_start_line(cmark_node *node) {
+  if (node == NULL) {
+    return 0;
+  }
+  return node->start_line;
+}
+
+int cmark_node_get_start_column(cmark_node *node) {
+  if (node == NULL) {
+    return 0;
+  }
+  return node->start_column;
+}
+
+int cmark_node_get_end_line(cmark_node *node) {
+  if (node == NULL) {
+    return 0;
+  }
+  return node->end_line;
+}
+
+int cmark_node_get_end_column(cmark_node *node) {
+  if (node == NULL) {
+    return 0;
+  }
+  return node->end_column;
+}
+
+// Unlink a node without adjusting its next, prev, and parent pointers.
+static void S_node_unlink(cmark_node *node) {
+  if (node == NULL) {
+    return;
+  }
+
+  if (node->prev) {
+    node->prev->next = node->next;
+  }
+  if (node->next) {
+    node->next->prev = node->prev;
+  }
+
+  // Adjust first_child and last_child of parent.
+  cmark_node *parent = node->parent;
+  if (parent) {
+    if (parent->first_child == node) {
+      parent->first_child = node->next;
+    }
+    if (parent->last_child == node) {
+      parent->last_child = node->prev;
+    }
+  }
+}
+
+void cmark_node_unlink(cmark_node *node) {
+  S_node_unlink(node);
+
+  node->next = NULL;
+  node->prev = NULL;
+  node->parent = NULL;
+}
+
+int cmark_node_insert_before(cmark_node *node, cmark_node *sibling) {
+  if (node == NULL || sibling == NULL) {
+    return 0;
+  }
+
+  if (!node->parent || !S_can_contain(node->parent, sibling)) {
+    return 0;
+  }
+
+  S_node_unlink(sibling);
+
+  cmark_node *old_prev = node->prev;
+
+  // Insert 'sibling' between 'old_prev' and 'node'.
+  if (old_prev) {
+    old_prev->next = sibling;
+  }
+  sibling->prev = old_prev;
+  sibling->next = node;
+  node->prev = sibling;
+
+  // Set new parent.
+  cmark_node *parent = node->parent;
+  sibling->parent = parent;
+
+  // Adjust first_child of parent if inserted as first child.
+  if (parent && !old_prev) {
+    parent->first_child = sibling;
+  }
+
+  return 1;
+}
+
+int cmark_node_insert_after(cmark_node *node, cmark_node *sibling) {
+  if (node == NULL || sibling == NULL) {
+    return 0;
+  }
+
+  if (!node->parent || !S_can_contain(node->parent, sibling)) {
+    return 0;
+  }
+
+  S_node_unlink(sibling);
+
+  cmark_node *old_next = node->next;
+
+  // Insert 'sibling' between 'node' and 'old_next'.
+  if (old_next) {
+    old_next->prev = sibling;
+  }
+  sibling->next = old_next;
+  sibling->prev = node;
+  node->next = sibling;
+
+  // Set new parent.
+  cmark_node *parent = node->parent;
+  sibling->parent = parent;
+
+  // Adjust last_child of parent if inserted as last child.
+  if (parent && !old_next) {
+    parent->last_child = sibling;
+  }
+
+  return 1;
+}
+
+int cmark_node_replace(cmark_node *oldnode, cmark_node *newnode) {
+  if (!cmark_node_insert_before(oldnode, newnode)) {
+    return 0;
+  }
+  cmark_node_unlink(oldnode);
+  return 1;
+}
+
+int cmark_node_prepend_child(cmark_node *node, cmark_node *child) {
+  if (!S_can_contain(node, child)) {
+    return 0;
+  }
+
+  S_node_unlink(child);
+
+  cmark_node *old_first_child = node->first_child;
+
+  child->next = old_first_child;
+  child->prev = NULL;
+  child->parent = node;
+  node->first_child = child;
+
+  if (old_first_child) {
+    old_first_child->prev = child;
+  } else {
+    // Also set last_child if node previously had no children.
+    node->last_child = child;
+  }
+
+  return 1;
+}
+
+int cmark_node_append_child(cmark_node *node, cmark_node *child) {
+  if (!S_can_contain(node, child)) {
+    return 0;
+  }
+
+  S_node_unlink(child);
+
+  cmark_node *old_last_child = node->last_child;
+
+  child->next = NULL;
+  child->prev = old_last_child;
+  child->parent = node;
+  node->last_child = child;
+
+  if (old_last_child) {
+    old_last_child->next = child;
+  } else {
+    // Also set first_child if node previously had no children.
+    node->first_child = child;
+  }
+
+  return 1;
+}
+
+static void S_print_error(FILE *out, cmark_node *node, const char *elem) {
+  if (out == NULL) {
+    return;
+  }
+  fprintf(out, "Invalid '%s' in node type %s at %d:%d\n", elem,
+          cmark_node_get_type_string(node), node->start_line,
+          node->start_column);
+}
+
+int cmark_node_check(cmark_node *node, FILE *out) {
+  cmark_node *cur;
+  int errors = 0;
+
+  if (!node) {
+    return 0;
+  }
+
+  cur = node;
+  for (;;) {
+    if (cur->first_child) {
+      if (cur->first_child->prev != NULL) {
+        S_print_error(out, cur->first_child, "prev");
+        cur->first_child->prev = NULL;
+        ++errors;
+      }
+      if (cur->first_child->parent != cur) {
+        S_print_error(out, cur->first_child, "parent");
+        cur->first_child->parent = cur;
+        ++errors;
+      }
+      cur = cur->first_child;
+      continue;
+    }
+
+  next_sibling:
+    if (cur == node) {
+      break;
+    }
+    if (cur->next) {
+      if (cur->next->prev != cur) {
+        S_print_error(out, cur->next, "prev");
+        cur->next->prev = cur;
+        ++errors;
+      }
+      if (cur->next->parent != cur->parent) {
+        S_print_error(out, cur->next, "parent");
+        cur->next->parent = cur->parent;
+        ++errors;
+      }
+      cur = cur->next;
+      continue;
+    }
+
+    if (cur->parent->last_child != cur) {
+      S_print_error(out, cur->parent, "last_child");
+      cur->parent->last_child = cur;
+      ++errors;
+    }
+    cur = cur->parent;
+    goto next_sibling;
+  }
+
+  return errors;
+}
diff --git a/Sources/libcmark_gfm/plaintext.c b/Sources/libcmark_gfm/plaintext.c
new file mode 100644
index 0000000..910adf4
--- /dev/null
+++ b/Sources/libcmark_gfm/plaintext.c
@@ -0,0 +1,213 @@
+#include "node.h"
+#include "syntax_extension.h"
+#include "render.h"
+
+#define OUT(s, wrap, escaping) renderer->out(renderer, node, s, wrap, escaping)
+#define LIT(s) renderer->out(renderer, node, s, false, LITERAL)
+#define CR() renderer->cr(renderer)
+#define BLANKLINE() renderer->blankline(renderer)
+#define LISTMARKER_SIZE 20
+
+// Functions to convert cmark_nodes to plain text strings.
+
+static CMARK_INLINE void outc(cmark_renderer *renderer, cmark_node *node, 
+                              cmark_escaping escape,
+                              int32_t c, unsigned char nextc) {
+  cmark_render_code_point(renderer, c);
+}
+
+// if node is a block node, returns node.
+// otherwise returns first block-level node that is an ancestor of node.
+// if there is no block-level ancestor, returns NULL.
+static cmark_node *get_containing_block(cmark_node *node) {
+  while (node) {
+    if (CMARK_NODE_BLOCK_P(node)) {
+      return node;
+    } else {
+      node = node->parent;
+    }
+  }
+  return NULL;
+}
+
+static int S_render_node(cmark_renderer *renderer, cmark_node *node,
+                         cmark_event_type ev_type, int options) {
+  cmark_node *tmp;
+  int list_number;
+  cmark_delim_type list_delim;
+  int i;
+  bool entering = (ev_type == CMARK_EVENT_ENTER);
+  char listmarker[LISTMARKER_SIZE];
+  bool first_in_list_item;
+  bufsize_t marker_width;
+  bool allow_wrap = renderer->width > 0 && !(CMARK_OPT_NOBREAKS & options) &&
+                    !(CMARK_OPT_HARDBREAKS & options);
+
+  // Don't adjust tight list status til we've started the list.
+  // Otherwise we loose the blank line between a paragraph and
+  // a following list.
+  if (!(node->type == CMARK_NODE_ITEM && node->prev == NULL && entering)) {
+    tmp = get_containing_block(node);
+    renderer->in_tight_list_item =
+        tmp && // tmp might be NULL if there is no containing block
+        ((tmp->type == CMARK_NODE_ITEM &&
+          cmark_node_get_list_tight(tmp->parent)) ||
+         (tmp && tmp->parent && tmp->parent->type == CMARK_NODE_ITEM &&
+          cmark_node_get_list_tight(tmp->parent->parent)));
+  }
+
+  if (node->extension && node->extension->plaintext_render_func) {
+    node->extension->plaintext_render_func(node->extension, renderer, node, ev_type, options);
+    return 1;
+  }
+
+  switch (node->type) {
+  case CMARK_NODE_DOCUMENT:
+    break;
+
+  case CMARK_NODE_BLOCK_QUOTE:
+    break;
+
+  case CMARK_NODE_LIST:
+    if (!entering && node->next && (node->next->type == CMARK_NODE_CODE_BLOCK ||
+                                    node->next->type == CMARK_NODE_LIST)) {
+      CR();
+    }
+    break;
+
+  case CMARK_NODE_ITEM:
+    if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {
+      marker_width = 4;
+    } else {
+      list_number = cmark_node_get_list_start(node->parent);
+      list_delim = cmark_node_get_list_delim(node->parent);
+      tmp = node;
+      while (tmp->prev) {
+        tmp = tmp->prev;
+        list_number += 1;
+      }
+      // we ensure a width of at least 4 so
+      // we get nice transition from single digits
+      // to double
+      snprintf(listmarker, LISTMARKER_SIZE, "%d%s%s", list_number,
+               list_delim == CMARK_PAREN_DELIM ? ")" : ".",
+               list_number < 10 ? "  " : " ");
+      marker_width = (bufsize_t)strlen(listmarker);
+    }
+    if (entering) {
+      if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {
+        LIT("  - ");
+        renderer->begin_content = true;
+      } else {
+        LIT(listmarker);
+        renderer->begin_content = true;
+      }
+      for (i = marker_width; i--;) {
+        cmark_strbuf_putc(renderer->prefix, ' ');
+      }
+    } else {
+      cmark_strbuf_truncate(renderer->prefix,
+                            renderer->prefix->size - marker_width);
+      CR();
+    }
+    break;
+
+  case CMARK_NODE_HEADING:
+    if (entering) {
+      renderer->begin_content = true;
+      renderer->no_linebreaks = true;
+    } else {
+      renderer->no_linebreaks = false;
+      BLANKLINE();
+    }
+    break;
+
+  case CMARK_NODE_CODE_BLOCK:
+    first_in_list_item = node->prev == NULL && node->parent &&
+                         node->parent->type == CMARK_NODE_ITEM;
+
+    if (!first_in_list_item) {
+      BLANKLINE();
+    }
+    OUT(cmark_node_get_literal(node), false, LITERAL);
+    BLANKLINE();
+    break;
+
+  case CMARK_NODE_HTML_BLOCK:
+    break;
+
+  case CMARK_NODE_CUSTOM_BLOCK:
+    break;
+
+  case CMARK_NODE_THEMATIC_BREAK:
+    BLANKLINE();
+    break;
+
+  case CMARK_NODE_PARAGRAPH:
+    if (!entering) {
+      BLANKLINE();
+    }
+    break;
+
+  case CMARK_NODE_TEXT:
+    OUT(cmark_node_get_literal(node), allow_wrap, NORMAL);
+    break;
+
+  case CMARK_NODE_LINEBREAK:
+    CR();
+    break;
+
+  case CMARK_NODE_SOFTBREAK:
+    if (CMARK_OPT_HARDBREAKS & options) {
+      CR();
+    } else if (!renderer->no_linebreaks && renderer->width == 0 &&
+               !(CMARK_OPT_HARDBREAKS & options) &&
+               !(CMARK_OPT_NOBREAKS & options)) {
+      CR();
+    } else {
+      OUT(" ", allow_wrap, LITERAL);
+    }
+    break;
+
+  case CMARK_NODE_CODE:
+    OUT(cmark_node_get_literal(node), allow_wrap, LITERAL);
+    break;
+
+  case CMARK_NODE_HTML_INLINE:
+    break;
+
+  case CMARK_NODE_CUSTOM_INLINE:
+    break;
+
+  case CMARK_NODE_STRONG:
+    break;
+
+  case CMARK_NODE_EMPH:
+    break;
+
+  case CMARK_NODE_LINK:
+    break;
+
+  case CMARK_NODE_IMAGE:
+    break;
+
+  default:
+    assert(false);
+    break;
+  }
+
+  return 1;
+}
+
+char *cmark_render_plaintext(cmark_node *root, int options, int width) {
+  return cmark_render_plaintext_with_mem(root, options, width, cmark_node_mem(root));
+}
+
+char *cmark_render_plaintext_with_mem(cmark_node *root, int options, int width, cmark_mem *mem) {
+  if (options & CMARK_OPT_HARDBREAKS) {
+    // disable breaking on width, since it has
+    // a different meaning with OPT_HARDBREAKS
+    width = 0;
+  }
+  return cmark_render(mem, root, options, width, outc, S_render_node);
+}
diff --git a/Sources/libcmark_gfm/plugin.c b/Sources/libcmark_gfm/plugin.c
new file mode 100644
index 0000000..3992fe1
--- /dev/null
+++ b/Sources/libcmark_gfm/plugin.c
@@ -0,0 +1,36 @@
+#include 
+
+#include "plugin.h"
+
+extern cmark_mem CMARK_DEFAULT_MEM_ALLOCATOR;
+
+int cmark_plugin_register_syntax_extension(cmark_plugin    * plugin,
+                                        cmark_syntax_extension * extension) {
+  plugin->syntax_extensions = cmark_llist_append(&CMARK_DEFAULT_MEM_ALLOCATOR, plugin->syntax_extensions, extension);
+  return 1;
+}
+
+cmark_plugin *
+cmark_plugin_new(void) {
+  cmark_plugin *res = (cmark_plugin *) CMARK_DEFAULT_MEM_ALLOCATOR.calloc(1, sizeof(cmark_plugin));
+
+  res->syntax_extensions = NULL;
+
+  return res;
+}
+
+void
+cmark_plugin_free(cmark_plugin *plugin) {
+  cmark_llist_free_full(&CMARK_DEFAULT_MEM_ALLOCATOR,
+                        plugin->syntax_extensions,
+                        (cmark_free_func) cmark_syntax_extension_free);
+  CMARK_DEFAULT_MEM_ALLOCATOR.free(plugin);
+}
+
+cmark_llist *
+cmark_plugin_steal_syntax_extensions(cmark_plugin *plugin) {
+  cmark_llist *res = plugin->syntax_extensions;
+
+  plugin->syntax_extensions = NULL;
+  return res;
+}
diff --git a/Sources/libcmark_gfm/references.c b/Sources/libcmark_gfm/references.c
new file mode 100644
index 0000000..2cd4b44
--- /dev/null
+++ b/Sources/libcmark_gfm/references.c
@@ -0,0 +1,42 @@
+#include "cmark.h"
+#include "parser.h"
+#include "references.h"
+#include "inlines.h"
+#include "chunk.h"
+
+static void reference_free(cmark_map *map, cmark_map_entry *_ref) {
+  cmark_reference *ref = (cmark_reference *)_ref;
+  cmark_mem *mem = map->mem;
+  if (ref != NULL) {
+    mem->free(ref->entry.label);
+    cmark_chunk_free(mem, &ref->url);
+    cmark_chunk_free(mem, &ref->title);
+    mem->free(ref);
+  }
+}
+
+void cmark_reference_create(cmark_map *map, cmark_chunk *label,
+                            cmark_chunk *url, cmark_chunk *title) {
+  cmark_reference *ref;
+  unsigned char *reflabel = normalize_map_label(map->mem, label);
+
+  /* empty reference name, or composed from only whitespace */
+  if (reflabel == NULL)
+    return;
+
+  assert(map->sorted == NULL);
+
+  ref = (cmark_reference *)map->mem->calloc(1, sizeof(*ref));
+  ref->entry.label = reflabel;
+  ref->url = cmark_clean_url(map->mem, url);
+  ref->title = cmark_clean_title(map->mem, title);
+  ref->entry.age = map->size;
+  ref->entry.next = map->refs;
+
+  map->refs = (cmark_map_entry *)ref;
+  map->size++;
+}
+
+cmark_map *cmark_reference_map_new(cmark_mem *mem) {
+  return cmark_map_new(mem, reference_free);
+}
diff --git a/Sources/libcmark_gfm/registry.c b/Sources/libcmark_gfm/registry.c
new file mode 100644
index 0000000..3ff01f2
--- /dev/null
+++ b/Sources/libcmark_gfm/registry.c
@@ -0,0 +1,63 @@
+#include 
+#include 
+#include 
+
+#include "config.h"
+#include "cmark.h"
+#include "syntax_extension.h"
+#include "registry.h"
+#include "plugin.h"
+
+extern cmark_mem CMARK_DEFAULT_MEM_ALLOCATOR;
+
+static cmark_llist *syntax_extensions = NULL;
+
+void cmark_register_plugin(cmark_plugin_init_func reg_fn) {
+  cmark_plugin *plugin = cmark_plugin_new();
+
+  if (!reg_fn(plugin)) {
+    cmark_plugin_free(plugin);
+    return;
+  }
+
+  cmark_llist *syntax_extensions_list = cmark_plugin_steal_syntax_extensions(plugin),
+              *it;
+
+  for (it = syntax_extensions_list; it; it = it->next) {
+    syntax_extensions = cmark_llist_append(&CMARK_DEFAULT_MEM_ALLOCATOR, syntax_extensions, it->data);
+  }
+
+  cmark_llist_free(&CMARK_DEFAULT_MEM_ALLOCATOR, syntax_extensions_list);
+  cmark_plugin_free(plugin);
+}
+
+void cmark_release_plugins(void) {
+  if (syntax_extensions) {
+    cmark_llist_free_full(
+        &CMARK_DEFAULT_MEM_ALLOCATOR,
+        syntax_extensions,
+        (cmark_free_func) cmark_syntax_extension_free);
+    syntax_extensions = NULL;
+  }
+}
+
+cmark_llist *cmark_list_syntax_extensions(cmark_mem *mem) {
+  cmark_llist *it;
+  cmark_llist *res = NULL;
+
+  for (it = syntax_extensions; it; it = it->next) {
+    res = cmark_llist_append(mem, res, it->data);
+  }
+  return res;
+}
+
+cmark_syntax_extension *cmark_find_syntax_extension(const char *name) {
+  cmark_llist *tmp;
+
+  for (tmp = syntax_extensions; tmp; tmp = tmp->next) {
+    cmark_syntax_extension *ext = (cmark_syntax_extension *) tmp->data;
+    if (!strcmp(ext->name, name))
+      return ext;
+  }
+  return NULL;
+}
diff --git a/Sources/libcmark_gfm/render.c b/Sources/libcmark_gfm/render.c
new file mode 100644
index 0000000..7f09024
--- /dev/null
+++ b/Sources/libcmark_gfm/render.c
@@ -0,0 +1,202 @@
+#include 
+#include "buffer.h"
+#include "chunk.h"
+#include "cmark.h"
+#include "utf8.h"
+#include "render.h"
+#include "node.h"
+#include "syntax_extension.h"
+
+static CMARK_INLINE void S_cr(cmark_renderer *renderer) {
+  if (renderer->need_cr < 1) {
+    renderer->need_cr = 1;
+  }
+}
+
+static CMARK_INLINE void S_blankline(cmark_renderer *renderer) {
+  if (renderer->need_cr < 2) {
+    renderer->need_cr = 2;
+  }
+}
+
+static void S_out(cmark_renderer *renderer, cmark_node *node,
+                  const char *source, bool wrap,
+                  cmark_escaping escape) {
+  int length = (int)strlen(source);
+  unsigned char nextc;
+  int32_t c;
+  int i = 0;
+  int last_nonspace;
+  int len;
+  cmark_chunk remainder = cmark_chunk_literal("");
+  int k = renderer->buffer->size - 1;
+
+  cmark_syntax_extension *ext = NULL;
+  cmark_node *n = node;
+  while (n && !ext) {
+    ext = n->extension;
+    if (!ext)
+      n = n->parent;
+  }
+  if (ext && !ext->commonmark_escape_func)
+    ext = NULL;
+
+  wrap = wrap && !renderer->no_linebreaks;
+
+  if (renderer->in_tight_list_item && renderer->need_cr > 1) {
+    renderer->need_cr = 1;
+  }
+  while (renderer->need_cr) {
+    if (k < 0 || renderer->buffer->ptr[k] == '\n') {
+      k -= 1;
+    } else {
+      cmark_strbuf_putc(renderer->buffer, '\n');
+      if (renderer->need_cr > 1) {
+        cmark_strbuf_put(renderer->buffer, renderer->prefix->ptr,
+                         renderer->prefix->size);
+      }
+    }
+    renderer->column = 0;
+    renderer->begin_line = true;
+    renderer->begin_content = true;
+    renderer->need_cr -= 1;
+  }
+
+  while (i < length) {
+    if (renderer->begin_line) {
+      cmark_strbuf_put(renderer->buffer, renderer->prefix->ptr,
+                       renderer->prefix->size);
+      // note: this assumes prefix is ascii:
+      renderer->column = renderer->prefix->size;
+    }
+
+    len = cmark_utf8proc_iterate((const uint8_t *)source + i, length - i, &c);
+    if (len == -1) { // error condition
+      return;        // return without rendering rest of string
+    }
+
+    if (ext && ext->commonmark_escape_func(ext, node, c))
+      cmark_strbuf_putc(renderer->buffer, '\\');
+
+    nextc = source[i + len];
+    if (c == 32 && wrap) {
+      if (!renderer->begin_line) {
+        last_nonspace = renderer->buffer->size;
+        cmark_strbuf_putc(renderer->buffer, ' ');
+        renderer->column += 1;
+        renderer->begin_line = false;
+        renderer->begin_content = false;
+        // skip following spaces
+        while (source[i + 1] == ' ') {
+          i++;
+        }
+        // We don't allow breaks that make a digit the first character
+        // because this causes problems with commonmark output.
+        if (!cmark_isdigit(source[i + 1])) {
+          renderer->last_breakable = last_nonspace;
+        }
+      }
+
+    } else if (c == 10) {
+      cmark_strbuf_putc(renderer->buffer, '\n');
+      renderer->column = 0;
+      renderer->begin_line = true;
+      renderer->begin_content = true;
+      renderer->last_breakable = 0;
+    } else if (escape == LITERAL) {
+      cmark_render_code_point(renderer, c);
+      renderer->begin_line = false;
+      // we don't set 'begin_content' to false til we've
+      // finished parsing a digit.  Reason:  in commonmark
+      // we need to escape a potential list marker after
+      // a digit:
+      renderer->begin_content =
+          renderer->begin_content && cmark_isdigit((char)c) == 1;
+    } else {
+      (renderer->outc)(renderer, node, escape, c, nextc);
+      renderer->begin_line = false;
+      renderer->begin_content =
+          renderer->begin_content && cmark_isdigit((char)c) == 1;
+    }
+
+    // If adding the character went beyond width, look for an
+    // earlier place where the line could be broken:
+    if (renderer->width > 0 && renderer->column > renderer->width &&
+        !renderer->begin_line && renderer->last_breakable > 0) {
+
+      // copy from last_breakable to remainder
+      cmark_chunk_set_cstr(renderer->mem, &remainder,
+                           (char *)renderer->buffer->ptr +
+                               renderer->last_breakable + 1);
+      // truncate at last_breakable
+      cmark_strbuf_truncate(renderer->buffer, renderer->last_breakable);
+      // add newline, prefix, and remainder
+      cmark_strbuf_putc(renderer->buffer, '\n');
+      cmark_strbuf_put(renderer->buffer, renderer->prefix->ptr,
+                       renderer->prefix->size);
+      cmark_strbuf_put(renderer->buffer, remainder.data, remainder.len);
+      renderer->column = renderer->prefix->size + remainder.len;
+      cmark_chunk_free(renderer->mem, &remainder);
+      renderer->last_breakable = 0;
+      renderer->begin_line = false;
+      renderer->begin_content = false;
+    }
+
+    i += len;
+  }
+}
+
+// Assumes no newlines, assumes ascii content:
+void cmark_render_ascii(cmark_renderer *renderer, const char *s) {
+  int origsize = renderer->buffer->size;
+  cmark_strbuf_puts(renderer->buffer, s);
+  renderer->column += renderer->buffer->size - origsize;
+}
+
+void cmark_render_code_point(cmark_renderer *renderer, uint32_t c) {
+  cmark_utf8proc_encode_char(c, renderer->buffer);
+  renderer->column += 1;
+}
+
+char *cmark_render(cmark_mem *mem, cmark_node *root, int options, int width,
+                   void (*outc)(cmark_renderer *, cmark_node *,
+                                cmark_escaping, int32_t,
+                                unsigned char),
+                   int (*render_node)(cmark_renderer *renderer,
+                                      cmark_node *node,
+                                      cmark_event_type ev_type, int options)) {
+  cmark_strbuf pref = CMARK_BUF_INIT(mem);
+  cmark_strbuf buf = CMARK_BUF_INIT(mem);
+  cmark_node *cur;
+  cmark_event_type ev_type;
+  char *result;
+  cmark_iter *iter = cmark_iter_new(root);
+
+  cmark_renderer renderer = {mem,   &buf, &pref, 0,           width,
+                             0,     0,    true,  true,        false,
+                             false, outc, S_cr,  S_blankline, S_out,
+                             0};
+
+  while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {
+    cur = cmark_iter_get_node(iter);
+    if (!render_node(&renderer, cur, ev_type, options)) {
+      // a false value causes us to skip processing
+      // the node's contents.  this is used for
+      // autolinks.
+      cmark_iter_reset(iter, cur, CMARK_EVENT_EXIT);
+    }
+  }
+
+  // ensure final newline
+  if (renderer.buffer->ptr[renderer.buffer->size - 1] != '\n') {
+    cmark_strbuf_putc(renderer.buffer, '\n');
+  }
+
+  result = (char *)cmark_strbuf_detach(renderer.buffer);
+
+  cmark_iter_free(iter);
+  cmark_strbuf_free(renderer.prefix);
+  cmark_strbuf_free(renderer.buffer);
+
+  return result;
+}
diff --git a/Sources/libcmark_gfm/scanners.c b/Sources/libcmark_gfm/scanners.c
new file mode 100644
index 0000000..4c56995
--- /dev/null
+++ b/Sources/libcmark_gfm/scanners.c
@@ -0,0 +1,18195 @@
+/* Generated by re2c 0.15.3 */
+#include 
+#include "chunk.h"
+#include "scanners.h"
+
+bufsize_t _scan_at(bufsize_t (*scanner)(const unsigned char *), cmark_chunk *c,
+                   bufsize_t offset) {
+  bufsize_t res;
+  unsigned char *ptr = (unsigned char *)c->data;
+
+  if (ptr == NULL || offset > c->len) {
+    return 0;
+  } else {
+    unsigned char lim = ptr[c->len];
+
+    ptr[c->len] = '\0';
+    res = scanner(ptr + offset);
+    ptr[c->len] = lim;
+  }
+
+  return res;
+}
+
+// Try to match a scheme including colon.
+bufsize_t _scan_scheme(const unsigned char *p) {
+  const unsigned char *marker = NULL;
+  const unsigned char *start = p;
+
+  {
+    unsigned char yych;
+    yych = *p;
+    if (yych <= '@')
+      goto yy2;
+    if (yych <= 'Z')
+      goto yy4;
+    if (yych <= '`')
+      goto yy2;
+    if (yych <= 'z')
+      goto yy4;
+  yy2:
+    ++p;
+  yy3 : { return 0; }
+  yy4:
+    yych = *(marker = ++p);
+    if (yych <= '/') {
+      if (yych <= '+') {
+        if (yych <= '*')
+          goto yy3;
+      } else {
+        if (yych <= ',')
+          goto yy3;
+        if (yych >= '/')
+          goto yy3;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '9')
+          goto yy5;
+        if (yych <= '@')
+          goto yy3;
+      } else {
+        if (yych <= '`')
+          goto yy3;
+        if (yych >= '{')
+          goto yy3;
+      }
+    }
+  yy5:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych == '+')
+          goto yy9;
+      } else {
+        if (yych != '/')
+          goto yy9;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych >= 'A')
+          goto yy9;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych <= 'z')
+          goto yy9;
+      }
+    }
+  yy6:
+    p = marker;
+    goto yy3;
+  yy7:
+    ++p;
+    { return (bufsize_t)(p - start); }
+  yy9:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy6;
+      } else {
+        if (yych == '/')
+          goto yy6;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych <= '@')
+          goto yy6;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych >= '{')
+          goto yy6;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy6;
+      } else {
+        if (yych == '/')
+          goto yy6;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych <= '@')
+          goto yy6;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych >= '{')
+          goto yy6;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy6;
+      } else {
+        if (yych == '/')
+          goto yy6;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych <= '@')
+          goto yy6;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych >= '{')
+          goto yy6;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy6;
+      } else {
+        if (yych == '/')
+          goto yy6;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych <= '@')
+          goto yy6;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych >= '{')
+          goto yy6;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy6;
+      } else {
+        if (yych == '/')
+          goto yy6;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych <= '@')
+          goto yy6;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych >= '{')
+          goto yy6;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy6;
+      } else {
+        if (yych == '/')
+          goto yy6;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych <= '@')
+          goto yy6;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych >= '{')
+          goto yy6;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy6;
+      } else {
+        if (yych == '/')
+          goto yy6;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych <= '@')
+          goto yy6;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych >= '{')
+          goto yy6;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy6;
+      } else {
+        if (yych == '/')
+          goto yy6;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych <= '@')
+          goto yy6;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych >= '{')
+          goto yy6;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy6;
+      } else {
+        if (yych == '/')
+          goto yy6;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych <= '@')
+          goto yy6;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych >= '{')
+          goto yy6;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy6;
+      } else {
+        if (yych == '/')
+          goto yy6;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych <= '@')
+          goto yy6;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych >= '{')
+          goto yy6;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy6;
+      } else {
+        if (yych == '/')
+          goto yy6;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych <= '@')
+          goto yy6;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych >= '{')
+          goto yy6;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy6;
+      } else {
+        if (yych == '/')
+          goto yy6;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych <= '@')
+          goto yy6;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych >= '{')
+          goto yy6;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy6;
+      } else {
+        if (yych == '/')
+          goto yy6;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych <= '@')
+          goto yy6;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych >= '{')
+          goto yy6;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy6;
+      } else {
+        if (yych == '/')
+          goto yy6;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych <= '@')
+          goto yy6;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych >= '{')
+          goto yy6;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy6;
+      } else {
+        if (yych == '/')
+          goto yy6;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych <= '@')
+          goto yy6;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych >= '{')
+          goto yy6;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy6;
+      } else {
+        if (yych == '/')
+          goto yy6;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych <= '@')
+          goto yy6;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych >= '{')
+          goto yy6;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy6;
+      } else {
+        if (yych == '/')
+          goto yy6;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych <= '@')
+          goto yy6;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych >= '{')
+          goto yy6;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy6;
+      } else {
+        if (yych == '/')
+          goto yy6;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych <= '@')
+          goto yy6;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych >= '{')
+          goto yy6;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy6;
+      } else {
+        if (yych == '/')
+          goto yy6;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych <= '@')
+          goto yy6;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych >= '{')
+          goto yy6;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy6;
+      } else {
+        if (yych == '/')
+          goto yy6;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych <= '@')
+          goto yy6;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych >= '{')
+          goto yy6;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy6;
+      } else {
+        if (yych == '/')
+          goto yy6;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych <= '@')
+          goto yy6;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych >= '{')
+          goto yy6;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy6;
+      } else {
+        if (yych == '/')
+          goto yy6;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych <= '@')
+          goto yy6;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych >= '{')
+          goto yy6;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy6;
+      } else {
+        if (yych == '/')
+          goto yy6;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych <= '@')
+          goto yy6;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych >= '{')
+          goto yy6;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy6;
+      } else {
+        if (yych == '/')
+          goto yy6;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych <= '@')
+          goto yy6;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych >= '{')
+          goto yy6;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy6;
+      } else {
+        if (yych == '/')
+          goto yy6;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych <= '@')
+          goto yy6;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych >= '{')
+          goto yy6;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy6;
+      } else {
+        if (yych == '/')
+          goto yy6;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych <= '@')
+          goto yy6;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych >= '{')
+          goto yy6;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy6;
+      } else {
+        if (yych == '/')
+          goto yy6;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych <= '@')
+          goto yy6;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych >= '{')
+          goto yy6;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy6;
+      } else {
+        if (yych == '/')
+          goto yy6;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych <= '@')
+          goto yy6;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych >= '{')
+          goto yy6;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy6;
+      } else {
+        if (yych == '/')
+          goto yy6;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy7;
+        if (yych <= '@')
+          goto yy6;
+      } else {
+        if (yych <= '`')
+          goto yy6;
+        if (yych >= '{')
+          goto yy6;
+      }
+    }
+    ++p;
+    if ((yych = *p) == ':')
+      goto yy7;
+    goto yy6;
+  }
+}
+
+// Try to match URI autolink after first <, returning number of chars matched.
+bufsize_t _scan_autolink_uri(const unsigned char *p) {
+  const unsigned char *marker = NULL;
+  const unsigned char *start = p;
+
+  {
+    unsigned char yych;
+    static const unsigned char yybm[] = {
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   128, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 128, 128, 128, 0,   128, 0,   128, 128, 128, 128, 128, 128, 128,
+        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 128, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,
+    };
+    yych = *p;
+    if (yych <= '@')
+      goto yy41;
+    if (yych <= 'Z')
+      goto yy43;
+    if (yych <= '`')
+      goto yy41;
+    if (yych <= 'z')
+      goto yy43;
+  yy41:
+    ++p;
+  yy42 : { return 0; }
+  yy43:
+    yych = *(marker = ++p);
+    if (yych <= '/') {
+      if (yych <= '+') {
+        if (yych <= '*')
+          goto yy42;
+      } else {
+        if (yych <= ',')
+          goto yy42;
+        if (yych >= '/')
+          goto yy42;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '9')
+          goto yy44;
+        if (yych <= '@')
+          goto yy42;
+      } else {
+        if (yych <= '`')
+          goto yy42;
+        if (yych >= '{')
+          goto yy42;
+      }
+    }
+  yy44:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych == '+')
+          goto yy48;
+      } else {
+        if (yych != '/')
+          goto yy48;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych >= 'A')
+          goto yy48;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych <= 'z')
+          goto yy48;
+      }
+    }
+  yy45:
+    p = marker;
+    goto yy42;
+  yy46:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 128) {
+      goto yy46;
+    }
+    if (yych <= 0xEC) {
+      if (yych <= 0xC1) {
+        if (yych <= '<')
+          goto yy45;
+        if (yych <= '>')
+          goto yy85;
+        goto yy45;
+      } else {
+        if (yych <= 0xDF)
+          goto yy78;
+        if (yych <= 0xE0)
+          goto yy79;
+        goto yy80;
+      }
+    } else {
+      if (yych <= 0xF0) {
+        if (yych <= 0xED)
+          goto yy84;
+        if (yych <= 0xEF)
+          goto yy80;
+        goto yy81;
+      } else {
+        if (yych <= 0xF3)
+          goto yy82;
+        if (yych <= 0xF4)
+          goto yy83;
+        goto yy45;
+      }
+    }
+  yy48:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy45;
+      } else {
+        if (yych == '/')
+          goto yy45;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych <= '@')
+          goto yy45;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych >= '{')
+          goto yy45;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy45;
+      } else {
+        if (yych == '/')
+          goto yy45;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych <= '@')
+          goto yy45;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych >= '{')
+          goto yy45;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy45;
+      } else {
+        if (yych == '/')
+          goto yy45;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych <= '@')
+          goto yy45;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych >= '{')
+          goto yy45;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy45;
+      } else {
+        if (yych == '/')
+          goto yy45;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych <= '@')
+          goto yy45;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych >= '{')
+          goto yy45;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy45;
+      } else {
+        if (yych == '/')
+          goto yy45;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych <= '@')
+          goto yy45;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych >= '{')
+          goto yy45;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy45;
+      } else {
+        if (yych == '/')
+          goto yy45;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych <= '@')
+          goto yy45;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych >= '{')
+          goto yy45;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy45;
+      } else {
+        if (yych == '/')
+          goto yy45;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych <= '@')
+          goto yy45;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych >= '{')
+          goto yy45;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy45;
+      } else {
+        if (yych == '/')
+          goto yy45;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych <= '@')
+          goto yy45;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych >= '{')
+          goto yy45;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy45;
+      } else {
+        if (yych == '/')
+          goto yy45;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych <= '@')
+          goto yy45;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych >= '{')
+          goto yy45;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy45;
+      } else {
+        if (yych == '/')
+          goto yy45;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych <= '@')
+          goto yy45;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych >= '{')
+          goto yy45;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy45;
+      } else {
+        if (yych == '/')
+          goto yy45;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych <= '@')
+          goto yy45;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych >= '{')
+          goto yy45;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy45;
+      } else {
+        if (yych == '/')
+          goto yy45;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych <= '@')
+          goto yy45;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych >= '{')
+          goto yy45;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy45;
+      } else {
+        if (yych == '/')
+          goto yy45;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych <= '@')
+          goto yy45;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych >= '{')
+          goto yy45;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy45;
+      } else {
+        if (yych == '/')
+          goto yy45;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych <= '@')
+          goto yy45;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych >= '{')
+          goto yy45;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy45;
+      } else {
+        if (yych == '/')
+          goto yy45;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych <= '@')
+          goto yy45;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych >= '{')
+          goto yy45;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy45;
+      } else {
+        if (yych == '/')
+          goto yy45;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych <= '@')
+          goto yy45;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych >= '{')
+          goto yy45;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy45;
+      } else {
+        if (yych == '/')
+          goto yy45;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych <= '@')
+          goto yy45;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych >= '{')
+          goto yy45;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy45;
+      } else {
+        if (yych == '/')
+          goto yy45;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych <= '@')
+          goto yy45;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych >= '{')
+          goto yy45;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy45;
+      } else {
+        if (yych == '/')
+          goto yy45;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych <= '@')
+          goto yy45;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych >= '{')
+          goto yy45;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy45;
+      } else {
+        if (yych == '/')
+          goto yy45;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych <= '@')
+          goto yy45;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych >= '{')
+          goto yy45;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy45;
+      } else {
+        if (yych == '/')
+          goto yy45;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych <= '@')
+          goto yy45;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych >= '{')
+          goto yy45;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy45;
+      } else {
+        if (yych == '/')
+          goto yy45;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych <= '@')
+          goto yy45;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych >= '{')
+          goto yy45;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy45;
+      } else {
+        if (yych == '/')
+          goto yy45;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych <= '@')
+          goto yy45;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych >= '{')
+          goto yy45;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy45;
+      } else {
+        if (yych == '/')
+          goto yy45;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych <= '@')
+          goto yy45;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych >= '{')
+          goto yy45;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy45;
+      } else {
+        if (yych == '/')
+          goto yy45;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych <= '@')
+          goto yy45;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych >= '{')
+          goto yy45;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy45;
+      } else {
+        if (yych == '/')
+          goto yy45;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych <= '@')
+          goto yy45;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych >= '{')
+          goto yy45;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy45;
+      } else {
+        if (yych == '/')
+          goto yy45;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych <= '@')
+          goto yy45;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych >= '{')
+          goto yy45;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy45;
+      } else {
+        if (yych == '/')
+          goto yy45;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych <= '@')
+          goto yy45;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych >= '{')
+          goto yy45;
+      }
+    }
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych <= ',') {
+        if (yych != '+')
+          goto yy45;
+      } else {
+        if (yych == '/')
+          goto yy45;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= ':')
+          goto yy46;
+        if (yych <= '@')
+          goto yy45;
+      } else {
+        if (yych <= '`')
+          goto yy45;
+        if (yych >= '{')
+          goto yy45;
+      }
+    }
+    yych = *++p;
+    if (yych == ':')
+      goto yy46;
+    goto yy45;
+  yy78:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy45;
+    if (yych <= 0xBF)
+      goto yy46;
+    goto yy45;
+  yy79:
+    ++p;
+    yych = *p;
+    if (yych <= 0x9F)
+      goto yy45;
+    if (yych <= 0xBF)
+      goto yy78;
+    goto yy45;
+  yy80:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy45;
+    if (yych <= 0xBF)
+      goto yy78;
+    goto yy45;
+  yy81:
+    ++p;
+    yych = *p;
+    if (yych <= 0x8F)
+      goto yy45;
+    if (yych <= 0xBF)
+      goto yy80;
+    goto yy45;
+  yy82:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy45;
+    if (yych <= 0xBF)
+      goto yy80;
+    goto yy45;
+  yy83:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy45;
+    if (yych <= 0x8F)
+      goto yy80;
+    goto yy45;
+  yy84:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy45;
+    if (yych <= 0x9F)
+      goto yy78;
+    goto yy45;
+  yy85:
+    ++p;
+    { return (bufsize_t)(p - start); }
+  }
+}
+
+// Try to match email autolink after first <, returning num of chars matched.
+bufsize_t _scan_autolink_email(const unsigned char *p) {
+  const unsigned char *marker = NULL;
+  const unsigned char *start = p;
+
+  {
+    unsigned char yych;
+    static const unsigned char yybm[] = {
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   128, 0,   128, 128, 128, 128, 128, 0,   0,
+        128, 128, 0,   128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 128, 0,   0,   0,   128, 0,   128, 0,   128, 128, 128, 128, 128,
+        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 128, 128, 128, 128, 128, 128, 0,   0,   0,   128, 128, 128, 128,
+        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,
+    };
+    yych = *p;
+    if (yych <= '9') {
+      if (yych <= '\'') {
+        if (yych == '!')
+          goto yy91;
+        if (yych >= '#')
+          goto yy91;
+      } else {
+        if (yych <= ')')
+          goto yy89;
+        if (yych != ',')
+          goto yy91;
+      }
+    } else {
+      if (yych <= '?') {
+        if (yych == '=')
+          goto yy91;
+        if (yych >= '?')
+          goto yy91;
+      } else {
+        if (yych <= 'Z') {
+          if (yych >= 'A')
+            goto yy91;
+        } else {
+          if (yych <= ']')
+            goto yy89;
+          if (yych <= '~')
+            goto yy91;
+        }
+      }
+    }
+  yy89:
+    ++p;
+  yy90 : { return 0; }
+  yy91:
+    yych = *(marker = ++p);
+    if (yych <= ',') {
+      if (yych <= '"') {
+        if (yych == '!')
+          goto yy95;
+        goto yy90;
+      } else {
+        if (yych <= '\'')
+          goto yy95;
+        if (yych <= ')')
+          goto yy90;
+        if (yych <= '+')
+          goto yy95;
+        goto yy90;
+      }
+    } else {
+      if (yych <= '>') {
+        if (yych <= '9')
+          goto yy95;
+        if (yych == '=')
+          goto yy95;
+        goto yy90;
+      } else {
+        if (yych <= 'Z')
+          goto yy95;
+        if (yych <= ']')
+          goto yy90;
+        if (yych <= '~')
+          goto yy95;
+        goto yy90;
+      }
+    }
+  yy92:
+    yych = *++p;
+    if (yych <= '@') {
+      if (yych <= '/')
+        goto yy93;
+      if (yych <= '9')
+        goto yy96;
+    } else {
+      if (yych <= 'Z')
+        goto yy96;
+      if (yych <= '`')
+        goto yy93;
+      if (yych <= 'z')
+        goto yy96;
+    }
+  yy93:
+    p = marker;
+    goto yy90;
+  yy94:
+    ++p;
+    yych = *p;
+  yy95:
+    if (yybm[0 + yych] & 128) {
+      goto yy94;
+    }
+    if (yych <= '>')
+      goto yy93;
+    if (yych <= '@')
+      goto yy92;
+    goto yy93;
+  yy96:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy98;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych >= ':')
+          goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy227;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy226;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy226;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy226;
+        goto yy93;
+      }
+    }
+  yy98:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy227;
+      if (yych <= '/')
+        goto yy93;
+      goto yy226;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+        goto yy226;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy226;
+        goto yy93;
+      }
+    }
+  yy99:
+    ++p;
+    yych = *p;
+    if (yych <= '@') {
+      if (yych <= '/')
+        goto yy93;
+      if (yych <= '9')
+        goto yy102;
+      goto yy93;
+    } else {
+      if (yych <= 'Z')
+        goto yy102;
+      if (yych <= '`')
+        goto yy93;
+      if (yych <= 'z')
+        goto yy102;
+      goto yy93;
+    }
+  yy100:
+    ++p;
+    { return (bufsize_t)(p - start); }
+  yy102:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy104;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych >= ':')
+          goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy106;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy105;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy105;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy105;
+        goto yy93;
+      }
+    }
+  yy104:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy106;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy105:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy108;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy107;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy107;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy107;
+        goto yy93;
+      }
+    }
+  yy106:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy108;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy107:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy110;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy109;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy109;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy109;
+        goto yy93;
+      }
+    }
+  yy108:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy110;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy109:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy112;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy111;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy111;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy111;
+        goto yy93;
+      }
+    }
+  yy110:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy112;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy111:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy114;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy113;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy113;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy113;
+        goto yy93;
+      }
+    }
+  yy112:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy114;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy113:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy116;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy115;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy115;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy115;
+        goto yy93;
+      }
+    }
+  yy114:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy116;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy115:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy118;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy117;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy117;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy117;
+        goto yy93;
+      }
+    }
+  yy116:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy118;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy117:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy120;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy119;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy119;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy119;
+        goto yy93;
+      }
+    }
+  yy118:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy120;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy119:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy122;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy121;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy121;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy121;
+        goto yy93;
+      }
+    }
+  yy120:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy122;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy121:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy124;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy123;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy123;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy123;
+        goto yy93;
+      }
+    }
+  yy122:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy124;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy123:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy126;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy125;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy125;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy125;
+        goto yy93;
+      }
+    }
+  yy124:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy126;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy125:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy128;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy127;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy127;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy127;
+        goto yy93;
+      }
+    }
+  yy126:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy128;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy127:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy130;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy129;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy129;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy129;
+        goto yy93;
+      }
+    }
+  yy128:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy130;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy129:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy132;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy131;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy131;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy131;
+        goto yy93;
+      }
+    }
+  yy130:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy132;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy131:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy134;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy133;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy133;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy133;
+        goto yy93;
+      }
+    }
+  yy132:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy134;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy133:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy136;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy135;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy135;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy135;
+        goto yy93;
+      }
+    }
+  yy134:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy136;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy135:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy138;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy137;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy137;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy137;
+        goto yy93;
+      }
+    }
+  yy136:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy138;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy137:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy140;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy139;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy139;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy139;
+        goto yy93;
+      }
+    }
+  yy138:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy140;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy139:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy142;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy141;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy141;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy141;
+        goto yy93;
+      }
+    }
+  yy140:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy142;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy141:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy144;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy143;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy143;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy143;
+        goto yy93;
+      }
+    }
+  yy142:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy144;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy143:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy146;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy145;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy145;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy145;
+        goto yy93;
+      }
+    }
+  yy144:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy146;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy145:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy148;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy147;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy147;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy147;
+        goto yy93;
+      }
+    }
+  yy146:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy148;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy147:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy150;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy149;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy149;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy149;
+        goto yy93;
+      }
+    }
+  yy148:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy150;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy149:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy152;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy151;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy151;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy151;
+        goto yy93;
+      }
+    }
+  yy150:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy152;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy151:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy154;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy153;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy153;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy153;
+        goto yy93;
+      }
+    }
+  yy152:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy154;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy153:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy156;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy155;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy155;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy155;
+        goto yy93;
+      }
+    }
+  yy154:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy156;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy155:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy158;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy157;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy157;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy157;
+        goto yy93;
+      }
+    }
+  yy156:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy158;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy157:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy160;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy159;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy159;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy159;
+        goto yy93;
+      }
+    }
+  yy158:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy160;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy159:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy162;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy161;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy161;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy161;
+        goto yy93;
+      }
+    }
+  yy160:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy162;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy161:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy164;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy163;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy163;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy163;
+        goto yy93;
+      }
+    }
+  yy162:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy164;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy163:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy166;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy165;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy165;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy165;
+        goto yy93;
+      }
+    }
+  yy164:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy166;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy165:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy168;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy167;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy167;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy167;
+        goto yy93;
+      }
+    }
+  yy166:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy168;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy167:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy170;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy169;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy169;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy169;
+        goto yy93;
+      }
+    }
+  yy168:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy170;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy169:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy172;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy171;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy171;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy171;
+        goto yy93;
+      }
+    }
+  yy170:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy172;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy171:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy174;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy173;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy173;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy173;
+        goto yy93;
+      }
+    }
+  yy172:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy174;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy173:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy176;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy175;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy175;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy175;
+        goto yy93;
+      }
+    }
+  yy174:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy176;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy175:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy178;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy177;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy177;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy177;
+        goto yy93;
+      }
+    }
+  yy176:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy178;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy177:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy180;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy179;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy179;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy179;
+        goto yy93;
+      }
+    }
+  yy178:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy180;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy179:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy182;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy181;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy181;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy181;
+        goto yy93;
+      }
+    }
+  yy180:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy182;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy181:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy184;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy183;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy183;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy183;
+        goto yy93;
+      }
+    }
+  yy182:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy184;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy183:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy186;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy185;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy185;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy185;
+        goto yy93;
+      }
+    }
+  yy184:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy186;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy185:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy188;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy187;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy187;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy187;
+        goto yy93;
+      }
+    }
+  yy186:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy188;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy187:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy190;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy189;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy189;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy189;
+        goto yy93;
+      }
+    }
+  yy188:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy190;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy189:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy192;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy191;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy191;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy191;
+        goto yy93;
+      }
+    }
+  yy190:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy192;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy191:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy194;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy193;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy193;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy193;
+        goto yy93;
+      }
+    }
+  yy192:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy194;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy193:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy196;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy195;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy195;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy195;
+        goto yy93;
+      }
+    }
+  yy194:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy196;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy195:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy198;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy197;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy197;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy197;
+        goto yy93;
+      }
+    }
+  yy196:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy198;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy197:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy200;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy199;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy199;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy199;
+        goto yy93;
+      }
+    }
+  yy198:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy200;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy199:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy202;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy201;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy201;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy201;
+        goto yy93;
+      }
+    }
+  yy200:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy202;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy201:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy204;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy203;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy203;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy203;
+        goto yy93;
+      }
+    }
+  yy202:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy204;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy203:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy206;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy205;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy205;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy205;
+        goto yy93;
+      }
+    }
+  yy204:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy206;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy205:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy208;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy207;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy207;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy207;
+        goto yy93;
+      }
+    }
+  yy206:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy208;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy207:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy210;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy209;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy209;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy209;
+        goto yy93;
+      }
+    }
+  yy208:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy210;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy209:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy212;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy211;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy211;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy211;
+        goto yy93;
+      }
+    }
+  yy210:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy212;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy211:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy214;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy213;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy213;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy213;
+        goto yy93;
+      }
+    }
+  yy212:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy214;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy213:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy216;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy215;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy215;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy215;
+        goto yy93;
+      }
+    }
+  yy214:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy216;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy215:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy218;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy217;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy217;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy217;
+        goto yy93;
+      }
+    }
+  yy216:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy218;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy217:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy220;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy219;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy219;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy219;
+        goto yy93;
+      }
+    }
+  yy218:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy220;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy219:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy222;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy221;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy221;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy221;
+        goto yy93;
+      }
+    }
+  yy220:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy222;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy221:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy224;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy223;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy223;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy223;
+        goto yy93;
+      }
+    }
+  yy222:
+    ++p;
+    yych = *p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy224;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy223:
+    ++p;
+    yych = *p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= '-')
+          goto yy93;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy225;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy225;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy225;
+        goto yy93;
+      }
+    }
+  yy224:
+    ++p;
+    yych = *p;
+    if (yych <= '@') {
+      if (yych <= '/')
+        goto yy93;
+      if (yych >= ':')
+        goto yy93;
+    } else {
+      if (yych <= 'Z')
+        goto yy225;
+      if (yych <= '`')
+        goto yy93;
+      if (yych >= '{')
+        goto yy93;
+    }
+  yy225:
+    ++p;
+    yych = *p;
+    if (yych == '.')
+      goto yy99;
+    if (yych == '>')
+      goto yy100;
+    goto yy93;
+  yy226:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy229;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy228;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy228;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy228;
+        goto yy93;
+      }
+    }
+  yy227:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy229;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy228:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy231;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy230;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy230;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy230;
+        goto yy93;
+      }
+    }
+  yy229:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy231;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy230:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy233;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy232;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy232;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy232;
+        goto yy93;
+      }
+    }
+  yy231:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy233;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy232:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy235;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy234;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy234;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy234;
+        goto yy93;
+      }
+    }
+  yy233:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy235;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy234:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy237;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy236;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy236;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy236;
+        goto yy93;
+      }
+    }
+  yy235:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy237;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy236:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy239;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy238;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy238;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy238;
+        goto yy93;
+      }
+    }
+  yy237:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy239;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy238:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy241;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy240;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy240;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy240;
+        goto yy93;
+      }
+    }
+  yy239:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy241;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy240:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy243;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy242;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy242;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy242;
+        goto yy93;
+      }
+    }
+  yy241:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy243;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy242:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy245;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy244;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy244;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy244;
+        goto yy93;
+      }
+    }
+  yy243:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy245;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy244:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy247;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy246;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy246;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy246;
+        goto yy93;
+      }
+    }
+  yy245:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy247;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy246:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy249;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy248;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy248;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy248;
+        goto yy93;
+      }
+    }
+  yy247:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy249;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy248:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy251;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy250;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy250;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy250;
+        goto yy93;
+      }
+    }
+  yy249:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy251;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy250:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy253;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy252;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy252;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy252;
+        goto yy93;
+      }
+    }
+  yy251:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy253;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy252:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy255;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy254;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy254;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy254;
+        goto yy93;
+      }
+    }
+  yy253:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy255;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy254:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy257;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy256;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy256;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy256;
+        goto yy93;
+      }
+    }
+  yy255:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy257;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy256:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy259;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy258;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy258;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy258;
+        goto yy93;
+      }
+    }
+  yy257:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy259;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy258:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy261;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy260;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy260;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy260;
+        goto yy93;
+      }
+    }
+  yy259:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy261;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy260:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy263;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy262;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy262;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy262;
+        goto yy93;
+      }
+    }
+  yy261:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy263;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy262:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy265;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy264;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy264;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy264;
+        goto yy93;
+      }
+    }
+  yy263:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy265;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy264:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy267;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy266;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy266;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy266;
+        goto yy93;
+      }
+    }
+  yy265:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy267;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy266:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy269;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy268;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy268;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy268;
+        goto yy93;
+      }
+    }
+  yy267:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy269;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy268:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy271;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy270;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy270;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy270;
+        goto yy93;
+      }
+    }
+  yy269:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy271;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy270:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy273;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy272;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy272;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy272;
+        goto yy93;
+      }
+    }
+  yy271:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy273;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy272:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy275;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy274;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy274;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy274;
+        goto yy93;
+      }
+    }
+  yy273:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy275;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy274:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy277;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy276;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy276;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy276;
+        goto yy93;
+      }
+    }
+  yy275:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy277;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy276:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy279;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy278;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy278;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy278;
+        goto yy93;
+      }
+    }
+  yy277:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy279;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy278:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy281;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy280;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy280;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy280;
+        goto yy93;
+      }
+    }
+  yy279:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy281;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy280:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy283;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy282;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy282;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy282;
+        goto yy93;
+      }
+    }
+  yy281:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy283;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy282:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy285;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy284;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy284;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy284;
+        goto yy93;
+      }
+    }
+  yy283:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy285;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy284:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy287;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy286;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy286;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy286;
+        goto yy93;
+      }
+    }
+  yy285:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy287;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy286:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy289;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy288;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy288;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy288;
+        goto yy93;
+      }
+    }
+  yy287:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy289;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy288:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy291;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy290;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy290;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy290;
+        goto yy93;
+      }
+    }
+  yy289:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy291;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy290:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy293;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy292;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy292;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy292;
+        goto yy93;
+      }
+    }
+  yy291:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy293;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy292:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy295;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy294;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy294;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy294;
+        goto yy93;
+      }
+    }
+  yy293:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy295;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy294:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy297;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy296;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy296;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy296;
+        goto yy93;
+      }
+    }
+  yy295:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy297;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy296:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy299;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy298;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy298;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy298;
+        goto yy93;
+      }
+    }
+  yy297:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy299;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy298:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy301;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy300;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy300;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy300;
+        goto yy93;
+      }
+    }
+  yy299:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy301;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy300:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy303;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy302;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy302;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy302;
+        goto yy93;
+      }
+    }
+  yy301:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy303;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy302:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy305;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy304;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy304;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy304;
+        goto yy93;
+      }
+    }
+  yy303:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy305;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy304:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy307;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy306;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy306;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy306;
+        goto yy93;
+      }
+    }
+  yy305:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy307;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy306:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy309;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy308;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy308;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy308;
+        goto yy93;
+      }
+    }
+  yy307:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy309;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy308:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy311;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy310;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy310;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy310;
+        goto yy93;
+      }
+    }
+  yy309:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy311;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy310:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy313;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy312;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy312;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy312;
+        goto yy93;
+      }
+    }
+  yy311:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy313;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy312:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy315;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy314;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy314;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy314;
+        goto yy93;
+      }
+    }
+  yy313:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy315;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy314:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy317;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy316;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy316;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy316;
+        goto yy93;
+      }
+    }
+  yy315:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy317;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy316:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy319;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy318;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy318;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy318;
+        goto yy93;
+      }
+    }
+  yy317:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy319;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy318:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy321;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy320;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy320;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy320;
+        goto yy93;
+      }
+    }
+  yy319:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy321;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy320:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy323;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy322;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy322;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy322;
+        goto yy93;
+      }
+    }
+  yy321:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy323;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy322:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy325;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy324;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy324;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy324;
+        goto yy93;
+      }
+    }
+  yy323:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy325;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy324:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy327;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy326;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy326;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy326;
+        goto yy93;
+      }
+    }
+  yy325:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy327;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy326:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy329;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy328;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy328;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy328;
+        goto yy93;
+      }
+    }
+  yy327:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy329;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy328:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy331;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy330;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy330;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy330;
+        goto yy93;
+      }
+    }
+  yy329:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy331;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy330:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy333;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy332;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy332;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy332;
+        goto yy93;
+      }
+    }
+  yy331:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy333;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy332:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy335;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy334;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy334;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy334;
+        goto yy93;
+      }
+    }
+  yy333:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy335;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy334:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy337;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy336;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy336;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy336;
+        goto yy93;
+      }
+    }
+  yy335:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy337;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy336:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy339;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy338;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy338;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy338;
+        goto yy93;
+      }
+    }
+  yy337:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy339;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy338:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy341;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy340;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy340;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy340;
+        goto yy93;
+      }
+    }
+  yy339:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy341;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy340:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy343;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy342;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy342;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy342;
+        goto yy93;
+      }
+    }
+  yy341:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy343;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy342:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= ',')
+          goto yy93;
+        if (yych <= '-')
+          goto yy345;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy344;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy344;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy344;
+        goto yy93;
+      }
+    }
+  yy343:
+    yych = *++p;
+    if (yych <= '9') {
+      if (yych == '-')
+        goto yy345;
+      if (yych <= '/')
+        goto yy93;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy93;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych >= '{')
+          goto yy93;
+      }
+    }
+  yy344:
+    yych = *++p;
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych <= '-')
+          goto yy93;
+        goto yy99;
+      } else {
+        if (yych <= '/')
+          goto yy93;
+        if (yych <= '9')
+          goto yy225;
+        goto yy93;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy100;
+        if (yych <= '@')
+          goto yy93;
+        goto yy225;
+      } else {
+        if (yych <= '`')
+          goto yy93;
+        if (yych <= 'z')
+          goto yy225;
+        goto yy93;
+      }
+    }
+  yy345:
+    ++p;
+    if ((yych = *p) <= '@') {
+      if (yych <= '/')
+        goto yy93;
+      if (yych <= '9')
+        goto yy225;
+      goto yy93;
+    } else {
+      if (yych <= 'Z')
+        goto yy225;
+      if (yych <= '`')
+        goto yy93;
+      if (yych <= 'z')
+        goto yy225;
+      goto yy93;
+    }
+  }
+}
+
+// Try to match an HTML tag after first <, returning num of chars matched.
+bufsize_t _scan_html_tag(const unsigned char *p) {
+  const unsigned char *marker = NULL;
+  const unsigned char *start = p;
+
+  {
+    unsigned char yych;
+    static const unsigned char yybm[] = {
+        /* table 1 .. 8: 0 */
+        0, 239, 239, 239, 239, 239, 239, 239, 239, 238, 238, 238, 238, 238, 239,
+        239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239,
+        239, 239, 239, 238, 239, 234, 239, 239, 239, 239, 236, 239, 239, 239,
+        239, 239, 207, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239,
+        239, 239, 239, 238, 238, 174, 231, 239, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 239, 239, 111, 239, 239, 238, 239, 239,
+        239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239,
+        239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239,
+        239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        /* table 9 .. 11: 256 */
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 64, 64, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        160, 128, 0, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 128, 0,
+        0, 0, 0, 0, 0, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
+        160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
+        160, 0, 0, 0, 0, 128, 0, 160, 160, 160, 160, 160, 160, 160, 160, 160,
+        160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
+        160, 160, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    };
+    yych = *p;
+    if (yych <= '>') {
+      if (yych <= '!') {
+        if (yych >= '!')
+          goto yy350;
+      } else {
+        if (yych == '/')
+          goto yy351;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '?')
+          goto yy352;
+        if (yych >= 'A')
+          goto yy353;
+      } else {
+        if (yych <= '`')
+          goto yy348;
+        if (yych <= 'z')
+          goto yy353;
+      }
+    }
+  yy348:
+    ++p;
+  yy349 : { return 0; }
+  yy350:
+    yych = *(marker = ++p);
+    if (yybm[0 + yych] & 16) {
+      goto yy426;
+    }
+    if (yych == '-')
+      goto yy428;
+    if (yych <= '@')
+      goto yy349;
+    if (yych <= '[')
+      goto yy425;
+    goto yy349;
+  yy351:
+    yych = *(marker = ++p);
+    if (yych <= '@')
+      goto yy349;
+    if (yych <= 'Z')
+      goto yy421;
+    if (yych <= '`')
+      goto yy349;
+    if (yych <= 'z')
+      goto yy421;
+    goto yy349;
+  yy352:
+    yych = *(marker = ++p);
+    if (yych <= 0x00)
+      goto yy349;
+    if (yych <= 0x7F)
+      goto yy405;
+    if (yych <= 0xC1)
+      goto yy349;
+    if (yych <= 0xF4)
+      goto yy405;
+    goto yy349;
+  yy353:
+    yych = *(marker = ++p);
+    if (yybm[256 + yych] & 64) {
+      goto yy357;
+    }
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych != '-')
+          goto yy349;
+      } else {
+        if (yych <= '/')
+          goto yy359;
+        if (yych >= ':')
+          goto yy349;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy360;
+        if (yych <= '@')
+          goto yy349;
+      } else {
+        if (yych <= '`')
+          goto yy349;
+        if (yych >= '{')
+          goto yy349;
+      }
+    }
+  yy354:
+    ++p;
+    yych = *p;
+    if (yybm[256 + yych] & 64) {
+      goto yy357;
+    }
+    if (yych <= '=') {
+      if (yych <= '.') {
+        if (yych == '-')
+          goto yy354;
+      } else {
+        if (yych <= '/')
+          goto yy359;
+        if (yych <= '9')
+          goto yy354;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy360;
+        if (yych >= 'A')
+          goto yy354;
+      } else {
+        if (yych <= '`')
+          goto yy356;
+        if (yych <= 'z')
+          goto yy354;
+      }
+    }
+  yy356:
+    p = marker;
+    goto yy349;
+  yy357:
+    ++p;
+    yych = *p;
+    if (yybm[256 + yych] & 64) {
+      goto yy357;
+    }
+    if (yych <= '>') {
+      if (yych <= '9') {
+        if (yych != '/')
+          goto yy356;
+      } else {
+        if (yych <= ':')
+          goto yy362;
+        if (yych <= '=')
+          goto yy356;
+        goto yy360;
+      }
+    } else {
+      if (yych <= '^') {
+        if (yych <= '@')
+          goto yy356;
+        if (yych <= 'Z')
+          goto yy362;
+        goto yy356;
+      } else {
+        if (yych == '`')
+          goto yy356;
+        if (yych <= 'z')
+          goto yy362;
+        goto yy356;
+      }
+    }
+  yy359:
+    yych = *++p;
+    if (yych != '>')
+      goto yy356;
+  yy360:
+    ++p;
+    { return (bufsize_t)(p - start); }
+  yy362:
+    ++p;
+    yych = *p;
+    if (yybm[256 + yych] & 128) {
+      goto yy362;
+    }
+    if (yych <= ',') {
+      if (yych <= '\r') {
+        if (yych <= 0x08)
+          goto yy356;
+      } else {
+        if (yych != ' ')
+          goto yy356;
+      }
+    } else {
+      if (yych <= '<') {
+        if (yych <= '/')
+          goto yy359;
+        goto yy356;
+      } else {
+        if (yych <= '=')
+          goto yy366;
+        if (yych <= '>')
+          goto yy360;
+        goto yy356;
+      }
+    }
+  yy364:
+    ++p;
+    yych = *p;
+    if (yych <= '<') {
+      if (yych <= ' ') {
+        if (yych <= 0x08)
+          goto yy356;
+        if (yych <= '\r')
+          goto yy364;
+        if (yych <= 0x1F)
+          goto yy356;
+        goto yy364;
+      } else {
+        if (yych <= '/') {
+          if (yych <= '.')
+            goto yy356;
+          goto yy359;
+        } else {
+          if (yych == ':')
+            goto yy362;
+          goto yy356;
+        }
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '=')
+          goto yy366;
+        if (yych <= '>')
+          goto yy360;
+        if (yych <= '@')
+          goto yy356;
+        goto yy362;
+      } else {
+        if (yych <= '_') {
+          if (yych <= '^')
+            goto yy356;
+          goto yy362;
+        } else {
+          if (yych <= '`')
+            goto yy356;
+          if (yych <= 'z')
+            goto yy362;
+          goto yy356;
+        }
+      }
+    }
+  yy366:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 1) {
+      goto yy368;
+    }
+    if (yych <= 0xE0) {
+      if (yych <= '"') {
+        if (yych <= 0x00)
+          goto yy356;
+        if (yych >= '!')
+          goto yy379;
+      } else {
+        if (yych <= '\'')
+          goto yy377;
+        if (yych <= 0xC1)
+          goto yy356;
+        if (yych <= 0xDF)
+          goto yy370;
+        goto yy371;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych == 0xED)
+          goto yy376;
+        goto yy372;
+      } else {
+        if (yych <= 0xF0)
+          goto yy373;
+        if (yych <= 0xF3)
+          goto yy374;
+        if (yych <= 0xF4)
+          goto yy375;
+        goto yy356;
+      }
+    }
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 1) {
+      goto yy368;
+    }
+    if (yych <= 0xDF) {
+      if (yych <= '\'') {
+        if (yych <= 0x00)
+          goto yy356;
+        if (yych <= ' ')
+          goto yy402;
+        if (yych <= '"')
+          goto yy379;
+        goto yy377;
+      } else {
+        if (yych == '>')
+          goto yy360;
+        if (yych <= 0xC1)
+          goto yy356;
+        goto yy370;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych <= 0xE0)
+          goto yy371;
+        if (yych == 0xED)
+          goto yy376;
+        goto yy372;
+      } else {
+        if (yych <= 0xF0)
+          goto yy373;
+        if (yych <= 0xF3)
+          goto yy374;
+        if (yych <= 0xF4)
+          goto yy375;
+        goto yy356;
+      }
+    }
+  yy368:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 1) {
+      goto yy368;
+    }
+    if (yych <= 0xE0) {
+      if (yych <= '=') {
+        if (yych <= 0x00)
+          goto yy356;
+        if (yych <= ' ')
+          goto yy396;
+        goto yy356;
+      } else {
+        if (yych <= '>')
+          goto yy360;
+        if (yych <= 0xC1)
+          goto yy356;
+        if (yych >= 0xE0)
+          goto yy371;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych == 0xED)
+          goto yy376;
+        goto yy372;
+      } else {
+        if (yych <= 0xF0)
+          goto yy373;
+        if (yych <= 0xF3)
+          goto yy374;
+        if (yych <= 0xF4)
+          goto yy375;
+        goto yy356;
+      }
+    }
+  yy370:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy368;
+    goto yy356;
+  yy371:
+    ++p;
+    yych = *p;
+    if (yych <= 0x9F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy370;
+    goto yy356;
+  yy372:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy370;
+    goto yy356;
+  yy373:
+    ++p;
+    yych = *p;
+    if (yych <= 0x8F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy372;
+    goto yy356;
+  yy374:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy372;
+    goto yy356;
+  yy375:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0x8F)
+      goto yy372;
+    goto yy356;
+  yy376:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0x9F)
+      goto yy370;
+    goto yy356;
+  yy377:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 2) {
+      goto yy377;
+    }
+    if (yych <= 0xEC) {
+      if (yych <= 0xC1) {
+        if (yych <= 0x00)
+          goto yy356;
+        if (yych <= '\'')
+          goto yy388;
+        goto yy356;
+      } else {
+        if (yych <= 0xDF)
+          goto yy389;
+        if (yych <= 0xE0)
+          goto yy390;
+        goto yy391;
+      }
+    } else {
+      if (yych <= 0xF0) {
+        if (yych <= 0xED)
+          goto yy395;
+        if (yych <= 0xEF)
+          goto yy391;
+        goto yy392;
+      } else {
+        if (yych <= 0xF3)
+          goto yy393;
+        if (yych <= 0xF4)
+          goto yy394;
+        goto yy356;
+      }
+    }
+  yy379:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 4) {
+      goto yy379;
+    }
+    if (yych <= 0xEC) {
+      if (yych <= 0xC1) {
+        if (yych <= 0x00)
+          goto yy356;
+        if (yych <= '"')
+          goto yy388;
+        goto yy356;
+      } else {
+        if (yych <= 0xDF)
+          goto yy381;
+        if (yych <= 0xE0)
+          goto yy382;
+        goto yy383;
+      }
+    } else {
+      if (yych <= 0xF0) {
+        if (yych <= 0xED)
+          goto yy387;
+        if (yych <= 0xEF)
+          goto yy383;
+        goto yy384;
+      } else {
+        if (yych <= 0xF3)
+          goto yy385;
+        if (yych <= 0xF4)
+          goto yy386;
+        goto yy356;
+      }
+    }
+  yy381:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy379;
+    goto yy356;
+  yy382:
+    ++p;
+    yych = *p;
+    if (yych <= 0x9F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy381;
+    goto yy356;
+  yy383:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy381;
+    goto yy356;
+  yy384:
+    ++p;
+    yych = *p;
+    if (yych <= 0x8F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy383;
+    goto yy356;
+  yy385:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy383;
+    goto yy356;
+  yy386:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0x8F)
+      goto yy383;
+    goto yy356;
+  yy387:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0x9F)
+      goto yy381;
+    goto yy356;
+  yy388:
+    ++p;
+    yych = *p;
+    if (yybm[256 + yych] & 64) {
+      goto yy357;
+    }
+    if (yych == '/')
+      goto yy359;
+    if (yych == '>')
+      goto yy360;
+    goto yy356;
+  yy389:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy377;
+    goto yy356;
+  yy390:
+    ++p;
+    yych = *p;
+    if (yych <= 0x9F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy389;
+    goto yy356;
+  yy391:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy389;
+    goto yy356;
+  yy392:
+    ++p;
+    yych = *p;
+    if (yych <= 0x8F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy391;
+    goto yy356;
+  yy393:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy391;
+    goto yy356;
+  yy394:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0x8F)
+      goto yy391;
+    goto yy356;
+  yy395:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0x9F)
+      goto yy389;
+    goto yy356;
+  yy396:
+    ++p;
+    yych = *p;
+    if (yych <= '@') {
+      if (yych <= '"') {
+        if (yych <= '\r') {
+          if (yych <= 0x00)
+            goto yy356;
+          if (yych <= 0x08)
+            goto yy368;
+          goto yy396;
+        } else {
+          if (yych == ' ')
+            goto yy396;
+          if (yych <= '!')
+            goto yy368;
+          goto yy356;
+        }
+      } else {
+        if (yych <= ':') {
+          if (yych == '\'')
+            goto yy356;
+          if (yych <= '9')
+            goto yy368;
+        } else {
+          if (yych <= ';')
+            goto yy368;
+          if (yych <= '=')
+            goto yy356;
+          if (yych <= '>')
+            goto yy360;
+          goto yy368;
+        }
+      }
+    } else {
+      if (yych <= 0xDF) {
+        if (yych <= '`') {
+          if (yych <= 'Z')
+            goto yy398;
+          if (yych <= '^')
+            goto yy368;
+          if (yych >= '`')
+            goto yy356;
+        } else {
+          if (yych <= 'z')
+            goto yy398;
+          if (yych <= 0x7F)
+            goto yy368;
+          if (yych <= 0xC1)
+            goto yy356;
+          goto yy370;
+        }
+      } else {
+        if (yych <= 0xEF) {
+          if (yych <= 0xE0)
+            goto yy371;
+          if (yych == 0xED)
+            goto yy376;
+          goto yy372;
+        } else {
+          if (yych <= 0xF0)
+            goto yy373;
+          if (yych <= 0xF3)
+            goto yy374;
+          if (yych <= 0xF4)
+            goto yy375;
+          goto yy356;
+        }
+      }
+    }
+  yy398:
+    ++p;
+    yych = *p;
+    if (yych <= '>') {
+      if (yych <= '&') {
+        if (yych <= 0x1F) {
+          if (yych <= 0x00)
+            goto yy356;
+          if (yych <= 0x08)
+            goto yy368;
+          if (yych >= 0x0E)
+            goto yy368;
+        } else {
+          if (yych <= ' ')
+            goto yy400;
+          if (yych == '"')
+            goto yy356;
+          goto yy368;
+        }
+      } else {
+        if (yych <= '/') {
+          if (yych <= '\'')
+            goto yy356;
+          if (yych <= ',')
+            goto yy368;
+          if (yych <= '.')
+            goto yy398;
+          goto yy368;
+        } else {
+          if (yych <= ';') {
+            if (yych <= ':')
+              goto yy398;
+            goto yy368;
+          } else {
+            if (yych <= '<')
+              goto yy356;
+            if (yych <= '=')
+              goto yy366;
+            goto yy360;
+          }
+        }
+      }
+    } else {
+      if (yych <= 0xC1) {
+        if (yych <= '_') {
+          if (yych <= '@')
+            goto yy368;
+          if (yych <= 'Z')
+            goto yy398;
+          if (yych <= '^')
+            goto yy368;
+          goto yy398;
+        } else {
+          if (yych <= '`')
+            goto yy356;
+          if (yych <= 'z')
+            goto yy398;
+          if (yych <= 0x7F)
+            goto yy368;
+          goto yy356;
+        }
+      } else {
+        if (yych <= 0xED) {
+          if (yych <= 0xDF)
+            goto yy370;
+          if (yych <= 0xE0)
+            goto yy371;
+          if (yych <= 0xEC)
+            goto yy372;
+          goto yy376;
+        } else {
+          if (yych <= 0xF0) {
+            if (yych <= 0xEF)
+              goto yy372;
+            goto yy373;
+          } else {
+            if (yych <= 0xF3)
+              goto yy374;
+            if (yych <= 0xF4)
+              goto yy375;
+            goto yy356;
+          }
+        }
+      }
+    }
+  yy400:
+    ++p;
+    yych = *p;
+    if (yych <= '@') {
+      if (yych <= '&') {
+        if (yych <= 0x1F) {
+          if (yych <= 0x00)
+            goto yy356;
+          if (yych <= 0x08)
+            goto yy368;
+          if (yych <= '\r')
+            goto yy400;
+          goto yy368;
+        } else {
+          if (yych <= ' ')
+            goto yy400;
+          if (yych == '"')
+            goto yy356;
+          goto yy368;
+        }
+      } else {
+        if (yych <= ';') {
+          if (yych <= '\'')
+            goto yy356;
+          if (yych == ':')
+            goto yy398;
+          goto yy368;
+        } else {
+          if (yych <= '<')
+            goto yy356;
+          if (yych <= '=')
+            goto yy366;
+          if (yych <= '>')
+            goto yy360;
+          goto yy368;
+        }
+      }
+    } else {
+      if (yych <= 0xDF) {
+        if (yych <= '`') {
+          if (yych <= 'Z')
+            goto yy398;
+          if (yych <= '^')
+            goto yy368;
+          if (yych <= '_')
+            goto yy398;
+          goto yy356;
+        } else {
+          if (yych <= 'z')
+            goto yy398;
+          if (yych <= 0x7F)
+            goto yy368;
+          if (yych <= 0xC1)
+            goto yy356;
+          goto yy370;
+        }
+      } else {
+        if (yych <= 0xEF) {
+          if (yych <= 0xE0)
+            goto yy371;
+          if (yych == 0xED)
+            goto yy376;
+          goto yy372;
+        } else {
+          if (yych <= 0xF0)
+            goto yy373;
+          if (yych <= 0xF3)
+            goto yy374;
+          if (yych <= 0xF4)
+            goto yy375;
+          goto yy356;
+        }
+      }
+    }
+  yy402:
+    ++p;
+    yych = *p;
+    if (yych <= '@') {
+      if (yych <= '"') {
+        if (yych <= '\r') {
+          if (yych <= 0x00)
+            goto yy356;
+          if (yych <= 0x08)
+            goto yy368;
+          goto yy402;
+        } else {
+          if (yych == ' ')
+            goto yy402;
+          if (yych <= '!')
+            goto yy368;
+          goto yy379;
+        }
+      } else {
+        if (yych <= ':') {
+          if (yych == '\'')
+            goto yy377;
+          if (yych <= '9')
+            goto yy368;
+          goto yy398;
+        } else {
+          if (yych <= ';')
+            goto yy368;
+          if (yych <= '=')
+            goto yy356;
+          if (yych <= '>')
+            goto yy360;
+          goto yy368;
+        }
+      }
+    } else {
+      if (yych <= 0xDF) {
+        if (yych <= '`') {
+          if (yych <= 'Z')
+            goto yy398;
+          if (yych <= '^')
+            goto yy368;
+          if (yych <= '_')
+            goto yy398;
+          goto yy356;
+        } else {
+          if (yych <= 'z')
+            goto yy398;
+          if (yych <= 0x7F)
+            goto yy368;
+          if (yych <= 0xC1)
+            goto yy356;
+          goto yy370;
+        }
+      } else {
+        if (yych <= 0xEF) {
+          if (yych <= 0xE0)
+            goto yy371;
+          if (yych == 0xED)
+            goto yy376;
+          goto yy372;
+        } else {
+          if (yych <= 0xF0)
+            goto yy373;
+          if (yych <= 0xF3)
+            goto yy374;
+          if (yych <= 0xF4)
+            goto yy375;
+          goto yy356;
+        }
+      }
+    }
+  yy404:
+    ++p;
+    yych = *p;
+  yy405:
+    if (yybm[0 + yych] & 8) {
+      goto yy404;
+    }
+    if (yych <= 0xEC) {
+      if (yych <= 0xC1) {
+        if (yych <= 0x00)
+          goto yy356;
+        if (yych <= '?')
+          goto yy413;
+        goto yy356;
+      } else {
+        if (yych <= 0xDF)
+          goto yy406;
+        if (yych <= 0xE0)
+          goto yy407;
+        goto yy408;
+      }
+    } else {
+      if (yych <= 0xF0) {
+        if (yych <= 0xED)
+          goto yy412;
+        if (yych <= 0xEF)
+          goto yy408;
+        goto yy409;
+      } else {
+        if (yych <= 0xF3)
+          goto yy410;
+        if (yych <= 0xF4)
+          goto yy411;
+        goto yy356;
+      }
+    }
+  yy406:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy404;
+    goto yy356;
+  yy407:
+    ++p;
+    yych = *p;
+    if (yych <= 0x9F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy406;
+    goto yy356;
+  yy408:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy406;
+    goto yy356;
+  yy409:
+    ++p;
+    yych = *p;
+    if (yych <= 0x8F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy408;
+    goto yy356;
+  yy410:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy408;
+    goto yy356;
+  yy411:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0x8F)
+      goto yy408;
+    goto yy356;
+  yy412:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0x9F)
+      goto yy406;
+    goto yy356;
+  yy413:
+    ++p;
+    yych = *p;
+    if (yych <= 0xE0) {
+      if (yych <= '>') {
+        if (yych <= 0x00)
+          goto yy356;
+        if (yych <= '=')
+          goto yy404;
+        goto yy360;
+      } else {
+        if (yych <= 0x7F)
+          goto yy404;
+        if (yych <= 0xC1)
+          goto yy356;
+        if (yych >= 0xE0)
+          goto yy415;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych == 0xED)
+          goto yy420;
+        goto yy416;
+      } else {
+        if (yych <= 0xF0)
+          goto yy417;
+        if (yych <= 0xF3)
+          goto yy418;
+        if (yych <= 0xF4)
+          goto yy419;
+        goto yy356;
+      }
+    }
+  yy414:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy404;
+    goto yy356;
+  yy415:
+    ++p;
+    yych = *p;
+    if (yych <= 0x9F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy414;
+    goto yy356;
+  yy416:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy414;
+    goto yy356;
+  yy417:
+    ++p;
+    yych = *p;
+    if (yych <= 0x8F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy416;
+    goto yy356;
+  yy418:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy416;
+    goto yy356;
+  yy419:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0x8F)
+      goto yy416;
+    goto yy356;
+  yy420:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0x9F)
+      goto yy414;
+    goto yy356;
+  yy421:
+    ++p;
+    yych = *p;
+    if (yych <= '/') {
+      if (yych <= 0x1F) {
+        if (yych <= 0x08)
+          goto yy356;
+        if (yych >= 0x0E)
+          goto yy356;
+      } else {
+        if (yych <= ' ')
+          goto yy423;
+        if (yych == '-')
+          goto yy421;
+        goto yy356;
+      }
+    } else {
+      if (yych <= '@') {
+        if (yych <= '9')
+          goto yy421;
+        if (yych == '>')
+          goto yy360;
+        goto yy356;
+      } else {
+        if (yych <= 'Z')
+          goto yy421;
+        if (yych <= '`')
+          goto yy356;
+        if (yych <= 'z')
+          goto yy421;
+        goto yy356;
+      }
+    }
+  yy423:
+    ++p;
+    yych = *p;
+    if (yych <= 0x1F) {
+      if (yych <= 0x08)
+        goto yy356;
+      if (yych <= '\r')
+        goto yy423;
+      goto yy356;
+    } else {
+      if (yych <= ' ')
+        goto yy423;
+      if (yych == '>')
+        goto yy360;
+      goto yy356;
+    }
+  yy425:
+    yych = *++p;
+    if (yych == 'C')
+      goto yy461;
+    if (yych == 'c')
+      goto yy461;
+    goto yy356;
+  yy426:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 16) {
+      goto yy426;
+    }
+    if (yych <= 0x08)
+      goto yy356;
+    if (yych <= '\r')
+      goto yy450;
+    if (yych == ' ')
+      goto yy450;
+    goto yy356;
+  yy428:
+    yych = *++p;
+    if (yych != '-')
+      goto yy356;
+    yych = *++p;
+    if (yych <= 0xE0) {
+      if (yych <= '=') {
+        if (yych != '-')
+          goto yy432;
+      } else {
+        if (yych <= '>')
+          goto yy356;
+        if (yych <= 0xC1)
+          goto yy432;
+        if (yych <= 0xDF)
+          goto yy433;
+        goto yy434;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych == 0xED)
+          goto yy439;
+        goto yy435;
+      } else {
+        if (yych <= 0xF0)
+          goto yy436;
+        if (yych <= 0xF3)
+          goto yy437;
+        if (yych <= 0xF4)
+          goto yy438;
+        goto yy432;
+      }
+    }
+    yych = *++p;
+    if (yych <= 0xE0) {
+      if (yych <= '=') {
+        if (yych == '-')
+          goto yy449;
+        goto yy432;
+      } else {
+        if (yych <= '>')
+          goto yy356;
+        if (yych <= 0xC1)
+          goto yy432;
+        if (yych <= 0xDF)
+          goto yy433;
+        goto yy434;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych == 0xED)
+          goto yy439;
+        goto yy435;
+      } else {
+        if (yych <= 0xF0)
+          goto yy436;
+        if (yych <= 0xF3)
+          goto yy437;
+        if (yych <= 0xF4)
+          goto yy438;
+        goto yy432;
+      }
+    }
+  yy431:
+    ++p;
+    yych = *p;
+  yy432:
+    if (yybm[0 + yych] & 32) {
+      goto yy431;
+    }
+    if (yych <= 0xEC) {
+      if (yych <= 0xC1) {
+        if (yych <= 0x00)
+          goto yy356;
+        if (yych <= '-')
+          goto yy440;
+        goto yy356;
+      } else {
+        if (yych <= 0xDF)
+          goto yy441;
+        if (yych <= 0xE0)
+          goto yy442;
+        goto yy443;
+      }
+    } else {
+      if (yych <= 0xF0) {
+        if (yych <= 0xED)
+          goto yy447;
+        if (yych <= 0xEF)
+          goto yy443;
+        goto yy444;
+      } else {
+        if (yych <= 0xF3)
+          goto yy445;
+        if (yych <= 0xF4)
+          goto yy446;
+        goto yy356;
+      }
+    }
+  yy433:
+    yych = *++p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy431;
+    goto yy356;
+  yy434:
+    yych = *++p;
+    if (yych <= 0x9F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy433;
+    goto yy356;
+  yy435:
+    yych = *++p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy433;
+    goto yy356;
+  yy436:
+    yych = *++p;
+    if (yych <= 0x8F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy435;
+    goto yy356;
+  yy437:
+    yych = *++p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy435;
+    goto yy356;
+  yy438:
+    yych = *++p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0x8F)
+      goto yy435;
+    goto yy356;
+  yy439:
+    yych = *++p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0x9F)
+      goto yy433;
+    goto yy356;
+  yy440:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 32) {
+      goto yy431;
+    }
+    if (yych <= 0xEC) {
+      if (yych <= 0xC1) {
+        if (yych <= 0x00)
+          goto yy356;
+        if (yych <= '-')
+          goto yy448;
+        goto yy356;
+      } else {
+        if (yych <= 0xDF)
+          goto yy441;
+        if (yych <= 0xE0)
+          goto yy442;
+        goto yy443;
+      }
+    } else {
+      if (yych <= 0xF0) {
+        if (yych <= 0xED)
+          goto yy447;
+        if (yych <= 0xEF)
+          goto yy443;
+        goto yy444;
+      } else {
+        if (yych <= 0xF3)
+          goto yy445;
+        if (yych <= 0xF4)
+          goto yy446;
+        goto yy356;
+      }
+    }
+  yy441:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy431;
+    goto yy356;
+  yy442:
+    ++p;
+    yych = *p;
+    if (yych <= 0x9F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy441;
+    goto yy356;
+  yy443:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy441;
+    goto yy356;
+  yy444:
+    ++p;
+    yych = *p;
+    if (yych <= 0x8F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy443;
+    goto yy356;
+  yy445:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy443;
+    goto yy356;
+  yy446:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0x8F)
+      goto yy443;
+    goto yy356;
+  yy447:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0x9F)
+      goto yy441;
+    goto yy356;
+  yy448:
+    yych = *++p;
+    if (yych == '>')
+      goto yy360;
+    goto yy356;
+  yy449:
+    yych = *++p;
+    if (yych == '>')
+      goto yy360;
+    goto yy356;
+  yy450:
+    ++p;
+    yych = *p;
+    if (yych <= 0xC1) {
+      if (yych <= 0x1F) {
+        if (yych <= 0x00)
+          goto yy356;
+        if (yych <= 0x08)
+          goto yy452;
+        if (yych <= '\r')
+          goto yy450;
+      } else {
+        if (yych <= '=') {
+          if (yych <= ' ')
+            goto yy450;
+        } else {
+          if (yych <= '>')
+            goto yy360;
+          if (yych >= 0x80)
+            goto yy356;
+        }
+      }
+    } else {
+      if (yych <= 0xED) {
+        if (yych <= 0xDF)
+          goto yy454;
+        if (yych <= 0xE0)
+          goto yy455;
+        if (yych <= 0xEC)
+          goto yy456;
+        goto yy460;
+      } else {
+        if (yych <= 0xF0) {
+          if (yych <= 0xEF)
+            goto yy456;
+          goto yy457;
+        } else {
+          if (yych <= 0xF3)
+            goto yy458;
+          if (yych <= 0xF4)
+            goto yy459;
+          goto yy356;
+        }
+      }
+    }
+  yy452:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 64) {
+      goto yy452;
+    }
+    if (yych <= 0xEC) {
+      if (yych <= 0xC1) {
+        if (yych <= 0x00)
+          goto yy356;
+        if (yych <= '>')
+          goto yy360;
+        goto yy356;
+      } else {
+        if (yych <= 0xDF)
+          goto yy454;
+        if (yych <= 0xE0)
+          goto yy455;
+        goto yy456;
+      }
+    } else {
+      if (yych <= 0xF0) {
+        if (yych <= 0xED)
+          goto yy460;
+        if (yych <= 0xEF)
+          goto yy456;
+        goto yy457;
+      } else {
+        if (yych <= 0xF3)
+          goto yy458;
+        if (yych <= 0xF4)
+          goto yy459;
+        goto yy356;
+      }
+    }
+  yy454:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy452;
+    goto yy356;
+  yy455:
+    ++p;
+    yych = *p;
+    if (yych <= 0x9F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy454;
+    goto yy356;
+  yy456:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy454;
+    goto yy356;
+  yy457:
+    ++p;
+    yych = *p;
+    if (yych <= 0x8F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy456;
+    goto yy356;
+  yy458:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy456;
+    goto yy356;
+  yy459:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0x8F)
+      goto yy456;
+    goto yy356;
+  yy460:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0x9F)
+      goto yy454;
+    goto yy356;
+  yy461:
+    yych = *++p;
+    if (yych == 'D')
+      goto yy462;
+    if (yych != 'd')
+      goto yy356;
+  yy462:
+    yych = *++p;
+    if (yych == 'A')
+      goto yy463;
+    if (yych != 'a')
+      goto yy356;
+  yy463:
+    yych = *++p;
+    if (yych == 'T')
+      goto yy464;
+    if (yych != 't')
+      goto yy356;
+  yy464:
+    yych = *++p;
+    if (yych == 'A')
+      goto yy465;
+    if (yych != 'a')
+      goto yy356;
+  yy465:
+    yych = *++p;
+    if (yych != '[')
+      goto yy356;
+  yy466:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 128) {
+      goto yy466;
+    }
+    if (yych <= 0xEC) {
+      if (yych <= 0xC1) {
+        if (yych <= 0x00)
+          goto yy356;
+        if (yych <= ']')
+          goto yy475;
+        goto yy356;
+      } else {
+        if (yych <= 0xDF)
+          goto yy468;
+        if (yych <= 0xE0)
+          goto yy469;
+        goto yy470;
+      }
+    } else {
+      if (yych <= 0xF0) {
+        if (yych <= 0xED)
+          goto yy474;
+        if (yych <= 0xEF)
+          goto yy470;
+        goto yy471;
+      } else {
+        if (yych <= 0xF3)
+          goto yy472;
+        if (yych <= 0xF4)
+          goto yy473;
+        goto yy356;
+      }
+    }
+  yy468:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy466;
+    goto yy356;
+  yy469:
+    ++p;
+    yych = *p;
+    if (yych <= 0x9F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy468;
+    goto yy356;
+  yy470:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy468;
+    goto yy356;
+  yy471:
+    ++p;
+    yych = *p;
+    if (yych <= 0x8F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy470;
+    goto yy356;
+  yy472:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy470;
+    goto yy356;
+  yy473:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0x8F)
+      goto yy470;
+    goto yy356;
+  yy474:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0x9F)
+      goto yy468;
+    goto yy356;
+  yy475:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 128) {
+      goto yy466;
+    }
+    if (yych <= 0xEC) {
+      if (yych <= 0xC1) {
+        if (yych <= 0x00)
+          goto yy356;
+        if (yych >= '^')
+          goto yy356;
+      } else {
+        if (yych <= 0xDF)
+          goto yy477;
+        if (yych <= 0xE0)
+          goto yy478;
+        goto yy479;
+      }
+    } else {
+      if (yych <= 0xF0) {
+        if (yych <= 0xED)
+          goto yy483;
+        if (yych <= 0xEF)
+          goto yy479;
+        goto yy480;
+      } else {
+        if (yych <= 0xF3)
+          goto yy481;
+        if (yych <= 0xF4)
+          goto yy482;
+        goto yy356;
+      }
+    }
+    ++p;
+    yych = *p;
+    if (yych <= 0xE0) {
+      if (yych <= '>') {
+        if (yych <= 0x00)
+          goto yy356;
+        if (yych <= '=')
+          goto yy466;
+        goto yy360;
+      } else {
+        if (yych <= 0x7F)
+          goto yy466;
+        if (yych <= 0xC1)
+          goto yy356;
+        if (yych <= 0xDF)
+          goto yy484;
+        goto yy485;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych == 0xED)
+          goto yy490;
+        goto yy486;
+      } else {
+        if (yych <= 0xF0)
+          goto yy487;
+        if (yych <= 0xF3)
+          goto yy488;
+        if (yych <= 0xF4)
+          goto yy489;
+        goto yy356;
+      }
+    }
+  yy477:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy466;
+    goto yy356;
+  yy478:
+    ++p;
+    yych = *p;
+    if (yych <= 0x9F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy477;
+    goto yy356;
+  yy479:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy477;
+    goto yy356;
+  yy480:
+    ++p;
+    yych = *p;
+    if (yych <= 0x8F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy479;
+    goto yy356;
+  yy481:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy479;
+    goto yy356;
+  yy482:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0x8F)
+      goto yy479;
+    goto yy356;
+  yy483:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0x9F)
+      goto yy477;
+    goto yy356;
+  yy484:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy466;
+    goto yy356;
+  yy485:
+    ++p;
+    yych = *p;
+    if (yych <= 0x9F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy484;
+    goto yy356;
+  yy486:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy484;
+    goto yy356;
+  yy487:
+    ++p;
+    yych = *p;
+    if (yych <= 0x8F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy486;
+    goto yy356;
+  yy488:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0xBF)
+      goto yy486;
+    goto yy356;
+  yy489:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0x8F)
+      goto yy486;
+    goto yy356;
+  yy490:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy356;
+    if (yych <= 0x9F)
+      goto yy484;
+    goto yy356;
+  }
+}
+
+// Try to (liberally) match an HTML tag after first <, returning num of chars
+// matched.
+bufsize_t _scan_liberal_html_tag(const unsigned char *p) {
+  const unsigned char *marker = NULL;
+  const unsigned char *start = p;
+
+  {
+    unsigned char yych;
+    unsigned int yyaccept = 0;
+    static const unsigned char yybm[] = {
+        0,  64, 64, 64, 64, 64, 64, 64, 64,  64, 0,  64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 64, 64, 128, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,
+    };
+    yych = *p;
+    if (yych <= 0xE0) {
+      if (yych <= '\n') {
+        if (yych <= 0x00)
+          goto yy493;
+        if (yych <= '\t')
+          goto yy495;
+      } else {
+        if (yych <= 0x7F)
+          goto yy495;
+        if (yych <= 0xC1)
+          goto yy493;
+        if (yych <= 0xDF)
+          goto yy496;
+        goto yy497;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych == 0xED)
+          goto yy499;
+        goto yy498;
+      } else {
+        if (yych <= 0xF0)
+          goto yy500;
+        if (yych <= 0xF3)
+          goto yy501;
+        if (yych <= 0xF4)
+          goto yy502;
+      }
+    }
+  yy493:
+    ++p;
+  yy494 : { return 0; }
+  yy495:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= '\n') {
+      if (yych <= 0x00)
+        goto yy494;
+      if (yych <= '\t')
+        goto yy507;
+      goto yy494;
+    } else {
+      if (yych <= 0x7F)
+        goto yy507;
+      if (yych <= 0xC1)
+        goto yy494;
+      if (yych <= 0xF4)
+        goto yy507;
+      goto yy494;
+    }
+  yy496:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy494;
+    if (yych <= 0xBF)
+      goto yy506;
+    goto yy494;
+  yy497:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x9F)
+      goto yy494;
+    if (yych <= 0xBF)
+      goto yy505;
+    goto yy494;
+  yy498:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy494;
+    if (yych <= 0xBF)
+      goto yy505;
+    goto yy494;
+  yy499:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy494;
+    if (yych <= 0x9F)
+      goto yy505;
+    goto yy494;
+  yy500:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x8F)
+      goto yy494;
+    if (yych <= 0xBF)
+      goto yy503;
+    goto yy494;
+  yy501:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy494;
+    if (yych <= 0xBF)
+      goto yy503;
+    goto yy494;
+  yy502:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy494;
+    if (yych >= 0x90)
+      goto yy494;
+  yy503:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy504;
+    if (yych <= 0xBF)
+      goto yy505;
+  yy504:
+    p = marker;
+    if (yyaccept == 0) {
+      goto yy494;
+    } else {
+      goto yy510;
+    }
+  yy505:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy504;
+    if (yych >= 0xC0)
+      goto yy504;
+  yy506:
+    ++p;
+    yych = *p;
+  yy507:
+    if (yybm[0 + yych] & 64) {
+      goto yy506;
+    }
+    if (yych <= 0xEC) {
+      if (yych <= 0xC1) {
+        if (yych <= '\n')
+          goto yy504;
+        if (yych >= '?')
+          goto yy504;
+      } else {
+        if (yych <= 0xDF)
+          goto yy505;
+        if (yych <= 0xE0)
+          goto yy511;
+        goto yy503;
+      }
+    } else {
+      if (yych <= 0xF0) {
+        if (yych <= 0xED)
+          goto yy515;
+        if (yych <= 0xEF)
+          goto yy503;
+        goto yy512;
+      } else {
+        if (yych <= 0xF3)
+          goto yy513;
+        if (yych <= 0xF4)
+          goto yy514;
+        goto yy504;
+      }
+    }
+  yy508:
+    yyaccept = 1;
+    marker = ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 64) {
+      goto yy506;
+    }
+    if (yych <= 0xEC) {
+      if (yych <= 0xC1) {
+        if (yych <= '\n')
+          goto yy510;
+        if (yych <= '>')
+          goto yy508;
+      } else {
+        if (yych <= 0xDF)
+          goto yy505;
+        if (yych <= 0xE0)
+          goto yy511;
+        goto yy503;
+      }
+    } else {
+      if (yych <= 0xF0) {
+        if (yych <= 0xED)
+          goto yy515;
+        if (yych <= 0xEF)
+          goto yy503;
+        goto yy512;
+      } else {
+        if (yych <= 0xF3)
+          goto yy513;
+        if (yych <= 0xF4)
+          goto yy514;
+      }
+    }
+  yy510 : { return (bufsize_t)(p - start); }
+  yy511:
+    ++p;
+    yych = *p;
+    if (yych <= 0x9F)
+      goto yy504;
+    if (yych <= 0xBF)
+      goto yy505;
+    goto yy504;
+  yy512:
+    ++p;
+    yych = *p;
+    if (yych <= 0x8F)
+      goto yy504;
+    if (yych <= 0xBF)
+      goto yy503;
+    goto yy504;
+  yy513:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy504;
+    if (yych <= 0xBF)
+      goto yy503;
+    goto yy504;
+  yy514:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy504;
+    if (yych <= 0x8F)
+      goto yy503;
+    goto yy504;
+  yy515:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy504;
+    if (yych <= 0x9F)
+      goto yy505;
+    goto yy504;
+  }
+}
+
+// Try to match an HTML block tag start line, returning
+// an integer code for the type of block (1-6, matching the spec).
+// #7 is handled by a separate function, below.
+bufsize_t _scan_html_block_start(const unsigned char *p) {
+  const unsigned char *marker = NULL;
+
+  {
+    unsigned char yych;
+    yych = *p;
+    if (yych == '<')
+      goto yy520;
+    ++p;
+  yy519 : { return 0; }
+  yy520:
+    yych = *(marker = ++p);
+    switch (yych) {
+    case '!':
+      goto yy538;
+    case '/':
+      goto yy521;
+    case '?':
+      goto yy539;
+    case 'A':
+    case 'a':
+      goto yy524;
+    case 'B':
+    case 'b':
+      goto yy525;
+    case 'C':
+    case 'c':
+      goto yy526;
+    case 'D':
+    case 'd':
+      goto yy527;
+    case 'F':
+    case 'f':
+      goto yy528;
+    case 'H':
+    case 'h':
+      goto yy529;
+    case 'I':
+    case 'i':
+      goto yy530;
+    case 'L':
+    case 'l':
+      goto yy531;
+    case 'M':
+    case 'm':
+      goto yy532;
+    case 'N':
+    case 'n':
+      goto yy533;
+    case 'O':
+    case 'o':
+      goto yy534;
+    case 'P':
+    case 'p':
+      goto yy523;
+    case 'S':
+    case 's':
+      goto yy535;
+    case 'T':
+    case 't':
+      goto yy536;
+    case 'U':
+    case 'u':
+      goto yy537;
+    default:
+      goto yy519;
+    }
+  yy521:
+    yych = *++p;
+    switch (yych) {
+    case 'A':
+    case 'a':
+      goto yy524;
+    case 'B':
+    case 'b':
+      goto yy525;
+    case 'C':
+    case 'c':
+      goto yy526;
+    case 'D':
+    case 'd':
+      goto yy527;
+    case 'F':
+    case 'f':
+      goto yy528;
+    case 'H':
+    case 'h':
+      goto yy529;
+    case 'I':
+    case 'i':
+      goto yy530;
+    case 'L':
+    case 'l':
+      goto yy531;
+    case 'M':
+    case 'm':
+      goto yy532;
+    case 'N':
+    case 'n':
+      goto yy533;
+    case 'O':
+    case 'o':
+      goto yy534;
+    case 'P':
+    case 'p':
+      goto yy723;
+    case 'S':
+    case 's':
+      goto yy724;
+    case 'T':
+    case 't':
+      goto yy536;
+    case 'U':
+    case 'u':
+      goto yy537;
+    default:
+      goto yy522;
+    }
+  yy522:
+    p = marker;
+    goto yy519;
+  yy523:
+    yych = *++p;
+    if (yych <= '>') {
+      if (yych <= ' ') {
+        if (yych <= 0x08)
+          goto yy522;
+        if (yych <= '\r')
+          goto yy555;
+        if (yych <= 0x1F)
+          goto yy522;
+        goto yy555;
+      } else {
+        if (yych == '/')
+          goto yy557;
+        if (yych <= '=')
+          goto yy522;
+        goto yy555;
+      }
+    } else {
+      if (yych <= 'R') {
+        if (yych == 'A')
+          goto yy720;
+        if (yych <= 'Q')
+          goto yy522;
+        goto yy719;
+      } else {
+        if (yych <= 'a') {
+          if (yych <= '`')
+            goto yy522;
+          goto yy720;
+        } else {
+          if (yych == 'r')
+            goto yy719;
+          goto yy522;
+        }
+      }
+    }
+  yy524:
+    yych = *++p;
+    if (yych <= 'S') {
+      if (yych <= 'D') {
+        if (yych <= 'C')
+          goto yy522;
+        goto yy708;
+      } else {
+        if (yych <= 'Q')
+          goto yy522;
+        if (yych <= 'R')
+          goto yy707;
+        goto yy706;
+      }
+    } else {
+      if (yych <= 'q') {
+        if (yych == 'd')
+          goto yy708;
+        goto yy522;
+      } else {
+        if (yych <= 'r')
+          goto yy707;
+        if (yych <= 's')
+          goto yy706;
+        goto yy522;
+      }
+    }
+  yy525:
+    yych = *++p;
+    if (yych <= 'O') {
+      if (yych <= 'K') {
+        if (yych == 'A')
+          goto yy692;
+        goto yy522;
+      } else {
+        if (yych <= 'L')
+          goto yy691;
+        if (yych <= 'N')
+          goto yy522;
+        goto yy690;
+      }
+    } else {
+      if (yych <= 'k') {
+        if (yych == 'a')
+          goto yy692;
+        goto yy522;
+      } else {
+        if (yych <= 'l')
+          goto yy691;
+        if (yych == 'o')
+          goto yy690;
+        goto yy522;
+      }
+    }
+  yy526:
+    yych = *++p;
+    if (yych <= 'O') {
+      if (yych <= 'D') {
+        if (yych == 'A')
+          goto yy677;
+        goto yy522;
+      } else {
+        if (yych <= 'E')
+          goto yy676;
+        if (yych <= 'N')
+          goto yy522;
+        goto yy675;
+      }
+    } else {
+      if (yych <= 'd') {
+        if (yych == 'a')
+          goto yy677;
+        goto yy522;
+      } else {
+        if (yych <= 'e')
+          goto yy676;
+        if (yych == 'o')
+          goto yy675;
+        goto yy522;
+      }
+    }
+  yy527:
+    yych = *++p;
+    switch (yych) {
+    case 'D':
+    case 'L':
+    case 'T':
+    case 'd':
+    case 'l':
+    case 't':
+      goto yy554;
+    case 'E':
+    case 'e':
+      goto yy667;
+    case 'I':
+    case 'i':
+      goto yy666;
+    default:
+      goto yy522;
+    }
+  yy528:
+    yych = *++p;
+    if (yych <= 'R') {
+      if (yych <= 'N') {
+        if (yych == 'I')
+          goto yy642;
+        goto yy522;
+      } else {
+        if (yych <= 'O')
+          goto yy641;
+        if (yych <= 'Q')
+          goto yy522;
+        goto yy640;
+      }
+    } else {
+      if (yych <= 'n') {
+        if (yych == 'i')
+          goto yy642;
+        goto yy522;
+      } else {
+        if (yych <= 'o')
+          goto yy641;
+        if (yych == 'r')
+          goto yy640;
+        goto yy522;
+      }
+    }
+  yy529:
+    yych = *++p;
+    if (yych <= 'S') {
+      if (yych <= 'D') {
+        if (yych <= '0')
+          goto yy522;
+        if (yych <= '6')
+          goto yy554;
+        goto yy522;
+      } else {
+        if (yych <= 'E')
+          goto yy635;
+        if (yych == 'R')
+          goto yy554;
+        goto yy522;
+      }
+    } else {
+      if (yych <= 'q') {
+        if (yych <= 'T')
+          goto yy634;
+        if (yych == 'e')
+          goto yy635;
+        goto yy522;
+      } else {
+        if (yych <= 'r')
+          goto yy554;
+        if (yych == 't')
+          goto yy634;
+        goto yy522;
+      }
+    }
+  yy530:
+    yych = *++p;
+    if (yych == 'F')
+      goto yy630;
+    if (yych == 'f')
+      goto yy630;
+    goto yy522;
+  yy531:
+    yych = *++p;
+    if (yych <= 'I') {
+      if (yych == 'E')
+        goto yy625;
+      if (yych <= 'H')
+        goto yy522;
+      goto yy624;
+    } else {
+      if (yych <= 'e') {
+        if (yych <= 'd')
+          goto yy522;
+        goto yy625;
+      } else {
+        if (yych == 'i')
+          goto yy624;
+        goto yy522;
+      }
+    }
+  yy532:
+    yych = *++p;
+    if (yych <= 'E') {
+      if (yych == 'A')
+        goto yy616;
+      if (yych <= 'D')
+        goto yy522;
+      goto yy615;
+    } else {
+      if (yych <= 'a') {
+        if (yych <= '`')
+          goto yy522;
+        goto yy616;
+      } else {
+        if (yych == 'e')
+          goto yy615;
+        goto yy522;
+      }
+    }
+  yy533:
+    yych = *++p;
+    if (yych <= 'O') {
+      if (yych == 'A')
+        goto yy609;
+      if (yych <= 'N')
+        goto yy522;
+      goto yy608;
+    } else {
+      if (yych <= 'a') {
+        if (yych <= '`')
+          goto yy522;
+        goto yy609;
+      } else {
+        if (yych == 'o')
+          goto yy608;
+        goto yy522;
+      }
+    }
+  yy534:
+    yych = *++p;
+    if (yych <= 'P') {
+      if (yych == 'L')
+        goto yy554;
+      if (yych <= 'O')
+        goto yy522;
+      goto yy600;
+    } else {
+      if (yych <= 'l') {
+        if (yych <= 'k')
+          goto yy522;
+        goto yy554;
+      } else {
+        if (yych == 'p')
+          goto yy600;
+        goto yy522;
+      }
+    }
+  yy535:
+    yych = *++p;
+    switch (yych) {
+    case 'C':
+    case 'c':
+      goto yy577;
+    case 'E':
+    case 'e':
+      goto yy580;
+    case 'O':
+    case 'o':
+      goto yy579;
+    case 'T':
+    case 't':
+      goto yy576;
+    case 'U':
+    case 'u':
+      goto yy578;
+    default:
+      goto yy522;
+    }
+  yy536:
+    yych = *++p;
+    switch (yych) {
+    case 'A':
+    case 'a':
+      goto yy563;
+    case 'B':
+    case 'b':
+      goto yy562;
+    case 'D':
+    case 'd':
+      goto yy554;
+    case 'F':
+    case 'f':
+      goto yy561;
+    case 'H':
+    case 'h':
+      goto yy560;
+    case 'I':
+    case 'i':
+      goto yy559;
+    case 'R':
+    case 'r':
+      goto yy558;
+    default:
+      goto yy522;
+    }
+  yy537:
+    yych = *++p;
+    if (yych == 'L')
+      goto yy554;
+    if (yych == 'l')
+      goto yy554;
+    goto yy522;
+  yy538:
+    yych = *++p;
+    if (yych <= '@') {
+      if (yych == '-')
+        goto yy541;
+      goto yy522;
+    } else {
+      if (yych <= 'Z')
+        goto yy542;
+      if (yych <= '[')
+        goto yy544;
+      goto yy522;
+    }
+  yy539:
+    ++p;
+    { return 3; }
+  yy541:
+    yych = *++p;
+    if (yych == '-')
+      goto yy552;
+    goto yy522;
+  yy542:
+    ++p;
+    { return 4; }
+  yy544:
+    yych = *++p;
+    if (yych == 'C')
+      goto yy545;
+    if (yych != 'c')
+      goto yy522;
+  yy545:
+    yych = *++p;
+    if (yych == 'D')
+      goto yy546;
+    if (yych != 'd')
+      goto yy522;
+  yy546:
+    yych = *++p;
+    if (yych == 'A')
+      goto yy547;
+    if (yych != 'a')
+      goto yy522;
+  yy547:
+    yych = *++p;
+    if (yych == 'T')
+      goto yy548;
+    if (yych != 't')
+      goto yy522;
+  yy548:
+    yych = *++p;
+    if (yych == 'A')
+      goto yy549;
+    if (yych != 'a')
+      goto yy522;
+  yy549:
+    yych = *++p;
+    if (yych != '[')
+      goto yy522;
+    ++p;
+    { return 5; }
+  yy552:
+    ++p;
+    { return 2; }
+  yy554:
+    yych = *++p;
+    if (yych <= ' ') {
+      if (yych <= 0x08)
+        goto yy522;
+      if (yych <= '\r')
+        goto yy555;
+      if (yych <= 0x1F)
+        goto yy522;
+    } else {
+      if (yych <= '/') {
+        if (yych <= '.')
+          goto yy522;
+        goto yy557;
+      } else {
+        if (yych != '>')
+          goto yy522;
+      }
+    }
+  yy555:
+    ++p;
+    { return 6; }
+  yy557:
+    yych = *++p;
+    if (yych == '>')
+      goto yy555;
+    goto yy522;
+  yy558:
+    yych = *++p;
+    if (yych <= '/') {
+      if (yych <= 0x1F) {
+        if (yych <= 0x08)
+          goto yy522;
+        if (yych <= '\r')
+          goto yy555;
+        goto yy522;
+      } else {
+        if (yych <= ' ')
+          goto yy555;
+        if (yych <= '.')
+          goto yy522;
+        goto yy557;
+      }
+    } else {
+      if (yych <= '@') {
+        if (yych == '>')
+          goto yy555;
+        goto yy522;
+      } else {
+        if (yych <= 'A')
+          goto yy574;
+        if (yych == 'a')
+          goto yy574;
+        goto yy522;
+      }
+    }
+  yy559:
+    yych = *++p;
+    if (yych == 'T')
+      goto yy572;
+    if (yych == 't')
+      goto yy572;
+    goto yy522;
+  yy560:
+    yych = *++p;
+    if (yych <= '/') {
+      if (yych <= 0x1F) {
+        if (yych <= 0x08)
+          goto yy522;
+        if (yych <= '\r')
+          goto yy555;
+        goto yy522;
+      } else {
+        if (yych <= ' ')
+          goto yy555;
+        if (yych <= '.')
+          goto yy522;
+        goto yy557;
+      }
+    } else {
+      if (yych <= 'D') {
+        if (yych == '>')
+          goto yy555;
+        goto yy522;
+      } else {
+        if (yych <= 'E')
+          goto yy570;
+        if (yych == 'e')
+          goto yy570;
+        goto yy522;
+      }
+    }
+  yy561:
+    yych = *++p;
+    if (yych == 'O')
+      goto yy568;
+    if (yych == 'o')
+      goto yy568;
+    goto yy522;
+  yy562:
+    yych = *++p;
+    if (yych == 'O')
+      goto yy566;
+    if (yych == 'o')
+      goto yy566;
+    goto yy522;
+  yy563:
+    yych = *++p;
+    if (yych == 'B')
+      goto yy564;
+    if (yych != 'b')
+      goto yy522;
+  yy564:
+    yych = *++p;
+    if (yych == 'L')
+      goto yy565;
+    if (yych != 'l')
+      goto yy522;
+  yy565:
+    yych = *++p;
+    if (yych == 'E')
+      goto yy554;
+    if (yych == 'e')
+      goto yy554;
+    goto yy522;
+  yy566:
+    yych = *++p;
+    if (yych == 'D')
+      goto yy567;
+    if (yych != 'd')
+      goto yy522;
+  yy567:
+    yych = *++p;
+    if (yych == 'Y')
+      goto yy554;
+    if (yych == 'y')
+      goto yy554;
+    goto yy522;
+  yy568:
+    yych = *++p;
+    if (yych == 'O')
+      goto yy569;
+    if (yych != 'o')
+      goto yy522;
+  yy569:
+    yych = *++p;
+    if (yych == 'T')
+      goto yy554;
+    if (yych == 't')
+      goto yy554;
+    goto yy522;
+  yy570:
+    yych = *++p;
+    if (yych == 'A')
+      goto yy571;
+    if (yych != 'a')
+      goto yy522;
+  yy571:
+    yych = *++p;
+    if (yych == 'D')
+      goto yy554;
+    if (yych == 'd')
+      goto yy554;
+    goto yy522;
+  yy572:
+    yych = *++p;
+    if (yych == 'L')
+      goto yy573;
+    if (yych != 'l')
+      goto yy522;
+  yy573:
+    yych = *++p;
+    if (yych == 'E')
+      goto yy554;
+    if (yych == 'e')
+      goto yy554;
+    goto yy522;
+  yy574:
+    yych = *++p;
+    if (yych == 'C')
+      goto yy575;
+    if (yych != 'c')
+      goto yy522;
+  yy575:
+    yych = *++p;
+    if (yych == 'K')
+      goto yy554;
+    if (yych == 'k')
+      goto yy554;
+    goto yy522;
+  yy576:
+    yych = *++p;
+    if (yych == 'Y')
+      goto yy598;
+    if (yych == 'y')
+      goto yy598;
+    goto yy522;
+  yy577:
+    yych = *++p;
+    if (yych == 'R')
+      goto yy592;
+    if (yych == 'r')
+      goto yy592;
+    goto yy522;
+  yy578:
+    yych = *++p;
+    if (yych == 'M')
+      goto yy588;
+    if (yych == 'm')
+      goto yy588;
+    goto yy522;
+  yy579:
+    yych = *++p;
+    if (yych == 'U')
+      goto yy585;
+    if (yych == 'u')
+      goto yy585;
+    goto yy522;
+  yy580:
+    yych = *++p;
+    if (yych == 'C')
+      goto yy581;
+    if (yych != 'c')
+      goto yy522;
+  yy581:
+    yych = *++p;
+    if (yych == 'T')
+      goto yy582;
+    if (yych != 't')
+      goto yy522;
+  yy582:
+    yych = *++p;
+    if (yych == 'I')
+      goto yy583;
+    if (yych != 'i')
+      goto yy522;
+  yy583:
+    yych = *++p;
+    if (yych == 'O')
+      goto yy584;
+    if (yych != 'o')
+      goto yy522;
+  yy584:
+    yych = *++p;
+    if (yych == 'N')
+      goto yy554;
+    if (yych == 'n')
+      goto yy554;
+    goto yy522;
+  yy585:
+    yych = *++p;
+    if (yych == 'R')
+      goto yy586;
+    if (yych != 'r')
+      goto yy522;
+  yy586:
+    yych = *++p;
+    if (yych == 'C')
+      goto yy587;
+    if (yych != 'c')
+      goto yy522;
+  yy587:
+    yych = *++p;
+    if (yych == 'E')
+      goto yy554;
+    if (yych == 'e')
+      goto yy554;
+    goto yy522;
+  yy588:
+    yych = *++p;
+    if (yych == 'M')
+      goto yy589;
+    if (yych != 'm')
+      goto yy522;
+  yy589:
+    yych = *++p;
+    if (yych == 'A')
+      goto yy590;
+    if (yych != 'a')
+      goto yy522;
+  yy590:
+    yych = *++p;
+    if (yych == 'R')
+      goto yy591;
+    if (yych != 'r')
+      goto yy522;
+  yy591:
+    yych = *++p;
+    if (yych == 'Y')
+      goto yy554;
+    if (yych == 'y')
+      goto yy554;
+    goto yy522;
+  yy592:
+    yych = *++p;
+    if (yych == 'I')
+      goto yy593;
+    if (yych != 'i')
+      goto yy522;
+  yy593:
+    yych = *++p;
+    if (yych == 'P')
+      goto yy594;
+    if (yych != 'p')
+      goto yy522;
+  yy594:
+    yych = *++p;
+    if (yych == 'T')
+      goto yy595;
+    if (yych != 't')
+      goto yy522;
+  yy595:
+    yych = *++p;
+    if (yych <= 0x1F) {
+      if (yych <= 0x08)
+        goto yy522;
+      if (yych >= 0x0E)
+        goto yy522;
+    } else {
+      if (yych <= ' ')
+        goto yy596;
+      if (yych != '>')
+        goto yy522;
+    }
+  yy596:
+    ++p;
+    { return 1; }
+  yy598:
+    yych = *++p;
+    if (yych == 'L')
+      goto yy599;
+    if (yych != 'l')
+      goto yy522;
+  yy599:
+    yych = *++p;
+    if (yych == 'E')
+      goto yy595;
+    if (yych == 'e')
+      goto yy595;
+    goto yy522;
+  yy600:
+    yych = *++p;
+    if (yych == 'T')
+      goto yy601;
+    if (yych != 't')
+      goto yy522;
+  yy601:
+    yych = *++p;
+    if (yych <= 'I') {
+      if (yych == 'G')
+        goto yy603;
+      if (yych <= 'H')
+        goto yy522;
+    } else {
+      if (yych <= 'g') {
+        if (yych <= 'f')
+          goto yy522;
+        goto yy603;
+      } else {
+        if (yych != 'i')
+          goto yy522;
+      }
+    }
+    yych = *++p;
+    if (yych == 'O')
+      goto yy607;
+    if (yych == 'o')
+      goto yy607;
+    goto yy522;
+  yy603:
+    yych = *++p;
+    if (yych == 'R')
+      goto yy604;
+    if (yych != 'r')
+      goto yy522;
+  yy604:
+    yych = *++p;
+    if (yych == 'O')
+      goto yy605;
+    if (yych != 'o')
+      goto yy522;
+  yy605:
+    yych = *++p;
+    if (yych == 'U')
+      goto yy606;
+    if (yych != 'u')
+      goto yy522;
+  yy606:
+    yych = *++p;
+    if (yych == 'P')
+      goto yy554;
+    if (yych == 'p')
+      goto yy554;
+    goto yy522;
+  yy607:
+    yych = *++p;
+    if (yych == 'N')
+      goto yy554;
+    if (yych == 'n')
+      goto yy554;
+    goto yy522;
+  yy608:
+    yych = *++p;
+    if (yych == 'F')
+      goto yy610;
+    if (yych == 'f')
+      goto yy610;
+    goto yy522;
+  yy609:
+    yych = *++p;
+    if (yych == 'V')
+      goto yy554;
+    if (yych == 'v')
+      goto yy554;
+    goto yy522;
+  yy610:
+    yych = *++p;
+    if (yych == 'R')
+      goto yy611;
+    if (yych != 'r')
+      goto yy522;
+  yy611:
+    yych = *++p;
+    if (yych == 'A')
+      goto yy612;
+    if (yych != 'a')
+      goto yy522;
+  yy612:
+    yych = *++p;
+    if (yych == 'M')
+      goto yy613;
+    if (yych != 'm')
+      goto yy522;
+  yy613:
+    yych = *++p;
+    if (yych == 'E')
+      goto yy614;
+    if (yych != 'e')
+      goto yy522;
+  yy614:
+    yych = *++p;
+    if (yych == 'S')
+      goto yy554;
+    if (yych == 's')
+      goto yy554;
+    goto yy522;
+  yy615:
+    yych = *++p;
+    if (yych <= 'T') {
+      if (yych == 'N')
+        goto yy618;
+      if (yych <= 'S')
+        goto yy522;
+      goto yy619;
+    } else {
+      if (yych <= 'n') {
+        if (yych <= 'm')
+          goto yy522;
+        goto yy618;
+      } else {
+        if (yych == 't')
+          goto yy619;
+        goto yy522;
+      }
+    }
+  yy616:
+    yych = *++p;
+    if (yych == 'I')
+      goto yy617;
+    if (yych != 'i')
+      goto yy522;
+  yy617:
+    yych = *++p;
+    if (yych == 'N')
+      goto yy554;
+    if (yych == 'n')
+      goto yy554;
+    goto yy522;
+  yy618:
+    yych = *++p;
+    if (yych == 'U')
+      goto yy620;
+    if (yych == 'u')
+      goto yy620;
+    goto yy522;
+  yy619:
+    yych = *++p;
+    if (yych == 'A')
+      goto yy554;
+    if (yych == 'a')
+      goto yy554;
+    goto yy522;
+  yy620:
+    yych = *++p;
+    if (yych <= '/') {
+      if (yych <= 0x1F) {
+        if (yych <= 0x08)
+          goto yy522;
+        if (yych <= '\r')
+          goto yy555;
+        goto yy522;
+      } else {
+        if (yych <= ' ')
+          goto yy555;
+        if (yych <= '.')
+          goto yy522;
+        goto yy557;
+      }
+    } else {
+      if (yych <= 'H') {
+        if (yych == '>')
+          goto yy555;
+        goto yy522;
+      } else {
+        if (yych <= 'I')
+          goto yy621;
+        if (yych != 'i')
+          goto yy522;
+      }
+    }
+  yy621:
+    yych = *++p;
+    if (yych == 'T')
+      goto yy622;
+    if (yych != 't')
+      goto yy522;
+  yy622:
+    yych = *++p;
+    if (yych == 'E')
+      goto yy623;
+    if (yych != 'e')
+      goto yy522;
+  yy623:
+    yych = *++p;
+    if (yych == 'M')
+      goto yy554;
+    if (yych == 'm')
+      goto yy554;
+    goto yy522;
+  yy624:
+    yych = *++p;
+    if (yych <= '/') {
+      if (yych <= 0x1F) {
+        if (yych <= 0x08)
+          goto yy522;
+        if (yych <= '\r')
+          goto yy555;
+        goto yy522;
+      } else {
+        if (yych <= ' ')
+          goto yy555;
+        if (yych <= '.')
+          goto yy522;
+        goto yy557;
+      }
+    } else {
+      if (yych <= 'M') {
+        if (yych == '>')
+          goto yy555;
+        goto yy522;
+      } else {
+        if (yych <= 'N')
+          goto yy629;
+        if (yych == 'n')
+          goto yy629;
+        goto yy522;
+      }
+    }
+  yy625:
+    yych = *++p;
+    if (yych == 'G')
+      goto yy626;
+    if (yych != 'g')
+      goto yy522;
+  yy626:
+    yych = *++p;
+    if (yych == 'E')
+      goto yy627;
+    if (yych != 'e')
+      goto yy522;
+  yy627:
+    yych = *++p;
+    if (yych == 'N')
+      goto yy628;
+    if (yych != 'n')
+      goto yy522;
+  yy628:
+    yych = *++p;
+    if (yych == 'D')
+      goto yy554;
+    if (yych == 'd')
+      goto yy554;
+    goto yy522;
+  yy629:
+    yych = *++p;
+    if (yych == 'K')
+      goto yy554;
+    if (yych == 'k')
+      goto yy554;
+    goto yy522;
+  yy630:
+    yych = *++p;
+    if (yych == 'R')
+      goto yy631;
+    if (yych != 'r')
+      goto yy522;
+  yy631:
+    yych = *++p;
+    if (yych == 'A')
+      goto yy632;
+    if (yych != 'a')
+      goto yy522;
+  yy632:
+    yych = *++p;
+    if (yych == 'M')
+      goto yy633;
+    if (yych != 'm')
+      goto yy522;
+  yy633:
+    yych = *++p;
+    if (yych == 'E')
+      goto yy554;
+    if (yych == 'e')
+      goto yy554;
+    goto yy522;
+  yy634:
+    yych = *++p;
+    if (yych == 'M')
+      goto yy639;
+    if (yych == 'm')
+      goto yy639;
+    goto yy522;
+  yy635:
+    yych = *++p;
+    if (yych == 'A')
+      goto yy636;
+    if (yych != 'a')
+      goto yy522;
+  yy636:
+    yych = *++p;
+    if (yych == 'D')
+      goto yy637;
+    if (yych != 'd')
+      goto yy522;
+  yy637:
+    yych = *++p;
+    if (yych <= '/') {
+      if (yych <= 0x1F) {
+        if (yych <= 0x08)
+          goto yy522;
+        if (yych <= '\r')
+          goto yy555;
+        goto yy522;
+      } else {
+        if (yych <= ' ')
+          goto yy555;
+        if (yych <= '.')
+          goto yy522;
+        goto yy557;
+      }
+    } else {
+      if (yych <= 'D') {
+        if (yych == '>')
+          goto yy555;
+        goto yy522;
+      } else {
+        if (yych <= 'E')
+          goto yy638;
+        if (yych != 'e')
+          goto yy522;
+      }
+    }
+  yy638:
+    yych = *++p;
+    if (yych == 'R')
+      goto yy554;
+    if (yych == 'r')
+      goto yy554;
+    goto yy522;
+  yy639:
+    yych = *++p;
+    if (yych == 'L')
+      goto yy554;
+    if (yych == 'l')
+      goto yy554;
+    goto yy522;
+  yy640:
+    yych = *++p;
+    if (yych == 'A')
+      goto yy661;
+    if (yych == 'a')
+      goto yy661;
+    goto yy522;
+  yy641:
+    yych = *++p;
+    if (yych <= 'R') {
+      if (yych == 'O')
+        goto yy657;
+      if (yych <= 'Q')
+        goto yy522;
+      goto yy658;
+    } else {
+      if (yych <= 'o') {
+        if (yych <= 'n')
+          goto yy522;
+        goto yy657;
+      } else {
+        if (yych == 'r')
+          goto yy658;
+        goto yy522;
+      }
+    }
+  yy642:
+    yych = *++p;
+    if (yych <= 'G') {
+      if (yych == 'E')
+        goto yy643;
+      if (yych <= 'F')
+        goto yy522;
+      goto yy644;
+    } else {
+      if (yych <= 'e') {
+        if (yych <= 'd')
+          goto yy522;
+      } else {
+        if (yych == 'g')
+          goto yy644;
+        goto yy522;
+      }
+    }
+  yy643:
+    yych = *++p;
+    if (yych == 'L')
+      goto yy653;
+    if (yych == 'l')
+      goto yy653;
+    goto yy522;
+  yy644:
+    yych = *++p;
+    if (yych <= 'U') {
+      if (yych == 'C')
+        goto yy646;
+      if (yych <= 'T')
+        goto yy522;
+    } else {
+      if (yych <= 'c') {
+        if (yych <= 'b')
+          goto yy522;
+        goto yy646;
+      } else {
+        if (yych != 'u')
+          goto yy522;
+      }
+    }
+    yych = *++p;
+    if (yych == 'R')
+      goto yy652;
+    if (yych == 'r')
+      goto yy652;
+    goto yy522;
+  yy646:
+    yych = *++p;
+    if (yych == 'A')
+      goto yy647;
+    if (yych != 'a')
+      goto yy522;
+  yy647:
+    yych = *++p;
+    if (yych == 'P')
+      goto yy648;
+    if (yych != 'p')
+      goto yy522;
+  yy648:
+    yych = *++p;
+    if (yych == 'T')
+      goto yy649;
+    if (yych != 't')
+      goto yy522;
+  yy649:
+    yych = *++p;
+    if (yych == 'I')
+      goto yy650;
+    if (yych != 'i')
+      goto yy522;
+  yy650:
+    yych = *++p;
+    if (yych == 'O')
+      goto yy651;
+    if (yych != 'o')
+      goto yy522;
+  yy651:
+    yych = *++p;
+    if (yych == 'N')
+      goto yy554;
+    if (yych == 'n')
+      goto yy554;
+    goto yy522;
+  yy652:
+    yych = *++p;
+    if (yych == 'E')
+      goto yy554;
+    if (yych == 'e')
+      goto yy554;
+    goto yy522;
+  yy653:
+    yych = *++p;
+    if (yych == 'D')
+      goto yy654;
+    if (yych != 'd')
+      goto yy522;
+  yy654:
+    yych = *++p;
+    if (yych == 'S')
+      goto yy655;
+    if (yych != 's')
+      goto yy522;
+  yy655:
+    yych = *++p;
+    if (yych == 'E')
+      goto yy656;
+    if (yych != 'e')
+      goto yy522;
+  yy656:
+    yych = *++p;
+    if (yych == 'T')
+      goto yy554;
+    if (yych == 't')
+      goto yy554;
+    goto yy522;
+  yy657:
+    yych = *++p;
+    if (yych == 'T')
+      goto yy659;
+    if (yych == 't')
+      goto yy659;
+    goto yy522;
+  yy658:
+    yych = *++p;
+    if (yych == 'M')
+      goto yy554;
+    if (yych == 'm')
+      goto yy554;
+    goto yy522;
+  yy659:
+    yych = *++p;
+    if (yych == 'E')
+      goto yy660;
+    if (yych != 'e')
+      goto yy522;
+  yy660:
+    yych = *++p;
+    if (yych == 'R')
+      goto yy554;
+    if (yych == 'r')
+      goto yy554;
+    goto yy522;
+  yy661:
+    yych = *++p;
+    if (yych == 'M')
+      goto yy662;
+    if (yych != 'm')
+      goto yy522;
+  yy662:
+    yych = *++p;
+    if (yych == 'E')
+      goto yy663;
+    if (yych != 'e')
+      goto yy522;
+  yy663:
+    yych = *++p;
+    if (yych <= '/') {
+      if (yych <= 0x1F) {
+        if (yych <= 0x08)
+          goto yy522;
+        if (yych <= '\r')
+          goto yy555;
+        goto yy522;
+      } else {
+        if (yych <= ' ')
+          goto yy555;
+        if (yych <= '.')
+          goto yy522;
+        goto yy557;
+      }
+    } else {
+      if (yych <= 'R') {
+        if (yych == '>')
+          goto yy555;
+        goto yy522;
+      } else {
+        if (yych <= 'S')
+          goto yy664;
+        if (yych != 's')
+          goto yy522;
+      }
+    }
+  yy664:
+    yych = *++p;
+    if (yych == 'E')
+      goto yy665;
+    if (yych != 'e')
+      goto yy522;
+  yy665:
+    yych = *++p;
+    if (yych == 'T')
+      goto yy554;
+    if (yych == 't')
+      goto yy554;
+    goto yy522;
+  yy666:
+    yych = *++p;
+    if (yych <= 'V') {
+      if (yych <= 'Q') {
+        if (yych == 'A')
+          goto yy672;
+        goto yy522;
+      } else {
+        if (yych <= 'R')
+          goto yy554;
+        if (yych <= 'U')
+          goto yy522;
+        goto yy554;
+      }
+    } else {
+      if (yych <= 'q') {
+        if (yych == 'a')
+          goto yy672;
+        goto yy522;
+      } else {
+        if (yych <= 'r')
+          goto yy554;
+        if (yych == 'v')
+          goto yy554;
+        goto yy522;
+      }
+    }
+  yy667:
+    yych = *++p;
+    if (yych == 'T')
+      goto yy668;
+    if (yych != 't')
+      goto yy522;
+  yy668:
+    yych = *++p;
+    if (yych == 'A')
+      goto yy669;
+    if (yych != 'a')
+      goto yy522;
+  yy669:
+    yych = *++p;
+    if (yych == 'I')
+      goto yy670;
+    if (yych != 'i')
+      goto yy522;
+  yy670:
+    yych = *++p;
+    if (yych == 'L')
+      goto yy671;
+    if (yych != 'l')
+      goto yy522;
+  yy671:
+    yych = *++p;
+    if (yych == 'S')
+      goto yy554;
+    if (yych == 's')
+      goto yy554;
+    goto yy522;
+  yy672:
+    yych = *++p;
+    if (yych == 'L')
+      goto yy673;
+    if (yych != 'l')
+      goto yy522;
+  yy673:
+    yych = *++p;
+    if (yych == 'O')
+      goto yy674;
+    if (yych != 'o')
+      goto yy522;
+  yy674:
+    yych = *++p;
+    if (yych == 'G')
+      goto yy554;
+    if (yych == 'g')
+      goto yy554;
+    goto yy522;
+  yy675:
+    yych = *++p;
+    if (yych == 'L')
+      goto yy685;
+    if (yych == 'l')
+      goto yy685;
+    goto yy522;
+  yy676:
+    yych = *++p;
+    if (yych == 'N')
+      goto yy682;
+    if (yych == 'n')
+      goto yy682;
+    goto yy522;
+  yy677:
+    yych = *++p;
+    if (yych == 'P')
+      goto yy678;
+    if (yych != 'p')
+      goto yy522;
+  yy678:
+    yych = *++p;
+    if (yych == 'T')
+      goto yy679;
+    if (yych != 't')
+      goto yy522;
+  yy679:
+    yych = *++p;
+    if (yych == 'I')
+      goto yy680;
+    if (yych != 'i')
+      goto yy522;
+  yy680:
+    yych = *++p;
+    if (yych == 'O')
+      goto yy681;
+    if (yych != 'o')
+      goto yy522;
+  yy681:
+    yych = *++p;
+    if (yych == 'N')
+      goto yy554;
+    if (yych == 'n')
+      goto yy554;
+    goto yy522;
+  yy682:
+    yych = *++p;
+    if (yych == 'T')
+      goto yy683;
+    if (yych != 't')
+      goto yy522;
+  yy683:
+    yych = *++p;
+    if (yych == 'E')
+      goto yy684;
+    if (yych != 'e')
+      goto yy522;
+  yy684:
+    yych = *++p;
+    if (yych == 'R')
+      goto yy554;
+    if (yych == 'r')
+      goto yy554;
+    goto yy522;
+  yy685:
+    yych = *++p;
+    if (yych <= '/') {
+      if (yych <= 0x1F) {
+        if (yych <= 0x08)
+          goto yy522;
+        if (yych <= '\r')
+          goto yy555;
+        goto yy522;
+      } else {
+        if (yych <= ' ')
+          goto yy555;
+        if (yych <= '.')
+          goto yy522;
+        goto yy557;
+      }
+    } else {
+      if (yych <= 'F') {
+        if (yych == '>')
+          goto yy555;
+        goto yy522;
+      } else {
+        if (yych <= 'G')
+          goto yy686;
+        if (yych != 'g')
+          goto yy522;
+      }
+    }
+  yy686:
+    yych = *++p;
+    if (yych == 'R')
+      goto yy687;
+    if (yych != 'r')
+      goto yy522;
+  yy687:
+    yych = *++p;
+    if (yych == 'O')
+      goto yy688;
+    if (yych != 'o')
+      goto yy522;
+  yy688:
+    yych = *++p;
+    if (yych == 'U')
+      goto yy689;
+    if (yych != 'u')
+      goto yy522;
+  yy689:
+    yych = *++p;
+    if (yych == 'P')
+      goto yy554;
+    if (yych == 'p')
+      goto yy554;
+    goto yy522;
+  yy690:
+    yych = *++p;
+    if (yych == 'D')
+      goto yy705;
+    if (yych == 'd')
+      goto yy705;
+    goto yy522;
+  yy691:
+    yych = *++p;
+    if (yych == 'O')
+      goto yy698;
+    if (yych == 'o')
+      goto yy698;
+    goto yy522;
+  yy692:
+    yych = *++p;
+    if (yych == 'S')
+      goto yy693;
+    if (yych != 's')
+      goto yy522;
+  yy693:
+    yych = *++p;
+    if (yych == 'E')
+      goto yy694;
+    if (yych != 'e')
+      goto yy522;
+  yy694:
+    yych = *++p;
+    if (yych <= '/') {
+      if (yych <= 0x1F) {
+        if (yych <= 0x08)
+          goto yy522;
+        if (yych <= '\r')
+          goto yy555;
+        goto yy522;
+      } else {
+        if (yych <= ' ')
+          goto yy555;
+        if (yych <= '.')
+          goto yy522;
+        goto yy557;
+      }
+    } else {
+      if (yych <= 'E') {
+        if (yych == '>')
+          goto yy555;
+        goto yy522;
+      } else {
+        if (yych <= 'F')
+          goto yy695;
+        if (yych != 'f')
+          goto yy522;
+      }
+    }
+  yy695:
+    yych = *++p;
+    if (yych == 'O')
+      goto yy696;
+    if (yych != 'o')
+      goto yy522;
+  yy696:
+    yych = *++p;
+    if (yych == 'N')
+      goto yy697;
+    if (yych != 'n')
+      goto yy522;
+  yy697:
+    yych = *++p;
+    if (yych == 'T')
+      goto yy554;
+    if (yych == 't')
+      goto yy554;
+    goto yy522;
+  yy698:
+    yych = *++p;
+    if (yych == 'C')
+      goto yy699;
+    if (yych != 'c')
+      goto yy522;
+  yy699:
+    yych = *++p;
+    if (yych == 'K')
+      goto yy700;
+    if (yych != 'k')
+      goto yy522;
+  yy700:
+    yych = *++p;
+    if (yych == 'Q')
+      goto yy701;
+    if (yych != 'q')
+      goto yy522;
+  yy701:
+    yych = *++p;
+    if (yych == 'U')
+      goto yy702;
+    if (yych != 'u')
+      goto yy522;
+  yy702:
+    yych = *++p;
+    if (yych == 'O')
+      goto yy703;
+    if (yych != 'o')
+      goto yy522;
+  yy703:
+    yych = *++p;
+    if (yych == 'T')
+      goto yy704;
+    if (yych != 't')
+      goto yy522;
+  yy704:
+    yych = *++p;
+    if (yych == 'E')
+      goto yy554;
+    if (yych == 'e')
+      goto yy554;
+    goto yy522;
+  yy705:
+    yych = *++p;
+    if (yych == 'Y')
+      goto yy554;
+    if (yych == 'y')
+      goto yy554;
+    goto yy522;
+  yy706:
+    yych = *++p;
+    if (yych == 'I')
+      goto yy717;
+    if (yych == 'i')
+      goto yy717;
+    goto yy522;
+  yy707:
+    yych = *++p;
+    if (yych == 'T')
+      goto yy713;
+    if (yych == 't')
+      goto yy713;
+    goto yy522;
+  yy708:
+    yych = *++p;
+    if (yych == 'D')
+      goto yy709;
+    if (yych != 'd')
+      goto yy522;
+  yy709:
+    yych = *++p;
+    if (yych == 'R')
+      goto yy710;
+    if (yych != 'r')
+      goto yy522;
+  yy710:
+    yych = *++p;
+    if (yych == 'E')
+      goto yy711;
+    if (yych != 'e')
+      goto yy522;
+  yy711:
+    yych = *++p;
+    if (yych == 'S')
+      goto yy712;
+    if (yych != 's')
+      goto yy522;
+  yy712:
+    yych = *++p;
+    if (yych == 'S')
+      goto yy554;
+    if (yych == 's')
+      goto yy554;
+    goto yy522;
+  yy713:
+    yych = *++p;
+    if (yych == 'I')
+      goto yy714;
+    if (yych != 'i')
+      goto yy522;
+  yy714:
+    yych = *++p;
+    if (yych == 'C')
+      goto yy715;
+    if (yych != 'c')
+      goto yy522;
+  yy715:
+    yych = *++p;
+    if (yych == 'L')
+      goto yy716;
+    if (yych != 'l')
+      goto yy522;
+  yy716:
+    yych = *++p;
+    if (yych == 'E')
+      goto yy554;
+    if (yych == 'e')
+      goto yy554;
+    goto yy522;
+  yy717:
+    yych = *++p;
+    if (yych == 'D')
+      goto yy718;
+    if (yych != 'd')
+      goto yy522;
+  yy718:
+    yych = *++p;
+    if (yych == 'E')
+      goto yy554;
+    if (yych == 'e')
+      goto yy554;
+    goto yy522;
+  yy719:
+    yych = *++p;
+    if (yych == 'E')
+      goto yy595;
+    if (yych == 'e')
+      goto yy595;
+    goto yy522;
+  yy720:
+    yych = *++p;
+    if (yych == 'R')
+      goto yy721;
+    if (yych != 'r')
+      goto yy522;
+  yy721:
+    yych = *++p;
+    if (yych == 'A')
+      goto yy722;
+    if (yych != 'a')
+      goto yy522;
+  yy722:
+    yych = *++p;
+    if (yych == 'M')
+      goto yy554;
+    if (yych == 'm')
+      goto yy554;
+    goto yy522;
+  yy723:
+    yych = *++p;
+    if (yych <= '/') {
+      if (yych <= 0x1F) {
+        if (yych <= 0x08)
+          goto yy522;
+        if (yych <= '\r')
+          goto yy555;
+        goto yy522;
+      } else {
+        if (yych <= ' ')
+          goto yy555;
+        if (yych <= '.')
+          goto yy522;
+        goto yy557;
+      }
+    } else {
+      if (yych <= '@') {
+        if (yych == '>')
+          goto yy555;
+        goto yy522;
+      } else {
+        if (yych <= 'A')
+          goto yy720;
+        if (yych == 'a')
+          goto yy720;
+        goto yy522;
+      }
+    }
+  yy724:
+    ++p;
+    if ((yych = *p) <= 'U') {
+      if (yych <= 'N') {
+        if (yych == 'E')
+          goto yy580;
+        goto yy522;
+      } else {
+        if (yych <= 'O')
+          goto yy579;
+        if (yych <= 'T')
+          goto yy522;
+        goto yy578;
+      }
+    } else {
+      if (yych <= 'n') {
+        if (yych == 'e')
+          goto yy580;
+        goto yy522;
+      } else {
+        if (yych <= 'o')
+          goto yy579;
+        if (yych == 'u')
+          goto yy578;
+        goto yy522;
+      }
+    }
+  }
+}
+
+// Try to match an HTML block tag start line of type 7, returning
+// 7 if successful, 0 if not.
+bufsize_t _scan_html_block_start_7(const unsigned char *p) {
+  const unsigned char *marker = NULL;
+
+  {
+    unsigned char yych;
+    unsigned int yyaccept = 0;
+    static const unsigned char yybm[] = {
+        0,   224, 224, 224, 224, 224, 224, 224, 224, 198, 202, 194, 198, 194,
+        224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224,
+        224, 224, 224, 224, 198, 224, 64,  224, 224, 224, 224, 128, 224, 224,
+        224, 224, 224, 241, 240, 224, 241, 241, 241, 241, 241, 241, 241, 241,
+        241, 241, 240, 224, 192, 192, 192, 224, 224, 241, 241, 241, 241, 241,
+        241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241,
+        241, 241, 241, 241, 241, 241, 241, 224, 224, 224, 224, 240, 192, 241,
+        241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241,
+        241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 224, 224, 224,
+        224, 224, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,
+    };
+    yych = *p;
+    if (yych == '<')
+      goto yy729;
+    ++p;
+  yy728 : { return 0; }
+  yy729:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= '@') {
+      if (yych == '/')
+        goto yy733;
+      goto yy728;
+    } else {
+      if (yych <= 'Z')
+        goto yy730;
+      if (yych <= '`')
+        goto yy728;
+      if (yych >= '{')
+        goto yy728;
+    }
+  yy730:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 1) {
+      goto yy730;
+    }
+    if (yych <= ' ') {
+      if (yych <= 0x08)
+        goto yy732;
+      if (yych <= '\r')
+        goto yy744;
+      if (yych >= ' ')
+        goto yy744;
+    } else {
+      if (yych <= '/') {
+        if (yych >= '/')
+          goto yy746;
+      } else {
+        if (yych == '>')
+          goto yy738;
+      }
+    }
+  yy732:
+    p = marker;
+    if (yyaccept == 0) {
+      goto yy728;
+    } else {
+      goto yy742;
+    }
+  yy733:
+    yych = *++p;
+    if (yych <= '@')
+      goto yy732;
+    if (yych <= 'Z')
+      goto yy734;
+    if (yych <= '`')
+      goto yy732;
+    if (yych >= '{')
+      goto yy732;
+  yy734:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 2) {
+      goto yy736;
+    }
+    if (yych <= '=') {
+      if (yych <= '-') {
+        if (yych <= ',')
+          goto yy732;
+        goto yy734;
+      } else {
+        if (yych <= '/')
+          goto yy732;
+        if (yych <= '9')
+          goto yy734;
+        goto yy732;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '>')
+          goto yy738;
+        if (yych <= '@')
+          goto yy732;
+        goto yy734;
+      } else {
+        if (yych <= '`')
+          goto yy732;
+        if (yych <= 'z')
+          goto yy734;
+        goto yy732;
+      }
+    }
+  yy736:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 2) {
+      goto yy736;
+    }
+    if (yych != '>')
+      goto yy732;
+  yy738:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 4) {
+      goto yy738;
+    }
+    if (yych <= 0x08)
+      goto yy732;
+    if (yych <= '\n')
+      goto yy740;
+    if (yych <= '\v')
+      goto yy732;
+    if (yych <= '\r')
+      goto yy743;
+    goto yy732;
+  yy740:
+    yyaccept = 1;
+    marker = ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 4) {
+      goto yy738;
+    }
+    if (yych <= 0x08)
+      goto yy742;
+    if (yych <= '\n')
+      goto yy740;
+    if (yych <= '\v')
+      goto yy742;
+    if (yych <= '\r')
+      goto yy743;
+  yy742 : { return 7; }
+  yy743:
+    yych = *++p;
+    goto yy742;
+  yy744:
+    ++p;
+    yych = *p;
+    if (yych <= ':') {
+      if (yych <= ' ') {
+        if (yych <= 0x08)
+          goto yy732;
+        if (yych <= '\r')
+          goto yy744;
+        if (yych <= 0x1F)
+          goto yy732;
+        goto yy744;
+      } else {
+        if (yych == '/')
+          goto yy746;
+        if (yych <= '9')
+          goto yy732;
+        goto yy747;
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych == '>')
+          goto yy738;
+        if (yych <= '@')
+          goto yy732;
+        goto yy747;
+      } else {
+        if (yych <= '_') {
+          if (yych <= '^')
+            goto yy732;
+          goto yy747;
+        } else {
+          if (yych <= '`')
+            goto yy732;
+          if (yych <= 'z')
+            goto yy747;
+          goto yy732;
+        }
+      }
+    }
+  yy746:
+    yych = *++p;
+    if (yych == '>')
+      goto yy738;
+    goto yy732;
+  yy747:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 16) {
+      goto yy747;
+    }
+    if (yych <= ',') {
+      if (yych <= '\r') {
+        if (yych <= 0x08)
+          goto yy732;
+      } else {
+        if (yych != ' ')
+          goto yy732;
+      }
+    } else {
+      if (yych <= '<') {
+        if (yych <= '/')
+          goto yy746;
+        goto yy732;
+      } else {
+        if (yych <= '=')
+          goto yy751;
+        if (yych <= '>')
+          goto yy738;
+        goto yy732;
+      }
+    }
+  yy749:
+    ++p;
+    yych = *p;
+    if (yych <= '<') {
+      if (yych <= ' ') {
+        if (yych <= 0x08)
+          goto yy732;
+        if (yych <= '\r')
+          goto yy749;
+        if (yych <= 0x1F)
+          goto yy732;
+        goto yy749;
+      } else {
+        if (yych <= '/') {
+          if (yych <= '.')
+            goto yy732;
+          goto yy746;
+        } else {
+          if (yych == ':')
+            goto yy747;
+          goto yy732;
+        }
+      }
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '=')
+          goto yy751;
+        if (yych <= '>')
+          goto yy738;
+        if (yych <= '@')
+          goto yy732;
+        goto yy747;
+      } else {
+        if (yych <= '_') {
+          if (yych <= '^')
+            goto yy732;
+          goto yy747;
+        } else {
+          if (yych <= '`')
+            goto yy732;
+          if (yych <= 'z')
+            goto yy747;
+          goto yy732;
+        }
+      }
+    }
+  yy751:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 32) {
+      goto yy753;
+    }
+    if (yych <= 0xE0) {
+      if (yych <= '"') {
+        if (yych <= 0x00)
+          goto yy732;
+        if (yych >= '!')
+          goto yy764;
+      } else {
+        if (yych <= '\'')
+          goto yy762;
+        if (yych <= 0xC1)
+          goto yy732;
+        if (yych <= 0xDF)
+          goto yy755;
+        goto yy756;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych == 0xED)
+          goto yy761;
+        goto yy757;
+      } else {
+        if (yych <= 0xF0)
+          goto yy758;
+        if (yych <= 0xF3)
+          goto yy759;
+        if (yych <= 0xF4)
+          goto yy760;
+        goto yy732;
+      }
+    }
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 32) {
+      goto yy753;
+    }
+    if (yych <= 0xDF) {
+      if (yych <= '\'') {
+        if (yych <= 0x00)
+          goto yy732;
+        if (yych <= ' ')
+          goto yy787;
+        if (yych <= '"')
+          goto yy764;
+        goto yy762;
+      } else {
+        if (yych == '>')
+          goto yy738;
+        if (yych <= 0xC1)
+          goto yy732;
+        goto yy755;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych <= 0xE0)
+          goto yy756;
+        if (yych == 0xED)
+          goto yy761;
+        goto yy757;
+      } else {
+        if (yych <= 0xF0)
+          goto yy758;
+        if (yych <= 0xF3)
+          goto yy759;
+        if (yych <= 0xF4)
+          goto yy760;
+        goto yy732;
+      }
+    }
+  yy753:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 32) {
+      goto yy753;
+    }
+    if (yych <= 0xE0) {
+      if (yych <= '=') {
+        if (yych <= 0x00)
+          goto yy732;
+        if (yych <= ' ')
+          goto yy781;
+        goto yy732;
+      } else {
+        if (yych <= '>')
+          goto yy738;
+        if (yych <= 0xC1)
+          goto yy732;
+        if (yych >= 0xE0)
+          goto yy756;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych == 0xED)
+          goto yy761;
+        goto yy757;
+      } else {
+        if (yych <= 0xF0)
+          goto yy758;
+        if (yych <= 0xF3)
+          goto yy759;
+        if (yych <= 0xF4)
+          goto yy760;
+        goto yy732;
+      }
+    }
+  yy755:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy732;
+    if (yych <= 0xBF)
+      goto yy753;
+    goto yy732;
+  yy756:
+    ++p;
+    yych = *p;
+    if (yych <= 0x9F)
+      goto yy732;
+    if (yych <= 0xBF)
+      goto yy755;
+    goto yy732;
+  yy757:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy732;
+    if (yych <= 0xBF)
+      goto yy755;
+    goto yy732;
+  yy758:
+    ++p;
+    yych = *p;
+    if (yych <= 0x8F)
+      goto yy732;
+    if (yych <= 0xBF)
+      goto yy757;
+    goto yy732;
+  yy759:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy732;
+    if (yych <= 0xBF)
+      goto yy757;
+    goto yy732;
+  yy760:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy732;
+    if (yych <= 0x8F)
+      goto yy757;
+    goto yy732;
+  yy761:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy732;
+    if (yych <= 0x9F)
+      goto yy755;
+    goto yy732;
+  yy762:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 64) {
+      goto yy762;
+    }
+    if (yych <= 0xEC) {
+      if (yych <= 0xC1) {
+        if (yych <= 0x00)
+          goto yy732;
+        if (yych <= '\'')
+          goto yy773;
+        goto yy732;
+      } else {
+        if (yych <= 0xDF)
+          goto yy774;
+        if (yych <= 0xE0)
+          goto yy775;
+        goto yy776;
+      }
+    } else {
+      if (yych <= 0xF0) {
+        if (yych <= 0xED)
+          goto yy780;
+        if (yych <= 0xEF)
+          goto yy776;
+        goto yy777;
+      } else {
+        if (yych <= 0xF3)
+          goto yy778;
+        if (yych <= 0xF4)
+          goto yy779;
+        goto yy732;
+      }
+    }
+  yy764:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 128) {
+      goto yy764;
+    }
+    if (yych <= 0xEC) {
+      if (yych <= 0xC1) {
+        if (yych <= 0x00)
+          goto yy732;
+        if (yych <= '"')
+          goto yy773;
+        goto yy732;
+      } else {
+        if (yych <= 0xDF)
+          goto yy766;
+        if (yych <= 0xE0)
+          goto yy767;
+        goto yy768;
+      }
+    } else {
+      if (yych <= 0xF0) {
+        if (yych <= 0xED)
+          goto yy772;
+        if (yych <= 0xEF)
+          goto yy768;
+        goto yy769;
+      } else {
+        if (yych <= 0xF3)
+          goto yy770;
+        if (yych <= 0xF4)
+          goto yy771;
+        goto yy732;
+      }
+    }
+  yy766:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy732;
+    if (yych <= 0xBF)
+      goto yy764;
+    goto yy732;
+  yy767:
+    ++p;
+    yych = *p;
+    if (yych <= 0x9F)
+      goto yy732;
+    if (yych <= 0xBF)
+      goto yy766;
+    goto yy732;
+  yy768:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy732;
+    if (yych <= 0xBF)
+      goto yy766;
+    goto yy732;
+  yy769:
+    ++p;
+    yych = *p;
+    if (yych <= 0x8F)
+      goto yy732;
+    if (yych <= 0xBF)
+      goto yy768;
+    goto yy732;
+  yy770:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy732;
+    if (yych <= 0xBF)
+      goto yy768;
+    goto yy732;
+  yy771:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy732;
+    if (yych <= 0x8F)
+      goto yy768;
+    goto yy732;
+  yy772:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy732;
+    if (yych <= 0x9F)
+      goto yy766;
+    goto yy732;
+  yy773:
+    ++p;
+    yych = *p;
+    if (yych <= ' ') {
+      if (yych <= 0x08)
+        goto yy732;
+      if (yych <= '\r')
+        goto yy744;
+      if (yych <= 0x1F)
+        goto yy732;
+      goto yy744;
+    } else {
+      if (yych <= '/') {
+        if (yych <= '.')
+          goto yy732;
+        goto yy746;
+      } else {
+        if (yych == '>')
+          goto yy738;
+        goto yy732;
+      }
+    }
+  yy774:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy732;
+    if (yych <= 0xBF)
+      goto yy762;
+    goto yy732;
+  yy775:
+    ++p;
+    yych = *p;
+    if (yych <= 0x9F)
+      goto yy732;
+    if (yych <= 0xBF)
+      goto yy774;
+    goto yy732;
+  yy776:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy732;
+    if (yych <= 0xBF)
+      goto yy774;
+    goto yy732;
+  yy777:
+    ++p;
+    yych = *p;
+    if (yych <= 0x8F)
+      goto yy732;
+    if (yych <= 0xBF)
+      goto yy776;
+    goto yy732;
+  yy778:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy732;
+    if (yych <= 0xBF)
+      goto yy776;
+    goto yy732;
+  yy779:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy732;
+    if (yych <= 0x8F)
+      goto yy776;
+    goto yy732;
+  yy780:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy732;
+    if (yych <= 0x9F)
+      goto yy774;
+    goto yy732;
+  yy781:
+    ++p;
+    yych = *p;
+    if (yych <= '@') {
+      if (yych <= '"') {
+        if (yych <= '\r') {
+          if (yych <= 0x00)
+            goto yy732;
+          if (yych <= 0x08)
+            goto yy753;
+          goto yy781;
+        } else {
+          if (yych == ' ')
+            goto yy781;
+          if (yych <= '!')
+            goto yy753;
+          goto yy732;
+        }
+      } else {
+        if (yych <= ':') {
+          if (yych == '\'')
+            goto yy732;
+          if (yych <= '9')
+            goto yy753;
+        } else {
+          if (yych <= ';')
+            goto yy753;
+          if (yych <= '=')
+            goto yy732;
+          if (yych <= '>')
+            goto yy738;
+          goto yy753;
+        }
+      }
+    } else {
+      if (yych <= 0xDF) {
+        if (yych <= '`') {
+          if (yych <= 'Z')
+            goto yy783;
+          if (yych <= '^')
+            goto yy753;
+          if (yych >= '`')
+            goto yy732;
+        } else {
+          if (yych <= 'z')
+            goto yy783;
+          if (yych <= 0x7F)
+            goto yy753;
+          if (yych <= 0xC1)
+            goto yy732;
+          goto yy755;
+        }
+      } else {
+        if (yych <= 0xEF) {
+          if (yych <= 0xE0)
+            goto yy756;
+          if (yych == 0xED)
+            goto yy761;
+          goto yy757;
+        } else {
+          if (yych <= 0xF0)
+            goto yy758;
+          if (yych <= 0xF3)
+            goto yy759;
+          if (yych <= 0xF4)
+            goto yy760;
+          goto yy732;
+        }
+      }
+    }
+  yy783:
+    ++p;
+    yych = *p;
+    if (yych <= '>') {
+      if (yych <= '&') {
+        if (yych <= 0x1F) {
+          if (yych <= 0x00)
+            goto yy732;
+          if (yych <= 0x08)
+            goto yy753;
+          if (yych >= 0x0E)
+            goto yy753;
+        } else {
+          if (yych <= ' ')
+            goto yy785;
+          if (yych == '"')
+            goto yy732;
+          goto yy753;
+        }
+      } else {
+        if (yych <= '/') {
+          if (yych <= '\'')
+            goto yy732;
+          if (yych <= ',')
+            goto yy753;
+          if (yych <= '.')
+            goto yy783;
+          goto yy753;
+        } else {
+          if (yych <= ';') {
+            if (yych <= ':')
+              goto yy783;
+            goto yy753;
+          } else {
+            if (yych <= '<')
+              goto yy732;
+            if (yych <= '=')
+              goto yy751;
+            goto yy738;
+          }
+        }
+      }
+    } else {
+      if (yych <= 0xC1) {
+        if (yych <= '_') {
+          if (yych <= '@')
+            goto yy753;
+          if (yych <= 'Z')
+            goto yy783;
+          if (yych <= '^')
+            goto yy753;
+          goto yy783;
+        } else {
+          if (yych <= '`')
+            goto yy732;
+          if (yych <= 'z')
+            goto yy783;
+          if (yych <= 0x7F)
+            goto yy753;
+          goto yy732;
+        }
+      } else {
+        if (yych <= 0xED) {
+          if (yych <= 0xDF)
+            goto yy755;
+          if (yych <= 0xE0)
+            goto yy756;
+          if (yych <= 0xEC)
+            goto yy757;
+          goto yy761;
+        } else {
+          if (yych <= 0xF0) {
+            if (yych <= 0xEF)
+              goto yy757;
+            goto yy758;
+          } else {
+            if (yych <= 0xF3)
+              goto yy759;
+            if (yych <= 0xF4)
+              goto yy760;
+            goto yy732;
+          }
+        }
+      }
+    }
+  yy785:
+    ++p;
+    yych = *p;
+    if (yych <= '@') {
+      if (yych <= '&') {
+        if (yych <= 0x1F) {
+          if (yych <= 0x00)
+            goto yy732;
+          if (yych <= 0x08)
+            goto yy753;
+          if (yych <= '\r')
+            goto yy785;
+          goto yy753;
+        } else {
+          if (yych <= ' ')
+            goto yy785;
+          if (yych == '"')
+            goto yy732;
+          goto yy753;
+        }
+      } else {
+        if (yych <= ';') {
+          if (yych <= '\'')
+            goto yy732;
+          if (yych == ':')
+            goto yy783;
+          goto yy753;
+        } else {
+          if (yych <= '<')
+            goto yy732;
+          if (yych <= '=')
+            goto yy751;
+          if (yych <= '>')
+            goto yy738;
+          goto yy753;
+        }
+      }
+    } else {
+      if (yych <= 0xDF) {
+        if (yych <= '`') {
+          if (yych <= 'Z')
+            goto yy783;
+          if (yych <= '^')
+            goto yy753;
+          if (yych <= '_')
+            goto yy783;
+          goto yy732;
+        } else {
+          if (yych <= 'z')
+            goto yy783;
+          if (yych <= 0x7F)
+            goto yy753;
+          if (yych <= 0xC1)
+            goto yy732;
+          goto yy755;
+        }
+      } else {
+        if (yych <= 0xEF) {
+          if (yych <= 0xE0)
+            goto yy756;
+          if (yych == 0xED)
+            goto yy761;
+          goto yy757;
+        } else {
+          if (yych <= 0xF0)
+            goto yy758;
+          if (yych <= 0xF3)
+            goto yy759;
+          if (yych <= 0xF4)
+            goto yy760;
+          goto yy732;
+        }
+      }
+    }
+  yy787:
+    ++p;
+    yych = *p;
+    if (yych <= '@') {
+      if (yych <= '"') {
+        if (yych <= '\r') {
+          if (yych <= 0x00)
+            goto yy732;
+          if (yych <= 0x08)
+            goto yy753;
+          goto yy787;
+        } else {
+          if (yych == ' ')
+            goto yy787;
+          if (yych <= '!')
+            goto yy753;
+          goto yy764;
+        }
+      } else {
+        if (yych <= ':') {
+          if (yych == '\'')
+            goto yy762;
+          if (yych <= '9')
+            goto yy753;
+          goto yy783;
+        } else {
+          if (yych <= ';')
+            goto yy753;
+          if (yych <= '=')
+            goto yy732;
+          if (yych <= '>')
+            goto yy738;
+          goto yy753;
+        }
+      }
+    } else {
+      if (yych <= 0xDF) {
+        if (yych <= '`') {
+          if (yych <= 'Z')
+            goto yy783;
+          if (yych <= '^')
+            goto yy753;
+          if (yych <= '_')
+            goto yy783;
+          goto yy732;
+        } else {
+          if (yych <= 'z')
+            goto yy783;
+          if (yych <= 0x7F)
+            goto yy753;
+          if (yych <= 0xC1)
+            goto yy732;
+          goto yy755;
+        }
+      } else {
+        if (yych <= 0xEF) {
+          if (yych <= 0xE0)
+            goto yy756;
+          if (yych == 0xED)
+            goto yy761;
+          goto yy757;
+        } else {
+          if (yych <= 0xF0)
+            goto yy758;
+          if (yych <= 0xF3)
+            goto yy759;
+          if (yych <= 0xF4)
+            goto yy760;
+          goto yy732;
+        }
+      }
+    }
+  }
+}
+
+// Try to match an HTML block end line of type 1
+bufsize_t _scan_html_block_end_1(const unsigned char *p) {
+  const unsigned char *marker = NULL;
+  const unsigned char *start = p;
+
+  {
+    unsigned char yych;
+    unsigned int yyaccept = 0;
+    static const unsigned char yybm[] = {
+        0,  64, 64, 64, 64, 64, 64,  64, 64, 64, 0,  64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 128, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,
+    };
+    yych = *p;
+    if (yych <= 0xDF) {
+      if (yych <= ';') {
+        if (yych <= 0x00)
+          goto yy791;
+        if (yych != '\n')
+          goto yy793;
+      } else {
+        if (yych <= '<')
+          goto yy794;
+        if (yych <= 0x7F)
+          goto yy793;
+        if (yych >= 0xC2)
+          goto yy795;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych <= 0xE0)
+          goto yy796;
+        if (yych == 0xED)
+          goto yy798;
+        goto yy797;
+      } else {
+        if (yych <= 0xF0)
+          goto yy799;
+        if (yych <= 0xF3)
+          goto yy800;
+        if (yych <= 0xF4)
+          goto yy801;
+      }
+    }
+  yy791:
+    ++p;
+  yy792 : { return 0; }
+  yy793:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= '\n') {
+      if (yych <= 0x00)
+        goto yy792;
+      if (yych <= '\t')
+        goto yy806;
+      goto yy792;
+    } else {
+      if (yych <= 0x7F)
+        goto yy806;
+      if (yych <= 0xC1)
+        goto yy792;
+      if (yych <= 0xF4)
+        goto yy806;
+      goto yy792;
+    }
+  yy794:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= '.') {
+      if (yych <= 0x00)
+        goto yy792;
+      if (yych == '\n')
+        goto yy792;
+      goto yy806;
+    } else {
+      if (yych <= 0x7F) {
+        if (yych <= '/')
+          goto yy814;
+        goto yy806;
+      } else {
+        if (yych <= 0xC1)
+          goto yy792;
+        if (yych <= 0xF4)
+          goto yy806;
+        goto yy792;
+      }
+    }
+  yy795:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy792;
+    if (yych <= 0xBF)
+      goto yy805;
+    goto yy792;
+  yy796:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x9F)
+      goto yy792;
+    if (yych <= 0xBF)
+      goto yy804;
+    goto yy792;
+  yy797:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy792;
+    if (yych <= 0xBF)
+      goto yy804;
+    goto yy792;
+  yy798:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy792;
+    if (yych <= 0x9F)
+      goto yy804;
+    goto yy792;
+  yy799:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x8F)
+      goto yy792;
+    if (yych <= 0xBF)
+      goto yy802;
+    goto yy792;
+  yy800:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy792;
+    if (yych <= 0xBF)
+      goto yy802;
+    goto yy792;
+  yy801:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy792;
+    if (yych >= 0x90)
+      goto yy792;
+  yy802:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy803;
+    if (yych <= 0xBF)
+      goto yy804;
+  yy803:
+    p = marker;
+    if (yyaccept == 0) {
+      goto yy792;
+    } else {
+      goto yy820;
+    }
+  yy804:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy803;
+    if (yych >= 0xC0)
+      goto yy803;
+  yy805:
+    ++p;
+    yych = *p;
+  yy806:
+    if (yybm[0 + yych] & 64) {
+      goto yy805;
+    }
+    if (yych <= 0xEC) {
+      if (yych <= 0xC1) {
+        if (yych <= '\n')
+          goto yy803;
+        if (yych >= '=')
+          goto yy803;
+      } else {
+        if (yych <= 0xDF)
+          goto yy804;
+        if (yych <= 0xE0)
+          goto yy809;
+        goto yy802;
+      }
+    } else {
+      if (yych <= 0xF0) {
+        if (yych <= 0xED)
+          goto yy813;
+        if (yych <= 0xEF)
+          goto yy802;
+        goto yy810;
+      } else {
+        if (yych <= 0xF3)
+          goto yy811;
+        if (yych <= 0xF4)
+          goto yy812;
+        goto yy803;
+      }
+    }
+  yy807:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 128) {
+      goto yy807;
+    }
+    if (yych <= 0xDF) {
+      if (yych <= '.') {
+        if (yych <= 0x00)
+          goto yy803;
+        if (yych == '\n')
+          goto yy803;
+        goto yy805;
+      } else {
+        if (yych <= '/')
+          goto yy814;
+        if (yych <= 0x7F)
+          goto yy805;
+        if (yych <= 0xC1)
+          goto yy803;
+        goto yy804;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych <= 0xE0)
+          goto yy809;
+        if (yych == 0xED)
+          goto yy813;
+        goto yy802;
+      } else {
+        if (yych <= 0xF0)
+          goto yy810;
+        if (yych <= 0xF3)
+          goto yy811;
+        if (yych <= 0xF4)
+          goto yy812;
+        goto yy803;
+      }
+    }
+  yy809:
+    ++p;
+    yych = *p;
+    if (yych <= 0x9F)
+      goto yy803;
+    if (yych <= 0xBF)
+      goto yy804;
+    goto yy803;
+  yy810:
+    ++p;
+    yych = *p;
+    if (yych <= 0x8F)
+      goto yy803;
+    if (yych <= 0xBF)
+      goto yy802;
+    goto yy803;
+  yy811:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy803;
+    if (yych <= 0xBF)
+      goto yy802;
+    goto yy803;
+  yy812:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy803;
+    if (yych <= 0x8F)
+      goto yy802;
+    goto yy803;
+  yy813:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy803;
+    if (yych <= 0x9F)
+      goto yy804;
+    goto yy803;
+  yy814:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 128) {
+      goto yy807;
+    }
+    if (yych <= 's') {
+      if (yych <= 'P') {
+        if (yych <= '\t') {
+          if (yych <= 0x00)
+            goto yy803;
+          goto yy805;
+        } else {
+          if (yych <= '\n')
+            goto yy803;
+          if (yych <= 'O')
+            goto yy805;
+          goto yy816;
+        }
+      } else {
+        if (yych <= 'o') {
+          if (yych != 'S')
+            goto yy805;
+        } else {
+          if (yych <= 'p')
+            goto yy816;
+          if (yych <= 'r')
+            goto yy805;
+        }
+      }
+    } else {
+      if (yych <= 0xEC) {
+        if (yych <= 0xC1) {
+          if (yych <= 0x7F)
+            goto yy805;
+          goto yy803;
+        } else {
+          if (yych <= 0xDF)
+            goto yy804;
+          if (yych <= 0xE0)
+            goto yy809;
+          goto yy802;
+        }
+      } else {
+        if (yych <= 0xF0) {
+          if (yych <= 0xED)
+            goto yy813;
+          if (yych <= 0xEF)
+            goto yy802;
+          goto yy810;
+        } else {
+          if (yych <= 0xF3)
+            goto yy811;
+          if (yych <= 0xF4)
+            goto yy812;
+          goto yy803;
+        }
+      }
+    }
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 128) {
+      goto yy807;
+    }
+    if (yych <= 't') {
+      if (yych <= 'C') {
+        if (yych <= '\t') {
+          if (yych <= 0x00)
+            goto yy803;
+          goto yy805;
+        } else {
+          if (yych <= '\n')
+            goto yy803;
+          if (yych <= 'B')
+            goto yy805;
+          goto yy821;
+        }
+      } else {
+        if (yych <= 'b') {
+          if (yych == 'T')
+            goto yy822;
+          goto yy805;
+        } else {
+          if (yych <= 'c')
+            goto yy821;
+          if (yych <= 's')
+            goto yy805;
+          goto yy822;
+        }
+      }
+    } else {
+      if (yych <= 0xEC) {
+        if (yych <= 0xC1) {
+          if (yych <= 0x7F)
+            goto yy805;
+          goto yy803;
+        } else {
+          if (yych <= 0xDF)
+            goto yy804;
+          if (yych <= 0xE0)
+            goto yy809;
+          goto yy802;
+        }
+      } else {
+        if (yych <= 0xF0) {
+          if (yych <= 0xED)
+            goto yy813;
+          if (yych <= 0xEF)
+            goto yy802;
+          goto yy810;
+        } else {
+          if (yych <= 0xF3)
+            goto yy811;
+          if (yych <= 0xF4)
+            goto yy812;
+          goto yy803;
+        }
+      }
+    }
+  yy816:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 128) {
+      goto yy807;
+    }
+    if (yych <= 0xC1) {
+      if (yych <= 'Q') {
+        if (yych <= 0x00)
+          goto yy803;
+        if (yych == '\n')
+          goto yy803;
+        goto yy805;
+      } else {
+        if (yych <= 'q') {
+          if (yych >= 'S')
+            goto yy805;
+        } else {
+          if (yych <= 'r')
+            goto yy817;
+          if (yych <= 0x7F)
+            goto yy805;
+          goto yy803;
+        }
+      }
+    } else {
+      if (yych <= 0xED) {
+        if (yych <= 0xDF)
+          goto yy804;
+        if (yych <= 0xE0)
+          goto yy809;
+        if (yych <= 0xEC)
+          goto yy802;
+        goto yy813;
+      } else {
+        if (yych <= 0xF0) {
+          if (yych <= 0xEF)
+            goto yy802;
+          goto yy810;
+        } else {
+          if (yych <= 0xF3)
+            goto yy811;
+          if (yych <= 0xF4)
+            goto yy812;
+          goto yy803;
+        }
+      }
+    }
+  yy817:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 128) {
+      goto yy807;
+    }
+    if (yych <= 0xC1) {
+      if (yych <= 'D') {
+        if (yych <= 0x00)
+          goto yy803;
+        if (yych == '\n')
+          goto yy803;
+        goto yy805;
+      } else {
+        if (yych <= 'd') {
+          if (yych >= 'F')
+            goto yy805;
+        } else {
+          if (yych <= 'e')
+            goto yy818;
+          if (yych <= 0x7F)
+            goto yy805;
+          goto yy803;
+        }
+      }
+    } else {
+      if (yych <= 0xED) {
+        if (yych <= 0xDF)
+          goto yy804;
+        if (yych <= 0xE0)
+          goto yy809;
+        if (yych <= 0xEC)
+          goto yy802;
+        goto yy813;
+      } else {
+        if (yych <= 0xF0) {
+          if (yych <= 0xEF)
+            goto yy802;
+          goto yy810;
+        } else {
+          if (yych <= 0xF3)
+            goto yy811;
+          if (yych <= 0xF4)
+            goto yy812;
+          goto yy803;
+        }
+      }
+    }
+  yy818:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 128) {
+      goto yy807;
+    }
+    if (yych <= 0xDF) {
+      if (yych <= '=') {
+        if (yych <= 0x00)
+          goto yy803;
+        if (yych == '\n')
+          goto yy803;
+        goto yy805;
+      } else {
+        if (yych <= '>')
+          goto yy819;
+        if (yych <= 0x7F)
+          goto yy805;
+        if (yych <= 0xC1)
+          goto yy803;
+        goto yy804;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych <= 0xE0)
+          goto yy809;
+        if (yych == 0xED)
+          goto yy813;
+        goto yy802;
+      } else {
+        if (yych <= 0xF0)
+          goto yy810;
+        if (yych <= 0xF3)
+          goto yy811;
+        if (yych <= 0xF4)
+          goto yy812;
+        goto yy803;
+      }
+    }
+  yy819:
+    yyaccept = 1;
+    marker = ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 64) {
+      goto yy805;
+    }
+    if (yych <= 0xEC) {
+      if (yych <= 0xC1) {
+        if (yych <= '\n')
+          goto yy820;
+        if (yych <= '<')
+          goto yy807;
+      } else {
+        if (yych <= 0xDF)
+          goto yy804;
+        if (yych <= 0xE0)
+          goto yy809;
+        goto yy802;
+      }
+    } else {
+      if (yych <= 0xF0) {
+        if (yych <= 0xED)
+          goto yy813;
+        if (yych <= 0xEF)
+          goto yy802;
+        goto yy810;
+      } else {
+        if (yych <= 0xF3)
+          goto yy811;
+        if (yych <= 0xF4)
+          goto yy812;
+      }
+    }
+  yy820 : { return (bufsize_t)(p - start); }
+  yy821:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 128) {
+      goto yy807;
+    }
+    if (yych <= 0xC1) {
+      if (yych <= 'Q') {
+        if (yych <= 0x00)
+          goto yy803;
+        if (yych == '\n')
+          goto yy803;
+        goto yy805;
+      } else {
+        if (yych <= 'q') {
+          if (yych <= 'R')
+            goto yy825;
+          goto yy805;
+        } else {
+          if (yych <= 'r')
+            goto yy825;
+          if (yych <= 0x7F)
+            goto yy805;
+          goto yy803;
+        }
+      }
+    } else {
+      if (yych <= 0xED) {
+        if (yych <= 0xDF)
+          goto yy804;
+        if (yych <= 0xE0)
+          goto yy809;
+        if (yych <= 0xEC)
+          goto yy802;
+        goto yy813;
+      } else {
+        if (yych <= 0xF0) {
+          if (yych <= 0xEF)
+            goto yy802;
+          goto yy810;
+        } else {
+          if (yych <= 0xF3)
+            goto yy811;
+          if (yych <= 0xF4)
+            goto yy812;
+          goto yy803;
+        }
+      }
+    }
+  yy822:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 128) {
+      goto yy807;
+    }
+    if (yych <= 0xC1) {
+      if (yych <= 'X') {
+        if (yych <= 0x00)
+          goto yy803;
+        if (yych == '\n')
+          goto yy803;
+        goto yy805;
+      } else {
+        if (yych <= 'x') {
+          if (yych >= 'Z')
+            goto yy805;
+        } else {
+          if (yych <= 'y')
+            goto yy823;
+          if (yych <= 0x7F)
+            goto yy805;
+          goto yy803;
+        }
+      }
+    } else {
+      if (yych <= 0xED) {
+        if (yych <= 0xDF)
+          goto yy804;
+        if (yych <= 0xE0)
+          goto yy809;
+        if (yych <= 0xEC)
+          goto yy802;
+        goto yy813;
+      } else {
+        if (yych <= 0xF0) {
+          if (yych <= 0xEF)
+            goto yy802;
+          goto yy810;
+        } else {
+          if (yych <= 0xF3)
+            goto yy811;
+          if (yych <= 0xF4)
+            goto yy812;
+          goto yy803;
+        }
+      }
+    }
+  yy823:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 128) {
+      goto yy807;
+    }
+    if (yych <= 0xC1) {
+      if (yych <= 'K') {
+        if (yych <= 0x00)
+          goto yy803;
+        if (yych == '\n')
+          goto yy803;
+        goto yy805;
+      } else {
+        if (yych <= 'k') {
+          if (yych >= 'M')
+            goto yy805;
+        } else {
+          if (yych <= 'l')
+            goto yy824;
+          if (yych <= 0x7F)
+            goto yy805;
+          goto yy803;
+        }
+      }
+    } else {
+      if (yych <= 0xED) {
+        if (yych <= 0xDF)
+          goto yy804;
+        if (yych <= 0xE0)
+          goto yy809;
+        if (yych <= 0xEC)
+          goto yy802;
+        goto yy813;
+      } else {
+        if (yych <= 0xF0) {
+          if (yych <= 0xEF)
+            goto yy802;
+          goto yy810;
+        } else {
+          if (yych <= 0xF3)
+            goto yy811;
+          if (yych <= 0xF4)
+            goto yy812;
+          goto yy803;
+        }
+      }
+    }
+  yy824:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 128) {
+      goto yy807;
+    }
+    if (yych <= 0xC1) {
+      if (yych <= 'D') {
+        if (yych <= 0x00)
+          goto yy803;
+        if (yych == '\n')
+          goto yy803;
+        goto yy805;
+      } else {
+        if (yych <= 'd') {
+          if (yych <= 'E')
+            goto yy818;
+          goto yy805;
+        } else {
+          if (yych <= 'e')
+            goto yy818;
+          if (yych <= 0x7F)
+            goto yy805;
+          goto yy803;
+        }
+      }
+    } else {
+      if (yych <= 0xED) {
+        if (yych <= 0xDF)
+          goto yy804;
+        if (yych <= 0xE0)
+          goto yy809;
+        if (yych <= 0xEC)
+          goto yy802;
+        goto yy813;
+      } else {
+        if (yych <= 0xF0) {
+          if (yych <= 0xEF)
+            goto yy802;
+          goto yy810;
+        } else {
+          if (yych <= 0xF3)
+            goto yy811;
+          if (yych <= 0xF4)
+            goto yy812;
+          goto yy803;
+        }
+      }
+    }
+  yy825:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 128) {
+      goto yy807;
+    }
+    if (yych <= 0xC1) {
+      if (yych <= 'H') {
+        if (yych <= 0x00)
+          goto yy803;
+        if (yych == '\n')
+          goto yy803;
+        goto yy805;
+      } else {
+        if (yych <= 'h') {
+          if (yych >= 'J')
+            goto yy805;
+        } else {
+          if (yych <= 'i')
+            goto yy826;
+          if (yych <= 0x7F)
+            goto yy805;
+          goto yy803;
+        }
+      }
+    } else {
+      if (yych <= 0xED) {
+        if (yych <= 0xDF)
+          goto yy804;
+        if (yych <= 0xE0)
+          goto yy809;
+        if (yych <= 0xEC)
+          goto yy802;
+        goto yy813;
+      } else {
+        if (yych <= 0xF0) {
+          if (yych <= 0xEF)
+            goto yy802;
+          goto yy810;
+        } else {
+          if (yych <= 0xF3)
+            goto yy811;
+          if (yych <= 0xF4)
+            goto yy812;
+          goto yy803;
+        }
+      }
+    }
+  yy826:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 128) {
+      goto yy807;
+    }
+    if (yych <= 0xC1) {
+      if (yych <= 'O') {
+        if (yych <= 0x00)
+          goto yy803;
+        if (yych == '\n')
+          goto yy803;
+        goto yy805;
+      } else {
+        if (yych <= 'o') {
+          if (yych >= 'Q')
+            goto yy805;
+        } else {
+          if (yych <= 'p')
+            goto yy827;
+          if (yych <= 0x7F)
+            goto yy805;
+          goto yy803;
+        }
+      }
+    } else {
+      if (yych <= 0xED) {
+        if (yych <= 0xDF)
+          goto yy804;
+        if (yych <= 0xE0)
+          goto yy809;
+        if (yych <= 0xEC)
+          goto yy802;
+        goto yy813;
+      } else {
+        if (yych <= 0xF0) {
+          if (yych <= 0xEF)
+            goto yy802;
+          goto yy810;
+        } else {
+          if (yych <= 0xF3)
+            goto yy811;
+          if (yych <= 0xF4)
+            goto yy812;
+          goto yy803;
+        }
+      }
+    }
+  yy827:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 128) {
+      goto yy807;
+    }
+    if (yych <= 0xC1) {
+      if (yych <= 'S') {
+        if (yych <= 0x00)
+          goto yy803;
+        if (yych == '\n')
+          goto yy803;
+        goto yy805;
+      } else {
+        if (yych <= 's') {
+          if (yych <= 'T')
+            goto yy818;
+          goto yy805;
+        } else {
+          if (yych <= 't')
+            goto yy818;
+          if (yych <= 0x7F)
+            goto yy805;
+          goto yy803;
+        }
+      }
+    } else {
+      if (yych <= 0xED) {
+        if (yych <= 0xDF)
+          goto yy804;
+        if (yych <= 0xE0)
+          goto yy809;
+        if (yych <= 0xEC)
+          goto yy802;
+        goto yy813;
+      } else {
+        if (yych <= 0xF0) {
+          if (yych <= 0xEF)
+            goto yy802;
+          goto yy810;
+        } else {
+          if (yych <= 0xF3)
+            goto yy811;
+          if (yych <= 0xF4)
+            goto yy812;
+          goto yy803;
+        }
+      }
+    }
+  }
+}
+
+// Try to match an HTML block end line of type 2
+bufsize_t _scan_html_block_end_2(const unsigned char *p) {
+  const unsigned char *marker = NULL;
+  const unsigned char *start = p;
+
+  {
+    unsigned char yych;
+    unsigned int yyaccept = 0;
+    static const unsigned char yybm[] = {
+        0,  64, 64, 64, 64, 64, 64, 64, 64, 64,  0,  64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 64, 64, 64, 128, 64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,
+    };
+    yych = *p;
+    if (yych <= 0xDF) {
+      if (yych <= ',') {
+        if (yych <= 0x00)
+          goto yy830;
+        if (yych != '\n')
+          goto yy832;
+      } else {
+        if (yych <= '-')
+          goto yy833;
+        if (yych <= 0x7F)
+          goto yy832;
+        if (yych >= 0xC2)
+          goto yy834;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych <= 0xE0)
+          goto yy835;
+        if (yych == 0xED)
+          goto yy837;
+        goto yy836;
+      } else {
+        if (yych <= 0xF0)
+          goto yy838;
+        if (yych <= 0xF3)
+          goto yy839;
+        if (yych <= 0xF4)
+          goto yy840;
+      }
+    }
+  yy830:
+    ++p;
+  yy831 : { return 0; }
+  yy832:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= '\n') {
+      if (yych <= 0x00)
+        goto yy831;
+      if (yych <= '\t')
+        goto yy845;
+      goto yy831;
+    } else {
+      if (yych <= 0x7F)
+        goto yy845;
+      if (yych <= 0xC1)
+        goto yy831;
+      if (yych <= 0xF4)
+        goto yy845;
+      goto yy831;
+    }
+  yy833:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yybm[0 + yych] & 128) {
+      goto yy852;
+    }
+    if (yych <= '\n') {
+      if (yych <= 0x00)
+        goto yy831;
+      if (yych <= '\t')
+        goto yy845;
+      goto yy831;
+    } else {
+      if (yych <= 0x7F)
+        goto yy845;
+      if (yych <= 0xC1)
+        goto yy831;
+      if (yych <= 0xF4)
+        goto yy845;
+      goto yy831;
+    }
+  yy834:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy831;
+    if (yych <= 0xBF)
+      goto yy844;
+    goto yy831;
+  yy835:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x9F)
+      goto yy831;
+    if (yych <= 0xBF)
+      goto yy843;
+    goto yy831;
+  yy836:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy831;
+    if (yych <= 0xBF)
+      goto yy843;
+    goto yy831;
+  yy837:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy831;
+    if (yych <= 0x9F)
+      goto yy843;
+    goto yy831;
+  yy838:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x8F)
+      goto yy831;
+    if (yych <= 0xBF)
+      goto yy841;
+    goto yy831;
+  yy839:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy831;
+    if (yych <= 0xBF)
+      goto yy841;
+    goto yy831;
+  yy840:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy831;
+    if (yych >= 0x90)
+      goto yy831;
+  yy841:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy842;
+    if (yych <= 0xBF)
+      goto yy843;
+  yy842:
+    p = marker;
+    if (yyaccept == 0) {
+      goto yy831;
+    } else {
+      goto yy855;
+    }
+  yy843:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy842;
+    if (yych >= 0xC0)
+      goto yy842;
+  yy844:
+    ++p;
+    yych = *p;
+  yy845:
+    if (yybm[0 + yych] & 64) {
+      goto yy844;
+    }
+    if (yych <= 0xEC) {
+      if (yych <= 0xC1) {
+        if (yych <= '\n')
+          goto yy842;
+        if (yych >= '.')
+          goto yy842;
+      } else {
+        if (yych <= 0xDF)
+          goto yy843;
+        if (yych <= 0xE0)
+          goto yy847;
+        goto yy841;
+      }
+    } else {
+      if (yych <= 0xF0) {
+        if (yych <= 0xED)
+          goto yy851;
+        if (yych <= 0xEF)
+          goto yy841;
+        goto yy848;
+      } else {
+        if (yych <= 0xF3)
+          goto yy849;
+        if (yych <= 0xF4)
+          goto yy850;
+        goto yy842;
+      }
+    }
+  yy846:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 64) {
+      goto yy844;
+    }
+    if (yych <= 0xEC) {
+      if (yych <= 0xC1) {
+        if (yych <= '\n')
+          goto yy842;
+        if (yych <= '-')
+          goto yy852;
+        goto yy842;
+      } else {
+        if (yych <= 0xDF)
+          goto yy843;
+        if (yych >= 0xE1)
+          goto yy841;
+      }
+    } else {
+      if (yych <= 0xF0) {
+        if (yych <= 0xED)
+          goto yy851;
+        if (yych <= 0xEF)
+          goto yy841;
+        goto yy848;
+      } else {
+        if (yych <= 0xF3)
+          goto yy849;
+        if (yych <= 0xF4)
+          goto yy850;
+        goto yy842;
+      }
+    }
+  yy847:
+    ++p;
+    yych = *p;
+    if (yych <= 0x9F)
+      goto yy842;
+    if (yych <= 0xBF)
+      goto yy843;
+    goto yy842;
+  yy848:
+    ++p;
+    yych = *p;
+    if (yych <= 0x8F)
+      goto yy842;
+    if (yych <= 0xBF)
+      goto yy841;
+    goto yy842;
+  yy849:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy842;
+    if (yych <= 0xBF)
+      goto yy841;
+    goto yy842;
+  yy850:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy842;
+    if (yych <= 0x8F)
+      goto yy841;
+    goto yy842;
+  yy851:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy842;
+    if (yych <= 0x9F)
+      goto yy843;
+    goto yy842;
+  yy852:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 128) {
+      goto yy852;
+    }
+    if (yych <= 0xDF) {
+      if (yych <= '=') {
+        if (yych <= 0x00)
+          goto yy842;
+        if (yych == '\n')
+          goto yy842;
+        goto yy844;
+      } else {
+        if (yych <= '>')
+          goto yy854;
+        if (yych <= 0x7F)
+          goto yy844;
+        if (yych <= 0xC1)
+          goto yy842;
+        goto yy843;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych <= 0xE0)
+          goto yy847;
+        if (yych == 0xED)
+          goto yy851;
+        goto yy841;
+      } else {
+        if (yych <= 0xF0)
+          goto yy848;
+        if (yych <= 0xF3)
+          goto yy849;
+        if (yych <= 0xF4)
+          goto yy850;
+        goto yy842;
+      }
+    }
+  yy854:
+    yyaccept = 1;
+    marker = ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 64) {
+      goto yy844;
+    }
+    if (yych <= 0xEC) {
+      if (yych <= 0xC1) {
+        if (yych <= '\n')
+          goto yy855;
+        if (yych <= '-')
+          goto yy846;
+      } else {
+        if (yych <= 0xDF)
+          goto yy843;
+        if (yych <= 0xE0)
+          goto yy847;
+        goto yy841;
+      }
+    } else {
+      if (yych <= 0xF0) {
+        if (yych <= 0xED)
+          goto yy851;
+        if (yych <= 0xEF)
+          goto yy841;
+        goto yy848;
+      } else {
+        if (yych <= 0xF3)
+          goto yy849;
+        if (yych <= 0xF4)
+          goto yy850;
+      }
+    }
+  yy855 : { return (bufsize_t)(p - start); }
+  }
+}
+
+// Try to match an HTML block end line of type 3
+bufsize_t _scan_html_block_end_3(const unsigned char *p) {
+  const unsigned char *marker = NULL;
+  const unsigned char *start = p;
+
+  {
+    unsigned char yych;
+    unsigned int yyaccept = 0;
+    static const unsigned char yybm[] = {
+        0,  64, 64, 64, 64, 64, 64, 64, 64, 64,  0,  64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 64, 64, 64, 128, 64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,
+    };
+    yych = *p;
+    if (yych <= 0xDF) {
+      if (yych <= '>') {
+        if (yych <= 0x00)
+          goto yy858;
+        if (yych != '\n')
+          goto yy860;
+      } else {
+        if (yych <= '?')
+          goto yy861;
+        if (yych <= 0x7F)
+          goto yy860;
+        if (yych >= 0xC2)
+          goto yy862;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych <= 0xE0)
+          goto yy863;
+        if (yych == 0xED)
+          goto yy865;
+        goto yy864;
+      } else {
+        if (yych <= 0xF0)
+          goto yy866;
+        if (yych <= 0xF3)
+          goto yy867;
+        if (yych <= 0xF4)
+          goto yy868;
+      }
+    }
+  yy858:
+    ++p;
+  yy859 : { return 0; }
+  yy860:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= '\n') {
+      if (yych <= 0x00)
+        goto yy859;
+      if (yych <= '\t')
+        goto yy873;
+      goto yy859;
+    } else {
+      if (yych <= 0x7F)
+        goto yy873;
+      if (yych <= 0xC1)
+        goto yy859;
+      if (yych <= 0xF4)
+        goto yy873;
+      goto yy859;
+    }
+  yy861:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= '=') {
+      if (yych <= 0x00)
+        goto yy859;
+      if (yych == '\n')
+        goto yy859;
+      goto yy873;
+    } else {
+      if (yych <= 0x7F) {
+        if (yych <= '>')
+          goto yy881;
+        goto yy873;
+      } else {
+        if (yych <= 0xC1)
+          goto yy859;
+        if (yych <= 0xF4)
+          goto yy873;
+        goto yy859;
+      }
+    }
+  yy862:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy859;
+    if (yych <= 0xBF)
+      goto yy872;
+    goto yy859;
+  yy863:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x9F)
+      goto yy859;
+    if (yych <= 0xBF)
+      goto yy871;
+    goto yy859;
+  yy864:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy859;
+    if (yych <= 0xBF)
+      goto yy871;
+    goto yy859;
+  yy865:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy859;
+    if (yych <= 0x9F)
+      goto yy871;
+    goto yy859;
+  yy866:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x8F)
+      goto yy859;
+    if (yych <= 0xBF)
+      goto yy869;
+    goto yy859;
+  yy867:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy859;
+    if (yych <= 0xBF)
+      goto yy869;
+    goto yy859;
+  yy868:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy859;
+    if (yych >= 0x90)
+      goto yy859;
+  yy869:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy870;
+    if (yych <= 0xBF)
+      goto yy871;
+  yy870:
+    p = marker;
+    if (yyaccept == 0) {
+      goto yy859;
+    } else {
+      goto yy882;
+    }
+  yy871:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy870;
+    if (yych >= 0xC0)
+      goto yy870;
+  yy872:
+    ++p;
+    yych = *p;
+  yy873:
+    if (yybm[0 + yych] & 64) {
+      goto yy872;
+    }
+    if (yych <= 0xEC) {
+      if (yych <= 0xC1) {
+        if (yych <= '\n')
+          goto yy870;
+        if (yych >= '@')
+          goto yy870;
+      } else {
+        if (yych <= 0xDF)
+          goto yy871;
+        if (yych <= 0xE0)
+          goto yy876;
+        goto yy869;
+      }
+    } else {
+      if (yych <= 0xF0) {
+        if (yych <= 0xED)
+          goto yy880;
+        if (yych <= 0xEF)
+          goto yy869;
+        goto yy877;
+      } else {
+        if (yych <= 0xF3)
+          goto yy878;
+        if (yych <= 0xF4)
+          goto yy879;
+        goto yy870;
+      }
+    }
+  yy874:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 128) {
+      goto yy874;
+    }
+    if (yych <= 0xDF) {
+      if (yych <= '=') {
+        if (yych <= 0x00)
+          goto yy870;
+        if (yych == '\n')
+          goto yy870;
+        goto yy872;
+      } else {
+        if (yych <= '>')
+          goto yy881;
+        if (yych <= 0x7F)
+          goto yy872;
+        if (yych <= 0xC1)
+          goto yy870;
+        goto yy871;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych <= 0xE0)
+          goto yy876;
+        if (yych == 0xED)
+          goto yy880;
+        goto yy869;
+      } else {
+        if (yych <= 0xF0)
+          goto yy877;
+        if (yych <= 0xF3)
+          goto yy878;
+        if (yych <= 0xF4)
+          goto yy879;
+        goto yy870;
+      }
+    }
+  yy876:
+    ++p;
+    yych = *p;
+    if (yych <= 0x9F)
+      goto yy870;
+    if (yych <= 0xBF)
+      goto yy871;
+    goto yy870;
+  yy877:
+    ++p;
+    yych = *p;
+    if (yych <= 0x8F)
+      goto yy870;
+    if (yych <= 0xBF)
+      goto yy869;
+    goto yy870;
+  yy878:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy870;
+    if (yych <= 0xBF)
+      goto yy869;
+    goto yy870;
+  yy879:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy870;
+    if (yych <= 0x8F)
+      goto yy869;
+    goto yy870;
+  yy880:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy870;
+    if (yych <= 0x9F)
+      goto yy871;
+    goto yy870;
+  yy881:
+    yyaccept = 1;
+    marker = ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 64) {
+      goto yy872;
+    }
+    if (yych <= 0xEC) {
+      if (yych <= 0xC1) {
+        if (yych <= '\n')
+          goto yy882;
+        if (yych <= '?')
+          goto yy874;
+      } else {
+        if (yych <= 0xDF)
+          goto yy871;
+        if (yych <= 0xE0)
+          goto yy876;
+        goto yy869;
+      }
+    } else {
+      if (yych <= 0xF0) {
+        if (yych <= 0xED)
+          goto yy880;
+        if (yych <= 0xEF)
+          goto yy869;
+        goto yy877;
+      } else {
+        if (yych <= 0xF3)
+          goto yy878;
+        if (yych <= 0xF4)
+          goto yy879;
+      }
+    }
+  yy882 : { return (bufsize_t)(p - start); }
+  }
+}
+
+// Try to match an HTML block end line of type 4
+bufsize_t _scan_html_block_end_4(const unsigned char *p) {
+  const unsigned char *marker = NULL;
+  const unsigned char *start = p;
+
+  {
+    unsigned char yych;
+    unsigned int yyaccept = 0;
+    static const unsigned char yybm[] = {
+        0,  64, 64, 64, 64, 64, 64, 64, 64,  64, 0,  64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 64, 64, 128, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,
+    };
+    yych = *p;
+    if (yych <= 0xDF) {
+      if (yych <= '=') {
+        if (yych <= 0x00)
+          goto yy885;
+        if (yych != '\n')
+          goto yy887;
+      } else {
+        if (yych <= '>')
+          goto yy888;
+        if (yych <= 0x7F)
+          goto yy887;
+        if (yych >= 0xC2)
+          goto yy890;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych <= 0xE0)
+          goto yy891;
+        if (yych == 0xED)
+          goto yy893;
+        goto yy892;
+      } else {
+        if (yych <= 0xF0)
+          goto yy894;
+        if (yych <= 0xF3)
+          goto yy895;
+        if (yych <= 0xF4)
+          goto yy896;
+      }
+    }
+  yy885:
+    ++p;
+  yy886 : { return 0; }
+  yy887:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= '\n') {
+      if (yych <= 0x00)
+        goto yy886;
+      if (yych <= '\t')
+        goto yy901;
+      goto yy886;
+    } else {
+      if (yych <= 0x7F)
+        goto yy901;
+      if (yych <= 0xC1)
+        goto yy886;
+      if (yych <= 0xF4)
+        goto yy901;
+      goto yy886;
+    }
+  yy888:
+    yyaccept = 1;
+    yych = *(marker = ++p);
+    if (yych <= '\n') {
+      if (yych <= 0x00)
+        goto yy889;
+      if (yych <= '\t')
+        goto yy901;
+    } else {
+      if (yych <= 0x7F)
+        goto yy901;
+      if (yych <= 0xC1)
+        goto yy889;
+      if (yych <= 0xF4)
+        goto yy901;
+    }
+  yy889 : { return (bufsize_t)(p - start); }
+  yy890:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy886;
+    if (yych <= 0xBF)
+      goto yy900;
+    goto yy886;
+  yy891:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x9F)
+      goto yy886;
+    if (yych <= 0xBF)
+      goto yy899;
+    goto yy886;
+  yy892:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy886;
+    if (yych <= 0xBF)
+      goto yy899;
+    goto yy886;
+  yy893:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy886;
+    if (yych <= 0x9F)
+      goto yy899;
+    goto yy886;
+  yy894:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x8F)
+      goto yy886;
+    if (yych <= 0xBF)
+      goto yy897;
+    goto yy886;
+  yy895:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy886;
+    if (yych <= 0xBF)
+      goto yy897;
+    goto yy886;
+  yy896:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy886;
+    if (yych >= 0x90)
+      goto yy886;
+  yy897:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy898;
+    if (yych <= 0xBF)
+      goto yy899;
+  yy898:
+    p = marker;
+    if (yyaccept == 0) {
+      goto yy886;
+    } else {
+      goto yy889;
+    }
+  yy899:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy898;
+    if (yych >= 0xC0)
+      goto yy898;
+  yy900:
+    ++p;
+    yych = *p;
+  yy901:
+    if (yybm[0 + yych] & 64) {
+      goto yy900;
+    }
+    if (yych <= 0xEC) {
+      if (yych <= 0xC1) {
+        if (yych <= '\n')
+          goto yy898;
+        if (yych >= '?')
+          goto yy898;
+      } else {
+        if (yych <= 0xDF)
+          goto yy899;
+        if (yych <= 0xE0)
+          goto yy904;
+        goto yy897;
+      }
+    } else {
+      if (yych <= 0xF0) {
+        if (yych <= 0xED)
+          goto yy908;
+        if (yych <= 0xEF)
+          goto yy897;
+        goto yy905;
+      } else {
+        if (yych <= 0xF3)
+          goto yy906;
+        if (yych <= 0xF4)
+          goto yy907;
+        goto yy898;
+      }
+    }
+  yy902:
+    yyaccept = 1;
+    marker = ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 64) {
+      goto yy900;
+    }
+    if (yych <= 0xEC) {
+      if (yych <= 0xC1) {
+        if (yych <= '\n')
+          goto yy889;
+        if (yych <= '>')
+          goto yy902;
+        goto yy889;
+      } else {
+        if (yych <= 0xDF)
+          goto yy899;
+        if (yych >= 0xE1)
+          goto yy897;
+      }
+    } else {
+      if (yych <= 0xF0) {
+        if (yych <= 0xED)
+          goto yy908;
+        if (yych <= 0xEF)
+          goto yy897;
+        goto yy905;
+      } else {
+        if (yych <= 0xF3)
+          goto yy906;
+        if (yych <= 0xF4)
+          goto yy907;
+        goto yy889;
+      }
+    }
+  yy904:
+    ++p;
+    yych = *p;
+    if (yych <= 0x9F)
+      goto yy898;
+    if (yych <= 0xBF)
+      goto yy899;
+    goto yy898;
+  yy905:
+    ++p;
+    yych = *p;
+    if (yych <= 0x8F)
+      goto yy898;
+    if (yych <= 0xBF)
+      goto yy897;
+    goto yy898;
+  yy906:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy898;
+    if (yych <= 0xBF)
+      goto yy897;
+    goto yy898;
+  yy907:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy898;
+    if (yych <= 0x8F)
+      goto yy897;
+    goto yy898;
+  yy908:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy898;
+    if (yych <= 0x9F)
+      goto yy899;
+    goto yy898;
+  }
+}
+
+// Try to match an HTML block end line of type 5
+bufsize_t _scan_html_block_end_5(const unsigned char *p) {
+  const unsigned char *marker = NULL;
+  const unsigned char *start = p;
+
+  {
+    unsigned char yych;
+    unsigned int yyaccept = 0;
+    static const unsigned char yybm[] = {
+        0,  64, 64, 64,  64, 64, 64, 64, 64, 64, 0,  64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 128, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+        64, 64, 0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+        0,  0,  0,  0,
+    };
+    yych = *p;
+    if (yych <= 0xDF) {
+      if (yych <= '\\') {
+        if (yych <= 0x00)
+          goto yy911;
+        if (yych != '\n')
+          goto yy913;
+      } else {
+        if (yych <= ']')
+          goto yy914;
+        if (yych <= 0x7F)
+          goto yy913;
+        if (yych >= 0xC2)
+          goto yy915;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych <= 0xE0)
+          goto yy916;
+        if (yych == 0xED)
+          goto yy918;
+        goto yy917;
+      } else {
+        if (yych <= 0xF0)
+          goto yy919;
+        if (yych <= 0xF3)
+          goto yy920;
+        if (yych <= 0xF4)
+          goto yy921;
+      }
+    }
+  yy911:
+    ++p;
+  yy912 : { return 0; }
+  yy913:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= '\n') {
+      if (yych <= 0x00)
+        goto yy912;
+      if (yych <= '\t')
+        goto yy926;
+      goto yy912;
+    } else {
+      if (yych <= 0x7F)
+        goto yy926;
+      if (yych <= 0xC1)
+        goto yy912;
+      if (yych <= 0xF4)
+        goto yy926;
+      goto yy912;
+    }
+  yy914:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yybm[0 + yych] & 128) {
+      goto yy933;
+    }
+    if (yych <= '\n') {
+      if (yych <= 0x00)
+        goto yy912;
+      if (yych <= '\t')
+        goto yy926;
+      goto yy912;
+    } else {
+      if (yych <= 0x7F)
+        goto yy926;
+      if (yych <= 0xC1)
+        goto yy912;
+      if (yych <= 0xF4)
+        goto yy926;
+      goto yy912;
+    }
+  yy915:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy912;
+    if (yych <= 0xBF)
+      goto yy925;
+    goto yy912;
+  yy916:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x9F)
+      goto yy912;
+    if (yych <= 0xBF)
+      goto yy924;
+    goto yy912;
+  yy917:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy912;
+    if (yych <= 0xBF)
+      goto yy924;
+    goto yy912;
+  yy918:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy912;
+    if (yych <= 0x9F)
+      goto yy924;
+    goto yy912;
+  yy919:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x8F)
+      goto yy912;
+    if (yych <= 0xBF)
+      goto yy922;
+    goto yy912;
+  yy920:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy912;
+    if (yych <= 0xBF)
+      goto yy922;
+    goto yy912;
+  yy921:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x7F)
+      goto yy912;
+    if (yych >= 0x90)
+      goto yy912;
+  yy922:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy923;
+    if (yych <= 0xBF)
+      goto yy924;
+  yy923:
+    p = marker;
+    if (yyaccept == 0) {
+      goto yy912;
+    } else {
+      goto yy936;
+    }
+  yy924:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy923;
+    if (yych >= 0xC0)
+      goto yy923;
+  yy925:
+    ++p;
+    yych = *p;
+  yy926:
+    if (yybm[0 + yych] & 64) {
+      goto yy925;
+    }
+    if (yych <= 0xEC) {
+      if (yych <= 0xC1) {
+        if (yych <= '\n')
+          goto yy923;
+        if (yych >= '^')
+          goto yy923;
+      } else {
+        if (yych <= 0xDF)
+          goto yy924;
+        if (yych <= 0xE0)
+          goto yy928;
+        goto yy922;
+      }
+    } else {
+      if (yych <= 0xF0) {
+        if (yych <= 0xED)
+          goto yy932;
+        if (yych <= 0xEF)
+          goto yy922;
+        goto yy929;
+      } else {
+        if (yych <= 0xF3)
+          goto yy930;
+        if (yych <= 0xF4)
+          goto yy931;
+        goto yy923;
+      }
+    }
+  yy927:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 64) {
+      goto yy925;
+    }
+    if (yych <= 0xEC) {
+      if (yych <= 0xC1) {
+        if (yych <= '\n')
+          goto yy923;
+        if (yych <= ']')
+          goto yy933;
+        goto yy923;
+      } else {
+        if (yych <= 0xDF)
+          goto yy924;
+        if (yych >= 0xE1)
+          goto yy922;
+      }
+    } else {
+      if (yych <= 0xF0) {
+        if (yych <= 0xED)
+          goto yy932;
+        if (yych <= 0xEF)
+          goto yy922;
+        goto yy929;
+      } else {
+        if (yych <= 0xF3)
+          goto yy930;
+        if (yych <= 0xF4)
+          goto yy931;
+        goto yy923;
+      }
+    }
+  yy928:
+    ++p;
+    yych = *p;
+    if (yych <= 0x9F)
+      goto yy923;
+    if (yych <= 0xBF)
+      goto yy924;
+    goto yy923;
+  yy929:
+    ++p;
+    yych = *p;
+    if (yych <= 0x8F)
+      goto yy923;
+    if (yych <= 0xBF)
+      goto yy922;
+    goto yy923;
+  yy930:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy923;
+    if (yych <= 0xBF)
+      goto yy922;
+    goto yy923;
+  yy931:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy923;
+    if (yych <= 0x8F)
+      goto yy922;
+    goto yy923;
+  yy932:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy923;
+    if (yych <= 0x9F)
+      goto yy924;
+    goto yy923;
+  yy933:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 128) {
+      goto yy933;
+    }
+    if (yych <= 0xDF) {
+      if (yych <= '=') {
+        if (yych <= 0x00)
+          goto yy923;
+        if (yych == '\n')
+          goto yy923;
+        goto yy925;
+      } else {
+        if (yych <= '>')
+          goto yy935;
+        if (yych <= 0x7F)
+          goto yy925;
+        if (yych <= 0xC1)
+          goto yy923;
+        goto yy924;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych <= 0xE0)
+          goto yy928;
+        if (yych == 0xED)
+          goto yy932;
+        goto yy922;
+      } else {
+        if (yych <= 0xF0)
+          goto yy929;
+        if (yych <= 0xF3)
+          goto yy930;
+        if (yych <= 0xF4)
+          goto yy931;
+        goto yy923;
+      }
+    }
+  yy935:
+    yyaccept = 1;
+    marker = ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 64) {
+      goto yy925;
+    }
+    if (yych <= 0xEC) {
+      if (yych <= 0xC1) {
+        if (yych <= '\n')
+          goto yy936;
+        if (yych <= ']')
+          goto yy927;
+      } else {
+        if (yych <= 0xDF)
+          goto yy924;
+        if (yych <= 0xE0)
+          goto yy928;
+        goto yy922;
+      }
+    } else {
+      if (yych <= 0xF0) {
+        if (yych <= 0xED)
+          goto yy932;
+        if (yych <= 0xEF)
+          goto yy922;
+        goto yy929;
+      } else {
+        if (yych <= 0xF3)
+          goto yy930;
+        if (yych <= 0xF4)
+          goto yy931;
+      }
+    }
+  yy936 : { return (bufsize_t)(p - start); }
+  }
+}
+
+// Try to match a link title (in single quotes, in double quotes, or
+// in parentheses), returning number of chars matched.  Allow one
+// level of internal nesting (quotes within quotes).
+bufsize_t _scan_link_title(const unsigned char *p) {
+  const unsigned char *marker = NULL;
+  const unsigned char *start = p;
+
+  {
+    unsigned char yych;
+    unsigned int yyaccept = 0;
+    static const unsigned char yybm[] = {
+        0,   224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224,
+        224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224,
+        224, 224, 224, 224, 224, 224, 96,  224, 224, 224, 224, 160, 224, 192,
+        224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224,
+        224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224,
+        224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224,
+        224, 224, 224, 224, 224, 224, 224, 224, 16,  224, 224, 224, 224, 224,
+        224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224,
+        224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224,
+        224, 224, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,
+    };
+    yych = *p;
+    if (yych <= '&') {
+      if (yych == '"')
+        goto yy941;
+    } else {
+      if (yych <= '\'')
+        goto yy942;
+      if (yych <= '(')
+        goto yy943;
+    }
+    ++p;
+  yy940 : { return 0; }
+  yy941:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x00)
+      goto yy940;
+    if (yych <= 0x7F)
+      goto yy976;
+    if (yych <= 0xC1)
+      goto yy940;
+    if (yych <= 0xF4)
+      goto yy976;
+    goto yy940;
+  yy942:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x00)
+      goto yy940;
+    if (yych <= 0x7F)
+      goto yy962;
+    if (yych <= 0xC1)
+      goto yy940;
+    if (yych <= 0xF4)
+      goto yy962;
+    goto yy940;
+  yy943:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych <= 0x00)
+      goto yy940;
+    if (yych <= 0x7F)
+      goto yy948;
+    if (yych <= 0xC1)
+      goto yy940;
+    if (yych <= 0xF4)
+      goto yy948;
+    goto yy940;
+  yy944:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 32) {
+      goto yy947;
+    }
+    if (yych <= 0xE0) {
+      if (yych <= '\\') {
+        if (yych <= 0x00)
+          goto yy946;
+        if (yych <= ')')
+          goto yy958;
+        goto yy944;
+      } else {
+        if (yych <= 0xC1)
+          goto yy946;
+        if (yych <= 0xDF)
+          goto yy949;
+        goto yy950;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych == 0xED)
+          goto yy955;
+        goto yy951;
+      } else {
+        if (yych <= 0xF0)
+          goto yy952;
+        if (yych <= 0xF3)
+          goto yy953;
+        if (yych <= 0xF4)
+          goto yy954;
+      }
+    }
+  yy946:
+    p = marker;
+    if (yyaccept <= 1) {
+      if (yyaccept == 0) {
+        goto yy940;
+      } else {
+        goto yy957;
+      }
+    } else {
+      if (yyaccept == 2) {
+        goto yy971;
+      } else {
+        goto yy985;
+      }
+    }
+  yy947:
+    ++p;
+    yych = *p;
+  yy948:
+    if (yybm[0 + yych] & 32) {
+      goto yy947;
+    }
+    if (yych <= 0xE0) {
+      if (yych <= '\\') {
+        if (yych <= 0x00)
+          goto yy946;
+        if (yych <= ')')
+          goto yy956;
+        goto yy944;
+      } else {
+        if (yych <= 0xC1)
+          goto yy946;
+        if (yych >= 0xE0)
+          goto yy950;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych == 0xED)
+          goto yy955;
+        goto yy951;
+      } else {
+        if (yych <= 0xF0)
+          goto yy952;
+        if (yych <= 0xF3)
+          goto yy953;
+        if (yych <= 0xF4)
+          goto yy954;
+        goto yy946;
+      }
+    }
+  yy949:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy946;
+    if (yych <= 0xBF)
+      goto yy947;
+    goto yy946;
+  yy950:
+    ++p;
+    yych = *p;
+    if (yych <= 0x9F)
+      goto yy946;
+    if (yych <= 0xBF)
+      goto yy949;
+    goto yy946;
+  yy951:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy946;
+    if (yych <= 0xBF)
+      goto yy949;
+    goto yy946;
+  yy952:
+    ++p;
+    yych = *p;
+    if (yych <= 0x8F)
+      goto yy946;
+    if (yych <= 0xBF)
+      goto yy951;
+    goto yy946;
+  yy953:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy946;
+    if (yych <= 0xBF)
+      goto yy951;
+    goto yy946;
+  yy954:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy946;
+    if (yych <= 0x8F)
+      goto yy951;
+    goto yy946;
+  yy955:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy946;
+    if (yych <= 0x9F)
+      goto yy949;
+    goto yy946;
+  yy956:
+    ++p;
+  yy957 : { return (bufsize_t)(p - start); }
+  yy958:
+    yyaccept = 1;
+    marker = ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 32) {
+      goto yy947;
+    }
+    if (yych <= 0xE0) {
+      if (yych <= '\\') {
+        if (yych <= 0x00)
+          goto yy957;
+        if (yych <= ')')
+          goto yy956;
+        goto yy944;
+      } else {
+        if (yych <= 0xC1)
+          goto yy957;
+        if (yych <= 0xDF)
+          goto yy949;
+        goto yy950;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych == 0xED)
+          goto yy955;
+        goto yy951;
+      } else {
+        if (yych <= 0xF0)
+          goto yy952;
+        if (yych <= 0xF3)
+          goto yy953;
+        if (yych <= 0xF4)
+          goto yy954;
+        goto yy957;
+      }
+    }
+  yy959:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 64) {
+      goto yy961;
+    }
+    if (yych <= 0xE0) {
+      if (yych <= '\\') {
+        if (yych <= 0x00)
+          goto yy946;
+        if (yych <= '\'')
+          goto yy972;
+        goto yy959;
+      } else {
+        if (yych <= 0xC1)
+          goto yy946;
+        if (yych <= 0xDF)
+          goto yy963;
+        goto yy964;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych == 0xED)
+          goto yy969;
+        goto yy965;
+      } else {
+        if (yych <= 0xF0)
+          goto yy966;
+        if (yych <= 0xF3)
+          goto yy967;
+        if (yych <= 0xF4)
+          goto yy968;
+        goto yy946;
+      }
+    }
+  yy961:
+    ++p;
+    yych = *p;
+  yy962:
+    if (yybm[0 + yych] & 64) {
+      goto yy961;
+    }
+    if (yych <= 0xE0) {
+      if (yych <= '\\') {
+        if (yych <= 0x00)
+          goto yy946;
+        if (yych <= '\'')
+          goto yy970;
+        goto yy959;
+      } else {
+        if (yych <= 0xC1)
+          goto yy946;
+        if (yych >= 0xE0)
+          goto yy964;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych == 0xED)
+          goto yy969;
+        goto yy965;
+      } else {
+        if (yych <= 0xF0)
+          goto yy966;
+        if (yych <= 0xF3)
+          goto yy967;
+        if (yych <= 0xF4)
+          goto yy968;
+        goto yy946;
+      }
+    }
+  yy963:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy946;
+    if (yych <= 0xBF)
+      goto yy961;
+    goto yy946;
+  yy964:
+    ++p;
+    yych = *p;
+    if (yych <= 0x9F)
+      goto yy946;
+    if (yych <= 0xBF)
+      goto yy963;
+    goto yy946;
+  yy965:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy946;
+    if (yych <= 0xBF)
+      goto yy963;
+    goto yy946;
+  yy966:
+    ++p;
+    yych = *p;
+    if (yych <= 0x8F)
+      goto yy946;
+    if (yych <= 0xBF)
+      goto yy965;
+    goto yy946;
+  yy967:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy946;
+    if (yych <= 0xBF)
+      goto yy965;
+    goto yy946;
+  yy968:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy946;
+    if (yych <= 0x8F)
+      goto yy965;
+    goto yy946;
+  yy969:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy946;
+    if (yych <= 0x9F)
+      goto yy963;
+    goto yy946;
+  yy970:
+    ++p;
+  yy971 : { return (bufsize_t)(p - start); }
+  yy972:
+    yyaccept = 2;
+    marker = ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 64) {
+      goto yy961;
+    }
+    if (yych <= 0xE0) {
+      if (yych <= '\\') {
+        if (yych <= 0x00)
+          goto yy971;
+        if (yych <= '\'')
+          goto yy970;
+        goto yy959;
+      } else {
+        if (yych <= 0xC1)
+          goto yy971;
+        if (yych <= 0xDF)
+          goto yy963;
+        goto yy964;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych == 0xED)
+          goto yy969;
+        goto yy965;
+      } else {
+        if (yych <= 0xF0)
+          goto yy966;
+        if (yych <= 0xF3)
+          goto yy967;
+        if (yych <= 0xF4)
+          goto yy968;
+        goto yy971;
+      }
+    }
+  yy973:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 128) {
+      goto yy975;
+    }
+    if (yych <= 0xE0) {
+      if (yych <= '\\') {
+        if (yych <= 0x00)
+          goto yy946;
+        if (yych <= '"')
+          goto yy986;
+        goto yy973;
+      } else {
+        if (yych <= 0xC1)
+          goto yy946;
+        if (yych <= 0xDF)
+          goto yy977;
+        goto yy978;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych == 0xED)
+          goto yy983;
+        goto yy979;
+      } else {
+        if (yych <= 0xF0)
+          goto yy980;
+        if (yych <= 0xF3)
+          goto yy981;
+        if (yych <= 0xF4)
+          goto yy982;
+        goto yy946;
+      }
+    }
+  yy975:
+    ++p;
+    yych = *p;
+  yy976:
+    if (yybm[0 + yych] & 128) {
+      goto yy975;
+    }
+    if (yych <= 0xE0) {
+      if (yych <= '\\') {
+        if (yych <= 0x00)
+          goto yy946;
+        if (yych <= '"')
+          goto yy984;
+        goto yy973;
+      } else {
+        if (yych <= 0xC1)
+          goto yy946;
+        if (yych >= 0xE0)
+          goto yy978;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych == 0xED)
+          goto yy983;
+        goto yy979;
+      } else {
+        if (yych <= 0xF0)
+          goto yy980;
+        if (yych <= 0xF3)
+          goto yy981;
+        if (yych <= 0xF4)
+          goto yy982;
+        goto yy946;
+      }
+    }
+  yy977:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy946;
+    if (yych <= 0xBF)
+      goto yy975;
+    goto yy946;
+  yy978:
+    ++p;
+    yych = *p;
+    if (yych <= 0x9F)
+      goto yy946;
+    if (yych <= 0xBF)
+      goto yy977;
+    goto yy946;
+  yy979:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy946;
+    if (yych <= 0xBF)
+      goto yy977;
+    goto yy946;
+  yy980:
+    ++p;
+    yych = *p;
+    if (yych <= 0x8F)
+      goto yy946;
+    if (yych <= 0xBF)
+      goto yy979;
+    goto yy946;
+  yy981:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy946;
+    if (yych <= 0xBF)
+      goto yy979;
+    goto yy946;
+  yy982:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy946;
+    if (yych <= 0x8F)
+      goto yy979;
+    goto yy946;
+  yy983:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy946;
+    if (yych <= 0x9F)
+      goto yy977;
+    goto yy946;
+  yy984:
+    ++p;
+  yy985 : { return (bufsize_t)(p - start); }
+  yy986:
+    yyaccept = 3;
+    marker = ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 128) {
+      goto yy975;
+    }
+    if (yych <= 0xE0) {
+      if (yych <= '\\') {
+        if (yych <= 0x00)
+          goto yy985;
+        if (yych <= '"')
+          goto yy984;
+        goto yy973;
+      } else {
+        if (yych <= 0xC1)
+          goto yy985;
+        if (yych <= 0xDF)
+          goto yy977;
+        goto yy978;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych == 0xED)
+          goto yy983;
+        goto yy979;
+      } else {
+        if (yych <= 0xF0)
+          goto yy980;
+        if (yych <= 0xF3)
+          goto yy981;
+        if (yych <= 0xF4)
+          goto yy982;
+        goto yy985;
+      }
+    }
+  }
+}
+
+// Match space characters, including newlines.
+bufsize_t _scan_spacechars(const unsigned char *p) {
+  const unsigned char *start = p;
+
+  {
+    unsigned char yych;
+    static const unsigned char yybm[] = {
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   128, 0,   0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0,
+    };
+    yych = *p;
+    if (yych <= 0x08)
+      goto yy989;
+    if (yych <= '\r')
+      goto yy991;
+    if (yych == ' ')
+      goto yy991;
+  yy989:
+    ++p;
+    { return 0; }
+  yy991:
+    ++p;
+    yych = *p;
+    goto yy994;
+  yy992 : { return (bufsize_t)(p - start); }
+  yy993:
+    ++p;
+    yych = *p;
+  yy994:
+    if (yybm[0 + yych] & 128) {
+      goto yy993;
+    }
+    goto yy992;
+  }
+}
+
+// Match ATX heading start.
+bufsize_t _scan_atx_heading_start(const unsigned char *p) {
+  const unsigned char *marker = NULL;
+  const unsigned char *start = p;
+
+  {
+    unsigned char yych;
+    static const unsigned char yybm[] = {
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0,
+    };
+    yych = *p;
+    if (yych == '#')
+      goto yy999;
+    ++p;
+  yy998 : { return 0; }
+  yy999:
+    yych = *(marker = ++p);
+    if (yybm[0 + yych] & 128) {
+      goto yy1002;
+    }
+    if (yych <= '\f') {
+      if (yych <= 0x08)
+        goto yy998;
+      if (yych >= '\v')
+        goto yy998;
+    } else {
+      if (yych <= '\r')
+        goto yy1000;
+      if (yych == '#')
+        goto yy1004;
+      goto yy998;
+    }
+  yy1000:
+    ++p;
+  yy1001 : { return (bufsize_t)(p - start); }
+  yy1002:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 128) {
+      goto yy1002;
+    }
+    goto yy1001;
+  yy1004:
+    yych = *++p;
+    if (yybm[0 + yych] & 128) {
+      goto yy1002;
+    }
+    if (yych <= '\f') {
+      if (yych <= 0x08)
+        goto yy1005;
+      if (yych <= '\n')
+        goto yy1000;
+    } else {
+      if (yych <= '\r')
+        goto yy1000;
+      if (yych == '#')
+        goto yy1006;
+    }
+  yy1005:
+    p = marker;
+    goto yy998;
+  yy1006:
+    yych = *++p;
+    if (yybm[0 + yych] & 128) {
+      goto yy1002;
+    }
+    if (yych <= '\f') {
+      if (yych <= 0x08)
+        goto yy1005;
+      if (yych <= '\n')
+        goto yy1000;
+      goto yy1005;
+    } else {
+      if (yych <= '\r')
+        goto yy1000;
+      if (yych != '#')
+        goto yy1005;
+    }
+    yych = *++p;
+    if (yybm[0 + yych] & 128) {
+      goto yy1002;
+    }
+    if (yych <= '\f') {
+      if (yych <= 0x08)
+        goto yy1005;
+      if (yych <= '\n')
+        goto yy1000;
+      goto yy1005;
+    } else {
+      if (yych <= '\r')
+        goto yy1000;
+      if (yych != '#')
+        goto yy1005;
+    }
+    yych = *++p;
+    if (yybm[0 + yych] & 128) {
+      goto yy1002;
+    }
+    if (yych <= '\f') {
+      if (yych <= 0x08)
+        goto yy1005;
+      if (yych <= '\n')
+        goto yy1000;
+      goto yy1005;
+    } else {
+      if (yych <= '\r')
+        goto yy1000;
+      if (yych != '#')
+        goto yy1005;
+    }
+    ++p;
+    if (yybm[0 + (yych = *p)] & 128) {
+      goto yy1002;
+    }
+    if (yych <= 0x08)
+      goto yy1005;
+    if (yych <= '\n')
+      goto yy1000;
+    if (yych == '\r')
+      goto yy1000;
+    goto yy1005;
+  }
+}
+
+// Match setext heading line.  Return 1 for level-1 heading,
+// 2 for level-2, 0 for no match.
+bufsize_t _scan_setext_heading_line(const unsigned char *p) {
+  const unsigned char *marker = NULL;
+
+  {
+    unsigned char yych;
+    static const unsigned char yybm[] = {
+        0, 0,   0, 0, 0, 0, 0, 0, 0, 32, 0,  0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0,
+        0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  32, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0,
+        0, 128, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0,
+        0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0,
+        0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0,
+        0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0,
+        0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0,
+        0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0,
+        0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0,
+        0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0,
+        0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0,
+        0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0,
+    };
+    yych = *p;
+    if (yych == '-')
+      goto yy1014;
+    if (yych == '=')
+      goto yy1015;
+    ++p;
+  yy1013 : { return 0; }
+  yy1014:
+    yych = *(marker = ++p);
+    if (yybm[0 + yych] & 128) {
+      goto yy1027;
+    }
+    if (yych <= '\f') {
+      if (yych <= 0x08)
+        goto yy1013;
+      if (yych <= '\n')
+        goto yy1024;
+      goto yy1013;
+    } else {
+      if (yych <= '\r')
+        goto yy1024;
+      if (yych == ' ')
+        goto yy1024;
+      goto yy1013;
+    }
+  yy1015:
+    yych = *(marker = ++p);
+    if (yybm[0 + yych] & 64) {
+      goto yy1021;
+    }
+    if (yych <= '\f') {
+      if (yych <= 0x08)
+        goto yy1013;
+      if (yych <= '\n')
+        goto yy1017;
+      goto yy1013;
+    } else {
+      if (yych <= '\r')
+        goto yy1017;
+      if (yych == ' ')
+        goto yy1017;
+      goto yy1013;
+    }
+  yy1016:
+    ++p;
+    yych = *p;
+  yy1017:
+    if (yybm[0 + yych] & 32) {
+      goto yy1016;
+    }
+    if (yych <= 0x08)
+      goto yy1018;
+    if (yych <= '\n')
+      goto yy1019;
+    if (yych == '\r')
+      goto yy1019;
+  yy1018:
+    p = marker;
+    goto yy1013;
+  yy1019:
+    ++p;
+    { return 1; }
+  yy1021:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 32) {
+      goto yy1016;
+    }
+    if (yych <= '\f') {
+      if (yych <= 0x08)
+        goto yy1018;
+      if (yych <= '\n')
+        goto yy1019;
+      goto yy1018;
+    } else {
+      if (yych <= '\r')
+        goto yy1019;
+      if (yych == '=')
+        goto yy1021;
+      goto yy1018;
+    }
+  yy1023:
+    ++p;
+    yych = *p;
+  yy1024:
+    if (yych <= '\f') {
+      if (yych <= 0x08)
+        goto yy1018;
+      if (yych <= '\t')
+        goto yy1023;
+      if (yych >= '\v')
+        goto yy1018;
+    } else {
+      if (yych <= '\r')
+        goto yy1025;
+      if (yych == ' ')
+        goto yy1023;
+      goto yy1018;
+    }
+  yy1025:
+    ++p;
+    { return 2; }
+  yy1027:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 128) {
+      goto yy1027;
+    }
+    if (yych <= '\f') {
+      if (yych <= 0x08)
+        goto yy1018;
+      if (yych <= '\t')
+        goto yy1023;
+      if (yych <= '\n')
+        goto yy1025;
+      goto yy1018;
+    } else {
+      if (yych <= '\r')
+        goto yy1025;
+      if (yych == ' ')
+        goto yy1023;
+      goto yy1018;
+    }
+  }
+}
+
+// Scan a thematic break line: "...three or more hyphens, asterisks,
+// or underscores on a line by themselves. If you wish, you may use
+// spaces between the hyphens or asterisks."
+bufsize_t _scan_thematic_break(const unsigned char *p) {
+  const unsigned char *marker = NULL;
+  const unsigned char *start = p;
+
+  {
+    unsigned char yych;
+    static const unsigned char yybm[] = {
+        0, 0, 0,   0, 0, 0,  0, 0, 0, 240, 0, 0, 0,   0, 0, 0,  0, 0, 0, 0,
+        0, 0, 0,   0, 0, 0,  0, 0, 0, 0,   0, 0, 240, 0, 0, 0,  0, 0, 0, 0,
+        0, 0, 128, 0, 0, 64, 0, 0, 0, 0,   0, 0, 0,   0, 0, 0,  0, 0, 0, 0,
+        0, 0, 0,   0, 0, 0,  0, 0, 0, 0,   0, 0, 0,   0, 0, 0,  0, 0, 0, 0,
+        0, 0, 0,   0, 0, 0,  0, 0, 0, 0,   0, 0, 0,   0, 0, 32, 0, 0, 0, 0,
+        0, 0, 0,   0, 0, 0,  0, 0, 0, 0,   0, 0, 0,   0, 0, 0,  0, 0, 0, 0,
+        0, 0, 0,   0, 0, 0,  0, 0, 0, 0,   0, 0, 0,   0, 0, 0,  0, 0, 0, 0,
+        0, 0, 0,   0, 0, 0,  0, 0, 0, 0,   0, 0, 0,   0, 0, 0,  0, 0, 0, 0,
+        0, 0, 0,   0, 0, 0,  0, 0, 0, 0,   0, 0, 0,   0, 0, 0,  0, 0, 0, 0,
+        0, 0, 0,   0, 0, 0,  0, 0, 0, 0,   0, 0, 0,   0, 0, 0,  0, 0, 0, 0,
+        0, 0, 0,   0, 0, 0,  0, 0, 0, 0,   0, 0, 0,   0, 0, 0,  0, 0, 0, 0,
+        0, 0, 0,   0, 0, 0,  0, 0, 0, 0,   0, 0, 0,   0, 0, 0,  0, 0, 0, 0,
+        0, 0, 0,   0, 0, 0,  0, 0, 0, 0,   0, 0, 0,   0, 0, 0,
+    };
+    yych = *p;
+    if (yych <= ',') {
+      if (yych == '*')
+        goto yy1033;
+    } else {
+      if (yych <= '-')
+        goto yy1034;
+      if (yych == '_')
+        goto yy1035;
+    }
+    ++p;
+  yy1032 : { return 0; }
+  yy1033:
+    yych = *(marker = ++p);
+    if (yych <= 0x1F) {
+      if (yych == '\t')
+        goto yy1057;
+      goto yy1032;
+    } else {
+      if (yych <= ' ')
+        goto yy1057;
+      if (yych == '*')
+        goto yy1059;
+      goto yy1032;
+    }
+  yy1034:
+    yych = *(marker = ++p);
+    if (yych <= 0x1F) {
+      if (yych == '\t')
+        goto yy1047;
+      goto yy1032;
+    } else {
+      if (yych <= ' ')
+        goto yy1047;
+      if (yych == '-')
+        goto yy1049;
+      goto yy1032;
+    }
+  yy1035:
+    yych = *(marker = ++p);
+    if (yybm[0 + yych] & 16) {
+      goto yy1036;
+    }
+    if (yych == '_')
+      goto yy1039;
+    goto yy1032;
+  yy1036:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 16) {
+      goto yy1036;
+    }
+    if (yych == '_')
+      goto yy1039;
+  yy1038:
+    p = marker;
+    goto yy1032;
+  yy1039:
+    ++p;
+    yych = *p;
+    if (yych <= 0x1F) {
+      if (yych == '\t')
+        goto yy1039;
+      goto yy1038;
+    } else {
+      if (yych <= ' ')
+        goto yy1039;
+      if (yych != '_')
+        goto yy1038;
+    }
+  yy1041:
+    ++p;
+    yych = *p;
+    if (yych <= '\r') {
+      if (yych <= '\t') {
+        if (yych <= 0x08)
+          goto yy1038;
+        goto yy1041;
+      } else {
+        if (yych <= '\n')
+          goto yy1043;
+        if (yych <= '\f')
+          goto yy1038;
+      }
+    } else {
+      if (yych <= ' ') {
+        if (yych <= 0x1F)
+          goto yy1038;
+        goto yy1041;
+      } else {
+        if (yych == '_')
+          goto yy1045;
+        goto yy1038;
+      }
+    }
+  yy1043:
+    ++p;
+    { return (bufsize_t)(p - start); }
+  yy1045:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 32) {
+      goto yy1045;
+    }
+    if (yych <= 0x08)
+      goto yy1038;
+    if (yych <= '\n')
+      goto yy1043;
+    if (yych == '\r')
+      goto yy1043;
+    goto yy1038;
+  yy1047:
+    ++p;
+    yych = *p;
+    if (yych <= 0x1F) {
+      if (yych == '\t')
+        goto yy1047;
+      goto yy1038;
+    } else {
+      if (yych <= ' ')
+        goto yy1047;
+      if (yych != '-')
+        goto yy1038;
+    }
+  yy1049:
+    ++p;
+    yych = *p;
+    if (yych <= 0x1F) {
+      if (yych == '\t')
+        goto yy1049;
+      goto yy1038;
+    } else {
+      if (yych <= ' ')
+        goto yy1049;
+      if (yych != '-')
+        goto yy1038;
+    }
+  yy1051:
+    ++p;
+    yych = *p;
+    if (yych <= '\r') {
+      if (yych <= '\t') {
+        if (yych <= 0x08)
+          goto yy1038;
+        goto yy1051;
+      } else {
+        if (yych <= '\n')
+          goto yy1053;
+        if (yych <= '\f')
+          goto yy1038;
+      }
+    } else {
+      if (yych <= ' ') {
+        if (yych <= 0x1F)
+          goto yy1038;
+        goto yy1051;
+      } else {
+        if (yych == '-')
+          goto yy1055;
+        goto yy1038;
+      }
+    }
+  yy1053:
+    ++p;
+    { return (bufsize_t)(p - start); }
+  yy1055:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 64) {
+      goto yy1055;
+    }
+    if (yych <= 0x08)
+      goto yy1038;
+    if (yych <= '\n')
+      goto yy1053;
+    if (yych == '\r')
+      goto yy1053;
+    goto yy1038;
+  yy1057:
+    ++p;
+    yych = *p;
+    if (yych <= 0x1F) {
+      if (yych == '\t')
+        goto yy1057;
+      goto yy1038;
+    } else {
+      if (yych <= ' ')
+        goto yy1057;
+      if (yych != '*')
+        goto yy1038;
+    }
+  yy1059:
+    ++p;
+    yych = *p;
+    if (yych <= 0x1F) {
+      if (yych == '\t')
+        goto yy1059;
+      goto yy1038;
+    } else {
+      if (yych <= ' ')
+        goto yy1059;
+      if (yych != '*')
+        goto yy1038;
+    }
+  yy1061:
+    ++p;
+    yych = *p;
+    if (yych <= '\r') {
+      if (yych <= '\t') {
+        if (yych <= 0x08)
+          goto yy1038;
+        goto yy1061;
+      } else {
+        if (yych <= '\n')
+          goto yy1063;
+        if (yych <= '\f')
+          goto yy1038;
+      }
+    } else {
+      if (yych <= ' ') {
+        if (yych <= 0x1F)
+          goto yy1038;
+        goto yy1061;
+      } else {
+        if (yych == '*')
+          goto yy1065;
+        goto yy1038;
+      }
+    }
+  yy1063:
+    ++p;
+    { return (bufsize_t)(p - start); }
+  yy1065:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 128) {
+      goto yy1065;
+    }
+    if (yych <= 0x08)
+      goto yy1038;
+    if (yych <= '\n')
+      goto yy1063;
+    if (yych == '\r')
+      goto yy1063;
+    goto yy1038;
+  }
+}
+
+// Scan an opening code fence.
+bufsize_t _scan_open_code_fence(const unsigned char *p) {
+  const unsigned char *marker = NULL;
+  const unsigned char *start = p;
+
+  {
+    unsigned char yych;
+    static const unsigned char yybm[] = {
+        0,   160, 160, 160, 160, 160, 160, 160, 160, 160, 0,   160, 160, 0,
+        160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
+        160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
+        160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
+        160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
+        160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
+        160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 96,  160,
+        160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
+        160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
+        144, 160, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+        0,   0,   0,   0,
+    };
+    yych = *p;
+    if (yych == '`')
+      goto yy1071;
+    if (yych == '~')
+      goto yy1072;
+    ++p;
+  yy1070 : { return 0; }
+  yy1071:
+    yych = *(marker = ++p);
+    if (yych == '`')
+      goto yy1088;
+    goto yy1070;
+  yy1072:
+    yych = *(marker = ++p);
+    if (yych != '~')
+      goto yy1070;
+    yych = *++p;
+    if (yybm[0 + yych] & 16) {
+      goto yy1075;
+    }
+  yy1074:
+    p = marker;
+    goto yy1070;
+  yy1075:
+    ++p;
+    yych = *p;
+    marker = p;
+    if (yybm[0 + yych] & 32) {
+      goto yy1077;
+    }
+    if (yych <= 0xE0) {
+      if (yych <= '~') {
+        if (yych <= 0x00)
+          goto yy1074;
+        if (yych <= '\r')
+          goto yy1086;
+        goto yy1075;
+      } else {
+        if (yych <= 0xC1)
+          goto yy1074;
+        if (yych <= 0xDF)
+          goto yy1079;
+        goto yy1080;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych == 0xED)
+          goto yy1085;
+        goto yy1081;
+      } else {
+        if (yych <= 0xF0)
+          goto yy1082;
+        if (yych <= 0xF3)
+          goto yy1083;
+        if (yych <= 0xF4)
+          goto yy1084;
+        goto yy1074;
+      }
+    }
+  yy1077:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 32) {
+      goto yy1077;
+    }
+    if (yych <= 0xEC) {
+      if (yych <= 0xC1) {
+        if (yych <= 0x00)
+          goto yy1074;
+        if (yych <= '\r')
+          goto yy1086;
+        goto yy1074;
+      } else {
+        if (yych <= 0xDF)
+          goto yy1079;
+        if (yych <= 0xE0)
+          goto yy1080;
+        goto yy1081;
+      }
+    } else {
+      if (yych <= 0xF0) {
+        if (yych <= 0xED)
+          goto yy1085;
+        if (yych <= 0xEF)
+          goto yy1081;
+        goto yy1082;
+      } else {
+        if (yych <= 0xF3)
+          goto yy1083;
+        if (yych <= 0xF4)
+          goto yy1084;
+        goto yy1074;
+      }
+    }
+  yy1079:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy1074;
+    if (yych <= 0xBF)
+      goto yy1077;
+    goto yy1074;
+  yy1080:
+    ++p;
+    yych = *p;
+    if (yych <= 0x9F)
+      goto yy1074;
+    if (yych <= 0xBF)
+      goto yy1079;
+    goto yy1074;
+  yy1081:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy1074;
+    if (yych <= 0xBF)
+      goto yy1079;
+    goto yy1074;
+  yy1082:
+    ++p;
+    yych = *p;
+    if (yych <= 0x8F)
+      goto yy1074;
+    if (yych <= 0xBF)
+      goto yy1081;
+    goto yy1074;
+  yy1083:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy1074;
+    if (yych <= 0xBF)
+      goto yy1081;
+    goto yy1074;
+  yy1084:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy1074;
+    if (yych <= 0x8F)
+      goto yy1081;
+    goto yy1074;
+  yy1085:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy1074;
+    if (yych <= 0x9F)
+      goto yy1079;
+    goto yy1074;
+  yy1086:
+    ++p;
+    p = marker;
+    { return (bufsize_t)(p - start); }
+  yy1088:
+    yych = *++p;
+    if (yybm[0 + yych] & 64) {
+      goto yy1089;
+    }
+    goto yy1074;
+  yy1089:
+    ++p;
+    yych = *p;
+    marker = p;
+    if (yybm[0 + yych] & 128) {
+      goto yy1091;
+    }
+    if (yych <= 0xE0) {
+      if (yych <= '`') {
+        if (yych <= 0x00)
+          goto yy1074;
+        if (yych <= '\r')
+          goto yy1100;
+        goto yy1089;
+      } else {
+        if (yych <= 0xC1)
+          goto yy1074;
+        if (yych <= 0xDF)
+          goto yy1093;
+        goto yy1094;
+      }
+    } else {
+      if (yych <= 0xEF) {
+        if (yych == 0xED)
+          goto yy1099;
+        goto yy1095;
+      } else {
+        if (yych <= 0xF0)
+          goto yy1096;
+        if (yych <= 0xF3)
+          goto yy1097;
+        if (yych <= 0xF4)
+          goto yy1098;
+        goto yy1074;
+      }
+    }
+  yy1091:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 128) {
+      goto yy1091;
+    }
+    if (yych <= 0xEC) {
+      if (yych <= 0xC1) {
+        if (yych <= 0x00)
+          goto yy1074;
+        if (yych <= '\r')
+          goto yy1100;
+        goto yy1074;
+      } else {
+        if (yych <= 0xDF)
+          goto yy1093;
+        if (yych <= 0xE0)
+          goto yy1094;
+        goto yy1095;
+      }
+    } else {
+      if (yych <= 0xF0) {
+        if (yych <= 0xED)
+          goto yy1099;
+        if (yych <= 0xEF)
+          goto yy1095;
+        goto yy1096;
+      } else {
+        if (yych <= 0xF3)
+          goto yy1097;
+        if (yych <= 0xF4)
+          goto yy1098;
+        goto yy1074;
+      }
+    }
+  yy1093:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy1074;
+    if (yych <= 0xBF)
+      goto yy1091;
+    goto yy1074;
+  yy1094:
+    ++p;
+    yych = *p;
+    if (yych <= 0x9F)
+      goto yy1074;
+    if (yych <= 0xBF)
+      goto yy1093;
+    goto yy1074;
+  yy1095:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy1074;
+    if (yych <= 0xBF)
+      goto yy1093;
+    goto yy1074;
+  yy1096:
+    ++p;
+    yych = *p;
+    if (yych <= 0x8F)
+      goto yy1074;
+    if (yych <= 0xBF)
+      goto yy1095;
+    goto yy1074;
+  yy1097:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy1074;
+    if (yych <= 0xBF)
+      goto yy1095;
+    goto yy1074;
+  yy1098:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy1074;
+    if (yych <= 0x8F)
+      goto yy1095;
+    goto yy1074;
+  yy1099:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy1074;
+    if (yych <= 0x9F)
+      goto yy1093;
+    goto yy1074;
+  yy1100:
+    ++p;
+    p = marker;
+    { return (bufsize_t)(p - start); }
+  }
+}
+
+// Scan a closing code fence with length at least len.
+bufsize_t _scan_close_code_fence(const unsigned char *p) {
+  const unsigned char *marker = NULL;
+  const unsigned char *start = p;
+
+  {
+    unsigned char yych;
+    static const unsigned char yybm[] = {
+        0, 0, 0, 0, 0, 0, 0, 0, 0,   64, 0,  0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0,   0,  64, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0,   0,  0,  0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0,   0,  0,  0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 128, 0,  0,  0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0,   0,  0,  0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0,   0,  0,  0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0,   0,  0,  0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0,   0,  0,  0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0,   0,  0,  0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0,   0,  0,  0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0,   0,  0,  0, 0, 0,
+    };
+    yych = *p;
+    if (yych == '`')
+      goto yy1106;
+    if (yych == '~')
+      goto yy1107;
+    ++p;
+  yy1105 : { return 0; }
+  yy1106:
+    yych = *(marker = ++p);
+    if (yych == '`')
+      goto yy1116;
+    goto yy1105;
+  yy1107:
+    yych = *(marker = ++p);
+    if (yych != '~')
+      goto yy1105;
+    yych = *++p;
+    if (yybm[0 + yych] & 32) {
+      goto yy1110;
+    }
+  yy1109:
+    p = marker;
+    goto yy1105;
+  yy1110:
+    ++p;
+    yych = *p;
+    marker = p;
+    if (yybm[0 + yych] & 64) {
+      goto yy1112;
+    }
+    if (yych <= '\f') {
+      if (yych <= 0x08)
+        goto yy1109;
+      if (yych <= '\n')
+        goto yy1114;
+      goto yy1109;
+    } else {
+      if (yych <= '\r')
+        goto yy1114;
+      if (yych == '~')
+        goto yy1110;
+      goto yy1109;
+    }
+  yy1112:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 64) {
+      goto yy1112;
+    }
+    if (yych <= 0x08)
+      goto yy1109;
+    if (yych <= '\n')
+      goto yy1114;
+    if (yych != '\r')
+      goto yy1109;
+  yy1114:
+    ++p;
+    p = marker;
+    { return (bufsize_t)(p - start); }
+  yy1116:
+    yych = *++p;
+    if (yybm[0 + yych] & 128) {
+      goto yy1117;
+    }
+    goto yy1109;
+  yy1117:
+    ++p;
+    yych = *p;
+    marker = p;
+    if (yybm[0 + yych] & 128) {
+      goto yy1117;
+    }
+    if (yych <= '\f') {
+      if (yych <= 0x08)
+        goto yy1109;
+      if (yych <= '\t')
+        goto yy1119;
+      if (yych <= '\n')
+        goto yy1121;
+      goto yy1109;
+    } else {
+      if (yych <= '\r')
+        goto yy1121;
+      if (yych != ' ')
+        goto yy1109;
+    }
+  yy1119:
+    ++p;
+    yych = *p;
+    if (yych <= '\f') {
+      if (yych <= 0x08)
+        goto yy1109;
+      if (yych <= '\t')
+        goto yy1119;
+      if (yych >= '\v')
+        goto yy1109;
+    } else {
+      if (yych <= '\r')
+        goto yy1121;
+      if (yych == ' ')
+        goto yy1119;
+      goto yy1109;
+    }
+  yy1121:
+    ++p;
+    p = marker;
+    { return (bufsize_t)(p - start); }
+  }
+}
+
+// Scans an entity.
+// Returns number of chars matched.
+bufsize_t _scan_entity(const unsigned char *p) {
+  const unsigned char *marker = NULL;
+  const unsigned char *start = p;
+
+  {
+    unsigned char yych;
+    yych = *p;
+    if (yych == '&')
+      goto yy1127;
+    ++p;
+  yy1126 : { return 0; }
+  yy1127:
+    yych = *(marker = ++p);
+    if (yych <= '@') {
+      if (yych != '#')
+        goto yy1126;
+    } else {
+      if (yych <= 'Z')
+        goto yy1130;
+      if (yych <= '`')
+        goto yy1126;
+      if (yych <= 'z')
+        goto yy1130;
+      goto yy1126;
+    }
+    yych = *++p;
+    if (yych <= 'W') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1165;
+    } else {
+      if (yych <= 'X')
+        goto yy1164;
+      if (yych == 'x')
+        goto yy1164;
+    }
+  yy1129:
+    p = marker;
+    goto yy1126;
+  yy1130:
+    yych = *++p;
+    if (yych <= '@') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych >= ':')
+        goto yy1129;
+    } else {
+      if (yych <= 'Z')
+        goto yy1131;
+      if (yych <= '`')
+        goto yy1129;
+      if (yych >= '{')
+        goto yy1129;
+    }
+  yy1131:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1134;
+      if (yych <= ':')
+        goto yy1129;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+        goto yy1134;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych <= 'z')
+          goto yy1134;
+        goto yy1129;
+      }
+    }
+  yy1132:
+    ++p;
+    { return (bufsize_t)(p - start); }
+  yy1134:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1135;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= '{')
+          goto yy1129;
+      }
+    }
+  yy1135:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1136;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= '{')
+          goto yy1129;
+      }
+    }
+  yy1136:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1137;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= '{')
+          goto yy1129;
+      }
+    }
+  yy1137:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1138;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= '{')
+          goto yy1129;
+      }
+    }
+  yy1138:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1139;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= '{')
+          goto yy1129;
+      }
+    }
+  yy1139:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1140;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= '{')
+          goto yy1129;
+      }
+    }
+  yy1140:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1141;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= '{')
+          goto yy1129;
+      }
+    }
+  yy1141:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1142;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= '{')
+          goto yy1129;
+      }
+    }
+  yy1142:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1143;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= '{')
+          goto yy1129;
+      }
+    }
+  yy1143:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1144;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= '{')
+          goto yy1129;
+      }
+    }
+  yy1144:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1145;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= '{')
+          goto yy1129;
+      }
+    }
+  yy1145:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1146;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= '{')
+          goto yy1129;
+      }
+    }
+  yy1146:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1147;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= '{')
+          goto yy1129;
+      }
+    }
+  yy1147:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1148;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= '{')
+          goto yy1129;
+      }
+    }
+  yy1148:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1149;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= '{')
+          goto yy1129;
+      }
+    }
+  yy1149:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1150;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= '{')
+          goto yy1129;
+      }
+    }
+  yy1150:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1151;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= '{')
+          goto yy1129;
+      }
+    }
+  yy1151:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1152;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= '{')
+          goto yy1129;
+      }
+    }
+  yy1152:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1153;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= '{')
+          goto yy1129;
+      }
+    }
+  yy1153:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1154;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= '{')
+          goto yy1129;
+      }
+    }
+  yy1154:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1155;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= '{')
+          goto yy1129;
+      }
+    }
+  yy1155:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1156;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= '{')
+          goto yy1129;
+      }
+    }
+  yy1156:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1157;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= '{')
+          goto yy1129;
+      }
+    }
+  yy1157:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1158;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= '{')
+          goto yy1129;
+      }
+    }
+  yy1158:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1159;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= '{')
+          goto yy1129;
+      }
+    }
+  yy1159:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1160;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= '{')
+          goto yy1129;
+      }
+    }
+  yy1160:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1161;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= '{')
+          goto yy1129;
+      }
+    }
+  yy1161:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1162;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= '{')
+          goto yy1129;
+      }
+    }
+  yy1162:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1163;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'Z') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= '{')
+          goto yy1129;
+      }
+    }
+  yy1163:
+    yych = *++p;
+    if (yych == ';')
+      goto yy1132;
+    goto yy1129;
+  yy1164:
+    yych = *++p;
+    if (yych <= '@') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1172;
+      goto yy1129;
+    } else {
+      if (yych <= 'F')
+        goto yy1172;
+      if (yych <= '`')
+        goto yy1129;
+      if (yych <= 'f')
+        goto yy1172;
+      goto yy1129;
+    }
+  yy1165:
+    yych = *++p;
+    if (yych <= '/')
+      goto yy1129;
+    if (yych <= '9')
+      goto yy1166;
+    if (yych == ';')
+      goto yy1132;
+    goto yy1129;
+  yy1166:
+    yych = *++p;
+    if (yych <= '/')
+      goto yy1129;
+    if (yych <= '9')
+      goto yy1167;
+    if (yych == ';')
+      goto yy1132;
+    goto yy1129;
+  yy1167:
+    yych = *++p;
+    if (yych <= '/')
+      goto yy1129;
+    if (yych <= '9')
+      goto yy1168;
+    if (yych == ';')
+      goto yy1132;
+    goto yy1129;
+  yy1168:
+    yych = *++p;
+    if (yych <= '/')
+      goto yy1129;
+    if (yych <= '9')
+      goto yy1169;
+    if (yych == ';')
+      goto yy1132;
+    goto yy1129;
+  yy1169:
+    yych = *++p;
+    if (yych <= '/')
+      goto yy1129;
+    if (yych <= '9')
+      goto yy1170;
+    if (yych == ';')
+      goto yy1132;
+    goto yy1129;
+  yy1170:
+    yych = *++p;
+    if (yych <= '/')
+      goto yy1129;
+    if (yych <= '9')
+      goto yy1171;
+    if (yych == ';')
+      goto yy1132;
+    goto yy1129;
+  yy1171:
+    yych = *++p;
+    if (yych <= '/')
+      goto yy1129;
+    if (yych <= '9')
+      goto yy1163;
+    if (yych == ';')
+      goto yy1132;
+    goto yy1129;
+  yy1172:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1173;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'F') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= 'g')
+          goto yy1129;
+      }
+    }
+  yy1173:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1174;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'F') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= 'g')
+          goto yy1129;
+      }
+    }
+  yy1174:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1175;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'F') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= 'g')
+          goto yy1129;
+      }
+    }
+  yy1175:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1176;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'F') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= 'g')
+          goto yy1129;
+      }
+    }
+  yy1176:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1177;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'F') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= 'g')
+          goto yy1129;
+      }
+    }
+  yy1177:
+    yych = *++p;
+    if (yych <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1178;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'F') {
+        if (yych <= '@')
+          goto yy1129;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych >= 'g')
+          goto yy1129;
+      }
+    }
+  yy1178:
+    ++p;
+    if ((yych = *p) <= ';') {
+      if (yych <= '/')
+        goto yy1129;
+      if (yych <= '9')
+        goto yy1163;
+      if (yych <= ':')
+        goto yy1129;
+      goto yy1132;
+    } else {
+      if (yych <= 'F') {
+        if (yych <= '@')
+          goto yy1129;
+        goto yy1163;
+      } else {
+        if (yych <= '`')
+          goto yy1129;
+        if (yych <= 'f')
+          goto yy1163;
+        goto yy1129;
+      }
+    }
+  }
+}
+
+// Returns positive value if a URL begins in a way that is potentially
+// dangerous, with javascript:, vbscript:, file:, or data:, otherwise 0.
+bufsize_t _scan_dangerous_url(const unsigned char *p) {
+  const unsigned char *marker = NULL;
+  const unsigned char *start = p;
+
+  {
+    unsigned char yych;
+    unsigned int yyaccept = 0;
+    yych = *p;
+    if (yych <= 'V') {
+      if (yych <= 'F') {
+        if (yych == 'D')
+          goto yy1183;
+        if (yych >= 'F')
+          goto yy1184;
+      } else {
+        if (yych == 'J')
+          goto yy1185;
+        if (yych >= 'V')
+          goto yy1186;
+      }
+    } else {
+      if (yych <= 'f') {
+        if (yych == 'd')
+          goto yy1183;
+        if (yych >= 'f')
+          goto yy1184;
+      } else {
+        if (yych <= 'j') {
+          if (yych >= 'j')
+            goto yy1185;
+        } else {
+          if (yych == 'v')
+            goto yy1186;
+        }
+      }
+    }
+    ++p;
+  yy1182 : { return 0; }
+  yy1183:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych == 'A')
+      goto yy1209;
+    if (yych == 'a')
+      goto yy1209;
+    goto yy1182;
+  yy1184:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych == 'I')
+      goto yy1206;
+    if (yych == 'i')
+      goto yy1206;
+    goto yy1182;
+  yy1185:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych == 'A')
+      goto yy1197;
+    if (yych == 'a')
+      goto yy1197;
+    goto yy1182;
+  yy1186:
+    yyaccept = 0;
+    yych = *(marker = ++p);
+    if (yych == 'B')
+      goto yy1187;
+    if (yych != 'b')
+      goto yy1182;
+  yy1187:
+    yych = *++p;
+    if (yych == 'S')
+      goto yy1189;
+    if (yych == 's')
+      goto yy1189;
+  yy1188:
+    p = marker;
+    if (yyaccept == 0) {
+      goto yy1182;
+    } else {
+      goto yy1196;
+    }
+  yy1189:
+    yych = *++p;
+    if (yych == 'C')
+      goto yy1190;
+    if (yych != 'c')
+      goto yy1188;
+  yy1190:
+    yych = *++p;
+    if (yych == 'R')
+      goto yy1191;
+    if (yych != 'r')
+      goto yy1188;
+  yy1191:
+    yych = *++p;
+    if (yych == 'I')
+      goto yy1192;
+    if (yych != 'i')
+      goto yy1188;
+  yy1192:
+    yych = *++p;
+    if (yych == 'P')
+      goto yy1193;
+    if (yych != 'p')
+      goto yy1188;
+  yy1193:
+    yych = *++p;
+    if (yych == 'T')
+      goto yy1194;
+    if (yych != 't')
+      goto yy1188;
+  yy1194:
+    yych = *++p;
+    if (yych != ':')
+      goto yy1188;
+  yy1195:
+    ++p;
+  yy1196 : { return (bufsize_t)(p - start); }
+  yy1197:
+    yych = *++p;
+    if (yych == 'V')
+      goto yy1198;
+    if (yych != 'v')
+      goto yy1188;
+  yy1198:
+    yych = *++p;
+    if (yych == 'A')
+      goto yy1199;
+    if (yych != 'a')
+      goto yy1188;
+  yy1199:
+    yych = *++p;
+    if (yych == 'S')
+      goto yy1200;
+    if (yych != 's')
+      goto yy1188;
+  yy1200:
+    yych = *++p;
+    if (yych == 'C')
+      goto yy1201;
+    if (yych != 'c')
+      goto yy1188;
+  yy1201:
+    yych = *++p;
+    if (yych == 'R')
+      goto yy1202;
+    if (yych != 'r')
+      goto yy1188;
+  yy1202:
+    yych = *++p;
+    if (yych == 'I')
+      goto yy1203;
+    if (yych != 'i')
+      goto yy1188;
+  yy1203:
+    yych = *++p;
+    if (yych == 'P')
+      goto yy1204;
+    if (yych != 'p')
+      goto yy1188;
+  yy1204:
+    yych = *++p;
+    if (yych == 'T')
+      goto yy1205;
+    if (yych != 't')
+      goto yy1188;
+  yy1205:
+    yych = *++p;
+    if (yych == ':')
+      goto yy1195;
+    goto yy1188;
+  yy1206:
+    yych = *++p;
+    if (yych == 'L')
+      goto yy1207;
+    if (yych != 'l')
+      goto yy1188;
+  yy1207:
+    yych = *++p;
+    if (yych == 'E')
+      goto yy1208;
+    if (yych != 'e')
+      goto yy1188;
+  yy1208:
+    yych = *++p;
+    if (yych == ':')
+      goto yy1195;
+    goto yy1188;
+  yy1209:
+    yych = *++p;
+    if (yych == 'T')
+      goto yy1210;
+    if (yych != 't')
+      goto yy1188;
+  yy1210:
+    yych = *++p;
+    if (yych == 'A')
+      goto yy1211;
+    if (yych != 'a')
+      goto yy1188;
+  yy1211:
+    yych = *++p;
+    if (yych != ':')
+      goto yy1188;
+    yyaccept = 1;
+    yych = *(marker = ++p);
+    if (yych == 'I')
+      goto yy1213;
+    if (yych != 'i')
+      goto yy1196;
+  yy1213:
+    yych = *++p;
+    if (yych == 'M')
+      goto yy1214;
+    if (yych != 'm')
+      goto yy1188;
+  yy1214:
+    yych = *++p;
+    if (yych == 'A')
+      goto yy1215;
+    if (yych != 'a')
+      goto yy1188;
+  yy1215:
+    yych = *++p;
+    if (yych == 'G')
+      goto yy1216;
+    if (yych != 'g')
+      goto yy1188;
+  yy1216:
+    yych = *++p;
+    if (yych == 'E')
+      goto yy1217;
+    if (yych != 'e')
+      goto yy1188;
+  yy1217:
+    yych = *++p;
+    if (yych != '/')
+      goto yy1188;
+    yych = *++p;
+    if (yych <= 'W') {
+      if (yych <= 'J') {
+        if (yych == 'G')
+          goto yy1220;
+        if (yych <= 'I')
+          goto yy1188;
+        goto yy1221;
+      } else {
+        if (yych == 'P')
+          goto yy1219;
+        if (yych <= 'V')
+          goto yy1188;
+        goto yy1222;
+      }
+    } else {
+      if (yych <= 'j') {
+        if (yych == 'g')
+          goto yy1220;
+        if (yych <= 'i')
+          goto yy1188;
+        goto yy1221;
+      } else {
+        if (yych <= 'p') {
+          if (yych <= 'o')
+            goto yy1188;
+        } else {
+          if (yych == 'w')
+            goto yy1222;
+          goto yy1188;
+        }
+      }
+    }
+  yy1219:
+    yych = *++p;
+    if (yych == 'N')
+      goto yy1230;
+    if (yych == 'n')
+      goto yy1230;
+    goto yy1188;
+  yy1220:
+    yych = *++p;
+    if (yych == 'I')
+      goto yy1229;
+    if (yych == 'i')
+      goto yy1229;
+    goto yy1188;
+  yy1221:
+    yych = *++p;
+    if (yych == 'P')
+      goto yy1227;
+    if (yych == 'p')
+      goto yy1227;
+    goto yy1188;
+  yy1222:
+    yych = *++p;
+    if (yych == 'E')
+      goto yy1223;
+    if (yych != 'e')
+      goto yy1188;
+  yy1223:
+    yych = *++p;
+    if (yych == 'B')
+      goto yy1224;
+    if (yych != 'b')
+      goto yy1188;
+  yy1224:
+    yych = *++p;
+    if (yych == 'P')
+      goto yy1225;
+    if (yych != 'p')
+      goto yy1188;
+  yy1225:
+    ++p;
+    { return 0; }
+  yy1227:
+    yych = *++p;
+    if (yych == 'E')
+      goto yy1228;
+    if (yych != 'e')
+      goto yy1188;
+  yy1228:
+    yych = *++p;
+    if (yych == 'G')
+      goto yy1225;
+    if (yych == 'g')
+      goto yy1225;
+    goto yy1188;
+  yy1229:
+    yych = *++p;
+    if (yych == 'F')
+      goto yy1225;
+    if (yych == 'f')
+      goto yy1225;
+    goto yy1188;
+  yy1230:
+    ++p;
+    if ((yych = *p) == 'G')
+      goto yy1225;
+    if (yych == 'g')
+      goto yy1225;
+    goto yy1188;
+  }
+}
+
+// Scans a footnote definition opening.
+bufsize_t _scan_footnote_definition(const unsigned char *p) {
+  const unsigned char *marker = NULL;
+  const unsigned char *start = p;
+
+  {
+    unsigned char yych;
+    static const unsigned char yybm[] = {
+        0,   64, 64, 64, 64, 64, 64, 64, 64, 128, 0,  64, 64, 0,  64, 64,
+        64,  64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64,
+        128, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64,
+        64,  64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64,
+        64,  64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64,
+        64,  64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 0,  64, 64,
+        64,  64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64,
+        64,  64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64,
+        0,   0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,
+        0,   0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,
+        0,   0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,
+        0,   0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,
+        0,   0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,
+        0,   0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,
+        0,   0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,
+        0,   0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,
+    };
+    yych = *p;
+    if (yych == '[')
+      goto yy1235;
+    ++p;
+  yy1234 : { return 0; }
+  yy1235:
+    yych = *(marker = ++p);
+    if (yych != '^')
+      goto yy1234;
+    yych = *++p;
+    if (yych != ']')
+      goto yy1239;
+  yy1237:
+    p = marker;
+    goto yy1234;
+  yy1238:
+    ++p;
+    yych = *p;
+  yy1239:
+    if (yybm[0 + yych] & 64) {
+      goto yy1238;
+    }
+    if (yych <= 0xEC) {
+      if (yych <= 0xC1) {
+        if (yych <= ' ')
+          goto yy1237;
+        if (yych <= ']')
+          goto yy1247;
+        goto yy1237;
+      } else {
+        if (yych <= 0xDF)
+          goto yy1240;
+        if (yych <= 0xE0)
+          goto yy1241;
+        goto yy1242;
+      }
+    } else {
+      if (yych <= 0xF0) {
+        if (yych <= 0xED)
+          goto yy1246;
+        if (yych <= 0xEF)
+          goto yy1242;
+        goto yy1243;
+      } else {
+        if (yych <= 0xF3)
+          goto yy1244;
+        if (yych <= 0xF4)
+          goto yy1245;
+        goto yy1237;
+      }
+    }
+  yy1240:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy1237;
+    if (yych <= 0xBF)
+      goto yy1238;
+    goto yy1237;
+  yy1241:
+    ++p;
+    yych = *p;
+    if (yych <= 0x9F)
+      goto yy1237;
+    if (yych <= 0xBF)
+      goto yy1240;
+    goto yy1237;
+  yy1242:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy1237;
+    if (yych <= 0xBF)
+      goto yy1240;
+    goto yy1237;
+  yy1243:
+    ++p;
+    yych = *p;
+    if (yych <= 0x8F)
+      goto yy1237;
+    if (yych <= 0xBF)
+      goto yy1242;
+    goto yy1237;
+  yy1244:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy1237;
+    if (yych <= 0xBF)
+      goto yy1242;
+    goto yy1237;
+  yy1245:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy1237;
+    if (yych <= 0x8F)
+      goto yy1242;
+    goto yy1237;
+  yy1246:
+    ++p;
+    yych = *p;
+    if (yych <= 0x7F)
+      goto yy1237;
+    if (yych <= 0x9F)
+      goto yy1240;
+    goto yy1237;
+  yy1247:
+    yych = *++p;
+    if (yych != ':')
+      goto yy1237;
+  yy1248:
+    ++p;
+    yych = *p;
+    if (yybm[0 + yych] & 128) {
+      goto yy1248;
+    }
+    { return (bufsize_t)(p - start); }
+  }
+}
diff --git a/Sources/libcmark_gfm/strikethrough.c b/Sources/libcmark_gfm/strikethrough.c
new file mode 100644
index 0000000..4b76481
--- /dev/null
+++ b/Sources/libcmark_gfm/strikethrough.c
@@ -0,0 +1,157 @@
+#include "strikethrough.h"
+#include "parser.h"
+#include "render.h"
+
+cmark_node_type CMARK_NODE_STRIKETHROUGH;
+
+static cmark_node *match(cmark_syntax_extension *self, cmark_parser *parser,
+                         cmark_node *parent, unsigned char character,
+                         cmark_inline_parser *inline_parser) {
+  cmark_node *res = NULL;
+  int left_flanking, right_flanking, punct_before, punct_after, delims;
+  char buffer[101];
+
+  if (character != '~')
+    return NULL;
+
+  delims = cmark_inline_parser_scan_delimiters(
+      inline_parser, sizeof(buffer) - 1, '~',
+      &left_flanking,
+      &right_flanking, &punct_before, &punct_after);
+
+  memset(buffer, '~', delims);
+  buffer[delims] = 0;
+
+  res = cmark_node_new_with_mem(CMARK_NODE_TEXT, parser->mem);
+  cmark_node_set_literal(res, buffer);
+  res->start_line = res->end_line = cmark_inline_parser_get_line(inline_parser);
+  res->start_column = cmark_inline_parser_get_column(inline_parser) - delims;
+
+  if (left_flanking || right_flanking) {
+    cmark_inline_parser_push_delimiter(inline_parser, character, left_flanking,
+                                       right_flanking, res);
+  }
+
+  return res;
+}
+
+static delimiter *insert(cmark_syntax_extension *self, cmark_parser *parser,
+                         cmark_inline_parser *inline_parser, delimiter *opener,
+                         delimiter *closer) {
+  cmark_node *strikethrough;
+  cmark_node *tmp, *next;
+  delimiter *delim, *tmp_delim;
+  delimiter *res = closer->next;
+
+  strikethrough = opener->inl_text;
+
+  if (!cmark_node_set_type(strikethrough, CMARK_NODE_STRIKETHROUGH))
+    goto done;
+
+  cmark_node_set_syntax_extension(strikethrough, self);
+
+  cmark_node_set_string_content(strikethrough, "~");
+  tmp = cmark_node_next(opener->inl_text);
+
+  while (tmp) {
+    if (tmp == closer->inl_text)
+      break;
+    next = cmark_node_next(tmp);
+    cmark_node_append_child(strikethrough, tmp);
+    tmp = next;
+  }
+
+  strikethrough->end_column = closer->inl_text->start_column + closer->inl_text->as.literal.len - 1;
+  cmark_node_free(closer->inl_text);
+
+  delim = closer;
+  while (delim != NULL && delim != opener) {
+    tmp_delim = delim->previous;
+    cmark_inline_parser_remove_delimiter(inline_parser, delim);
+    delim = tmp_delim;
+  }
+
+  cmark_inline_parser_remove_delimiter(inline_parser, opener);
+
+done:
+  return res;
+}
+
+static const char *get_type_string(cmark_syntax_extension *extension,
+                                   cmark_node *node) {
+  return node->type == CMARK_NODE_STRIKETHROUGH ? "strikethrough" : "";
+}
+
+static int can_contain(cmark_syntax_extension *extension, cmark_node *node,
+                       cmark_node_type child_type) {
+  if (node->type != CMARK_NODE_STRIKETHROUGH)
+    return false;
+
+  return CMARK_NODE_TYPE_INLINE_P(child_type);
+}
+
+static void commonmark_render(cmark_syntax_extension *extension,
+                              cmark_renderer *renderer, cmark_node *node,
+                              cmark_event_type ev_type, int options) {
+  renderer->out(renderer, node, cmark_node_get_string_content(node), false, LITERAL);
+}
+
+static void latex_render(cmark_syntax_extension *extension,
+                         cmark_renderer *renderer, cmark_node *node,
+                         cmark_event_type ev_type, int options) {
+  // requires \usepackage{ulem}
+  bool entering = (ev_type == CMARK_EVENT_ENTER);
+  if (entering) {
+    renderer->out(renderer, node, "\\sout{", false, LITERAL);
+  } else {
+    renderer->out(renderer, node, "}", false, LITERAL);
+  }
+}
+
+static void man_render(cmark_syntax_extension *extension,
+                       cmark_renderer *renderer, cmark_node *node,
+                       cmark_event_type ev_type, int options) {
+  bool entering = (ev_type == CMARK_EVENT_ENTER);
+  if (entering) {
+    renderer->cr(renderer);
+    renderer->out(renderer, node, ".ST \"", false, LITERAL);
+  } else {
+    renderer->out(renderer, node, "\"", false, LITERAL);
+    renderer->cr(renderer);
+  }
+}
+
+static void html_render(cmark_syntax_extension *extension,
+                        cmark_html_renderer *renderer, cmark_node *node,
+                        cmark_event_type ev_type, int options) {
+  bool entering = (ev_type == CMARK_EVENT_ENTER);
+  if (entering) {
+    cmark_strbuf_puts(renderer->html, "");
+  } else {
+    cmark_strbuf_puts(renderer->html, "");
+  }
+}
+
+cmark_syntax_extension *create_strikethrough_extension(void) {
+  cmark_syntax_extension *ext = cmark_syntax_extension_new("strikethrough");
+  cmark_llist *special_chars = NULL;
+
+  cmark_syntax_extension_set_get_type_string_func(ext, get_type_string);
+  cmark_syntax_extension_set_can_contain_func(ext, can_contain);
+  cmark_syntax_extension_set_commonmark_render_func(ext, commonmark_render);
+  cmark_syntax_extension_set_latex_render_func(ext, latex_render);
+  cmark_syntax_extension_set_man_render_func(ext, man_render);
+  cmark_syntax_extension_set_html_render_func(ext, html_render);
+  CMARK_NODE_STRIKETHROUGH = cmark_syntax_extension_add_node(1);
+
+  cmark_syntax_extension_set_match_inline_func(ext, match);
+  cmark_syntax_extension_set_inline_from_delim_func(ext, insert);
+
+  cmark_mem *mem = cmark_get_default_mem_allocator();
+  special_chars = cmark_llist_append(mem, special_chars, (void *)'~');
+  cmark_syntax_extension_set_special_inline_chars(ext, special_chars);
+
+  cmark_syntax_extension_set_emphasis(ext, 1);
+
+  return ext;
+}
diff --git a/Sources/libcmark_gfm/syntax_extension.c b/Sources/libcmark_gfm/syntax_extension.c
new file mode 100644
index 0000000..d079efa
--- /dev/null
+++ b/Sources/libcmark_gfm/syntax_extension.c
@@ -0,0 +1,139 @@
+#include 
+#include 
+
+#include "cmark.h"
+#include "syntax_extension.h"
+#include "buffer.h"
+
+extern cmark_mem CMARK_DEFAULT_MEM_ALLOCATOR;
+
+static cmark_mem *_mem = &CMARK_DEFAULT_MEM_ALLOCATOR;
+
+void cmark_syntax_extension_free(cmark_mem *mem, cmark_syntax_extension *extension) {
+  if (extension->free_function && extension->priv) {
+    extension->free_function(mem, extension->priv);
+  }
+
+  cmark_llist_free(mem, extension->special_inline_chars);
+  mem->free(extension->name);
+  mem->free(extension);
+}
+
+cmark_syntax_extension *cmark_syntax_extension_new(const char *name) {
+  cmark_syntax_extension *res = (cmark_syntax_extension *) _mem->calloc(1, sizeof(cmark_syntax_extension));
+  res->name = (char *) _mem->calloc(1, sizeof(char) * (strlen(name)) + 1);
+  strcpy(res->name, name);
+  return res;
+}
+
+cmark_node_type cmark_syntax_extension_add_node(int is_inline) {
+  cmark_node_type *ref = !is_inline ? &CMARK_NODE_LAST_BLOCK : &CMARK_NODE_LAST_INLINE;
+
+  if ((*ref & CMARK_NODE_VALUE_MASK) == CMARK_NODE_VALUE_MASK) {
+    assert(false);
+    return (cmark_node_type) 0;
+  }
+
+  return *ref = (cmark_node_type) ((int) *ref + 1);
+}
+
+void cmark_syntax_extension_set_emphasis(cmark_syntax_extension *extension,
+                                         int emphasis) {
+  extension->emphasis = emphasis == 1;
+}
+
+void cmark_syntax_extension_set_open_block_func(cmark_syntax_extension *extension,
+                                                cmark_open_block_func func) {
+  extension->try_opening_block = func;
+}
+
+void cmark_syntax_extension_set_match_block_func(cmark_syntax_extension *extension,
+                                                 cmark_match_block_func func) {
+  extension->last_block_matches = func;
+}
+
+void cmark_syntax_extension_set_match_inline_func(cmark_syntax_extension *extension,
+                                                  cmark_match_inline_func func) {
+  extension->match_inline = func;
+}
+
+void cmark_syntax_extension_set_inline_from_delim_func(cmark_syntax_extension *extension,
+                                                       cmark_inline_from_delim_func func) {
+  extension->insert_inline_from_delim = func;
+}
+
+void cmark_syntax_extension_set_special_inline_chars(cmark_syntax_extension *extension,
+                                                     cmark_llist *special_chars) {
+  extension->special_inline_chars = special_chars;
+}
+
+void cmark_syntax_extension_set_get_type_string_func(cmark_syntax_extension *extension,
+                                                     cmark_get_type_string_func func) {
+  extension->get_type_string_func = func;
+}
+
+void cmark_syntax_extension_set_can_contain_func(cmark_syntax_extension *extension,
+                                                 cmark_can_contain_func func) {
+  extension->can_contain_func = func;
+}
+
+void cmark_syntax_extension_set_contains_inlines_func(cmark_syntax_extension *extension,
+                                                      cmark_contains_inlines_func func) {
+  extension->contains_inlines_func = func;
+}
+
+void cmark_syntax_extension_set_commonmark_render_func(cmark_syntax_extension *extension,
+                                                       cmark_common_render_func func) {
+  extension->commonmark_render_func = func;
+}
+
+void cmark_syntax_extension_set_plaintext_render_func(cmark_syntax_extension *extension,
+                                                      cmark_common_render_func func) {
+  extension->plaintext_render_func = func;
+}
+
+void cmark_syntax_extension_set_latex_render_func(cmark_syntax_extension *extension,
+                                                  cmark_common_render_func func) {
+  extension->latex_render_func = func;
+}
+
+void cmark_syntax_extension_set_man_render_func(cmark_syntax_extension *extension,
+                                                cmark_common_render_func func) {
+  extension->man_render_func = func;
+}
+
+void cmark_syntax_extension_set_html_render_func(cmark_syntax_extension *extension,
+                                                 cmark_html_render_func func) {
+  extension->html_render_func = func;
+}
+
+void cmark_syntax_extension_set_html_filter_func(cmark_syntax_extension *extension,
+                                                 cmark_html_filter_func func) {
+  extension->html_filter_func = func;
+}
+
+void cmark_syntax_extension_set_postprocess_func(cmark_syntax_extension *extension,
+                                                 cmark_postprocess_func func) {
+  extension->postprocess_func = func;
+}
+
+void cmark_syntax_extension_set_private(cmark_syntax_extension *extension,
+                                        void *priv,
+                                        cmark_free_func free_func) {
+  extension->priv = priv;
+  extension->free_function = free_func;
+}
+
+void *cmark_syntax_extension_get_private(cmark_syntax_extension *extension) {
+    return extension->priv;
+}
+
+void cmark_syntax_extension_set_opaque_free_func(cmark_syntax_extension *extension,
+                                                 cmark_opaque_free_func func) {
+  extension->opaque_free_func = func;
+}
+
+void cmark_syntax_extension_set_commonmark_escape_func(cmark_syntax_extension *extension,
+                                                       cmark_commonmark_escape_func func) {
+  extension->commonmark_escape_func = func;
+}
diff --git a/Sources/libcmark_gfm/table.c b/Sources/libcmark_gfm/table.c
new file mode 100644
index 0000000..044343d
--- /dev/null
+++ b/Sources/libcmark_gfm/table.c
@@ -0,0 +1,683 @@
+#include "cmark_extension_api.h"
+#include "html.h"
+#include "inlines.h"
+#include "parser.h"
+#include "references.h"
+#include 
+#include "render.h"
+
+#include "ext_scanners.h"
+#include "strikethrough.h"
+#include "table.h"
+
+cmark_node_type CMARK_NODE_TABLE, CMARK_NODE_TABLE_ROW,
+    CMARK_NODE_TABLE_CELL;
+
+typedef struct {
+  uint16_t n_columns;
+  cmark_llist *cells;
+} table_row;
+
+typedef struct {
+  uint16_t n_columns;
+  uint8_t *alignments;
+} node_table;
+
+typedef struct {
+  bool is_header;
+} node_table_row;
+
+typedef struct {
+  cmark_strbuf *buf;
+  int start_offset, end_offset, internal_offset;
+} node_cell;
+
+static void free_table_cell(cmark_mem *mem, void *data) {
+  node_cell *cell = (node_cell *)data;
+  cmark_strbuf_free((cmark_strbuf *)cell->buf);
+  mem->free(cell->buf);
+  mem->free(cell);
+}
+
+static void free_table_row(cmark_mem *mem, table_row *row) {
+  if (!row)
+    return;
+
+  cmark_llist_free_full(mem, row->cells, (cmark_free_func)free_table_cell);
+
+  mem->free(row);
+}
+
+static void free_node_table(cmark_mem *mem, void *ptr) {
+  node_table *t = (node_table *)ptr;
+  mem->free(t->alignments);
+  mem->free(t);
+}
+
+static void free_node_table_row(cmark_mem *mem, void *ptr) {
+  mem->free(ptr);
+}
+
+static int get_n_table_columns(cmark_node *node) {
+  if (!node || node->type != CMARK_NODE_TABLE)
+    return -1;
+
+  return (int)((node_table *)node->as.opaque)->n_columns;
+}
+
+static int set_n_table_columns(cmark_node *node, uint16_t n_columns) {
+  if (!node || node->type != CMARK_NODE_TABLE)
+    return 0;
+
+  ((node_table *)node->as.opaque)->n_columns = n_columns;
+  return 1;
+}
+
+static uint8_t *get_table_alignments(cmark_node *node) {
+  if (!node || node->type != CMARK_NODE_TABLE)
+    return 0;
+
+  return ((node_table *)node->as.opaque)->alignments;
+}
+
+static int set_table_alignments(cmark_node *node, uint8_t *alignments) {
+  if (!node || node->type != CMARK_NODE_TABLE)
+    return 0;
+
+  ((node_table *)node->as.opaque)->alignments = alignments;
+  return 1;
+}
+
+static cmark_strbuf *unescape_pipes(cmark_mem *mem, unsigned char *string, bufsize_t len)
+{
+  cmark_strbuf *res = (cmark_strbuf *)mem->calloc(1, sizeof(cmark_strbuf));
+  bufsize_t r, w;
+
+  cmark_strbuf_init(mem, res, len + 1);
+  cmark_strbuf_put(res, string, len);
+  cmark_strbuf_putc(res, '\0');
+
+  for (r = 0, w = 0; r < len; ++r) {
+    if (res->ptr[r] == '\\' && res->ptr[r + 1] == '|')
+      r++;
+
+    res->ptr[w++] = res->ptr[r];
+  }
+
+  cmark_strbuf_truncate(res, w);
+
+  return res;
+}
+
+static table_row *row_from_string(cmark_syntax_extension *self,
+                                  cmark_parser *parser, unsigned char *string,
+                                  int len) {
+  table_row *row = NULL;
+  bufsize_t cell_matched, pipe_matched, offset;
+
+  row = (table_row *)parser->mem->calloc(1, sizeof(table_row));
+  row->n_columns = 0;
+  row->cells = NULL;
+
+  offset = scan_table_cell_end(string, len, 0);
+
+  do {
+    cell_matched = scan_table_cell(string, len, offset);
+    pipe_matched = scan_table_cell_end(string, len, offset + cell_matched);
+
+    if (cell_matched || pipe_matched) {
+      cmark_strbuf *cell_buf = unescape_pipes(parser->mem, string + offset,
+          cell_matched);
+      cmark_strbuf_trim(cell_buf);
+
+      node_cell *cell = (node_cell *)parser->mem->calloc(1, sizeof(*cell));
+      cell->buf = cell_buf;
+      cell->start_offset = offset;
+      cell->end_offset = offset + cell_matched - 1;
+      while (cell->start_offset > 0 && string[cell->start_offset - 1] != '|') {
+        --cell->start_offset;
+        ++cell->internal_offset;
+      }
+      row->n_columns += 1;
+      row->cells = cmark_llist_append(parser->mem, row->cells, cell);
+    }
+
+    offset += cell_matched + pipe_matched;
+
+    if (!pipe_matched) {
+      pipe_matched = scan_table_row_end(string, len, offset);
+      offset += pipe_matched;
+    }
+  } while ((cell_matched || pipe_matched) && offset < len);
+
+  if (offset != len || !row->n_columns) {
+    free_table_row(parser->mem, row);
+    row = NULL;
+  }
+
+  return row;
+}
+
+static cmark_node *try_opening_table_header(cmark_syntax_extension *self,
+                                            cmark_parser *parser,
+                                            cmark_node *parent_container,
+                                            unsigned char *input, int len) {
+  bufsize_t matched =
+      scan_table_start(input, len, cmark_parser_get_first_nonspace(parser));
+  cmark_node *table_header;
+  table_row *header_row = NULL;
+  table_row *marker_row = NULL;
+  node_table_row *ntr;
+  const char *parent_string;
+  uint16_t i;
+
+  if (!matched)
+    return parent_container;
+
+  parent_string = cmark_node_get_string_content(parent_container);
+
+  cmark_arena_push();
+
+  header_row = row_from_string(self, parser, (unsigned char *)parent_string,
+                               (int)strlen(parent_string));
+
+  if (!header_row) {
+    free_table_row(parser->mem, header_row);
+    cmark_arena_pop();
+    return parent_container;
+  }
+
+  marker_row = row_from_string(self, parser,
+                               input + cmark_parser_get_first_nonspace(parser),
+                               len - cmark_parser_get_first_nonspace(parser));
+
+  assert(marker_row);
+
+  if (header_row->n_columns != marker_row->n_columns) {
+    free_table_row(parser->mem, header_row);
+    free_table_row(parser->mem, marker_row);
+    cmark_arena_pop();
+    return parent_container;
+  }
+
+  if (cmark_arena_pop()) {
+    header_row = row_from_string(self, parser, (unsigned char *)parent_string,
+                                 (int)strlen(parent_string));
+    marker_row = row_from_string(self, parser,
+                                 input + cmark_parser_get_first_nonspace(parser),
+                                 len - cmark_parser_get_first_nonspace(parser));
+  }
+
+  if (!cmark_node_set_type(parent_container, CMARK_NODE_TABLE)) {
+    free_table_row(parser->mem, header_row);
+    free_table_row(parser->mem, marker_row);
+    return parent_container;
+  }
+
+  cmark_node_set_syntax_extension(parent_container, self);
+
+  parent_container->as.opaque = parser->mem->calloc(1, sizeof(node_table));
+
+  set_n_table_columns(parent_container, header_row->n_columns);
+
+  uint8_t *alignments =
+      (uint8_t *)parser->mem->calloc(header_row->n_columns, sizeof(uint8_t));
+  cmark_llist *it = marker_row->cells;
+  for (i = 0; it; it = it->next, ++i) {
+    node_cell *node = (node_cell *)it->data;
+    bool left = node->buf->ptr[0] == ':', right = node->buf->ptr[node->buf->size - 1] == ':';
+
+    if (left && right)
+      alignments[i] = 'c';
+    else if (left)
+      alignments[i] = 'l';
+    else if (right)
+      alignments[i] = 'r';
+  }
+  set_table_alignments(parent_container, alignments);
+
+  table_header =
+      cmark_parser_add_child(parser, parent_container, CMARK_NODE_TABLE_ROW,
+                             parent_container->start_column);
+  cmark_node_set_syntax_extension(table_header, self);
+  table_header->end_column = parent_container->start_column + (int)strlen(parent_string) - 2;
+  table_header->start_line = table_header->end_line = parent_container->start_line;
+
+  table_header->as.opaque = ntr = (node_table_row *)parser->mem->calloc(1, sizeof(node_table_row));
+  ntr->is_header = true;
+
+  {
+    cmark_llist *tmp;
+
+    for (tmp = header_row->cells; tmp; tmp = tmp->next) {
+      node_cell *cell = (node_cell *) tmp->data;
+      cmark_node *header_cell = cmark_parser_add_child(parser, table_header,
+          CMARK_NODE_TABLE_CELL, parent_container->start_column + cell->start_offset);
+      header_cell->start_line = header_cell->end_line = parent_container->start_line;
+      header_cell->internal_offset = cell->internal_offset;
+      header_cell->end_column = parent_container->start_column + cell->end_offset;
+      cmark_node_set_string_content(header_cell, (char *) cell->buf->ptr);
+      cmark_node_set_syntax_extension(header_cell, self);
+    }
+  }
+
+  cmark_parser_advance_offset(
+      parser, (char *)input,
+      (int)strlen((char *)input) - 1 - cmark_parser_get_offset(parser), false);
+
+  free_table_row(parser->mem, header_row);
+  free_table_row(parser->mem, marker_row);
+  return parent_container;
+}
+
+static cmark_node *try_opening_table_row(cmark_syntax_extension *self,
+                                         cmark_parser *parser,
+                                         cmark_node *parent_container,
+                                         unsigned char *input, int len) {
+  cmark_node *table_row_block;
+  table_row *row;
+
+  if (cmark_parser_is_blank(parser))
+    return NULL;
+
+  table_row_block =
+      cmark_parser_add_child(parser, parent_container, CMARK_NODE_TABLE_ROW,
+                             parent_container->start_column);
+  cmark_node_set_syntax_extension(table_row_block, self);
+  table_row_block->end_column = parent_container->end_column;
+  table_row_block->as.opaque = parser->mem->calloc(1, sizeof(node_table_row));
+
+  row = row_from_string(self, parser, input + cmark_parser_get_first_nonspace(parser),
+      len - cmark_parser_get_first_nonspace(parser));
+
+  {
+    cmark_llist *tmp;
+    int i, table_columns = get_n_table_columns(parent_container);
+
+    for (tmp = row->cells, i = 0; tmp && i < table_columns; tmp = tmp->next, ++i) {
+      node_cell *cell = (node_cell *) tmp->data;
+      cmark_node *node = cmark_parser_add_child(parser, table_row_block,
+          CMARK_NODE_TABLE_CELL, parent_container->start_column + cell->start_offset);
+      node->internal_offset = cell->internal_offset;
+      node->end_column = parent_container->start_column + cell->end_offset;
+      cmark_node_set_string_content(node, (char *) cell->buf->ptr);
+      cmark_node_set_syntax_extension(node, self);
+    }
+
+    for (; i < table_columns; ++i) {
+      cmark_node *node = cmark_parser_add_child(
+          parser, table_row_block, CMARK_NODE_TABLE_CELL, 0);
+      cmark_node_set_syntax_extension(node, self);
+    }
+  }
+
+  free_table_row(parser->mem, row);
+
+  cmark_parser_advance_offset(parser, (char *)input,
+                              len - 1 - cmark_parser_get_offset(parser), false);
+
+  return table_row_block;
+}
+
+static cmark_node *try_opening_table_block(cmark_syntax_extension *self,
+                                           int indented, cmark_parser *parser,
+                                           cmark_node *parent_container,
+                                           unsigned char *input, int len) {
+  cmark_node_type parent_type = cmark_node_get_type(parent_container);
+
+  if (!indented && parent_type == CMARK_NODE_PARAGRAPH) {
+    return try_opening_table_header(self, parser, parent_container, input, len);
+  } else if (!indented && parent_type == CMARK_NODE_TABLE) {
+    return try_opening_table_row(self, parser, parent_container, input, len);
+  }
+
+  return NULL;
+}
+
+static int matches(cmark_syntax_extension *self, cmark_parser *parser,
+                   unsigned char *input, int len,
+                   cmark_node *parent_container) {
+  int res = 0;
+
+  if (cmark_node_get_type(parent_container) == CMARK_NODE_TABLE) {
+    cmark_arena_push();
+    table_row *new_row = row_from_string(
+        self, parser, input + cmark_parser_get_first_nonspace(parser),
+        len - cmark_parser_get_first_nonspace(parser));
+    if (new_row && new_row->n_columns)
+      res = 1;
+    free_table_row(parser->mem, new_row);
+    cmark_arena_pop();
+  }
+
+  return res;
+}
+
+static const char *get_type_string(cmark_syntax_extension *self,
+                                   cmark_node *node) {
+  if (node->type == CMARK_NODE_TABLE) {
+    return "table";
+  } else if (node->type == CMARK_NODE_TABLE_ROW) {
+    if (((node_table_row *)node->as.opaque)->is_header)
+      return "table_header";
+    else
+      return "table_row";
+  } else if (node->type == CMARK_NODE_TABLE_CELL) {
+    return "table_cell";
+  }
+
+  return "";
+}
+
+static int can_contain(cmark_syntax_extension *extension, cmark_node *node,
+                       cmark_node_type child_type) {
+  if (node->type == CMARK_NODE_TABLE) {
+    return child_type == CMARK_NODE_TABLE_ROW;
+  } else if (node->type == CMARK_NODE_TABLE_ROW) {
+    return child_type == CMARK_NODE_TABLE_CELL;
+  } else if (node->type == CMARK_NODE_TABLE_CELL) {
+    return child_type == CMARK_NODE_TEXT || child_type == CMARK_NODE_CODE ||
+           child_type == CMARK_NODE_EMPH || child_type == CMARK_NODE_STRONG ||
+           child_type == CMARK_NODE_LINK || child_type == CMARK_NODE_IMAGE ||
+           child_type == CMARK_NODE_STRIKETHROUGH ||
+           child_type == CMARK_NODE_HTML_INLINE;
+  }
+  return false;
+}
+
+static int contains_inlines(cmark_syntax_extension *extension,
+                            cmark_node *node) {
+  return node->type == CMARK_NODE_TABLE_CELL;
+}
+
+static void commonmark_render(cmark_syntax_extension *extension,
+                              cmark_renderer *renderer, cmark_node *node,
+                              cmark_event_type ev_type, int options) {
+  bool entering = (ev_type == CMARK_EVENT_ENTER);
+
+  if (node->type == CMARK_NODE_TABLE) {
+    renderer->blankline(renderer);
+  } else if (node->type == CMARK_NODE_TABLE_ROW) {
+    if (entering) {
+      renderer->cr(renderer);
+      renderer->out(renderer, node, "|", false, LITERAL);
+    }
+  } else if (node->type == CMARK_NODE_TABLE_CELL) {
+    if (entering) {
+      renderer->out(renderer, node, " ", false, LITERAL);
+    } else {
+      renderer->out(renderer, node, " |", false, LITERAL);
+      if (((node_table_row *)node->parent->as.opaque)->is_header &&
+          !node->next) {
+        int i;
+        uint8_t *alignments = get_table_alignments(node->parent->parent);
+        uint16_t n_cols =
+            ((node_table *)node->parent->parent->as.opaque)->n_columns;
+        renderer->cr(renderer);
+        renderer->out(renderer, node, "|", false, LITERAL);
+        for (i = 0; i < n_cols; i++) {
+          switch (alignments[i]) {
+          case 0:   renderer->out(renderer, node, " --- |", false, LITERAL); break;
+          case 'l': renderer->out(renderer, node, " :-- |", false, LITERAL); break;
+          case 'c': renderer->out(renderer, node, " :-: |", false, LITERAL); break;
+          case 'r': renderer->out(renderer, node, " --: |", false, LITERAL); break;
+          }
+        }
+        renderer->cr(renderer);
+      }
+    }
+  } else {
+    assert(false);
+  }
+}
+
+static void latex_render(cmark_syntax_extension *extension,
+                         cmark_renderer *renderer, cmark_node *node,
+                         cmark_event_type ev_type, int options) {
+  bool entering = (ev_type == CMARK_EVENT_ENTER);
+
+  if (node->type == CMARK_NODE_TABLE) {
+    if (entering) {
+      int i;
+      uint16_t n_cols;
+      uint8_t *alignments = get_table_alignments(node);
+
+      renderer->cr(renderer);
+      renderer->out(renderer, node, "\\begin{table}", false, LITERAL);
+      renderer->cr(renderer);
+      renderer->out(renderer, node, "\\begin{tabular}{", false, LITERAL);
+
+      n_cols = ((node_table *)node->as.opaque)->n_columns;
+      for (i = 0; i < n_cols; i++) {
+        switch(alignments[i]) {
+        case 0:
+        case 'l':
+          renderer->out(renderer, node, "l", false, LITERAL);
+          break;
+        case 'c':
+          renderer->out(renderer, node, "c", false, LITERAL);
+          break;
+        case 'r':
+          renderer->out(renderer, node, "r", false, LITERAL);
+          break;
+        }
+      }
+      renderer->out(renderer, node, "}", false, LITERAL);
+      renderer->cr(renderer);
+    } else {
+      renderer->out(renderer, node, "\\end{tabular}", false, LITERAL);
+      renderer->cr(renderer);
+      renderer->out(renderer, node, "\\end{table}", false, LITERAL);
+      renderer->cr(renderer);
+    }
+  } else if (node->type == CMARK_NODE_TABLE_ROW) {
+    if (!entering) {
+      renderer->cr(renderer);
+    }
+  } else if (node->type == CMARK_NODE_TABLE_CELL) {
+    if (!entering) {
+      if (node->next) {
+        renderer->out(renderer, node, " & ", false, LITERAL);
+      } else {
+        renderer->out(renderer, node, " \\\\", false, LITERAL);
+      }
+    }
+  } else {
+    assert(false);
+  }
+}
+
+static void man_render(cmark_syntax_extension *extension,
+                       cmark_renderer *renderer, cmark_node *node,
+                       cmark_event_type ev_type, int options) {
+  bool entering = (ev_type == CMARK_EVENT_ENTER);
+
+  if (node->type == CMARK_NODE_TABLE) {
+    if (entering) {
+      int i;
+      uint16_t n_cols;
+      uint8_t *alignments = get_table_alignments(node);
+
+      renderer->cr(renderer);
+      renderer->out(renderer, node, ".TS", false, LITERAL);
+      renderer->cr(renderer);
+      renderer->out(renderer, node, "tab(@);", false, LITERAL);
+      renderer->cr(renderer);
+
+      n_cols = ((node_table *)node->as.opaque)->n_columns;
+
+      for (i = 0; i < n_cols; i++) {
+        switch (alignments[i]) {
+        case 'l':
+          renderer->out(renderer, node, "l", false, LITERAL);
+          break;
+        case 0:
+        case 'c':
+          renderer->out(renderer, node, "c", false, LITERAL);
+          break;
+        case 'r':
+          renderer->out(renderer, node, "r", false, LITERAL);
+          break;
+        }
+      }
+
+      if (n_cols) {
+        renderer->out(renderer, node, ".", false, LITERAL);
+        renderer->cr(renderer);
+      }
+    } else {
+      renderer->out(renderer, node, ".TE", false, LITERAL);
+      renderer->cr(renderer);
+    }
+  } else if (node->type == CMARK_NODE_TABLE_ROW) {
+    if (!entering) {
+      renderer->cr(renderer);
+    }
+  } else if (node->type == CMARK_NODE_TABLE_CELL) {
+    if (!entering && node->next) {
+      renderer->out(renderer, node, "@", false, LITERAL);
+    }
+  } else {
+    assert(false);
+  }
+}
+
+struct html_table_state {
+  unsigned need_closing_table_body : 1;
+  unsigned in_table_header : 1;
+};
+
+static void html_render(cmark_syntax_extension *extension,
+                        cmark_html_renderer *renderer, cmark_node *node,
+                        cmark_event_type ev_type, int options) {
+  bool entering = (ev_type == CMARK_EVENT_ENTER);
+  cmark_strbuf *html = renderer->html;
+  cmark_node *n;
+
+  // XXX: we just monopolise renderer->opaque.
+  struct html_table_state *table_state =
+      (struct html_table_state *)&renderer->opaque;
+
+  if (node->type == CMARK_NODE_TABLE) {
+    if (entering) {
+      cmark_html_render_cr(html);
+      cmark_strbuf_puts(html, "');
+      table_state->need_closing_table_body = false;
+    } else {
+      if (table_state->need_closing_table_body)
+        cmark_strbuf_puts(html, "");
+      table_state->need_closing_table_body = false;
+      cmark_strbuf_puts(html, "\n");
+    }
+  } else if (node->type == CMARK_NODE_TABLE_ROW) {
+    if (entering) {
+      cmark_html_render_cr(html);
+      if (((node_table_row *)node->as.opaque)->is_header) {
+        table_state->in_table_header = 1;
+        cmark_strbuf_puts(html, "");
+        cmark_html_render_cr(html);
+      } else if (!table_state->need_closing_table_body) {
+        cmark_strbuf_puts(html, "");
+        cmark_html_render_cr(html);
+        table_state->need_closing_table_body = 1;
+      }
+      cmark_strbuf_puts(html, "');
+    } else {
+      cmark_html_render_cr(html);
+      cmark_strbuf_puts(html, "");
+      if (((node_table_row *)node->as.opaque)->is_header) {
+        cmark_html_render_cr(html);
+        cmark_strbuf_puts(html, "");
+        table_state->in_table_header = false;
+      }
+    }
+  } else if (node->type == CMARK_NODE_TABLE_CELL) {
+    uint8_t *alignments = get_table_alignments(node->parent->parent);
+    if (entering) {
+      cmark_html_render_cr(html);
+      if (table_state->in_table_header) {
+        cmark_strbuf_puts(html, "parent->first_child; n; n = n->next, ++i)
+        if (n == node)
+          break;
+
+      switch (alignments[i]) {
+      case 'l': cmark_strbuf_puts(html, " align=\"left\""); break;
+      case 'c': cmark_strbuf_puts(html, " align=\"center\""); break;
+      case 'r': cmark_strbuf_puts(html, " align=\"right\""); break;
+      }
+
+      cmark_html_render_sourcepos(node, html, options);
+      cmark_strbuf_putc(html, '>');
+    } else {
+      if (table_state->in_table_header) {
+        cmark_strbuf_puts(html, "");
+      } else {
+        cmark_strbuf_puts(html, "");
+      }
+    }
+  } else {
+    assert(false);
+  }
+}
+
+static void opaque_free(cmark_syntax_extension *self, cmark_mem *mem, cmark_node *node) {
+  if (node->type == CMARK_NODE_TABLE) {
+    free_node_table(mem, node->as.opaque);
+  } else if (node->type == CMARK_NODE_TABLE_ROW) {
+    free_node_table_row(mem, node->as.opaque);
+  }
+}
+
+static int escape(cmark_syntax_extension *self, cmark_node *node, int c) {
+  return
+    node->type != CMARK_NODE_TABLE &&
+    node->type != CMARK_NODE_TABLE_ROW &&
+    node->type != CMARK_NODE_TABLE_CELL &&
+    c == '|';
+}
+
+cmark_syntax_extension *create_table_extension(void) {
+  cmark_syntax_extension *self = cmark_syntax_extension_new("table");
+
+  cmark_syntax_extension_set_match_block_func(self, matches);
+  cmark_syntax_extension_set_open_block_func(self, try_opening_table_block);
+  cmark_syntax_extension_set_get_type_string_func(self, get_type_string);
+  cmark_syntax_extension_set_can_contain_func(self, can_contain);
+  cmark_syntax_extension_set_contains_inlines_func(self, contains_inlines);
+  cmark_syntax_extension_set_commonmark_render_func(self, commonmark_render);
+  cmark_syntax_extension_set_plaintext_render_func(self, commonmark_render);
+  cmark_syntax_extension_set_latex_render_func(self, latex_render);
+  cmark_syntax_extension_set_man_render_func(self, man_render);
+  cmark_syntax_extension_set_html_render_func(self, html_render);
+  cmark_syntax_extension_set_opaque_free_func(self, opaque_free);
+  cmark_syntax_extension_set_commonmark_escape_func(self, escape);
+  CMARK_NODE_TABLE = cmark_syntax_extension_add_node(0);
+  CMARK_NODE_TABLE_ROW = cmark_syntax_extension_add_node(0);
+  CMARK_NODE_TABLE_CELL = cmark_syntax_extension_add_node(0);
+
+  return self;
+}
+
+uint16_t cmarkextensions_get_table_columns(cmark_node *node) {
+  if (node->type != CMARK_NODE_TABLE)
+    return 0;
+
+  return ((node_table *)node->as.opaque)->n_columns;
+}
+
+uint8_t *cmarkextensions_get_table_alignments(cmark_node *node) {
+  if (node->type != CMARK_NODE_TABLE)
+    return 0;
+
+  return ((node_table *)node->as.opaque)->alignments;
+}
diff --git a/Sources/libcmark_gfm/tagfilter.c b/Sources/libcmark_gfm/tagfilter.c
new file mode 100644
index 0000000..554943e
--- /dev/null
+++ b/Sources/libcmark_gfm/tagfilter.c
@@ -0,0 +1,60 @@
+#include "tagfilter.h"
+#include "parser.h"
+#include 
+
+static const char *blacklist[] = {
+    "title",   "textarea", "style",  "xmp",       "iframe",
+    "noembed", "noframes", "script", "plaintext", NULL,
+};
+
+static int is_tag(const unsigned char *tag_data, size_t tag_size,
+                  const char *tagname) {
+  size_t i;
+
+  if (tag_size < 3 || tag_data[0] != '<')
+    return 0;
+
+  i = 1;
+
+  if (tag_data[i] == '/') {
+    i++;
+  }
+
+  for (; i < tag_size; ++i, ++tagname) {
+    if (*tagname == 0)
+      break;
+
+    if (tolower(tag_data[i]) != *tagname)
+      return 0;
+  }
+
+  if (i == tag_size)
+    return 0;
+
+  if (cmark_isspace(tag_data[i]) || tag_data[i] == '>')
+    return 1;
+
+  if (tag_data[i] == '/' && tag_size >= i + 2 && tag_data[i + 1] == '>')
+    return 1;
+
+  return 0;
+}
+
+static int filter(cmark_syntax_extension *ext, const unsigned char *tag,
+                  size_t tag_len) {
+  const char **it;
+
+  for (it = blacklist; *it; ++it) {
+    if (is_tag(tag, tag_len, *it)) {
+      return 0;
+    }
+  }
+
+  return 1;
+}
+
+cmark_syntax_extension *create_tagfilter_extension(void) {
+  cmark_syntax_extension *ext = cmark_syntax_extension_new("tagfilter");
+  cmark_syntax_extension_set_html_filter_func(ext, filter);
+  return ext;
+}
diff --git a/Sources/libcmark_gfm/utf8.c b/Sources/libcmark_gfm/utf8.c
new file mode 100644
index 0000000..c29bbf7
--- /dev/null
+++ b/Sources/libcmark_gfm/utf8.c
@@ -0,0 +1,317 @@
+#include 
+#include 
+#include 
+
+#include "cmark_ctype.h"
+#include "utf8.h"
+
+static const int8_t utf8proc_utf8class[256] = {
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+    2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0};
+
+static void encode_unknown(cmark_strbuf *buf) {
+  static const uint8_t repl[] = {239, 191, 189};
+  cmark_strbuf_put(buf, repl, 3);
+}
+
+static int utf8proc_charlen(const uint8_t *str, bufsize_t str_len) {
+  int length, i;
+
+  if (!str_len)
+    return 0;
+
+  length = utf8proc_utf8class[str[0]];
+
+  if (!length)
+    return -1;
+
+  if (str_len >= 0 && (bufsize_t)length > str_len)
+    return -str_len;
+
+  for (i = 1; i < length; i++) {
+    if ((str[i] & 0xC0) != 0x80)
+      return -i;
+  }
+
+  return length;
+}
+
+// Validate a single UTF-8 character according to RFC 3629.
+static int utf8proc_valid(const uint8_t *str, bufsize_t str_len) {
+  int length = utf8proc_utf8class[str[0]];
+
+  if (!length)
+    return -1;
+
+  if ((bufsize_t)length > str_len)
+    return -str_len;
+
+  switch (length) {
+  case 2:
+    if ((str[1] & 0xC0) != 0x80)
+      return -1;
+    if (str[0] < 0xC2) {
+      // Overlong
+      return -length;
+    }
+    break;
+
+  case 3:
+    if ((str[1] & 0xC0) != 0x80)
+      return -1;
+    if ((str[2] & 0xC0) != 0x80)
+      return -2;
+    if (str[0] == 0xE0) {
+      if (str[1] < 0xA0) {
+        // Overlong
+        return -length;
+      }
+    } else if (str[0] == 0xED) {
+      if (str[1] >= 0xA0) {
+        // Surrogate
+        return -length;
+      }
+    }
+    break;
+
+  case 4:
+    if ((str[1] & 0xC0) != 0x80)
+      return -1;
+    if ((str[2] & 0xC0) != 0x80)
+      return -2;
+    if ((str[3] & 0xC0) != 0x80)
+      return -3;
+    if (str[0] == 0xF0) {
+      if (str[1] < 0x90) {
+        // Overlong
+        return -length;
+      }
+    } else if (str[0] >= 0xF4) {
+      if (str[0] > 0xF4 || str[1] >= 0x90) {
+        // Above 0x10FFFF
+        return -length;
+      }
+    }
+    break;
+  }
+
+  return length;
+}
+
+void cmark_utf8proc_check(cmark_strbuf *ob, const uint8_t *line,
+                          bufsize_t size) {
+  bufsize_t i = 0;
+
+  while (i < size) {
+    bufsize_t org = i;
+    int charlen = 0;
+
+    while (i < size) {
+      if (line[i] < 0x80 && line[i] != 0) {
+        i++;
+      } else if (line[i] >= 0x80) {
+        charlen = utf8proc_valid(line + i, size - i);
+        if (charlen < 0) {
+          charlen = -charlen;
+          break;
+        }
+        i += charlen;
+      } else if (line[i] == 0) {
+        // ASCII NUL is technically valid but rejected
+        // for security reasons.
+        charlen = 1;
+        break;
+      }
+    }
+
+    if (i > org) {
+      cmark_strbuf_put(ob, line + org, i - org);
+    }
+
+    if (i >= size) {
+      break;
+    } else {
+      // Invalid UTF-8
+      encode_unknown(ob);
+      i += charlen;
+    }
+  }
+}
+
+int cmark_utf8proc_iterate(const uint8_t *str, bufsize_t str_len,
+                           int32_t *dst) {
+  int length;
+  int32_t uc = -1;
+
+  *dst = -1;
+  length = utf8proc_charlen(str, str_len);
+  if (length < 0)
+    return -1;
+
+  switch (length) {
+  case 1:
+    uc = str[0];
+    break;
+  case 2:
+    uc = ((str[0] & 0x1F) << 6) + (str[1] & 0x3F);
+    if (uc < 0x80)
+      uc = -1;
+    break;
+  case 3:
+    uc = ((str[0] & 0x0F) << 12) + ((str[1] & 0x3F) << 6) + (str[2] & 0x3F);
+    if (uc < 0x800 || (uc >= 0xD800 && uc < 0xE000))
+      uc = -1;
+    break;
+  case 4:
+    uc = ((str[0] & 0x07) << 18) + ((str[1] & 0x3F) << 12) +
+         ((str[2] & 0x3F) << 6) + (str[3] & 0x3F);
+    if (uc < 0x10000 || uc >= 0x110000)
+      uc = -1;
+    break;
+  }
+
+  if (uc < 0)
+    return -1;
+
+  *dst = uc;
+  return length;
+}
+
+void cmark_utf8proc_encode_char(int32_t uc, cmark_strbuf *buf) {
+  uint8_t dst[4];
+  bufsize_t len = 0;
+
+  assert(uc >= 0);
+
+  if (uc < 0x80) {
+    dst[0] = (uint8_t)(uc);
+    len = 1;
+  } else if (uc < 0x800) {
+    dst[0] = (uint8_t)(0xC0 + (uc >> 6));
+    dst[1] = 0x80 + (uc & 0x3F);
+    len = 2;
+  } else if (uc == 0xFFFF) {
+    dst[0] = 0xFF;
+    len = 1;
+  } else if (uc == 0xFFFE) {
+    dst[0] = 0xFE;
+    len = 1;
+  } else if (uc < 0x10000) {
+    dst[0] = (uint8_t)(0xE0 + (uc >> 12));
+    dst[1] = 0x80 + ((uc >> 6) & 0x3F);
+    dst[2] = 0x80 + (uc & 0x3F);
+    len = 3;
+  } else if (uc < 0x110000) {
+    dst[0] = (uint8_t)(0xF0 + (uc >> 18));
+    dst[1] = 0x80 + ((uc >> 12) & 0x3F);
+    dst[2] = 0x80 + ((uc >> 6) & 0x3F);
+    dst[3] = 0x80 + (uc & 0x3F);
+    len = 4;
+  } else {
+    encode_unknown(buf);
+    return;
+  }
+
+  cmark_strbuf_put(buf, dst, len);
+}
+
+void cmark_utf8proc_case_fold(cmark_strbuf *dest, const uint8_t *str,
+                              bufsize_t len) {
+  int32_t c;
+
+#define bufpush(x) cmark_utf8proc_encode_char(x, dest)
+
+  while (len > 0) {
+    bufsize_t char_len = cmark_utf8proc_iterate(str, len, &c);
+
+    if (char_len >= 0) {
+#include "case_fold_switch.inc"
+    } else {
+      encode_unknown(dest);
+      char_len = -char_len;
+    }
+
+    str += char_len;
+    len -= char_len;
+  }
+}
+
+// matches anything in the Zs class, plus LF, CR, TAB, FF.
+int cmark_utf8proc_is_space(int32_t uc) {
+  return (uc == 9 || uc == 10 || uc == 12 || uc == 13 || uc == 32 ||
+          uc == 160 || uc == 5760 || (uc >= 8192 && uc <= 8202) || uc == 8239 ||
+          uc == 8287 || uc == 12288);
+}
+
+// matches anything in the P[cdefios] classes.
+int cmark_utf8proc_is_punctuation(int32_t uc) {
+  return (
+      (uc < 128 && cmark_ispunct((char)uc)) || uc == 161 || uc == 167 ||
+      uc == 171 || uc == 182 || uc == 183 || uc == 187 || uc == 191 ||
+      uc == 894 || uc == 903 || (uc >= 1370 && uc <= 1375) || uc == 1417 ||
+      uc == 1418 || uc == 1470 || uc == 1472 || uc == 1475 || uc == 1478 ||
+      uc == 1523 || uc == 1524 || uc == 1545 || uc == 1546 || uc == 1548 ||
+      uc == 1549 || uc == 1563 || uc == 1566 || uc == 1567 ||
+      (uc >= 1642 && uc <= 1645) || uc == 1748 || (uc >= 1792 && uc <= 1805) ||
+      (uc >= 2039 && uc <= 2041) || (uc >= 2096 && uc <= 2110) || uc == 2142 ||
+      uc == 2404 || uc == 2405 || uc == 2416 || uc == 2800 || uc == 3572 ||
+      uc == 3663 || uc == 3674 || uc == 3675 || (uc >= 3844 && uc <= 3858) ||
+      uc == 3860 || (uc >= 3898 && uc <= 3901) || uc == 3973 ||
+      (uc >= 4048 && uc <= 4052) || uc == 4057 || uc == 4058 ||
+      (uc >= 4170 && uc <= 4175) || uc == 4347 || (uc >= 4960 && uc <= 4968) ||
+      uc == 5120 || uc == 5741 || uc == 5742 || uc == 5787 || uc == 5788 ||
+      (uc >= 5867 && uc <= 5869) || uc == 5941 || uc == 5942 ||
+      (uc >= 6100 && uc <= 6102) || (uc >= 6104 && uc <= 6106) ||
+      (uc >= 6144 && uc <= 6154) || uc == 6468 || uc == 6469 || uc == 6686 ||
+      uc == 6687 || (uc >= 6816 && uc <= 6822) || (uc >= 6824 && uc <= 6829) ||
+      (uc >= 7002 && uc <= 7008) || (uc >= 7164 && uc <= 7167) ||
+      (uc >= 7227 && uc <= 7231) || uc == 7294 || uc == 7295 ||
+      (uc >= 7360 && uc <= 7367) || uc == 7379 || (uc >= 8208 && uc <= 8231) ||
+      (uc >= 8240 && uc <= 8259) || (uc >= 8261 && uc <= 8273) ||
+      (uc >= 8275 && uc <= 8286) || uc == 8317 || uc == 8318 || uc == 8333 ||
+      uc == 8334 || (uc >= 8968 && uc <= 8971) || uc == 9001 || uc == 9002 ||
+      (uc >= 10088 && uc <= 10101) || uc == 10181 || uc == 10182 ||
+      (uc >= 10214 && uc <= 10223) || (uc >= 10627 && uc <= 10648) ||
+      (uc >= 10712 && uc <= 10715) || uc == 10748 || uc == 10749 ||
+      (uc >= 11513 && uc <= 11516) || uc == 11518 || uc == 11519 ||
+      uc == 11632 || (uc >= 11776 && uc <= 11822) ||
+      (uc >= 11824 && uc <= 11842) || (uc >= 12289 && uc <= 12291) ||
+      (uc >= 12296 && uc <= 12305) || (uc >= 12308 && uc <= 12319) ||
+      uc == 12336 || uc == 12349 || uc == 12448 || uc == 12539 || uc == 42238 ||
+      uc == 42239 || (uc >= 42509 && uc <= 42511) || uc == 42611 ||
+      uc == 42622 || (uc >= 42738 && uc <= 42743) ||
+      (uc >= 43124 && uc <= 43127) || uc == 43214 || uc == 43215 ||
+      (uc >= 43256 && uc <= 43258) || uc == 43310 || uc == 43311 ||
+      uc == 43359 || (uc >= 43457 && uc <= 43469) || uc == 43486 ||
+      uc == 43487 || (uc >= 43612 && uc <= 43615) || uc == 43742 ||
+      uc == 43743 || uc == 43760 || uc == 43761 || uc == 44011 || uc == 64830 ||
+      uc == 64831 || (uc >= 65040 && uc <= 65049) ||
+      (uc >= 65072 && uc <= 65106) || (uc >= 65108 && uc <= 65121) ||
+      uc == 65123 || uc == 65128 || uc == 65130 || uc == 65131 ||
+      (uc >= 65281 && uc <= 65283) || (uc >= 65285 && uc <= 65290) ||
+      (uc >= 65292 && uc <= 65295) || uc == 65306 || uc == 65307 ||
+      uc == 65311 || uc == 65312 || (uc >= 65339 && uc <= 65341) ||
+      uc == 65343 || uc == 65371 || uc == 65373 ||
+      (uc >= 65375 && uc <= 65381) || (uc >= 65792 && uc <= 65794) ||
+      uc == 66463 || uc == 66512 || uc == 66927 || uc == 67671 || uc == 67871 ||
+      uc == 67903 || (uc >= 68176 && uc <= 68184) || uc == 68223 ||
+      (uc >= 68336 && uc <= 68342) || (uc >= 68409 && uc <= 68415) ||
+      (uc >= 68505 && uc <= 68508) || (uc >= 69703 && uc <= 69709) ||
+      uc == 69819 || uc == 69820 || (uc >= 69822 && uc <= 69825) ||
+      (uc >= 69952 && uc <= 69955) || uc == 70004 || uc == 70005 ||
+      (uc >= 70085 && uc <= 70088) || uc == 70093 ||
+      (uc >= 70200 && uc <= 70205) || uc == 70854 ||
+      (uc >= 71105 && uc <= 71113) || (uc >= 71233 && uc <= 71235) ||
+      (uc >= 74864 && uc <= 74868) || uc == 92782 || uc == 92783 ||
+      uc == 92917 || (uc >= 92983 && uc <= 92987) || uc == 92996 ||
+      uc == 113823);
+}
diff --git a/Sources/libcmark_gfm/xml.c b/Sources/libcmark_gfm/xml.c
new file mode 100644
index 0000000..ea53b99
--- /dev/null
+++ b/Sources/libcmark_gfm/xml.c
@@ -0,0 +1,174 @@
+#include 
+#include 
+#include 
+#include 
+
+#include "config.h"
+#include "cmark.h"
+#include "node.h"
+#include "buffer.h"
+#include "houdini.h"
+
+#define BUFFER_SIZE 100
+
+// Functions to convert cmark_nodes to XML strings.
+
+static void escape_xml(cmark_strbuf *dest, const unsigned char *source,
+                       bufsize_t length) {
+  houdini_escape_html0(dest, source, length, 0);
+}
+
+struct render_state {
+  cmark_strbuf *xml;
+  int indent;
+};
+
+static CMARK_INLINE void indent(struct render_state *state) {
+  int i;
+  for (i = 0; i < state->indent; i++) {
+    cmark_strbuf_putc(state->xml, ' ');
+  }
+}
+
+static int S_render_node(cmark_node *node, cmark_event_type ev_type,
+                         struct render_state *state, int options) {
+  cmark_strbuf *xml = state->xml;
+  bool literal = false;
+  cmark_delim_type delim;
+  bool entering = (ev_type == CMARK_EVENT_ENTER);
+  char buffer[BUFFER_SIZE];
+
+  if (entering) {
+    indent(state);
+    cmark_strbuf_putc(xml, '<');
+    cmark_strbuf_puts(xml, cmark_node_get_type_string(node));
+
+    if (options & CMARK_OPT_SOURCEPOS && node->start_line != 0) {
+      snprintf(buffer, BUFFER_SIZE, " sourcepos=\"%d:%d-%d:%d\"",
+               node->start_line, node->start_column, node->end_line,
+               node->end_column);
+      cmark_strbuf_puts(xml, buffer);
+    }
+
+    literal = false;
+
+    switch (node->type) {
+    case CMARK_NODE_DOCUMENT:
+      cmark_strbuf_puts(xml, " xmlns=\"http://commonmark.org/xml/1.0\"");
+      break;
+    case CMARK_NODE_TEXT:
+    case CMARK_NODE_CODE:
+    case CMARK_NODE_HTML_BLOCK:
+    case CMARK_NODE_HTML_INLINE:
+      cmark_strbuf_puts(xml, ">");
+      escape_xml(xml, node->as.literal.data, node->as.literal.len);
+      cmark_strbuf_puts(xml, "as.heading.level);
+      cmark_strbuf_puts(xml, buffer);
+      break;
+    case CMARK_NODE_CODE_BLOCK:
+      if (node->as.code.info.len > 0) {
+        cmark_strbuf_puts(xml, " info=\"");
+        escape_xml(xml, node->as.code.info.data, node->as.code.info.len);
+        cmark_strbuf_putc(xml, '"');
+      }
+      cmark_strbuf_puts(xml, ">");
+      escape_xml(xml, node->as.code.literal.data, node->as.code.literal.len);
+      cmark_strbuf_puts(xml, "as.custom.on_enter.data,
+                 node->as.custom.on_enter.len);
+      cmark_strbuf_putc(xml, '"');
+      cmark_strbuf_puts(xml, " on_exit=\"");
+      escape_xml(xml, node->as.custom.on_exit.data,
+                 node->as.custom.on_exit.len);
+      cmark_strbuf_putc(xml, '"');
+      break;
+    case CMARK_NODE_LINK:
+    case CMARK_NODE_IMAGE:
+      cmark_strbuf_puts(xml, " destination=\"");
+      escape_xml(xml, node->as.link.url.data, node->as.link.url.len);
+      cmark_strbuf_putc(xml, '"');
+      cmark_strbuf_puts(xml, " title=\"");
+      escape_xml(xml, node->as.link.title.data, node->as.link.title.len);
+      cmark_strbuf_putc(xml, '"');
+      break;
+    default:
+      break;
+    }
+    if (node->first_child) {
+      state->indent += 2;
+    } else if (!literal) {
+      cmark_strbuf_puts(xml, " /");
+    }
+    cmark_strbuf_puts(xml, ">\n");
+
+  } else if (node->first_child) {
+    state->indent -= 2;
+    indent(state);
+    cmark_strbuf_puts(xml, "\n");
+  }
+
+  return 1;
+}
+
+char *cmark_render_xml(cmark_node *root, int options) {
+  return cmark_render_xml_with_mem(root, options, cmark_node_mem(root));
+}
+
+char *cmark_render_xml_with_mem(cmark_node *root, int options, cmark_mem *mem) {
+  char *result;
+  cmark_strbuf xml = CMARK_BUF_INIT(mem);
+  cmark_event_type ev_type;
+  cmark_node *cur;
+  struct render_state state = {&xml, 0};
+
+  cmark_iter *iter = cmark_iter_new(root);
+
+  cmark_strbuf_puts(state.xml, "\n");
+  cmark_strbuf_puts(state.xml,
+                    "\n");
+  while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {
+    cur = cmark_iter_get_node(iter);
+    S_render_node(cur, ev_type, &state, options);
+  }
+  result = (char *)cmark_strbuf_detach(&xml);
+
+  cmark_iter_free(iter);
+  return result;
+}
diff --git a/libcmark_gfm.podspec b/libcmark_gfm.podspec
new file mode 100755
index 0000000..bc71f69
--- /dev/null
+++ b/libcmark_gfm.podspec
@@ -0,0 +1,24 @@
+Pod::Spec.new do |s|
+
+  s.name         = "libcmark_gfm"
+  s.version      = "0.28.0"
+  s.summary      = "Swift compatible framework for cmark-gfm"
+
+  s.description  = <<-DESC
+                   Swift compatible framework for Github's fork of cmark.
+                   DESC
+
+  s.homepage     = "https://github.com/KristopherGBaker/libcmark_gfm"
+  s.license      = "BSD2"
+  s.author             = { "Kristopher Baker" => "Kristopher Baker" }
+  s.ios.deployment_target = "9.0"
+  s.osx.deployment_target = "10.10"
+  s.tvos.deployment_target = "9.0"
+  s.watchos.deployment_target = "2.0"
+
+  s.source       = { :git => "https://github.com/KristopherGBaker/libcmark_gfm.git", :tag => "#{s.version}" }
+  s.source_files = "Sources/libcmark_gfm/**/*{.c,.h}"
+  s.preserve_paths = "Sources/libcmark_gfm/**/*"
+  s.public_header_files = "Sources/libcmark_gfm/include/*.h"
+
+end
diff --git a/libcmark_gfm.xcodeproj/project.pbxproj b/libcmark_gfm.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..cf5414b
--- /dev/null
+++ b/libcmark_gfm.xcodeproj/project.pbxproj
@@ -0,0 +1,1292 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 48;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		A288C7D41FEF500200667F4A /* xml.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7591FEF500200667F4A /* xml.c */; };
+		A288C7D51FEF500200667F4A /* strikethrough.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C75A1FEF500200667F4A /* strikethrough.c */; };
+		A288C7D61FEF500200667F4A /* cmark.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C75B1FEF500200667F4A /* cmark.c */; };
+		A288C7D71FEF500200667F4A /* man.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C75C1FEF500200667F4A /* man.c */; };
+		A288C7D81FEF500200667F4A /* buffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C75D1FEF500200667F4A /* buffer.c */; };
+		A288C7D91FEF500200667F4A /* autolink.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C75E1FEF500200667F4A /* autolink.c */; };
+		A288C7DA1FEF500200667F4A /* blocks.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C75F1FEF500200667F4A /* blocks.c */; };
+		A288C7DB1FEF500200667F4A /* cmark_ctype.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7601FEF500200667F4A /* cmark_ctype.c */; };
+		A288C7DC1FEF500200667F4A /* table.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7611FEF500200667F4A /* table.c */; };
+		A288C7DD1FEF500200667F4A /* inlines.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7621FEF500200667F4A /* inlines.c */; };
+		A288C7DE1FEF500200667F4A /* latex.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7631FEF500200667F4A /* latex.c */; };
+		A288C7DF1FEF500200667F4A /* houdini_href_e.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7641FEF500200667F4A /* houdini_href_e.c */; };
+		A288C7E01FEF500200667F4A /* syntax_extension.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7651FEF500200667F4A /* syntax_extension.c */; };
+		A288C7E31FEF500200667F4A /* ext_scanners.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7681FEF500200667F4A /* ext_scanners.c */; };
+		A288C7E41FEF500200667F4A /* tagfilter.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7691FEF500200667F4A /* tagfilter.c */; };
+		A288C7E51FEF500200667F4A /* houdini_html_e.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C76A1FEF500200667F4A /* houdini_html_e.c */; };
+		A288C7E61FEF500200667F4A /* cmarkextensions_export.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C76C1FEF500200667F4A /* cmarkextensions_export.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C7E71FEF500200667F4A /* cmark_export.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C76D1FEF500200667F4A /* cmark_export.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C7E81FEF500200667F4A /* html.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C76E1FEF500200667F4A /* html.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C7EA1FEF500200667F4A /* plugin.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7701FEF500200667F4A /* plugin.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C7EB1FEF500200667F4A /* map.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7711FEF500200667F4A /* map.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C7EC1FEF500200667F4A /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7721FEF500200667F4A /* config.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C7ED1FEF500200667F4A /* chunk.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7731FEF500200667F4A /* chunk.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C7EE1FEF500200667F4A /* footnotes.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7741FEF500200667F4A /* footnotes.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C7EF1FEF500200667F4A /* parser.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7751FEF500200667F4A /* parser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C7F01FEF500200667F4A /* scanners.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7761FEF500200667F4A /* scanners.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C7F21FEF500200667F4A /* node.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7781FEF500200667F4A /* node.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C7F31FEF500200667F4A /* core-extensions.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7791FEF500200667F4A /* core-extensions.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C7F41FEF500200667F4A /* registry.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C77B1FEF500200667F4A /* registry.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C7F51FEF500200667F4A /* cmark_version.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C77C1FEF500200667F4A /* cmark_version.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C7F61FEF500200667F4A /* autolink.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C77D1FEF500200667F4A /* autolink.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C7F71FEF500200667F4A /* cmark_ctype.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C77E1FEF500200667F4A /* cmark_ctype.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C7F81FEF500200667F4A /* buffer.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C77F1FEF500200667F4A /* buffer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C7F91FEF500200667F4A /* cmark.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7801FEF500200667F4A /* cmark.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C7FA1FEF500200667F4A /* strikethrough.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7811FEF500200667F4A /* strikethrough.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C7FB1FEF500200667F4A /* cmark_extension_api.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7821FEF500200667F4A /* cmark_extension_api.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C7FC1FEF500200667F4A /* syntax_extension.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7831FEF500200667F4A /* syntax_extension.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C7FD1FEF500200667F4A /* inlines.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7841FEF500200667F4A /* inlines.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C7FE1FEF500200667F4A /* table.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7851FEF500200667F4A /* table.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C7FF1FEF500200667F4A /* tagfilter.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7861FEF500200667F4A /* tagfilter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C8001FEF500200667F4A /* ext_scanners.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7871FEF500200667F4A /* ext_scanners.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C8011FEF500200667F4A /* houdini.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7881FEF500200667F4A /* houdini.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C8021FEF500200667F4A /* iterator.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7891FEF500200667F4A /* iterator.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C8031FEF500200667F4A /* utf8.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C78A1FEF500200667F4A /* utf8.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C8041FEF500200667F4A /* references.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C78B1FEF500200667F4A /* references.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C8051FEF500200667F4A /* render.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C78C1FEF500200667F4A /* render.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A288C8061FEF500200667F4A /* plaintext.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C78D1FEF500200667F4A /* plaintext.c */; };
+		A288C8071FEF500200667F4A /* utf8.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C78E1FEF500200667F4A /* utf8.c */; };
+		A288C8081FEF500200667F4A /* references.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C78F1FEF500200667F4A /* references.c */; };
+		A288C8091FEF500200667F4A /* render.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7901FEF500200667F4A /* render.c */; };
+		A288C80A1FEF500200667F4A /* iterator.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7911FEF500200667F4A /* iterator.c */; };
+		A288C80B1FEF500200667F4A /* arena.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7921FEF500200667F4A /* arena.c */; };
+		A288C80C1FEF500200667F4A /* linked_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7931FEF500200667F4A /* linked_list.c */; };
+		A288C80D1FEF500200667F4A /* commonmark.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7941FEF500200667F4A /* commonmark.c */; };
+		A288C80E1FEF500200667F4A /* map.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7951FEF500200667F4A /* map.c */; };
+		A288C8101FEF500200667F4A /* html.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7971FEF500200667F4A /* html.c */; };
+		A288C8111FEF500200667F4A /* plugin.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7981FEF500200667F4A /* plugin.c */; };
+		A288C8121FEF500200667F4A /* scanners.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7991FEF500200667F4A /* scanners.c */; };
+		A288C8131FEF500200667F4A /* footnotes.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C79A1FEF500200667F4A /* footnotes.c */; };
+		A288C8141FEF500200667F4A /* houdini_html_u.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C79B1FEF500200667F4A /* houdini_html_u.c */; };
+		A288C8151FEF500200667F4A /* registry.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C79C1FEF500200667F4A /* registry.c */; };
+		A288C8161FEF500200667F4A /* node.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C79D1FEF500200667F4A /* node.c */; };
+		A288C8171FEF500200667F4A /* core-extensions.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C79E1FEF500200667F4A /* core-extensions.c */; };
+		A2BD076B1FEF60DB005E1FC7 /* libcmark_gfm.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BD076A1FEF60DB005E1FC7 /* libcmark_gfm.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD07A21FEF6BA4005E1FC7 /* arena.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7921FEF500200667F4A /* arena.c */; };
+		A2BD07A31FEF6BA4005E1FC7 /* autolink.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C75E1FEF500200667F4A /* autolink.c */; };
+		A2BD07A41FEF6BA4005E1FC7 /* blocks.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C75F1FEF500200667F4A /* blocks.c */; };
+		A2BD07A51FEF6BA4005E1FC7 /* buffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C75D1FEF500200667F4A /* buffer.c */; };
+		A2BD07A61FEF6BA4005E1FC7 /* cmark_ctype.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7601FEF500200667F4A /* cmark_ctype.c */; };
+		A2BD07A71FEF6BA4005E1FC7 /* cmark.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C75B1FEF500200667F4A /* cmark.c */; };
+		A2BD07A81FEF6BA4005E1FC7 /* commonmark.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7941FEF500200667F4A /* commonmark.c */; };
+		A2BD07A91FEF6BA4005E1FC7 /* core-extensions.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C79E1FEF500200667F4A /* core-extensions.c */; };
+		A2BD07AA1FEF6BA4005E1FC7 /* ext_scanners.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7681FEF500200667F4A /* ext_scanners.c */; };
+		A2BD07AB1FEF6BA4005E1FC7 /* footnotes.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C79A1FEF500200667F4A /* footnotes.c */; };
+		A2BD07AC1FEF6BA4005E1FC7 /* houdini_href_e.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7641FEF500200667F4A /* houdini_href_e.c */; };
+		A2BD07AD1FEF6BA4005E1FC7 /* houdini_html_e.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C76A1FEF500200667F4A /* houdini_html_e.c */; };
+		A2BD07AE1FEF6BA4005E1FC7 /* houdini_html_u.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C79B1FEF500200667F4A /* houdini_html_u.c */; };
+		A2BD07AF1FEF6BA4005E1FC7 /* html.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7971FEF500200667F4A /* html.c */; };
+		A2BD07B01FEF6BA4005E1FC7 /* inlines.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7621FEF500200667F4A /* inlines.c */; };
+		A2BD07B11FEF6BA4005E1FC7 /* iterator.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7911FEF500200667F4A /* iterator.c */; };
+		A2BD07B21FEF6BA4005E1FC7 /* latex.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7631FEF500200667F4A /* latex.c */; };
+		A2BD07B31FEF6BA4005E1FC7 /* linked_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7931FEF500200667F4A /* linked_list.c */; };
+		A2BD07B41FEF6BA4005E1FC7 /* man.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C75C1FEF500200667F4A /* man.c */; };
+		A2BD07B51FEF6BA4005E1FC7 /* map.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7951FEF500200667F4A /* map.c */; };
+		A2BD07B61FEF6BA4005E1FC7 /* node.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C79D1FEF500200667F4A /* node.c */; };
+		A2BD07B71FEF6BA4005E1FC7 /* plaintext.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C78D1FEF500200667F4A /* plaintext.c */; };
+		A2BD07B81FEF6BA4005E1FC7 /* plugin.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7981FEF500200667F4A /* plugin.c */; };
+		A2BD07B91FEF6BA4005E1FC7 /* references.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C78F1FEF500200667F4A /* references.c */; };
+		A2BD07BA1FEF6BA4005E1FC7 /* registry.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C79C1FEF500200667F4A /* registry.c */; };
+		A2BD07BB1FEF6BA4005E1FC7 /* render.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7901FEF500200667F4A /* render.c */; };
+		A2BD07BC1FEF6BA4005E1FC7 /* scanners.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7991FEF500200667F4A /* scanners.c */; };
+		A2BD07BD1FEF6BA4005E1FC7 /* strikethrough.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C75A1FEF500200667F4A /* strikethrough.c */; };
+		A2BD07BE1FEF6BA4005E1FC7 /* syntax_extension.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7651FEF500200667F4A /* syntax_extension.c */; };
+		A2BD07BF1FEF6BA4005E1FC7 /* table.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7611FEF500200667F4A /* table.c */; };
+		A2BD07C01FEF6BA4005E1FC7 /* tagfilter.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7691FEF500200667F4A /* tagfilter.c */; };
+		A2BD07C11FEF6BA4005E1FC7 /* utf8.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C78E1FEF500200667F4A /* utf8.c */; };
+		A2BD07C21FEF6BA4005E1FC7 /* xml.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7591FEF500200667F4A /* xml.c */; };
+		A2BD07C31FEF6BA5005E1FC7 /* arena.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7921FEF500200667F4A /* arena.c */; };
+		A2BD07C41FEF6BA5005E1FC7 /* autolink.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C75E1FEF500200667F4A /* autolink.c */; };
+		A2BD07C51FEF6BA5005E1FC7 /* blocks.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C75F1FEF500200667F4A /* blocks.c */; };
+		A2BD07C61FEF6BA5005E1FC7 /* buffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C75D1FEF500200667F4A /* buffer.c */; };
+		A2BD07C71FEF6BA5005E1FC7 /* cmark_ctype.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7601FEF500200667F4A /* cmark_ctype.c */; };
+		A2BD07C81FEF6BA5005E1FC7 /* cmark.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C75B1FEF500200667F4A /* cmark.c */; };
+		A2BD07C91FEF6BA5005E1FC7 /* commonmark.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7941FEF500200667F4A /* commonmark.c */; };
+		A2BD07CA1FEF6BA5005E1FC7 /* core-extensions.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C79E1FEF500200667F4A /* core-extensions.c */; };
+		A2BD07CB1FEF6BA5005E1FC7 /* ext_scanners.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7681FEF500200667F4A /* ext_scanners.c */; };
+		A2BD07CC1FEF6BA5005E1FC7 /* footnotes.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C79A1FEF500200667F4A /* footnotes.c */; };
+		A2BD07CD1FEF6BA5005E1FC7 /* houdini_href_e.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7641FEF500200667F4A /* houdini_href_e.c */; };
+		A2BD07CE1FEF6BA5005E1FC7 /* houdini_html_e.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C76A1FEF500200667F4A /* houdini_html_e.c */; };
+		A2BD07CF1FEF6BA5005E1FC7 /* houdini_html_u.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C79B1FEF500200667F4A /* houdini_html_u.c */; };
+		A2BD07D01FEF6BA5005E1FC7 /* html.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7971FEF500200667F4A /* html.c */; };
+		A2BD07D11FEF6BA5005E1FC7 /* inlines.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7621FEF500200667F4A /* inlines.c */; };
+		A2BD07D21FEF6BA5005E1FC7 /* iterator.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7911FEF500200667F4A /* iterator.c */; };
+		A2BD07D31FEF6BA5005E1FC7 /* latex.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7631FEF500200667F4A /* latex.c */; };
+		A2BD07D41FEF6BA5005E1FC7 /* linked_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7931FEF500200667F4A /* linked_list.c */; };
+		A2BD07D51FEF6BA5005E1FC7 /* man.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C75C1FEF500200667F4A /* man.c */; };
+		A2BD07D61FEF6BA5005E1FC7 /* map.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7951FEF500200667F4A /* map.c */; };
+		A2BD07D71FEF6BA5005E1FC7 /* node.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C79D1FEF500200667F4A /* node.c */; };
+		A2BD07D81FEF6BA5005E1FC7 /* plaintext.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C78D1FEF500200667F4A /* plaintext.c */; };
+		A2BD07D91FEF6BA5005E1FC7 /* plugin.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7981FEF500200667F4A /* plugin.c */; };
+		A2BD07DA1FEF6BA5005E1FC7 /* references.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C78F1FEF500200667F4A /* references.c */; };
+		A2BD07DB1FEF6BA5005E1FC7 /* registry.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C79C1FEF500200667F4A /* registry.c */; };
+		A2BD07DC1FEF6BA5005E1FC7 /* render.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7901FEF500200667F4A /* render.c */; };
+		A2BD07DD1FEF6BA5005E1FC7 /* scanners.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7991FEF500200667F4A /* scanners.c */; };
+		A2BD07DE1FEF6BA5005E1FC7 /* strikethrough.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C75A1FEF500200667F4A /* strikethrough.c */; };
+		A2BD07DF1FEF6BA5005E1FC7 /* syntax_extension.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7651FEF500200667F4A /* syntax_extension.c */; };
+		A2BD07E01FEF6BA5005E1FC7 /* table.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7611FEF500200667F4A /* table.c */; };
+		A2BD07E11FEF6BA5005E1FC7 /* tagfilter.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7691FEF500200667F4A /* tagfilter.c */; };
+		A2BD07E21FEF6BA5005E1FC7 /* utf8.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C78E1FEF500200667F4A /* utf8.c */; };
+		A2BD07E31FEF6BA5005E1FC7 /* xml.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7591FEF500200667F4A /* xml.c */; };
+		A2BD07E41FEF6BA5005E1FC7 /* arena.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7921FEF500200667F4A /* arena.c */; };
+		A2BD07E51FEF6BA5005E1FC7 /* autolink.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C75E1FEF500200667F4A /* autolink.c */; };
+		A2BD07E61FEF6BA5005E1FC7 /* blocks.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C75F1FEF500200667F4A /* blocks.c */; };
+		A2BD07E71FEF6BA5005E1FC7 /* buffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C75D1FEF500200667F4A /* buffer.c */; };
+		A2BD07E81FEF6BA5005E1FC7 /* cmark_ctype.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7601FEF500200667F4A /* cmark_ctype.c */; };
+		A2BD07E91FEF6BA5005E1FC7 /* cmark.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C75B1FEF500200667F4A /* cmark.c */; };
+		A2BD07EA1FEF6BA5005E1FC7 /* commonmark.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7941FEF500200667F4A /* commonmark.c */; };
+		A2BD07EB1FEF6BA5005E1FC7 /* core-extensions.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C79E1FEF500200667F4A /* core-extensions.c */; };
+		A2BD07EC1FEF6BA5005E1FC7 /* ext_scanners.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7681FEF500200667F4A /* ext_scanners.c */; };
+		A2BD07ED1FEF6BA5005E1FC7 /* footnotes.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C79A1FEF500200667F4A /* footnotes.c */; };
+		A2BD07EE1FEF6BA5005E1FC7 /* houdini_href_e.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7641FEF500200667F4A /* houdini_href_e.c */; };
+		A2BD07EF1FEF6BA5005E1FC7 /* houdini_html_e.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C76A1FEF500200667F4A /* houdini_html_e.c */; };
+		A2BD07F01FEF6BA5005E1FC7 /* houdini_html_u.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C79B1FEF500200667F4A /* houdini_html_u.c */; };
+		A2BD07F11FEF6BA5005E1FC7 /* html.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7971FEF500200667F4A /* html.c */; };
+		A2BD07F21FEF6BA5005E1FC7 /* inlines.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7621FEF500200667F4A /* inlines.c */; };
+		A2BD07F31FEF6BA5005E1FC7 /* iterator.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7911FEF500200667F4A /* iterator.c */; };
+		A2BD07F41FEF6BA5005E1FC7 /* latex.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7631FEF500200667F4A /* latex.c */; };
+		A2BD07F51FEF6BA5005E1FC7 /* linked_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7931FEF500200667F4A /* linked_list.c */; };
+		A2BD07F61FEF6BA5005E1FC7 /* man.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C75C1FEF500200667F4A /* man.c */; };
+		A2BD07F71FEF6BA5005E1FC7 /* map.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7951FEF500200667F4A /* map.c */; };
+		A2BD07F81FEF6BA5005E1FC7 /* node.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C79D1FEF500200667F4A /* node.c */; };
+		A2BD07F91FEF6BA5005E1FC7 /* plaintext.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C78D1FEF500200667F4A /* plaintext.c */; };
+		A2BD07FA1FEF6BA5005E1FC7 /* plugin.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7981FEF500200667F4A /* plugin.c */; };
+		A2BD07FB1FEF6BA5005E1FC7 /* references.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C78F1FEF500200667F4A /* references.c */; };
+		A2BD07FC1FEF6BA5005E1FC7 /* registry.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C79C1FEF500200667F4A /* registry.c */; };
+		A2BD07FD1FEF6BA5005E1FC7 /* render.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7901FEF500200667F4A /* render.c */; };
+		A2BD07FE1FEF6BA5005E1FC7 /* scanners.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7991FEF500200667F4A /* scanners.c */; };
+		A2BD07FF1FEF6BA5005E1FC7 /* strikethrough.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C75A1FEF500200667F4A /* strikethrough.c */; };
+		A2BD08001FEF6BA5005E1FC7 /* syntax_extension.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7651FEF500200667F4A /* syntax_extension.c */; };
+		A2BD08011FEF6BA5005E1FC7 /* table.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7611FEF500200667F4A /* table.c */; };
+		A2BD08021FEF6BA5005E1FC7 /* tagfilter.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7691FEF500200667F4A /* tagfilter.c */; };
+		A2BD08031FEF6BA5005E1FC7 /* utf8.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C78E1FEF500200667F4A /* utf8.c */; };
+		A2BD08041FEF6BA5005E1FC7 /* xml.c in Sources */ = {isa = PBXBuildFile; fileRef = A288C7591FEF500200667F4A /* xml.c */; };
+		A2BD08051FEF6BAD005E1FC7 /* libcmark_gfm.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BD076A1FEF60DB005E1FC7 /* libcmark_gfm.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08061FEF6BAD005E1FC7 /* autolink.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C77D1FEF500200667F4A /* autolink.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08071FEF6BAD005E1FC7 /* buffer.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C77F1FEF500200667F4A /* buffer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08081FEF6BAD005E1FC7 /* chunk.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7731FEF500200667F4A /* chunk.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08091FEF6BAD005E1FC7 /* cmark_ctype.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C77E1FEF500200667F4A /* cmark_ctype.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD080A1FEF6BAD005E1FC7 /* cmark_export.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C76D1FEF500200667F4A /* cmark_export.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD080B1FEF6BAD005E1FC7 /* cmark_extension_api.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7821FEF500200667F4A /* cmark_extension_api.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD080C1FEF6BAD005E1FC7 /* cmark_version.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C77C1FEF500200667F4A /* cmark_version.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD080D1FEF6BAD005E1FC7 /* cmark.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7801FEF500200667F4A /* cmark.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD080E1FEF6BAD005E1FC7 /* cmarkextensions_export.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C76C1FEF500200667F4A /* cmarkextensions_export.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD080F1FEF6BAD005E1FC7 /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7721FEF500200667F4A /* config.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08101FEF6BAD005E1FC7 /* core-extensions.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7791FEF500200667F4A /* core-extensions.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08111FEF6BAD005E1FC7 /* ext_scanners.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7871FEF500200667F4A /* ext_scanners.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08121FEF6BAD005E1FC7 /* footnotes.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7741FEF500200667F4A /* footnotes.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08131FEF6BAD005E1FC7 /* houdini.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7881FEF500200667F4A /* houdini.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08141FEF6BAD005E1FC7 /* html.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C76E1FEF500200667F4A /* html.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08151FEF6BAD005E1FC7 /* inlines.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7841FEF500200667F4A /* inlines.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08161FEF6BAD005E1FC7 /* iterator.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7891FEF500200667F4A /* iterator.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08171FEF6BAD005E1FC7 /* map.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7711FEF500200667F4A /* map.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08181FEF6BAD005E1FC7 /* node.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7781FEF500200667F4A /* node.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08191FEF6BAD005E1FC7 /* parser.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7751FEF500200667F4A /* parser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD081A1FEF6BAD005E1FC7 /* plugin.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7701FEF500200667F4A /* plugin.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD081B1FEF6BAD005E1FC7 /* references.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C78B1FEF500200667F4A /* references.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD081C1FEF6BAD005E1FC7 /* registry.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C77B1FEF500200667F4A /* registry.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD081D1FEF6BAD005E1FC7 /* render.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C78C1FEF500200667F4A /* render.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD081E1FEF6BAD005E1FC7 /* scanners.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7761FEF500200667F4A /* scanners.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD081F1FEF6BAD005E1FC7 /* strikethrough.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7811FEF500200667F4A /* strikethrough.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08201FEF6BAD005E1FC7 /* syntax_extension.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7831FEF500200667F4A /* syntax_extension.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08211FEF6BAD005E1FC7 /* table.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7851FEF500200667F4A /* table.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08221FEF6BAD005E1FC7 /* tagfilter.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7861FEF500200667F4A /* tagfilter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08231FEF6BAD005E1FC7 /* utf8.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C78A1FEF500200667F4A /* utf8.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08241FEF6BAE005E1FC7 /* libcmark_gfm.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BD076A1FEF60DB005E1FC7 /* libcmark_gfm.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08251FEF6BAE005E1FC7 /* autolink.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C77D1FEF500200667F4A /* autolink.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08261FEF6BAE005E1FC7 /* buffer.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C77F1FEF500200667F4A /* buffer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08271FEF6BAE005E1FC7 /* chunk.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7731FEF500200667F4A /* chunk.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08281FEF6BAE005E1FC7 /* cmark_ctype.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C77E1FEF500200667F4A /* cmark_ctype.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08291FEF6BAE005E1FC7 /* cmark_export.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C76D1FEF500200667F4A /* cmark_export.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD082A1FEF6BAE005E1FC7 /* cmark_extension_api.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7821FEF500200667F4A /* cmark_extension_api.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD082B1FEF6BAE005E1FC7 /* cmark_version.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C77C1FEF500200667F4A /* cmark_version.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD082C1FEF6BAE005E1FC7 /* cmark.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7801FEF500200667F4A /* cmark.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD082D1FEF6BAE005E1FC7 /* cmarkextensions_export.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C76C1FEF500200667F4A /* cmarkextensions_export.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD082E1FEF6BAE005E1FC7 /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7721FEF500200667F4A /* config.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD082F1FEF6BAE005E1FC7 /* core-extensions.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7791FEF500200667F4A /* core-extensions.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08301FEF6BAE005E1FC7 /* ext_scanners.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7871FEF500200667F4A /* ext_scanners.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08311FEF6BAE005E1FC7 /* footnotes.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7741FEF500200667F4A /* footnotes.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08321FEF6BAE005E1FC7 /* houdini.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7881FEF500200667F4A /* houdini.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08331FEF6BAE005E1FC7 /* html.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C76E1FEF500200667F4A /* html.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08341FEF6BAE005E1FC7 /* inlines.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7841FEF500200667F4A /* inlines.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08351FEF6BAE005E1FC7 /* iterator.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7891FEF500200667F4A /* iterator.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08361FEF6BAE005E1FC7 /* map.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7711FEF500200667F4A /* map.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08371FEF6BAE005E1FC7 /* node.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7781FEF500200667F4A /* node.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08381FEF6BAE005E1FC7 /* parser.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7751FEF500200667F4A /* parser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08391FEF6BAE005E1FC7 /* plugin.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7701FEF500200667F4A /* plugin.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD083A1FEF6BAE005E1FC7 /* references.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C78B1FEF500200667F4A /* references.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD083B1FEF6BAE005E1FC7 /* registry.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C77B1FEF500200667F4A /* registry.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD083C1FEF6BAE005E1FC7 /* render.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C78C1FEF500200667F4A /* render.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD083D1FEF6BAE005E1FC7 /* scanners.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7761FEF500200667F4A /* scanners.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD083E1FEF6BAE005E1FC7 /* strikethrough.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7811FEF500200667F4A /* strikethrough.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD083F1FEF6BAE005E1FC7 /* syntax_extension.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7831FEF500200667F4A /* syntax_extension.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08401FEF6BAE005E1FC7 /* table.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7851FEF500200667F4A /* table.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08411FEF6BAE005E1FC7 /* tagfilter.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7861FEF500200667F4A /* tagfilter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08421FEF6BAE005E1FC7 /* utf8.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C78A1FEF500200667F4A /* utf8.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08431FEF6BAF005E1FC7 /* libcmark_gfm.h in Headers */ = {isa = PBXBuildFile; fileRef = A2BD076A1FEF60DB005E1FC7 /* libcmark_gfm.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08441FEF6BAF005E1FC7 /* autolink.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C77D1FEF500200667F4A /* autolink.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08451FEF6BAF005E1FC7 /* buffer.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C77F1FEF500200667F4A /* buffer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08461FEF6BAF005E1FC7 /* chunk.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7731FEF500200667F4A /* chunk.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08471FEF6BAF005E1FC7 /* cmark_ctype.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C77E1FEF500200667F4A /* cmark_ctype.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08481FEF6BAF005E1FC7 /* cmark_export.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C76D1FEF500200667F4A /* cmark_export.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08491FEF6BAF005E1FC7 /* cmark_extension_api.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7821FEF500200667F4A /* cmark_extension_api.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD084A1FEF6BAF005E1FC7 /* cmark_version.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C77C1FEF500200667F4A /* cmark_version.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD084B1FEF6BAF005E1FC7 /* cmark.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7801FEF500200667F4A /* cmark.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD084C1FEF6BAF005E1FC7 /* cmarkextensions_export.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C76C1FEF500200667F4A /* cmarkextensions_export.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD084D1FEF6BAF005E1FC7 /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7721FEF500200667F4A /* config.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD084E1FEF6BAF005E1FC7 /* core-extensions.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7791FEF500200667F4A /* core-extensions.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD084F1FEF6BAF005E1FC7 /* ext_scanners.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7871FEF500200667F4A /* ext_scanners.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08501FEF6BAF005E1FC7 /* footnotes.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7741FEF500200667F4A /* footnotes.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08511FEF6BAF005E1FC7 /* houdini.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7881FEF500200667F4A /* houdini.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08521FEF6BAF005E1FC7 /* html.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C76E1FEF500200667F4A /* html.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08531FEF6BAF005E1FC7 /* inlines.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7841FEF500200667F4A /* inlines.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08541FEF6BAF005E1FC7 /* iterator.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7891FEF500200667F4A /* iterator.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08551FEF6BAF005E1FC7 /* map.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7711FEF500200667F4A /* map.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08561FEF6BAF005E1FC7 /* node.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7781FEF500200667F4A /* node.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08571FEF6BAF005E1FC7 /* parser.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7751FEF500200667F4A /* parser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08581FEF6BAF005E1FC7 /* plugin.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7701FEF500200667F4A /* plugin.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08591FEF6BAF005E1FC7 /* references.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C78B1FEF500200667F4A /* references.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD085A1FEF6BAF005E1FC7 /* registry.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C77B1FEF500200667F4A /* registry.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD085B1FEF6BAF005E1FC7 /* render.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C78C1FEF500200667F4A /* render.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD085C1FEF6BAF005E1FC7 /* scanners.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7761FEF500200667F4A /* scanners.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD085D1FEF6BAF005E1FC7 /* strikethrough.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7811FEF500200667F4A /* strikethrough.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD085E1FEF6BAF005E1FC7 /* syntax_extension.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7831FEF500200667F4A /* syntax_extension.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD085F1FEF6BAF005E1FC7 /* table.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7851FEF500200667F4A /* table.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08601FEF6BAF005E1FC7 /* tagfilter.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C7861FEF500200667F4A /* tagfilter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		A2BD08611FEF6BAF005E1FC7 /* utf8.h in Headers */ = {isa = PBXBuildFile; fileRef = A288C78A1FEF500200667F4A /* utf8.h */; settings = {ATTRIBUTES = (Public, ); }; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+		A288C74C1FEF4F6D00667F4A /* libcmark_gfm.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = libcmark_gfm.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		A288C7591FEF500200667F4A /* xml.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xml.c; sourceTree = ""; };
+		A288C75A1FEF500200667F4A /* strikethrough.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = strikethrough.c; sourceTree = ""; };
+		A288C75B1FEF500200667F4A /* cmark.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmark.c; sourceTree = ""; };
+		A288C75C1FEF500200667F4A /* man.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = man.c; sourceTree = ""; };
+		A288C75D1FEF500200667F4A /* buffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = buffer.c; sourceTree = ""; };
+		A288C75E1FEF500200667F4A /* autolink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = autolink.c; sourceTree = ""; };
+		A288C75F1FEF500200667F4A /* blocks.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocks.c; sourceTree = ""; };
+		A288C7601FEF500200667F4A /* cmark_ctype.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmark_ctype.c; sourceTree = ""; };
+		A288C7611FEF500200667F4A /* table.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = table.c; sourceTree = ""; };
+		A288C7621FEF500200667F4A /* inlines.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = inlines.c; sourceTree = ""; };
+		A288C7631FEF500200667F4A /* latex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = latex.c; sourceTree = ""; };
+		A288C7641FEF500200667F4A /* houdini_href_e.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = houdini_href_e.c; sourceTree = ""; };
+		A288C7651FEF500200667F4A /* syntax_extension.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = syntax_extension.c; sourceTree = ""; };
+		A288C7661FEF500200667F4A /* case_fold_switch.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = case_fold_switch.inc; sourceTree = ""; };
+		A288C7671FEF500200667F4A /* entities.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = entities.inc; sourceTree = ""; };
+		A288C7681FEF500200667F4A /* ext_scanners.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ext_scanners.c; sourceTree = ""; };
+		A288C7691FEF500200667F4A /* tagfilter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tagfilter.c; sourceTree = ""; };
+		A288C76A1FEF500200667F4A /* houdini_html_e.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = houdini_html_e.c; sourceTree = ""; };
+		A288C76C1FEF500200667F4A /* cmarkextensions_export.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cmarkextensions_export.h; sourceTree = ""; };
+		A288C76D1FEF500200667F4A /* cmark_export.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cmark_export.h; sourceTree = ""; };
+		A288C76E1FEF500200667F4A /* html.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = html.h; sourceTree = ""; };
+		A288C7701FEF500200667F4A /* plugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = plugin.h; sourceTree = ""; };
+		A288C7711FEF500200667F4A /* map.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = map.h; sourceTree = ""; };
+		A288C7721FEF500200667F4A /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = ""; };
+		A288C7731FEF500200667F4A /* chunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = chunk.h; sourceTree = ""; };
+		A288C7741FEF500200667F4A /* footnotes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = footnotes.h; sourceTree = ""; };
+		A288C7751FEF500200667F4A /* parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = parser.h; sourceTree = ""; };
+		A288C7761FEF500200667F4A /* scanners.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scanners.h; sourceTree = ""; };
+		A288C7781FEF500200667F4A /* node.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = node.h; sourceTree = ""; };
+		A288C7791FEF500200667F4A /* core-extensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "core-extensions.h"; sourceTree = ""; };
+		A288C77B1FEF500200667F4A /* registry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = registry.h; sourceTree = ""; };
+		A288C77C1FEF500200667F4A /* cmark_version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cmark_version.h; sourceTree = ""; };
+		A288C77D1FEF500200667F4A /* autolink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = autolink.h; sourceTree = ""; };
+		A288C77E1FEF500200667F4A /* cmark_ctype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cmark_ctype.h; sourceTree = ""; };
+		A288C77F1FEF500200667F4A /* buffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = buffer.h; sourceTree = ""; };
+		A288C7801FEF500200667F4A /* cmark.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cmark.h; sourceTree = ""; };
+		A288C7811FEF500200667F4A /* strikethrough.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = strikethrough.h; sourceTree = ""; };
+		A288C7821FEF500200667F4A /* cmark_extension_api.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cmark_extension_api.h; sourceTree = ""; };
+		A288C7831FEF500200667F4A /* syntax_extension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = syntax_extension.h; sourceTree = ""; };
+		A288C7841FEF500200667F4A /* inlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = inlines.h; sourceTree = ""; };
+		A288C7851FEF500200667F4A /* table.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = table.h; sourceTree = ""; };
+		A288C7861FEF500200667F4A /* tagfilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tagfilter.h; sourceTree = ""; };
+		A288C7871FEF500200667F4A /* ext_scanners.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ext_scanners.h; sourceTree = ""; };
+		A288C7881FEF500200667F4A /* houdini.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = houdini.h; sourceTree = ""; };
+		A288C7891FEF500200667F4A /* iterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iterator.h; sourceTree = ""; };
+		A288C78A1FEF500200667F4A /* utf8.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utf8.h; sourceTree = ""; };
+		A288C78B1FEF500200667F4A /* references.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = references.h; sourceTree = ""; };
+		A288C78C1FEF500200667F4A /* render.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = render.h; sourceTree = ""; };
+		A288C78D1FEF500200667F4A /* plaintext.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = plaintext.c; sourceTree = ""; };
+		A288C78E1FEF500200667F4A /* utf8.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = utf8.c; sourceTree = ""; };
+		A288C78F1FEF500200667F4A /* references.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = references.c; sourceTree = ""; };
+		A288C7901FEF500200667F4A /* render.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = render.c; sourceTree = ""; };
+		A288C7911FEF500200667F4A /* iterator.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = iterator.c; sourceTree = ""; };
+		A288C7921FEF500200667F4A /* arena.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = arena.c; sourceTree = ""; };
+		A288C7931FEF500200667F4A /* linked_list.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = linked_list.c; sourceTree = ""; };
+		A288C7941FEF500200667F4A /* commonmark.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = commonmark.c; sourceTree = ""; };
+		A288C7951FEF500200667F4A /* map.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = map.c; sourceTree = ""; };
+		A288C7971FEF500200667F4A /* html.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = html.c; sourceTree = ""; };
+		A288C7981FEF500200667F4A /* plugin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = plugin.c; sourceTree = ""; };
+		A288C7991FEF500200667F4A /* scanners.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = scanners.c; sourceTree = ""; };
+		A288C79A1FEF500200667F4A /* footnotes.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = footnotes.c; sourceTree = ""; };
+		A288C79B1FEF500200667F4A /* houdini_html_u.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = houdini_html_u.c; sourceTree = ""; };
+		A288C79C1FEF500200667F4A /* registry.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = registry.c; sourceTree = ""; };
+		A288C79D1FEF500200667F4A /* node.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = node.c; sourceTree = ""; };
+		A288C79E1FEF500200667F4A /* core-extensions.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "core-extensions.c"; sourceTree = ""; };
+		A288C8451FEF509300667F4A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+		A288C8471FEF511A00667F4A /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; };
+		A288C8481FEF511A00667F4A /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; };
+		A288C8491FEF51AD00667F4A /* libcmark_gfm.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; fileEncoding = 4; path = libcmark_gfm.podspec; sourceTree = ""; };
+		A2BD076A1FEF60DB005E1FC7 /* libcmark_gfm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = libcmark_gfm.h; sourceTree = ""; };
+		A2BD07801FEF6B65005E1FC7 /* libcmark_gfm.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = libcmark_gfm.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		A2BD078D1FEF6B76005E1FC7 /* libcmark_gfm.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = libcmark_gfm.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		A2BD079A1FEF6B8E005E1FC7 /* libcmark_gfm.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = libcmark_gfm.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		A2BD08621FEF6FC9005E1FC7 /* .travis.yml */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; path = .travis.yml; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		A288C7481FEF4F6D00667F4A /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		A2BD077C1FEF6B65005E1FC7 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		A2BD07891FEF6B76005E1FC7 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		A2BD07961FEF6B8E005E1FC7 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		A288C7421FEF4F6D00667F4A = {
+			isa = PBXGroup;
+			children = (
+				A2BD08621FEF6FC9005E1FC7 /* .travis.yml */,
+				A288C8491FEF51AD00667F4A /* libcmark_gfm.podspec */,
+				A288C8471FEF511A00667F4A /* Package.swift */,
+				A288C8481FEF511A00667F4A /* README.md */,
+				A288C7571FEF500200667F4A /* Sources */,
+				A288C74D1FEF4F6D00667F4A /* Products */,
+			);
+			sourceTree = "";
+		};
+		A288C74D1FEF4F6D00667F4A /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				A288C74C1FEF4F6D00667F4A /* libcmark_gfm.framework */,
+				A2BD07801FEF6B65005E1FC7 /* libcmark_gfm.framework */,
+				A2BD078D1FEF6B76005E1FC7 /* libcmark_gfm.framework */,
+				A2BD079A1FEF6B8E005E1FC7 /* libcmark_gfm.framework */,
+			);
+			name = Products;
+			sourceTree = "";
+		};
+		A288C7571FEF500200667F4A /* Sources */ = {
+			isa = PBXGroup;
+			children = (
+				A288C8451FEF509300667F4A /* Info.plist */,
+				A288C7581FEF500200667F4A /* libcmark_gfm */,
+			);
+			path = Sources;
+			sourceTree = "";
+		};
+		A288C7581FEF500200667F4A /* libcmark_gfm */ = {
+			isa = PBXGroup;
+			children = (
+				A288C7921FEF500200667F4A /* arena.c */,
+				A288C75E1FEF500200667F4A /* autolink.c */,
+				A288C75F1FEF500200667F4A /* blocks.c */,
+				A288C75D1FEF500200667F4A /* buffer.c */,
+				A288C7661FEF500200667F4A /* case_fold_switch.inc */,
+				A288C7601FEF500200667F4A /* cmark_ctype.c */,
+				A288C75B1FEF500200667F4A /* cmark.c */,
+				A288C7941FEF500200667F4A /* commonmark.c */,
+				A288C79E1FEF500200667F4A /* core-extensions.c */,
+				A288C7671FEF500200667F4A /* entities.inc */,
+				A288C7681FEF500200667F4A /* ext_scanners.c */,
+				A288C79A1FEF500200667F4A /* footnotes.c */,
+				A288C7641FEF500200667F4A /* houdini_href_e.c */,
+				A288C76A1FEF500200667F4A /* houdini_html_e.c */,
+				A288C79B1FEF500200667F4A /* houdini_html_u.c */,
+				A288C7971FEF500200667F4A /* html.c */,
+				A288C76B1FEF500200667F4A /* include */,
+				A288C7621FEF500200667F4A /* inlines.c */,
+				A288C7911FEF500200667F4A /* iterator.c */,
+				A288C7631FEF500200667F4A /* latex.c */,
+				A288C7931FEF500200667F4A /* linked_list.c */,
+				A288C75C1FEF500200667F4A /* man.c */,
+				A288C7951FEF500200667F4A /* map.c */,
+				A288C79D1FEF500200667F4A /* node.c */,
+				A288C78D1FEF500200667F4A /* plaintext.c */,
+				A288C7981FEF500200667F4A /* plugin.c */,
+				A288C78F1FEF500200667F4A /* references.c */,
+				A288C79C1FEF500200667F4A /* registry.c */,
+				A288C7901FEF500200667F4A /* render.c */,
+				A288C7991FEF500200667F4A /* scanners.c */,
+				A288C75A1FEF500200667F4A /* strikethrough.c */,
+				A288C7651FEF500200667F4A /* syntax_extension.c */,
+				A288C7611FEF500200667F4A /* table.c */,
+				A288C7691FEF500200667F4A /* tagfilter.c */,
+				A288C78E1FEF500200667F4A /* utf8.c */,
+				A288C7591FEF500200667F4A /* xml.c */,
+			);
+			path = libcmark_gfm;
+			sourceTree = "";
+		};
+		A288C76B1FEF500200667F4A /* include */ = {
+			isa = PBXGroup;
+			children = (
+				A288C77D1FEF500200667F4A /* autolink.h */,
+				A288C77F1FEF500200667F4A /* buffer.h */,
+				A288C7731FEF500200667F4A /* chunk.h */,
+				A288C77E1FEF500200667F4A /* cmark_ctype.h */,
+				A288C76D1FEF500200667F4A /* cmark_export.h */,
+				A288C7821FEF500200667F4A /* cmark_extension_api.h */,
+				A288C77C1FEF500200667F4A /* cmark_version.h */,
+				A288C7801FEF500200667F4A /* cmark.h */,
+				A288C76C1FEF500200667F4A /* cmarkextensions_export.h */,
+				A288C7721FEF500200667F4A /* config.h */,
+				A288C7791FEF500200667F4A /* core-extensions.h */,
+				A288C7871FEF500200667F4A /* ext_scanners.h */,
+				A288C7741FEF500200667F4A /* footnotes.h */,
+				A288C7881FEF500200667F4A /* houdini.h */,
+				A288C76E1FEF500200667F4A /* html.h */,
+				A288C7841FEF500200667F4A /* inlines.h */,
+				A288C7891FEF500200667F4A /* iterator.h */,
+				A2BD076A1FEF60DB005E1FC7 /* libcmark_gfm.h */,
+				A288C7711FEF500200667F4A /* map.h */,
+				A288C7781FEF500200667F4A /* node.h */,
+				A288C7751FEF500200667F4A /* parser.h */,
+				A288C7701FEF500200667F4A /* plugin.h */,
+				A288C78B1FEF500200667F4A /* references.h */,
+				A288C77B1FEF500200667F4A /* registry.h */,
+				A288C78C1FEF500200667F4A /* render.h */,
+				A288C7761FEF500200667F4A /* scanners.h */,
+				A288C7811FEF500200667F4A /* strikethrough.h */,
+				A288C7831FEF500200667F4A /* syntax_extension.h */,
+				A288C7851FEF500200667F4A /* table.h */,
+				A288C7861FEF500200667F4A /* tagfilter.h */,
+				A288C78A1FEF500200667F4A /* utf8.h */,
+			);
+			path = include;
+			sourceTree = "";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+		A288C7491FEF4F6D00667F4A /* Headers */ = {
+			isa = PBXHeadersBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				A288C7EF1FEF500200667F4A /* parser.h in Headers */,
+				A288C7EE1FEF500200667F4A /* footnotes.h in Headers */,
+				A2BD076B1FEF60DB005E1FC7 /* libcmark_gfm.h in Headers */,
+				A288C8021FEF500200667F4A /* iterator.h in Headers */,
+				A288C7F21FEF500200667F4A /* node.h in Headers */,
+				A288C8041FEF500200667F4A /* references.h in Headers */,
+				A288C8051FEF500200667F4A /* render.h in Headers */,
+				A288C8031FEF500200667F4A /* utf8.h in Headers */,
+				A288C8011FEF500200667F4A /* houdini.h in Headers */,
+				A288C7F91FEF500200667F4A /* cmark.h in Headers */,
+				A288C7E71FEF500200667F4A /* cmark_export.h in Headers */,
+				A288C7FE1FEF500200667F4A /* table.h in Headers */,
+				A288C7EA1FEF500200667F4A /* plugin.h in Headers */,
+				A288C7FA1FEF500200667F4A /* strikethrough.h in Headers */,
+				A288C7FF1FEF500200667F4A /* tagfilter.h in Headers */,
+				A288C7EB1FEF500200667F4A /* map.h in Headers */,
+				A288C7F01FEF500200667F4A /* scanners.h in Headers */,
+				A288C7FB1FEF500200667F4A /* cmark_extension_api.h in Headers */,
+				A288C7E81FEF500200667F4A /* html.h in Headers */,
+				A288C7FC1FEF500200667F4A /* syntax_extension.h in Headers */,
+				A288C7F81FEF500200667F4A /* buffer.h in Headers */,
+				A288C7EC1FEF500200667F4A /* config.h in Headers */,
+				A288C7F41FEF500200667F4A /* registry.h in Headers */,
+				A288C7F51FEF500200667F4A /* cmark_version.h in Headers */,
+				A288C7FD1FEF500200667F4A /* inlines.h in Headers */,
+				A288C7ED1FEF500200667F4A /* chunk.h in Headers */,
+				A288C7F71FEF500200667F4A /* cmark_ctype.h in Headers */,
+				A288C7F61FEF500200667F4A /* autolink.h in Headers */,
+				A288C8001FEF500200667F4A /* ext_scanners.h in Headers */,
+				A288C7E61FEF500200667F4A /* cmarkextensions_export.h in Headers */,
+				A288C7F31FEF500200667F4A /* core-extensions.h in Headers */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		A2BD077D1FEF6B65005E1FC7 /* Headers */ = {
+			isa = PBXHeadersBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				A2BD080D1FEF6BAD005E1FC7 /* cmark.h in Headers */,
+				A2BD081F1FEF6BAD005E1FC7 /* strikethrough.h in Headers */,
+				A2BD08141FEF6BAD005E1FC7 /* html.h in Headers */,
+				A2BD080C1FEF6BAD005E1FC7 /* cmark_version.h in Headers */,
+				A2BD08231FEF6BAD005E1FC7 /* utf8.h in Headers */,
+				A2BD08051FEF6BAD005E1FC7 /* libcmark_gfm.h in Headers */,
+				A2BD08061FEF6BAD005E1FC7 /* autolink.h in Headers */,
+				A2BD080B1FEF6BAD005E1FC7 /* cmark_extension_api.h in Headers */,
+				A2BD08101FEF6BAD005E1FC7 /* core-extensions.h in Headers */,
+				A2BD08111FEF6BAD005E1FC7 /* ext_scanners.h in Headers */,
+				A2BD08161FEF6BAD005E1FC7 /* iterator.h in Headers */,
+				A2BD081C1FEF6BAD005E1FC7 /* registry.h in Headers */,
+				A2BD08201FEF6BAD005E1FC7 /* syntax_extension.h in Headers */,
+				A2BD081A1FEF6BAD005E1FC7 /* plugin.h in Headers */,
+				A2BD08211FEF6BAD005E1FC7 /* table.h in Headers */,
+				A2BD08081FEF6BAD005E1FC7 /* chunk.h in Headers */,
+				A2BD08181FEF6BAD005E1FC7 /* node.h in Headers */,
+				A2BD081D1FEF6BAD005E1FC7 /* render.h in Headers */,
+				A2BD08191FEF6BAD005E1FC7 /* parser.h in Headers */,
+				A2BD08151FEF6BAD005E1FC7 /* inlines.h in Headers */,
+				A2BD080A1FEF6BAD005E1FC7 /* cmark_export.h in Headers */,
+				A2BD08071FEF6BAD005E1FC7 /* buffer.h in Headers */,
+				A2BD08131FEF6BAD005E1FC7 /* houdini.h in Headers */,
+				A2BD081E1FEF6BAD005E1FC7 /* scanners.h in Headers */,
+				A2BD08221FEF6BAD005E1FC7 /* tagfilter.h in Headers */,
+				A2BD08121FEF6BAD005E1FC7 /* footnotes.h in Headers */,
+				A2BD08171FEF6BAD005E1FC7 /* map.h in Headers */,
+				A2BD080F1FEF6BAD005E1FC7 /* config.h in Headers */,
+				A2BD08091FEF6BAD005E1FC7 /* cmark_ctype.h in Headers */,
+				A2BD081B1FEF6BAD005E1FC7 /* references.h in Headers */,
+				A2BD080E1FEF6BAD005E1FC7 /* cmarkextensions_export.h in Headers */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		A2BD078A1FEF6B76005E1FC7 /* Headers */ = {
+			isa = PBXHeadersBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				A2BD082C1FEF6BAE005E1FC7 /* cmark.h in Headers */,
+				A2BD083E1FEF6BAE005E1FC7 /* strikethrough.h in Headers */,
+				A2BD08331FEF6BAE005E1FC7 /* html.h in Headers */,
+				A2BD082B1FEF6BAE005E1FC7 /* cmark_version.h in Headers */,
+				A2BD08421FEF6BAE005E1FC7 /* utf8.h in Headers */,
+				A2BD08241FEF6BAE005E1FC7 /* libcmark_gfm.h in Headers */,
+				A2BD08251FEF6BAE005E1FC7 /* autolink.h in Headers */,
+				A2BD082A1FEF6BAE005E1FC7 /* cmark_extension_api.h in Headers */,
+				A2BD082F1FEF6BAE005E1FC7 /* core-extensions.h in Headers */,
+				A2BD08301FEF6BAE005E1FC7 /* ext_scanners.h in Headers */,
+				A2BD08351FEF6BAE005E1FC7 /* iterator.h in Headers */,
+				A2BD083B1FEF6BAE005E1FC7 /* registry.h in Headers */,
+				A2BD083F1FEF6BAE005E1FC7 /* syntax_extension.h in Headers */,
+				A2BD08391FEF6BAE005E1FC7 /* plugin.h in Headers */,
+				A2BD08401FEF6BAE005E1FC7 /* table.h in Headers */,
+				A2BD08271FEF6BAE005E1FC7 /* chunk.h in Headers */,
+				A2BD08371FEF6BAE005E1FC7 /* node.h in Headers */,
+				A2BD083C1FEF6BAE005E1FC7 /* render.h in Headers */,
+				A2BD08381FEF6BAE005E1FC7 /* parser.h in Headers */,
+				A2BD08341FEF6BAE005E1FC7 /* inlines.h in Headers */,
+				A2BD08291FEF6BAE005E1FC7 /* cmark_export.h in Headers */,
+				A2BD08261FEF6BAE005E1FC7 /* buffer.h in Headers */,
+				A2BD08321FEF6BAE005E1FC7 /* houdini.h in Headers */,
+				A2BD083D1FEF6BAE005E1FC7 /* scanners.h in Headers */,
+				A2BD08411FEF6BAE005E1FC7 /* tagfilter.h in Headers */,
+				A2BD08311FEF6BAE005E1FC7 /* footnotes.h in Headers */,
+				A2BD08361FEF6BAE005E1FC7 /* map.h in Headers */,
+				A2BD082E1FEF6BAE005E1FC7 /* config.h in Headers */,
+				A2BD08281FEF6BAE005E1FC7 /* cmark_ctype.h in Headers */,
+				A2BD083A1FEF6BAE005E1FC7 /* references.h in Headers */,
+				A2BD082D1FEF6BAE005E1FC7 /* cmarkextensions_export.h in Headers */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		A2BD07971FEF6B8E005E1FC7 /* Headers */ = {
+			isa = PBXHeadersBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				A2BD084B1FEF6BAF005E1FC7 /* cmark.h in Headers */,
+				A2BD085D1FEF6BAF005E1FC7 /* strikethrough.h in Headers */,
+				A2BD08521FEF6BAF005E1FC7 /* html.h in Headers */,
+				A2BD084A1FEF6BAF005E1FC7 /* cmark_version.h in Headers */,
+				A2BD08611FEF6BAF005E1FC7 /* utf8.h in Headers */,
+				A2BD08431FEF6BAF005E1FC7 /* libcmark_gfm.h in Headers */,
+				A2BD08441FEF6BAF005E1FC7 /* autolink.h in Headers */,
+				A2BD08491FEF6BAF005E1FC7 /* cmark_extension_api.h in Headers */,
+				A2BD084E1FEF6BAF005E1FC7 /* core-extensions.h in Headers */,
+				A2BD084F1FEF6BAF005E1FC7 /* ext_scanners.h in Headers */,
+				A2BD08541FEF6BAF005E1FC7 /* iterator.h in Headers */,
+				A2BD085A1FEF6BAF005E1FC7 /* registry.h in Headers */,
+				A2BD085E1FEF6BAF005E1FC7 /* syntax_extension.h in Headers */,
+				A2BD08581FEF6BAF005E1FC7 /* plugin.h in Headers */,
+				A2BD085F1FEF6BAF005E1FC7 /* table.h in Headers */,
+				A2BD08461FEF6BAF005E1FC7 /* chunk.h in Headers */,
+				A2BD08561FEF6BAF005E1FC7 /* node.h in Headers */,
+				A2BD085B1FEF6BAF005E1FC7 /* render.h in Headers */,
+				A2BD08571FEF6BAF005E1FC7 /* parser.h in Headers */,
+				A2BD08531FEF6BAF005E1FC7 /* inlines.h in Headers */,
+				A2BD08481FEF6BAF005E1FC7 /* cmark_export.h in Headers */,
+				A2BD08451FEF6BAF005E1FC7 /* buffer.h in Headers */,
+				A2BD08511FEF6BAF005E1FC7 /* houdini.h in Headers */,
+				A2BD085C1FEF6BAF005E1FC7 /* scanners.h in Headers */,
+				A2BD08601FEF6BAF005E1FC7 /* tagfilter.h in Headers */,
+				A2BD08501FEF6BAF005E1FC7 /* footnotes.h in Headers */,
+				A2BD08551FEF6BAF005E1FC7 /* map.h in Headers */,
+				A2BD084D1FEF6BAF005E1FC7 /* config.h in Headers */,
+				A2BD08471FEF6BAF005E1FC7 /* cmark_ctype.h in Headers */,
+				A2BD08591FEF6BAF005E1FC7 /* references.h in Headers */,
+				A2BD084C1FEF6BAF005E1FC7 /* cmarkextensions_export.h in Headers */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+		A288C74B1FEF4F6D00667F4A /* libcmark_gfm-iOS */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = A288C7541FEF4F6D00667F4A /* Build configuration list for PBXNativeTarget "libcmark_gfm-iOS" */;
+			buildPhases = (
+				A288C7471FEF4F6D00667F4A /* Sources */,
+				A288C7481FEF4F6D00667F4A /* Frameworks */,
+				A288C7491FEF4F6D00667F4A /* Headers */,
+				A288C74A1FEF4F6D00667F4A /* Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = "libcmark_gfm-iOS";
+			productName = libcmark_gfm;
+			productReference = A288C74C1FEF4F6D00667F4A /* libcmark_gfm.framework */;
+			productType = "com.apple.product-type.framework";
+		};
+		A2BD077F1FEF6B65005E1FC7 /* libcmark_gfm-watchOS */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = A2BD07851FEF6B65005E1FC7 /* Build configuration list for PBXNativeTarget "libcmark_gfm-watchOS" */;
+			buildPhases = (
+				A2BD077B1FEF6B65005E1FC7 /* Sources */,
+				A2BD077C1FEF6B65005E1FC7 /* Frameworks */,
+				A2BD077D1FEF6B65005E1FC7 /* Headers */,
+				A2BD077E1FEF6B65005E1FC7 /* Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = "libcmark_gfm-watchOS";
+			productName = "libcmark_gfm-watchOS";
+			productReference = A2BD07801FEF6B65005E1FC7 /* libcmark_gfm.framework */;
+			productType = "com.apple.product-type.framework";
+		};
+		A2BD078C1FEF6B76005E1FC7 /* libcmark_gfm-tvOS */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = A2BD07921FEF6B76005E1FC7 /* Build configuration list for PBXNativeTarget "libcmark_gfm-tvOS" */;
+			buildPhases = (
+				A2BD07881FEF6B76005E1FC7 /* Sources */,
+				A2BD07891FEF6B76005E1FC7 /* Frameworks */,
+				A2BD078A1FEF6B76005E1FC7 /* Headers */,
+				A2BD078B1FEF6B76005E1FC7 /* Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = "libcmark_gfm-tvOS";
+			productName = "libcmark_gfm-tvOS";
+			productReference = A2BD078D1FEF6B76005E1FC7 /* libcmark_gfm.framework */;
+			productType = "com.apple.product-type.framework";
+		};
+		A2BD07991FEF6B8E005E1FC7 /* libcmark_gfm-macOS */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = A2BD079F1FEF6B8E005E1FC7 /* Build configuration list for PBXNativeTarget "libcmark_gfm-macOS" */;
+			buildPhases = (
+				A2BD07951FEF6B8E005E1FC7 /* Sources */,
+				A2BD07961FEF6B8E005E1FC7 /* Frameworks */,
+				A2BD07971FEF6B8E005E1FC7 /* Headers */,
+				A2BD07981FEF6B8E005E1FC7 /* Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = "libcmark_gfm-macOS";
+			productName = "libcmark_gfm-macOS";
+			productReference = A2BD079A1FEF6B8E005E1FC7 /* libcmark_gfm.framework */;
+			productType = "com.apple.product-type.framework";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		A288C7431FEF4F6D00667F4A /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				LastUpgradeCheck = 0920;
+				ORGANIZATIONNAME = "Kristopher Baker";
+				TargetAttributes = {
+					A288C74B1FEF4F6D00667F4A = {
+						CreatedOnToolsVersion = 9.2;
+						ProvisioningStyle = Automatic;
+					};
+					A2BD077F1FEF6B65005E1FC7 = {
+						CreatedOnToolsVersion = 9.2;
+						ProvisioningStyle = Automatic;
+					};
+					A2BD078C1FEF6B76005E1FC7 = {
+						CreatedOnToolsVersion = 9.2;
+						ProvisioningStyle = Automatic;
+					};
+					A2BD07991FEF6B8E005E1FC7 = {
+						CreatedOnToolsVersion = 9.2;
+						ProvisioningStyle = Automatic;
+					};
+				};
+			};
+			buildConfigurationList = A288C7461FEF4F6D00667F4A /* Build configuration list for PBXProject "libcmark_gfm" */;
+			compatibilityVersion = "Xcode 8.0";
+			developmentRegion = en;
+			hasScannedForEncodings = 0;
+			knownRegions = (
+				en,
+			);
+			mainGroup = A288C7421FEF4F6D00667F4A;
+			productRefGroup = A288C74D1FEF4F6D00667F4A /* Products */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				A288C74B1FEF4F6D00667F4A /* libcmark_gfm-iOS */,
+				A2BD077F1FEF6B65005E1FC7 /* libcmark_gfm-watchOS */,
+				A2BD078C1FEF6B76005E1FC7 /* libcmark_gfm-tvOS */,
+				A2BD07991FEF6B8E005E1FC7 /* libcmark_gfm-macOS */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+		A288C74A1FEF4F6D00667F4A /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		A2BD077E1FEF6B65005E1FC7 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		A2BD078B1FEF6B76005E1FC7 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		A2BD07981FEF6B8E005E1FC7 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		A288C7471FEF4F6D00667F4A /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				A288C8111FEF500200667F4A /* plugin.c in Sources */,
+				A288C7DB1FEF500200667F4A /* cmark_ctype.c in Sources */,
+				A288C7DA1FEF500200667F4A /* blocks.c in Sources */,
+				A288C7D61FEF500200667F4A /* cmark.c in Sources */,
+				A288C7DE1FEF500200667F4A /* latex.c in Sources */,
+				A288C7DC1FEF500200667F4A /* table.c in Sources */,
+				A288C8101FEF500200667F4A /* html.c in Sources */,
+				A288C8171FEF500200667F4A /* core-extensions.c in Sources */,
+				A288C7E51FEF500200667F4A /* houdini_html_e.c in Sources */,
+				A288C7DF1FEF500200667F4A /* houdini_href_e.c in Sources */,
+				A288C8141FEF500200667F4A /* houdini_html_u.c in Sources */,
+				A288C8091FEF500200667F4A /* render.c in Sources */,
+				A288C7D41FEF500200667F4A /* xml.c in Sources */,
+				A288C7E41FEF500200667F4A /* tagfilter.c in Sources */,
+				A288C8071FEF500200667F4A /* utf8.c in Sources */,
+				A288C7E01FEF500200667F4A /* syntax_extension.c in Sources */,
+				A288C80D1FEF500200667F4A /* commonmark.c in Sources */,
+				A288C8151FEF500200667F4A /* registry.c in Sources */,
+				A288C8121FEF500200667F4A /* scanners.c in Sources */,
+				A288C8161FEF500200667F4A /* node.c in Sources */,
+				A288C7D91FEF500200667F4A /* autolink.c in Sources */,
+				A288C80A1FEF500200667F4A /* iterator.c in Sources */,
+				A288C80B1FEF500200667F4A /* arena.c in Sources */,
+				A288C7DD1FEF500200667F4A /* inlines.c in Sources */,
+				A288C80E1FEF500200667F4A /* map.c in Sources */,
+				A288C7D71FEF500200667F4A /* man.c in Sources */,
+				A288C8081FEF500200667F4A /* references.c in Sources */,
+				A288C7E31FEF500200667F4A /* ext_scanners.c in Sources */,
+				A288C80C1FEF500200667F4A /* linked_list.c in Sources */,
+				A288C7D81FEF500200667F4A /* buffer.c in Sources */,
+				A288C8131FEF500200667F4A /* footnotes.c in Sources */,
+				A288C7D51FEF500200667F4A /* strikethrough.c in Sources */,
+				A288C8061FEF500200667F4A /* plaintext.c in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		A2BD077B1FEF6B65005E1FC7 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				A2BD07C21FEF6BA4005E1FC7 /* xml.c in Sources */,
+				A2BD07BF1FEF6BA4005E1FC7 /* table.c in Sources */,
+				A2BD07AF1FEF6BA4005E1FC7 /* html.c in Sources */,
+				A2BD07AA1FEF6BA4005E1FC7 /* ext_scanners.c in Sources */,
+				A2BD07A91FEF6BA4005E1FC7 /* core-extensions.c in Sources */,
+				A2BD07A71FEF6BA4005E1FC7 /* cmark.c in Sources */,
+				A2BD07A81FEF6BA4005E1FC7 /* commonmark.c in Sources */,
+				A2BD07B11FEF6BA4005E1FC7 /* iterator.c in Sources */,
+				A2BD07B81FEF6BA4005E1FC7 /* plugin.c in Sources */,
+				A2BD07A41FEF6BA4005E1FC7 /* blocks.c in Sources */,
+				A2BD07AD1FEF6BA4005E1FC7 /* houdini_html_e.c in Sources */,
+				A2BD07AB1FEF6BA4005E1FC7 /* footnotes.c in Sources */,
+				A2BD07BC1FEF6BA4005E1FC7 /* scanners.c in Sources */,
+				A2BD07B71FEF6BA4005E1FC7 /* plaintext.c in Sources */,
+				A2BD07A31FEF6BA4005E1FC7 /* autolink.c in Sources */,
+				A2BD07A21FEF6BA4005E1FC7 /* arena.c in Sources */,
+				A2BD07B21FEF6BA4005E1FC7 /* latex.c in Sources */,
+				A2BD07B51FEF6BA4005E1FC7 /* map.c in Sources */,
+				A2BD07C01FEF6BA4005E1FC7 /* tagfilter.c in Sources */,
+				A2BD07BE1FEF6BA4005E1FC7 /* syntax_extension.c in Sources */,
+				A2BD07B91FEF6BA4005E1FC7 /* references.c in Sources */,
+				A2BD07B31FEF6BA4005E1FC7 /* linked_list.c in Sources */,
+				A2BD07A51FEF6BA4005E1FC7 /* buffer.c in Sources */,
+				A2BD07B41FEF6BA4005E1FC7 /* man.c in Sources */,
+				A2BD07BA1FEF6BA4005E1FC7 /* registry.c in Sources */,
+				A2BD07B01FEF6BA4005E1FC7 /* inlines.c in Sources */,
+				A2BD07AE1FEF6BA4005E1FC7 /* houdini_html_u.c in Sources */,
+				A2BD07AC1FEF6BA4005E1FC7 /* houdini_href_e.c in Sources */,
+				A2BD07A61FEF6BA4005E1FC7 /* cmark_ctype.c in Sources */,
+				A2BD07B61FEF6BA4005E1FC7 /* node.c in Sources */,
+				A2BD07BB1FEF6BA4005E1FC7 /* render.c in Sources */,
+				A2BD07C11FEF6BA4005E1FC7 /* utf8.c in Sources */,
+				A2BD07BD1FEF6BA4005E1FC7 /* strikethrough.c in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		A2BD07881FEF6B76005E1FC7 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				A2BD07E31FEF6BA5005E1FC7 /* xml.c in Sources */,
+				A2BD07E01FEF6BA5005E1FC7 /* table.c in Sources */,
+				A2BD07D01FEF6BA5005E1FC7 /* html.c in Sources */,
+				A2BD07CB1FEF6BA5005E1FC7 /* ext_scanners.c in Sources */,
+				A2BD07CA1FEF6BA5005E1FC7 /* core-extensions.c in Sources */,
+				A2BD07C81FEF6BA5005E1FC7 /* cmark.c in Sources */,
+				A2BD07C91FEF6BA5005E1FC7 /* commonmark.c in Sources */,
+				A2BD07D21FEF6BA5005E1FC7 /* iterator.c in Sources */,
+				A2BD07D91FEF6BA5005E1FC7 /* plugin.c in Sources */,
+				A2BD07C51FEF6BA5005E1FC7 /* blocks.c in Sources */,
+				A2BD07CE1FEF6BA5005E1FC7 /* houdini_html_e.c in Sources */,
+				A2BD07CC1FEF6BA5005E1FC7 /* footnotes.c in Sources */,
+				A2BD07DD1FEF6BA5005E1FC7 /* scanners.c in Sources */,
+				A2BD07D81FEF6BA5005E1FC7 /* plaintext.c in Sources */,
+				A2BD07C41FEF6BA5005E1FC7 /* autolink.c in Sources */,
+				A2BD07C31FEF6BA5005E1FC7 /* arena.c in Sources */,
+				A2BD07D31FEF6BA5005E1FC7 /* latex.c in Sources */,
+				A2BD07D61FEF6BA5005E1FC7 /* map.c in Sources */,
+				A2BD07E11FEF6BA5005E1FC7 /* tagfilter.c in Sources */,
+				A2BD07DF1FEF6BA5005E1FC7 /* syntax_extension.c in Sources */,
+				A2BD07DA1FEF6BA5005E1FC7 /* references.c in Sources */,
+				A2BD07D41FEF6BA5005E1FC7 /* linked_list.c in Sources */,
+				A2BD07C61FEF6BA5005E1FC7 /* buffer.c in Sources */,
+				A2BD07D51FEF6BA5005E1FC7 /* man.c in Sources */,
+				A2BD07DB1FEF6BA5005E1FC7 /* registry.c in Sources */,
+				A2BD07D11FEF6BA5005E1FC7 /* inlines.c in Sources */,
+				A2BD07CF1FEF6BA5005E1FC7 /* houdini_html_u.c in Sources */,
+				A2BD07CD1FEF6BA5005E1FC7 /* houdini_href_e.c in Sources */,
+				A2BD07C71FEF6BA5005E1FC7 /* cmark_ctype.c in Sources */,
+				A2BD07D71FEF6BA5005E1FC7 /* node.c in Sources */,
+				A2BD07DC1FEF6BA5005E1FC7 /* render.c in Sources */,
+				A2BD07E21FEF6BA5005E1FC7 /* utf8.c in Sources */,
+				A2BD07DE1FEF6BA5005E1FC7 /* strikethrough.c in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		A2BD07951FEF6B8E005E1FC7 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				A2BD08041FEF6BA5005E1FC7 /* xml.c in Sources */,
+				A2BD08011FEF6BA5005E1FC7 /* table.c in Sources */,
+				A2BD07F11FEF6BA5005E1FC7 /* html.c in Sources */,
+				A2BD07EC1FEF6BA5005E1FC7 /* ext_scanners.c in Sources */,
+				A2BD07EB1FEF6BA5005E1FC7 /* core-extensions.c in Sources */,
+				A2BD07E91FEF6BA5005E1FC7 /* cmark.c in Sources */,
+				A2BD07EA1FEF6BA5005E1FC7 /* commonmark.c in Sources */,
+				A2BD07F31FEF6BA5005E1FC7 /* iterator.c in Sources */,
+				A2BD07FA1FEF6BA5005E1FC7 /* plugin.c in Sources */,
+				A2BD07E61FEF6BA5005E1FC7 /* blocks.c in Sources */,
+				A2BD07EF1FEF6BA5005E1FC7 /* houdini_html_e.c in Sources */,
+				A2BD07ED1FEF6BA5005E1FC7 /* footnotes.c in Sources */,
+				A2BD07FE1FEF6BA5005E1FC7 /* scanners.c in Sources */,
+				A2BD07F91FEF6BA5005E1FC7 /* plaintext.c in Sources */,
+				A2BD07E51FEF6BA5005E1FC7 /* autolink.c in Sources */,
+				A2BD07E41FEF6BA5005E1FC7 /* arena.c in Sources */,
+				A2BD07F41FEF6BA5005E1FC7 /* latex.c in Sources */,
+				A2BD07F71FEF6BA5005E1FC7 /* map.c in Sources */,
+				A2BD08021FEF6BA5005E1FC7 /* tagfilter.c in Sources */,
+				A2BD08001FEF6BA5005E1FC7 /* syntax_extension.c in Sources */,
+				A2BD07FB1FEF6BA5005E1FC7 /* references.c in Sources */,
+				A2BD07F51FEF6BA5005E1FC7 /* linked_list.c in Sources */,
+				A2BD07E71FEF6BA5005E1FC7 /* buffer.c in Sources */,
+				A2BD07F61FEF6BA5005E1FC7 /* man.c in Sources */,
+				A2BD07FC1FEF6BA5005E1FC7 /* registry.c in Sources */,
+				A2BD07F21FEF6BA5005E1FC7 /* inlines.c in Sources */,
+				A2BD07F01FEF6BA5005E1FC7 /* houdini_html_u.c in Sources */,
+				A2BD07EE1FEF6BA5005E1FC7 /* houdini_href_e.c in Sources */,
+				A2BD07E81FEF6BA5005E1FC7 /* cmark_ctype.c in Sources */,
+				A2BD07F81FEF6BA5005E1FC7 /* node.c in Sources */,
+				A2BD07FD1FEF6BA5005E1FC7 /* render.c in Sources */,
+				A2BD08031FEF6BA5005E1FC7 /* utf8.c in Sources */,
+				A2BD07FF1FEF6BA5005E1FC7 /* strikethrough.c in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+		A288C7521FEF4F6D00667F4A /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_COMMA = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_STRICT_PROTOTYPES = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				CODE_SIGN_IDENTITY = "iPhone Developer";
+				COPY_PHASE_STRIP = NO;
+				CURRENT_PROJECT_VERSION = 1;
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				ENABLE_TESTABILITY = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu11;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+				MTL_ENABLE_DEBUG_INFO = YES;
+				ONLY_ACTIVE_ARCH = YES;
+				SDKROOT = iphoneos;
+				VERSIONING_SYSTEM = "apple-generic";
+				VERSION_INFO_PREFIX = "";
+			};
+			name = Debug;
+		};
+		A288C7531FEF4F6D00667F4A /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_COMMA = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_STRICT_PROTOTYPES = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				CODE_SIGN_IDENTITY = "iPhone Developer";
+				COPY_PHASE_STRIP = NO;
+				CURRENT_PROJECT_VERSION = 1;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_NS_ASSERTIONS = NO;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu11;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+				MTL_ENABLE_DEBUG_INFO = NO;
+				SDKROOT = iphoneos;
+				VALIDATE_PRODUCT = YES;
+				VERSIONING_SYSTEM = "apple-generic";
+				VERSION_INFO_PREFIX = "";
+			};
+			name = Release;
+		};
+		A288C7551FEF4F6D00667F4A /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				CODE_SIGN_STYLE = Automatic;
+				DEFINES_MODULE = YES;
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				DYLIB_INSTALL_NAME_BASE = "@rpath";
+				INFOPLIST_FILE = Sources/Info.plist;
+				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				PRODUCT_BUNDLE_IDENTIFIER = "com.krisbaker.libcmark-gfm";
+				PRODUCT_NAME = libcmark_gfm;
+				SKIP_INSTALL = YES;
+				TARGETED_DEVICE_FAMILY = "1,2";
+			};
+			name = Debug;
+		};
+		A288C7561FEF4F6D00667F4A /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				CODE_SIGN_STYLE = Automatic;
+				DEFINES_MODULE = YES;
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				DYLIB_INSTALL_NAME_BASE = "@rpath";
+				INFOPLIST_FILE = Sources/Info.plist;
+				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				PRODUCT_BUNDLE_IDENTIFIER = "com.krisbaker.libcmark-gfm";
+				PRODUCT_NAME = libcmark_gfm;
+				SKIP_INSTALL = YES;
+				TARGETED_DEVICE_FAMILY = "1,2";
+			};
+			name = Release;
+		};
+		A2BD07861FEF6B65005E1FC7 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				APPLICATION_EXTENSION_API_ONLY = YES;
+				CODE_SIGN_IDENTITY = "";
+				CODE_SIGN_STYLE = Automatic;
+				DEFINES_MODULE = YES;
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				DYLIB_INSTALL_NAME_BASE = "@rpath";
+				INFOPLIST_FILE = Sources/Info.plist;
+				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				PRODUCT_BUNDLE_IDENTIFIER = "com.krisbaker.libcmark-gfm";
+				PRODUCT_NAME = libcmark_gfm;
+				SDKROOT = watchos;
+				SKIP_INSTALL = YES;
+				TARGETED_DEVICE_FAMILY = 4;
+				WATCHOS_DEPLOYMENT_TARGET = 4.2;
+			};
+			name = Debug;
+		};
+		A2BD07871FEF6B65005E1FC7 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				APPLICATION_EXTENSION_API_ONLY = YES;
+				CODE_SIGN_IDENTITY = "";
+				CODE_SIGN_STYLE = Automatic;
+				DEFINES_MODULE = YES;
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				DYLIB_INSTALL_NAME_BASE = "@rpath";
+				INFOPLIST_FILE = Sources/Info.plist;
+				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				PRODUCT_BUNDLE_IDENTIFIER = "com.krisbaker.libcmark-gfm";
+				PRODUCT_NAME = libcmark_gfm;
+				SDKROOT = watchos;
+				SKIP_INSTALL = YES;
+				TARGETED_DEVICE_FAMILY = 4;
+				WATCHOS_DEPLOYMENT_TARGET = 4.2;
+			};
+			name = Release;
+		};
+		A2BD07931FEF6B76005E1FC7 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				CODE_SIGN_STYLE = Automatic;
+				DEFINES_MODULE = YES;
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				DYLIB_INSTALL_NAME_BASE = "@rpath";
+				INFOPLIST_FILE = Sources/Info.plist;
+				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				PRODUCT_BUNDLE_IDENTIFIER = "com.krisbaker.libcmark-gfm";
+				PRODUCT_NAME = libcmark_gfm;
+				SDKROOT = appletvos;
+				SKIP_INSTALL = YES;
+				TARGETED_DEVICE_FAMILY = 3;
+				TVOS_DEPLOYMENT_TARGET = 11.2;
+			};
+			name = Debug;
+		};
+		A2BD07941FEF6B76005E1FC7 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				CODE_SIGN_STYLE = Automatic;
+				DEFINES_MODULE = YES;
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				DYLIB_INSTALL_NAME_BASE = "@rpath";
+				INFOPLIST_FILE = Sources/Info.plist;
+				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				PRODUCT_BUNDLE_IDENTIFIER = "com.krisbaker.libcmark-gfm";
+				PRODUCT_NAME = libcmark_gfm;
+				SDKROOT = appletvos;
+				SKIP_INSTALL = YES;
+				TARGETED_DEVICE_FAMILY = 3;
+				TVOS_DEPLOYMENT_TARGET = 11.2;
+			};
+			name = Release;
+		};
+		A2BD07A01FEF6B8E005E1FC7 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "-";
+				CODE_SIGN_STYLE = Automatic;
+				COMBINE_HIDPI_IMAGES = YES;
+				DEFINES_MODULE = YES;
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				DYLIB_INSTALL_NAME_BASE = "@rpath";
+				FRAMEWORK_VERSION = A;
+				INFOPLIST_FILE = Sources/Info.plist;
+				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
+				MACOSX_DEPLOYMENT_TARGET = 10.13;
+				PRODUCT_BUNDLE_IDENTIFIER = "com.krisbaker.libcmark-gfm";
+				PRODUCT_NAME = libcmark_gfm;
+				SDKROOT = macosx;
+				SKIP_INSTALL = YES;
+			};
+			name = Debug;
+		};
+		A2BD07A11FEF6B8E005E1FC7 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "-";
+				CODE_SIGN_STYLE = Automatic;
+				COMBINE_HIDPI_IMAGES = YES;
+				DEFINES_MODULE = YES;
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				DYLIB_INSTALL_NAME_BASE = "@rpath";
+				FRAMEWORK_VERSION = A;
+				INFOPLIST_FILE = Sources/Info.plist;
+				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
+				MACOSX_DEPLOYMENT_TARGET = 10.13;
+				PRODUCT_BUNDLE_IDENTIFIER = "com.krisbaker.libcmark-gfm";
+				PRODUCT_NAME = libcmark_gfm;
+				SDKROOT = macosx;
+				SKIP_INSTALL = YES;
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		A288C7461FEF4F6D00667F4A /* Build configuration list for PBXProject "libcmark_gfm" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				A288C7521FEF4F6D00667F4A /* Debug */,
+				A288C7531FEF4F6D00667F4A /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		A288C7541FEF4F6D00667F4A /* Build configuration list for PBXNativeTarget "libcmark_gfm-iOS" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				A288C7551FEF4F6D00667F4A /* Debug */,
+				A288C7561FEF4F6D00667F4A /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		A2BD07851FEF6B65005E1FC7 /* Build configuration list for PBXNativeTarget "libcmark_gfm-watchOS" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				A2BD07861FEF6B65005E1FC7 /* Debug */,
+				A2BD07871FEF6B65005E1FC7 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		A2BD07921FEF6B76005E1FC7 /* Build configuration list for PBXNativeTarget "libcmark_gfm-tvOS" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				A2BD07931FEF6B76005E1FC7 /* Debug */,
+				A2BD07941FEF6B76005E1FC7 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		A2BD079F1FEF6B8E005E1FC7 /* Build configuration list for PBXNativeTarget "libcmark_gfm-macOS" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				A2BD07A01FEF6B8E005E1FC7 /* Debug */,
+				A2BD07A11FEF6B8E005E1FC7 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = A288C7431FEF4F6D00667F4A /* Project object */;
+}
diff --git a/libcmark_gfm.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/libcmark_gfm.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..ba177f4
--- /dev/null
+++ b/libcmark_gfm.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+   
+   
+
diff --git a/libcmark_gfm.xcodeproj/xcshareddata/xcschemes/libcmark_gfm-iOS.xcscheme b/libcmark_gfm.xcodeproj/xcshareddata/xcschemes/libcmark_gfm-iOS.xcscheme
new file mode 100644
index 0000000..8818012
--- /dev/null
+++ b/libcmark_gfm.xcodeproj/xcshareddata/xcschemes/libcmark_gfm-iOS.xcscheme
@@ -0,0 +1,82 @@
+
+
+   
+      
+         
+            
+            
+         
+      
+   
+   
+      
+      
+      
+      
+   
+   
+      
+         
+         
+      
+      
+      
+   
+   
+      
+         
+         
+      
+   
+   
+   
+   
+   
+
diff --git a/libcmark_gfm.xcodeproj/xcshareddata/xcschemes/libcmark_gfm-macOS.xcscheme b/libcmark_gfm.xcodeproj/xcshareddata/xcschemes/libcmark_gfm-macOS.xcscheme
new file mode 100644
index 0000000..b39520e
--- /dev/null
+++ b/libcmark_gfm.xcodeproj/xcshareddata/xcschemes/libcmark_gfm-macOS.xcscheme
@@ -0,0 +1,82 @@
+
+
+   
+      
+         
+            
+            
+         
+      
+   
+   
+      
+      
+      
+      
+   
+   
+      
+         
+         
+      
+      
+      
+   
+   
+      
+         
+         
+      
+   
+   
+   
+   
+   
+
diff --git a/libcmark_gfm.xcodeproj/xcshareddata/xcschemes/libcmark_gfm-tvOS.xcscheme b/libcmark_gfm.xcodeproj/xcshareddata/xcschemes/libcmark_gfm-tvOS.xcscheme
new file mode 100644
index 0000000..77deff4
--- /dev/null
+++ b/libcmark_gfm.xcodeproj/xcshareddata/xcschemes/libcmark_gfm-tvOS.xcscheme
@@ -0,0 +1,82 @@
+
+
+   
+      
+         
+            
+            
+         
+      
+   
+   
+      
+      
+      
+      
+   
+   
+      
+         
+         
+      
+      
+      
+   
+   
+      
+         
+         
+      
+   
+   
+   
+   
+   
+
diff --git a/libcmark_gfm.xcodeproj/xcshareddata/xcschemes/libcmark_gfm-watchOS.xcscheme b/libcmark_gfm.xcodeproj/xcshareddata/xcschemes/libcmark_gfm-watchOS.xcscheme
new file mode 100644
index 0000000..445d5ed
--- /dev/null
+++ b/libcmark_gfm.xcodeproj/xcshareddata/xcschemes/libcmark_gfm-watchOS.xcscheme
@@ -0,0 +1,82 @@
+
+
+   
+      
+         
+            
+            
+         
+      
+   
+   
+      
+      
+      
+      
+   
+   
+      
+         
+         
+      
+      
+      
+   
+   
+      
+         
+         
+      
+   
+   
+   
+   
+   
+
diff --git a/libcmark_gfm.xcodeproj/xcshareddata/xcschemes/libcmark_gfm.xcscheme b/libcmark_gfm.xcodeproj/xcshareddata/xcschemes/libcmark_gfm.xcscheme
new file mode 100644
index 0000000..8818012
--- /dev/null
+++ b/libcmark_gfm.xcodeproj/xcshareddata/xcschemes/libcmark_gfm.xcscheme
@@ -0,0 +1,82 @@
+
+
+   
+      
+         
+            
+            
+         
+      
+   
+   
+      
+      
+      
+      
+   
+   
+      
+         
+         
+      
+      
+      
+   
+   
+      
+         
+         
+      
+   
+   
+   
+   
+   
+