From f1ad70fef4d5e8a3532b8b8d30750996622b9c93 Mon Sep 17 00:00:00 2001 From: Xavier Mendez Date: Mon, 3 Nov 2014 23:02:45 +0100 Subject: [PATCH] Squashed commits for rewrite --- .gitignore | 18 +- .gitmodules | 3 + .travis.yml | 4 +- CMakeLists.txt | 62 + Makefile | 68 - Makefile.win | 36 - bin/common.h | 151 +- bin/hoedown.c | 737 +- bin/noop.c | 82 + bin/noop.h | 28 + bin/smartypants.c | 228 - data/autolink_schemes.gperf | 166 + data/html_blocks.gperf | 52 + hoedown.def | 40 - html_block_names.gperf | 24 - src/_autolink_schemes.c | 1319 ++ src/{html_blocks.c => _html_blocks.c} | 215 +- src/_html_entities.h | 19287 ++++++++++++++++ src/autolink.c | 400 +- src/autolink.h | 32 +- src/buffer.c | 350 +- src/buffer.h | 56 +- src/document.c | 4838 ++-- src/document.h | 309 +- src/escape.c | 295 +- src/escape.h | 12 +- src/html.c | 1018 +- src/html.h | 52 +- src/html_smartypants.c | 425 - src/pool.c | 63 + src/pool.h | 60 + src/stack.c | 79 - src/stack.h | 52 - src/version.c | 10 +- src/version.h | 4 +- stmd | 1 + test/MarkdownTest_1.0.3/MarkdownTest.pl | 177 - .../Tests/Amps and angle encoding.html | 17 - .../Tests/Amps and angle encoding.text | 21 - test/MarkdownTest_1.0.3/Tests/Auto links.html | 18 - test/MarkdownTest_1.0.3/Tests/Auto links.text | 13 - .../Tests/Backslash escapes.html | 118 - .../Tests/Backslash escapes.text | 120 - .../Tests/Blockquotes with code blocks.html | 15 - .../Tests/Blockquotes with code blocks.text | 11 - .../MarkdownTest_1.0.3/Tests/Code Blocks.html | 18 - .../MarkdownTest_1.0.3/Tests/Code Blocks.text | 14 - test/MarkdownTest_1.0.3/Tests/Code Spans.html | 6 - test/MarkdownTest_1.0.3/Tests/Code Spans.text | 6 - ...apped paragraphs with list-like lines.html | 8 - ...apped paragraphs with list-like lines.text | 8 - .../Tests/Horizontal rules.html | 71 - .../Tests/Horizontal rules.text | 67 - .../Tests/Inline HTML (Advanced).html | 15 - .../Tests/Inline HTML (Advanced).text | 15 - .../Tests/Inline HTML (Simple).html | 72 - .../Tests/Inline HTML (Simple).text | 69 - .../Tests/Inline HTML comments.html | 13 - .../Tests/Inline HTML comments.text | 13 - .../Tests/Links, inline style.html | 11 - .../Tests/Links, inline style.text | 12 - .../Tests/Links, reference style.html | 52 - .../Tests/Links, reference style.text | 71 - .../Tests/Links, shortcut references.html | 9 - .../Tests/Links, shortcut references.text | 20 - .../Tests/Literal quotes in titles.html | 3 - .../Tests/Literal quotes in titles.text | 7 - .../Markdown Documentation - Basics.html | 314 - .../Markdown Documentation - Basics.text | 306 - .../Markdown Documentation - Syntax.html | 942 - .../Markdown Documentation - Syntax.text | 888 - .../Tests/Nested blockquotes.html | 9 - .../Tests/Nested blockquotes.text | 5 - .../Tests/Ordered and unordered lists.html | 148 - .../Tests/Ordered and unordered lists.text | 131 - .../Tests/Strong and em together.html | 7 - .../Tests/Strong and em together.text | 7 - test/MarkdownTest_1.0.3/Tests/Tabs.html | 25 - test/MarkdownTest_1.0.3/Tests/Tabs.text | 21 - test/MarkdownTest_1.0.3/Tests/Tidyness.html | 8 - test/MarkdownTest_1.0.3/Tests/Tidyness.text | 5 - test/Tests/Escape character.html | 51 - test/Tests/Escape character.text | 51 - test/Tests/Math.html | 31 - test/Tests/Math.text | 31 - test/config.json | 101 - test/runner.py | 108 - 87 files changed, 24993 insertions(+), 9862 deletions(-) create mode 100644 .gitmodules create mode 100644 CMakeLists.txt delete mode 100644 Makefile delete mode 100644 Makefile.win create mode 100644 bin/noop.c create mode 100644 bin/noop.h delete mode 100644 bin/smartypants.c create mode 100644 data/autolink_schemes.gperf create mode 100644 data/html_blocks.gperf delete mode 100644 hoedown.def delete mode 100644 html_block_names.gperf create mode 100644 src/_autolink_schemes.c rename src/{html_blocks.c => _html_blocks.c} (66%) create mode 100644 src/_html_entities.h delete mode 100644 src/html_smartypants.c create mode 100644 src/pool.c create mode 100644 src/pool.h delete mode 100644 src/stack.c delete mode 100644 src/stack.h create mode 160000 stmd delete mode 100755 test/MarkdownTest_1.0.3/MarkdownTest.pl delete mode 100644 test/MarkdownTest_1.0.3/Tests/Amps and angle encoding.html delete mode 100644 test/MarkdownTest_1.0.3/Tests/Amps and angle encoding.text delete mode 100644 test/MarkdownTest_1.0.3/Tests/Auto links.html delete mode 100644 test/MarkdownTest_1.0.3/Tests/Auto links.text delete mode 100644 test/MarkdownTest_1.0.3/Tests/Backslash escapes.html delete mode 100644 test/MarkdownTest_1.0.3/Tests/Backslash escapes.text delete mode 100644 test/MarkdownTest_1.0.3/Tests/Blockquotes with code blocks.html delete mode 100644 test/MarkdownTest_1.0.3/Tests/Blockquotes with code blocks.text delete mode 100644 test/MarkdownTest_1.0.3/Tests/Code Blocks.html delete mode 100644 test/MarkdownTest_1.0.3/Tests/Code Blocks.text delete mode 100644 test/MarkdownTest_1.0.3/Tests/Code Spans.html delete mode 100644 test/MarkdownTest_1.0.3/Tests/Code Spans.text delete mode 100644 test/MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.html delete mode 100644 test/MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.text delete mode 100644 test/MarkdownTest_1.0.3/Tests/Horizontal rules.html delete mode 100644 test/MarkdownTest_1.0.3/Tests/Horizontal rules.text delete mode 100644 test/MarkdownTest_1.0.3/Tests/Inline HTML (Advanced).html delete mode 100644 test/MarkdownTest_1.0.3/Tests/Inline HTML (Advanced).text delete mode 100644 test/MarkdownTest_1.0.3/Tests/Inline HTML (Simple).html delete mode 100644 test/MarkdownTest_1.0.3/Tests/Inline HTML (Simple).text delete mode 100644 test/MarkdownTest_1.0.3/Tests/Inline HTML comments.html delete mode 100644 test/MarkdownTest_1.0.3/Tests/Inline HTML comments.text delete mode 100644 test/MarkdownTest_1.0.3/Tests/Links, inline style.html delete mode 100644 test/MarkdownTest_1.0.3/Tests/Links, inline style.text delete mode 100644 test/MarkdownTest_1.0.3/Tests/Links, reference style.html delete mode 100644 test/MarkdownTest_1.0.3/Tests/Links, reference style.text delete mode 100644 test/MarkdownTest_1.0.3/Tests/Links, shortcut references.html delete mode 100644 test/MarkdownTest_1.0.3/Tests/Links, shortcut references.text delete mode 100644 test/MarkdownTest_1.0.3/Tests/Literal quotes in titles.html delete mode 100644 test/MarkdownTest_1.0.3/Tests/Literal quotes in titles.text delete mode 100644 test/MarkdownTest_1.0.3/Tests/Markdown Documentation - Basics.html delete mode 100644 test/MarkdownTest_1.0.3/Tests/Markdown Documentation - Basics.text delete mode 100644 test/MarkdownTest_1.0.3/Tests/Markdown Documentation - Syntax.html delete mode 100644 test/MarkdownTest_1.0.3/Tests/Markdown Documentation - Syntax.text delete mode 100644 test/MarkdownTest_1.0.3/Tests/Nested blockquotes.html delete mode 100644 test/MarkdownTest_1.0.3/Tests/Nested blockquotes.text delete mode 100644 test/MarkdownTest_1.0.3/Tests/Ordered and unordered lists.html delete mode 100644 test/MarkdownTest_1.0.3/Tests/Ordered and unordered lists.text delete mode 100644 test/MarkdownTest_1.0.3/Tests/Strong and em together.html delete mode 100644 test/MarkdownTest_1.0.3/Tests/Strong and em together.text delete mode 100644 test/MarkdownTest_1.0.3/Tests/Tabs.html delete mode 100644 test/MarkdownTest_1.0.3/Tests/Tabs.text delete mode 100644 test/MarkdownTest_1.0.3/Tests/Tidyness.html delete mode 100644 test/MarkdownTest_1.0.3/Tests/Tidyness.text delete mode 100644 test/Tests/Escape character.html delete mode 100644 test/Tests/Escape character.text delete mode 100644 test/Tests/Math.html delete mode 100644 test/Tests/Math.text delete mode 100644 test/config.json delete mode 100755 test/runner.py diff --git a/.gitignore b/.gitignore index e885c6c..e6f5b3c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,13 @@ -*.o -*.obj *.exe +*.dll +*.exp +*.lib hoedown -hoedown.dll -hoedown.exp -hoedown.lib -smartypants -libhoedown.so* +libhoedown.* + +Makefile +CMakeFiles +CMakeCache.txt +cmake_install.cmake +install_manifest.txt +compile_commands.json diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..a8378ff --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "stmd"] + path = stmd + url = https://github.com/jgm/stmd diff --git a/.travis.yml b/.travis.yml index 27c07a9..f18b757 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,4 @@ compiler: - gcc perl: - "5.12" -before_install: - - sudo apt-get install -qq tidy -script: make test +script: cmake . && make test diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..b546652 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,62 @@ +cmake_minimum_required (VERSION 2.6) +project (Hoedown) + +option (BUILD_SHARED_LIBS "Wether to build Hoedown as a shared library" true) +option (BUILD_CLI "Wether to build the hoedown executable" true) + +set (FLAGS "-std=c99 -Wall -Wextra -Wno-unused-parameter") + + +# Pregenerated files +add_custom_target(_html_blocks.c + gperf -L ANSI-C -N hoedown_find_block_tag -7 -c -C -E -S 1 --ignore-case -m100 data/html_blocks.gperf > src/_html_blocks.c +) +add_custom_target(_autolink_schemes.c + gperf -L ANSI-C -N hoedown_find_autolink_scheme -l -c -C -E -S 1 --ignore-case -m100 data/autolink_schemes.gperf > src/_autolink_schemes.c +) + + +# Library +add_library(libhoedown + src/autolink.c + src/buffer.c + src/document.c + src/escape.c + src/html.c + src/pool.c + src/version.c + + src/_html_blocks.c + src/_autolink_schemes.c +) + +set_target_properties(libhoedown PROPERTIES + COMPILE_FLAGS ${FLAGS} + OUTPUT_NAME hoedown + SOVERSION 4 + VERSION 4.0.0 +) + +install(TARGETS libhoedown DESTINATION lib) +install(DIRECTORY src/ DESTINATION include/hoedown + FILES_MATCHING PATTERN "*.h" + PATTERN "_*" EXCLUDE +) + + +# Executables +if (BUILD_CLI) + add_executable(hoedown bin/hoedown.c bin/noop.c) + target_link_libraries(hoedown libhoedown rt) + + set_target_properties(hoedown PROPERTIES COMPILE_FLAGS ${FLAGS}) + include_directories(${PROJECT_SOURCE_DIR}/src) + + install(TARGETS hoedown DESTINATION bin) + + get_target_property(HOEDOWN_LOCATION hoedown LOCATION) + add_custom_target(test + perl stmd/runtests.pl stmd/spec.txt ${HOEDOWN_LOCATION} + DEPENDS hoedown + ) +endif (BUILD_CLI) diff --git a/Makefile b/Makefile deleted file mode 100644 index ae5f92c..0000000 --- a/Makefile +++ /dev/null @@ -1,68 +0,0 @@ -CFLAGS = -g -O3 -ansi -pedantic -Wall -Wextra -Wno-unused-parameter -Isrc - -ifneq ($(OS),Windows_NT) - CFLAGS += -fPIC -endif - -HOEDOWN_SRC=\ - src/autolink.o \ - src/buffer.o \ - src/document.o \ - src/escape.o \ - src/html.o \ - src/html_blocks.o \ - src/html_smartypants.o \ - src/stack.o \ - src/version.o - -.PHONY: all test test-pl clean - -all: libhoedown.so hoedown smartypants - -# Libraries - -libhoedown.so: libhoedown.so.1 - ln -f -s $^ $@ - -libhoedown.so.1: $(HOEDOWN_SRC) - $(CC) -shared $^ $(LDFLAGS) -o $@ - -libhoedown.a: $(HOEDOWN_SRC) - $(AR) rcs libhoedown.a $^ - -# Executables - -hoedown: bin/hoedown.o $(HOEDOWN_SRC) - $(CC) $^ $(LDFLAGS) -o $@ - -smartypants: bin/smartypants.o $(HOEDOWN_SRC) - $(CC) $^ $(LDFLAGS) -o $@ - -# Perfect hashing - -src/html_blocks.c: html_block_names.gperf - gperf -L ANSI-C -N hoedown_find_block_tag -c -C -E -S 1 --ignore-case -m100 $^ > $@ - -# Testing - -test: hoedown - python test/runner.py - -test-pl: hoedown - perl test/MarkdownTest_1.0.3/MarkdownTest.pl \ - --script=./hoedown --testdir=test/MarkdownTest_1.0.3/Tests --tidy - -# Housekeeping - -clean: - $(RM) src/*.o bin/*.o - $(RM) libhoedown.so libhoedown.so.1 libhoedown.a - $(RM) hoedown smartypants hoedown.exe smartypants.exe - -# Generic object compilations - -%.o: %.c - $(CC) $(CFLAGS) -c -o $@ $< - -src/html_blocks.o: src/html_blocks.c - $(CC) $(CFLAGS) -Wno-static-in-inline -c -o $@ $< diff --git a/Makefile.win b/Makefile.win deleted file mode 100644 index cda24b9..0000000 --- a/Makefile.win +++ /dev/null @@ -1,36 +0,0 @@ -CC = cl -CFLAGS = /O2 /sdl /Isrc /D_CRT_SECURE_NO_WARNINGS - -HOEDOWN_SRC = \ - src\autolink.obj \ - src\buffer.obj \ - src\document.obj \ - src\escape.obj \ - src\html.obj \ - src\html_blocks.obj \ - src\html_smartypants.obj \ - src\stack.obj \ - src\version.obj - -all: hoedown.dll hoedown.exe smartypants.exe - -hoedown.dll: $(HOEDOWN_SRC) hoedown.def - $(CC) $(HOEDOWN_SRC) hoedown.def /link /DLL $(LDFLAGS) /out:$@ - -hoedown.exe: bin\hoedown.obj $(HOEDOWN_SRC) - $(CC) bin\hoedown.obj $(HOEDOWN_SRC) /link $(LDFLAGS) /out:$@ - -smartypants.exe: bin\smartypants.obj $(HOEDOWN_SRC) - $(CC) bin\smartypants.obj $(HOEDOWN_SRC) /link $(LDFLAGS) /out:$@ - -# Housekeeping - -clean: - del $(HOEDOWN_SRC) - del hoedown.dll hoedown.exp hoedown.lib - del hoedown.exe smartypants.exe - -# Generic object compilations - -.c.obj: - $(CC) $(CFLAGS) /c $< /Fo$@ diff --git a/bin/common.h b/bin/common.h index 5d55acc..d40423f 100644 --- a/bin/common.h +++ b/bin/common.h @@ -10,99 +10,90 @@ #define count_of(arr) (sizeof(arr)/sizeof(0[arr])) -int -parseint(const char *string, long *result) -{ - char *end; - errno = 0; - *result = strtol(string, &end, 10); - return !(*end || errno); +static int parseint(const char *string, long *result) { + char *end; + errno = 0; + *result = strtol(string, &end, 10); + return !(*end || errno); } -const char * -strprefix(const char *str, const char *prefix) -{ - while (*prefix) { - if (!(*str && *str == *prefix)) return 0; - prefix++; str++; - } - return str; +static const char *strprefix(const char *str, const char *prefix) { + while (*prefix) { + if (!(*str && *str == *prefix)) return 0; + prefix++; str++; + } + return str; } -void -print_option(char short_opt, const char *long_opt, const char *description) -{ - if (short_opt) - printf(" -%c, ", short_opt); - else - printf(" "); +static void print_option(char short_opt, const char *long_opt, const char *description) { + if (short_opt) + printf(" -%c, ", short_opt); + else + printf(" "); - printf("--%-13s %s\n", long_opt, description); + printf("--%-15s %s\n", long_opt, description); } -void -print_version() -{ - printf("Built with Hoedown " HOEDOWN_VERSION ".\n"); +static void print_version() { + printf("Built with Hoedown " HOEDOWN_VERSION ".\n"); } -int -parse_options( - int argc, char **argv, - int(*parse_short_option)(char opt, char *next, void *opaque), - int(*parse_long_option)(char *opt, char *next, void *opaque), - int(*parse_argument)(int argn, char *arg, int is_forced, void *opaque), - void *opaque) -{ - int result; - int i = 1, regular_args = 0; +static int parse_options( + int argc, char **argv, + int(*parse_short_option)(char opt, char *next, void *opaque), + int(*parse_long_option)(char *opt, char *next, void *opaque), + int(*parse_argument)(int argn, char *arg, int is_forced, void *opaque), + void *opaque +){ + int result; + int i = 1, regular_args = 0; - /* Parse options mixed with arguments */ - while (i < argc) { - char *arg = argv[i]; + /* Parse options mixed with arguments */ + while (i < argc) { + char *arg = argv[i]; - if (arg[0] == '-' && arg[1]) { - char *next_arg = (i+1 < argc) ? argv[i+1] : NULL; + if (arg[0] == '-' && arg[1]) { + char *next_arg = (i+1 < argc) ? argv[i+1] : NULL; - if (arg[1] == '-' && !arg[2]) { - /* '--' signals end of options */ - i++; - break; - } + if (arg[1] == '-' && !arg[2]) { + /* '--' signals end of options */ + i++; + break; + } - if (arg[1] == '-') { - /* Long option */ - result = parse_long_option(arg + 2, next_arg, opaque); - if (!result) return 0; - i += result; - } else { - /* Sequence of short options */ - size_t pos; - for (pos = 1; arg[pos]; pos++) { - char *next = (arg[pos+1]) ? arg + pos+1 : next_arg; - result = parse_short_option(arg[pos], next, opaque); - if (!result) return 0; - if (result == 2) { - i++; - break; - } - } - i++; - } - } else { - /* Argument */ - result = parse_argument(regular_args++, arg, 0, opaque); - if (!result) return 0; - i++; - } - } + if (arg[1] == '-') { + /* Long option */ + result = parse_long_option(arg + 2, next_arg, opaque); + if (!result) return 0; + i += result; + } else { + /* Sequence of short options */ + size_t pos; + for (pos = 1; arg[pos]; pos++) { + char *next = (arg[pos+1]) ? arg + pos+1 : next_arg; + result = parse_short_option(arg[pos], next, opaque); + if (!result) return 0; + if (result == 2) { + i++; + break; + } + } + i++; + } + } else { + /* Argument */ + result = parse_argument(regular_args++, arg, 0, opaque); + if (!result) return 0; + i++; + } + } - /* Parse rest as forced arguments */ - while (i < argc) { - result = parse_argument(regular_args++, argv[i], 1, opaque); - if (!result) return 0; - i++; - } + /* Parse rest as forced arguments */ + while (i < argc) { + result = parse_argument(regular_args++, argv[i], 1, opaque); + if (!result) return 0; + i++; + } - return 1; + return 1; } diff --git a/bin/hoedown.c b/bin/hoedown.c index 5aac21a..99bb50e 100644 --- a/bin/hoedown.c +++ b/bin/hoedown.c @@ -1,67 +1,93 @@ +#if __STDC_VERSION__ >= 199901L +#define _XOPEN_SOURCE 600 +#else +#define _XOPEN_SOURCE 500 +#endif /* __STDC_VERSION__ */ + #include "document.h" #include "html.h" #include "common.h" -/*#include */ +#include "noop.h" + +#include /* FEATURES INFO / DEFAULTS */ enum renderer_type { - RENDERER_HTML, - RENDERER_HTML_TOC + RENDERER_HTML, + RENDERER_NOOP }; -struct extension_category_info { - unsigned int flags; - const char *option_name; - const char *label; +struct preset_info { + hoedown_features flags; + const char *option_name; + const char *label; + const char *description; }; -struct extension_info { - unsigned int flag; - const char *option_name; - const char *description; +struct feature_category_info { + hoedown_features flags; + const char *option_name; + const char *label; }; -struct html_flag_info { - unsigned int flag; - const char *option_name; - const char *description; +struct feature_info { + hoedown_features flag; + const char *option_name; + const char *description; }; -static struct extension_category_info categories_info[] = { - {HOEDOWN_EXT_BLOCK, "block", "Block extensions"}, - {HOEDOWN_EXT_SPAN, "span", "Span extensions"}, - {HOEDOWN_EXT_FLAGS, "flags", "Other flags"}, - {HOEDOWN_EXT_NEGATIVE, "negative", "Negative flags"}, +static struct preset_info presets_info[] = { + {HOEDOWN_FT_COMMONMARK, "stmd", "CommonMark", "Parse standard CommonMark. The default."}, + {HOEDOWN_FT_MARKDOWN, "markdown", "Markdown", "Parse classic Markdown."}, + {0, "none", "None", "Start with all flags disabled."}, }; -static struct extension_info extensions_info[] = { - {HOEDOWN_EXT_TABLES, "tables", "Parse PHP-Markdown style tables."}, - {HOEDOWN_EXT_FENCED_CODE, "fenced-code", "Parse fenced code blocks."}, - {HOEDOWN_EXT_FOOTNOTES, "footnotes", "Parse footnotes."}, - - {HOEDOWN_EXT_AUTOLINK, "autolink", "Automatically turn safe URLs into links."}, - {HOEDOWN_EXT_STRIKETHROUGH, "strikethrough", "Parse ~~stikethrough~~ spans."}, - {HOEDOWN_EXT_UNDERLINE, "underline", "Parse _underline_ instead of emphasis."}, - {HOEDOWN_EXT_HIGHLIGHT, "highlight", "Parse ==highlight== spans."}, - {HOEDOWN_EXT_QUOTE, "quote", "Render \"quotes\" as quotes."}, - {HOEDOWN_EXT_SUPERSCRIPT, "superscript", "Parse super^script."}, - {HOEDOWN_EXT_MATH, "math", "Parse TeX $$math$$ syntax, Kramdown style."}, - - {HOEDOWN_EXT_NO_INTRA_EMPHASIS, "disable-intra-emphasis", "Disable emphasis_between_words."}, - {HOEDOWN_EXT_SPACE_HEADERS, "space-headers", "Require a space after '#' in headers."}, - {HOEDOWN_EXT_MATH_EXPLICIT, "math-explicit", "Instead of guessing by context, parse $inline math$ and $$always block math$$ (requires --math)."}, - - {HOEDOWN_EXT_DISABLE_INDENTED_CODE, "disable-indented-code", "Don't parse indented code blocks."}, +static struct feature_category_info categories_info[] = { + {HOEDOWN_FT_BLOCK, "block", "Block construct features"}, + {HOEDOWN_FT_INLINE, "inline", "Inline construct features"}, + {HOEDOWN_FT_OTHER, "other", "Other features"}, + {HOEDOWN_FT_FLAGS, "flags", "Feature flags"}, }; -static struct html_flag_info html_flags_info[] = { - {HOEDOWN_HTML_SKIP_HTML, "skip-html", "Strip all HTML tags."}, - {HOEDOWN_HTML_ESCAPE, "escape", "Escape all HTML."}, - {HOEDOWN_HTML_HARD_WRAP, "hard-wrap", "Render each linebreak as
."}, - {HOEDOWN_HTML_USE_XHTML, "xhtml", "Render XHTML."}, +static struct feature_info features_info[] = { + {HOEDOWN_FT_DIRECTIVE, "directive", "Parse generic directive syntax."}, + {HOEDOWN_FT_INDENTED_CODE_BLOCK, "indented-code-block", "Parse indented code blocks."}, + {HOEDOWN_FT_FENCED_CODE_BLOCK, "fenced-code-block", "Parse fenced code blocks."}, + {HOEDOWN_FT_HORIZONTAL_RULE, "horizontal-rule", "Parse horizontal rules."}, + {HOEDOWN_FT_ATX_HEADER, "atx-header", "Parse ATX headers."}, + {HOEDOWN_FT_SETEXT_HEADER, "setext-header", "Parse Setext headers"}, + {HOEDOWN_FT_LIST, "list", "Parse bullet and numbered lists."}, + {HOEDOWN_FT_QUOTE_BLOCK, "quote-block", "Parse email-style quote blocks."}, + {HOEDOWN_FT_HTML_BLOCK, "html-block", "Parse raw HTML blocks."}, + {HOEDOWN_FT_TABLE, "table", "Parse Kramdown style tables."}, + + {HOEDOWN_FT_ROLE, "role", "Parse generic role syntax."}, + {HOEDOWN_FT_ESCAPE, "escape", "Parse backslash escapes."}, + {HOEDOWN_FT_HARD_LINEBREAK, "hard-linebreak", "Parse backslash linebreaks."}, + {HOEDOWN_FT_LINEBREAK, "linebreak", "Parse two-space linebreaks."}, + {HOEDOWN_FT_SOFT_LINEBREAK, "soft-linebreak", "Parse newlines as linebreaks."}, + {HOEDOWN_FT_URI_AUTOLINK, "uri-autolink", "Parse URI autolinks between angle brackets."}, + {HOEDOWN_FT_EMAIL_AUTOLINK, "email-autolink", "Parse email autolinks between angle brackets."}, + {HOEDOWN_FT_HTML, "html", "Parse inline HTML."}, + {HOEDOWN_FT_ENTITY, "entity", "Parse HTML entities."}, + {HOEDOWN_FT_CODE_SPAN, "code-span", "Parse code spans between backticks."}, + {HOEDOWN_FT_EMPHASIS, "emphasis", "Parse emphasis and strong emphasis."}, + {HOEDOWN_FT_LINK, "link", "Parse links and link references."}, + {HOEDOWN_FT_MATH, "math", "Parse Kramdown-style math spans."}, + {HOEDOWN_FT_SUPERSCRIPT, "superscript", "Parse superscript spans."}, + {HOEDOWN_FT_QUOTE, "quote", "Parse quote-delimited spans."}, + {HOEDOWN_FT_STRIKETHROUGH, "strikethrough", "Parse strikethrough spans."}, + {HOEDOWN_FT_HIGHLIGHT, "highlight", "Parse highlight spans."}, + {HOEDOWN_FT_FOOTNOTE, "footnote", "Parse footnotes and footnote references."}, + + {HOEDOWN_FT_PREPROCESS, "preprocess", "Preprocess the input. Hoedown can give bad results if input is not preprocessed."}, + + {HOEDOWN_FT_LINK_IMAGE, "link-image", "Allow links preceded by a bang to be rendered as images."}, + {HOEDOWN_FT_INTRA_EMPHASIS, "intra-emphasis", "Requires --emphasis. Allow underscores between words to be parsed as emphasis."}, + {HOEDOWN_FT_MATH_EXPLICIT, "math-explicit", "Requires --math. Enables parsing $...$ as inline math and restricts $$...$$ to block math."}, }; static const char *category_prefix = "all-"; @@ -74,386 +100,383 @@ static const char *negative_prefix = "no-"; /* PRINT HELP */ -void -print_help(const char *basename) -{ - size_t i; - size_t e; +static void print_feature_option(struct feature_info *feature) { + size_t i; - /* usage */ - printf("Usage: %s [OPTION]... [FILE]\n\n", basename); + /* prepare the description */ + char *desc = malloc(strlen(feature->description)+40); + memcpy(desc, feature->description, strlen(feature->description)+1); - /* description */ - printf("Process the Markdown in FILE (or standard input) and render it to standard output, using the Hoedown library. " - "Parsing and rendering can be customized through the options below. The default is to parse pure markdown and output HTML.\n\n"); + /* add tags to the description */ + for (i = 0; i < count_of(presets_info); i++) + if (feature->flag & presets_info[i].flags) { + strcat(desc, " ["); + strcat(desc, presets_info[i].label); + strcat(desc, "]"); + } - /* main options */ - printf("Main options:\n"); - print_option('n', "max-nesting=N", "Maximum level of block nesting parsed. Default is " str(DEF_MAX_NESTING) "."); - print_option('t', "toc-level=N", "Maximum level for headers included in the TOC. Zero disables TOC (the default)."); - print_option( 0, "html", "Render (X)HTML. The default."); - print_option( 0, "html-toc", "Render the Table of Contents in (X)HTML."); - print_option('T', "time", "Show time spent in rendering."); - print_option('i', "input-unit=N", "Reading block size. Default is " str(DEF_IUNIT) "."); - print_option('o', "output-unit=N", "Writing block size. Default is " str(DEF_OUNIT) "."); - print_option('h', "help", "Print this help text."); - print_option('v', "version", "Print Hoedown version."); - printf("\n"); + /* print feature option */ + print_option( 0, feature->option_name, desc); +} - /* extensions */ - for (i = 0; i < count_of(categories_info); i++) { - struct extension_category_info *category = categories_info+i; - printf("%s (--%s%s):\n", category->label, category_prefix, category->option_name); - for (e = 0; e < count_of(extensions_info); e++) { - struct extension_info *extension = extensions_info+e; - if (extension->flag & category->flags) { - print_option( 0, extension->option_name, extension->description); - } - } - printf("\n"); - } +static void print_help(const char *basename) { + size_t i, e; - /* html-specific */ - printf("HTML-specific options:\n"); - for (i = 0; i < count_of(html_flags_info); i++) { - struct html_flag_info *html_flag = html_flags_info+i; - print_option( 0, html_flag->option_name, html_flag->description); - } - printf("\n"); + /* usage */ + printf("Usage: %s [OPTION]... [FILE]\n\n", basename); - /* ending */ - printf("Flags and extensions can be negated by prepending 'no' to them, as in '--no-tables', '--no-span' or '--no-escape'. " - "Options are processed in order, so in case of contradictory options the last specified stands.\n\n"); + /* description */ + printf("Process the Markdown in FILE (or standard input) and render it to standard output, using the Hoedown library. " + "Parsing and rendering can be customized through the options below. The default is to parse pure CommonMark and output HTML.\n\n"); - printf("When FILE is '-', read standard input. If no FILE was given, read standard input. Use '--' to signal end of option parsing. " - "Exit status is 0 if no errors occurred, 1 with option parsing errors, 4 with memory allocation errors or 5 with I/O errors.\n\n"); + /* main options */ + printf("Main options:\n"); + print_option('n', "max-nesting=N", "Maximum level of block nesting parsed. Default is " str(DEF_MAX_NESTING) "."); + print_option( 0, "html", "Render (X)HTML. The default."); + print_option( 0, "noop", "Use a special renderer whose callbacks do nothing."); + print_option('T', "time", "Show time spent in rendering."); + print_option('i', "input-unit=N", "Reading block size. Default is " str(DEF_IUNIT) "."); + print_option('o', "output-unit=N", "Writing block size. Default is " str(DEF_OUNIT) "."); + print_option( 0, "block", "Parse block-level Markdown. The default."); + print_option( 0, "inline", "Parse inline-level Markdown."); + print_option('h', "help", "Print this help text."); + print_option('v', "version", "Print Hoedown version."); + printf("\n"); + + /* base presets */ + printf("Base presets:\n"); + for (i = 0; i < count_of(presets_info); i++) { + struct preset_info *preset = &presets_info[i]; + print_option( 0, preset->option_name, preset->description); + } + printf("\n"); + + /* features */ + for (i = 0; i < count_of(categories_info); i++) { + struct feature_category_info *category = &categories_info[i]; + printf("%s (--%s%s):\n", category->label, category_prefix, category->option_name); + for (e = 0; e < count_of(features_info); e++) { + struct feature_info *feature = &features_info[e]; + if (feature->flag & category->flags) + print_feature_option(feature); + } + printf("\n"); + } + + /* ending */ + printf("Feature flags can be negated by prepending 'no' to them, as in '--no-table', '--no-flags' or '--no-escape'. " + "Base presets override any flag given previously. Options are processed in order, so in case of contradictory options the last specified stands.\n\n"); + + printf("When FILE is '-', read standard input. If no FILE was given, read standard input. Use '--' to signal end of option parsing. " + "Exit status is 0 if no errors occured, 1 with option parsing errors, 4 with memory allocation errors or 5 with I/O errors.\n\n"); } /* OPTION PARSING */ struct option_data { - char *basename; - int done; + char *basename; + int done; - /* time reporting */ - int show_time; + /* time reporting */ + int show_time; - /* I/O */ - size_t iunit; - size_t ounit; - const char *filename; + /* I/O */ + size_t iunit; + size_t ounit; + const char *filename; - /* renderer */ - enum renderer_type renderer; - int toc_level; - hoedown_html_flags html_flags; + /* renderer */ + enum renderer_type renderer; - /* parsing */ - hoedown_extensions extensions; - size_t max_nesting; + /* parsing */ + int is_inline; + hoedown_features features; + size_t max_nesting; }; -int -parse_short_option(char opt, char *next, void *opaque) -{ - struct option_data *data = opaque; - long int num; - int isNum = next ? parseint(next, &num) : 0; +static int parse_short_option(char opt, char *next, void *opaque) { + struct option_data *data = opaque; + long int num; + int isNum = next ? parseint(next, &num) : 0; - if (opt == 'h') { - print_help(data->basename); - data->done = 1; - return 0; - } + if (opt == 'h') { + print_help(data->basename); + data->done = 1; + return 0; + } - if (opt == 'v') { - print_version(); - data->done = 1; - return 0; - } + if (opt == 'v') { + print_version(); + data->done = 1; + return 0; + } - if (opt == 'T') { - data->show_time = 1; - return 1; - } + if (opt == 'T') { + data->show_time = 1; + return 1; + } - /* options requiring value */ - /* FIXME: add validation */ + /* options requiring value */ + /* FIXME: add validation */ - if (opt == 'n' && isNum) { - data->max_nesting = num; - return 2; - } + if (opt == 'n' && isNum) { + data->max_nesting = num; + return 2; + } - if (opt == 't' && isNum) { - data->toc_level = num; - return 2; - } + if (opt == 'i' && isNum) { + data->iunit = num; + return 2; + } - if (opt == 'i' && isNum) { - data->iunit = num; - return 2; - } + if (opt == 'o' && isNum) { + data->ounit = num; + return 2; + } - if (opt == 'o' && isNum) { - data->ounit = num; - return 2; - } - - fprintf(stderr, "Wrong option '-%c' found.\n", opt); - return 0; + fprintf(stderr, "Wrong option '-%c' found.\n", opt); + return 0; } -int -parse_category_option(char *opt, struct option_data *data) -{ - size_t i; - const char *name = strprefix(opt, category_prefix); - if (!name) return 0; +static int parse_preset_option(char *opt, struct option_data *data) { + size_t i; - for (i = 0; i < count_of(categories_info); i++) { - struct extension_category_info *category = &categories_info[i]; - if (strcmp(name, category->option_name)==0) { - data->extensions |= category->flags; - return 1; - } - } + for (i = 0; i < count_of(presets_info); i++) { + struct preset_info *preset = &presets_info[i]; + if (strcmp(opt, preset->option_name)==0) { + data->features = preset->flags; + return 1; + } + } - return 0; + return 0; } -int -parse_flag_option(char *opt, struct option_data *data) -{ - size_t i; +static int parse_category_option(char *opt, struct option_data *data) { + size_t i; + const char *name = strprefix(opt, category_prefix); + if (!name) return 0; - for (i = 0; i < count_of(extensions_info); i++) { - struct extension_info *extension = &extensions_info[i]; - if (strcmp(opt, extension->option_name)==0) { - data->extensions |= extension->flag; - return 1; - } - } + for (i = 0; i < count_of(categories_info); i++) { + struct feature_category_info *category = &categories_info[i]; + if (strcmp(name, category->option_name)==0) { + data->features |= category->flags; + return 1; + } + } - for (i = 0; i < count_of(html_flags_info); i++) { - struct html_flag_info *html_flag = &html_flags_info[i]; - if (strcmp(opt, html_flag->option_name)==0) { - data->html_flags |= html_flag->flag; - return 1; - } - } - - return 0; + return 0; } -int -parse_negative_option(char *opt, struct option_data *data) -{ - size_t i; - const char *name = strprefix(opt, negative_prefix); - if (!name) return 0; +static int parse_flag_option(char *opt, struct option_data *data) { + size_t i; - for (i = 0; i < count_of(categories_info); i++) { - struct extension_category_info *category = &categories_info[i]; - if (strcmp(name, category->option_name)==0) { - data->extensions &= ~(category->flags); - return 1; - } - } + for (i = 0; i < count_of(features_info); i++) { + struct feature_info *feature = &features_info[i]; + if (strcmp(opt, feature->option_name)==0) { + data->features |= feature->flag; + return 1; + } + } - for (i = 0; i < count_of(extensions_info); i++) { - struct extension_info *extension = &extensions_info[i]; - if (strcmp(name, extension->option_name)==0) { - data->extensions &= ~(extension->flag); - return 1; - } - } - - for (i = 0; i < count_of(html_flags_info); i++) { - struct html_flag_info *html_flag = &html_flags_info[i]; - if (strcmp(name, html_flag->option_name)==0) { - data->html_flags &= ~(html_flag->flag); - return 1; - } - } - - return 0; + return 0; } -int -parse_long_option(char *opt, char *next, void *opaque) -{ - struct option_data *data = opaque; - long int num; - int isNum = next ? parseint(next, &num) : 0; +static int parse_negative_option(char *opt, struct option_data *data) { + size_t i; + const char *name = strprefix(opt, negative_prefix); + if (!name) return 0; - if (strcmp(opt, "help")==0) { - print_help(data->basename); - data->done = 1; - return 0; - } + for (i = 0; i < count_of(categories_info); i++) { + struct feature_category_info *category = &categories_info[i]; + if (strcmp(name, category->option_name)==0) { + data->features &= ~(category->flags); + return 1; + } + } - if (strcmp(opt, "version")==0) { - print_version(); - data->done = 1; - return 0; - } + for (i = 0; i < count_of(features_info); i++) { + struct feature_info *feature = &features_info[i]; + if (strcmp(name, feature->option_name)==0) { + data->features &= ~(feature->flag); + return 1; + } + } - if (strcmp(opt, "time")==0) { - data->show_time = 1; - return 1; - } - - /* FIXME: validation */ - - if (strcmp(opt, "max-nesting")==0 && isNum) { - data->max_nesting = num; - return 2; - } - if (strcmp(opt, "toc-level")==0 && isNum) { - data->toc_level = num; - return 2; - } - if (strcmp(opt, "input-unit")==0 && isNum) { - data->iunit = num; - return 2; - } - if (strcmp(opt, "output-unit")==0 && isNum) { - data->ounit = num; - return 2; - } - - if (strcmp(opt, "html")==0) { - data->renderer = RENDERER_HTML; - return 1; - } - if (strcmp(opt, "html-toc")==0) { - data->renderer = RENDERER_HTML_TOC; - return 1; - } - - if (parse_category_option(opt, data) || parse_flag_option(opt, data) || parse_negative_option(opt, data)) - return 1; - - fprintf(stderr, "Wrong option '--%s' found.\n", opt); - return 0; + return 0; } -int -parse_argument(int argn, char *arg, int is_forced, void *opaque) -{ - struct option_data *data = opaque; +static int parse_long_option(char *opt, char *next, void *opaque) { + struct option_data *data = opaque; + long int num; + int isNum = next ? parseint(next, &num) : 0; - if (argn == 0) { - /* Input file */ - if (strcmp(arg, "-")!=0 || is_forced) data->filename = arg; - return 1; - } + if (strcmp(opt, "help")==0) { + print_help(data->basename); + data->done = 1; + return 0; + } - fprintf(stderr, "Too many arguments.\n"); - return 0; + if (strcmp(opt, "version")==0) { + print_version(); + data->done = 1; + return 0; + } + + if (strcmp(opt, "time")==0) { + data->show_time = 1; + return 1; + } + + if (strcmp(opt, "block")==0) { + data->is_inline = 0; + return 1; + } + + if (strcmp(opt, "inline")==0) { + data->is_inline = 1; + return 1; + } + + /* FIXME: validation */ + + if (strcmp(opt, "max-nesting")==0 && isNum) { + data->max_nesting = num; + return 2; + } + if (strcmp(opt, "input-unit")==0 && isNum) { + data->iunit = num; + return 2; + } + if (strcmp(opt, "output-unit")==0 && isNum) { + data->ounit = num; + return 2; + } + + if (strcmp(opt, "html")==0) { + data->renderer = RENDERER_HTML; + return 1; + } + if (strcmp(opt, "noop")==0) { + data->renderer = RENDERER_NOOP; + return 1; + } + + if (parse_preset_option(opt, data) || parse_category_option(opt, data) || parse_flag_option(opt, data) || parse_negative_option(opt, data)) + return 1; + + fprintf(stderr, "Wrong option '--%s' found.\n", opt); + return 0; +} + +static int parse_argument(int argn, char *arg, int is_forced, void *opaque) { + struct option_data *data = opaque; + + if (argn == 0) { + /* Input file */ + if (strcmp(arg, "-")!=0 || is_forced) data->filename = arg; + return 1; + } + + fprintf(stderr, "Too many arguments.\n"); + return 0; } /* MAIN LOGIC */ -int -main(int argc, char **argv) -{ - struct option_data data; - /*struct timespec start, end;*/ - FILE *file = stdin; - hoedown_buffer *ib, *ob; - hoedown_renderer *renderer = NULL; - void (*renderer_free)(hoedown_renderer *) = NULL; - hoedown_document *document; +int main(int argc, char **argv) { + struct option_data data; + struct timespec start, end; + FILE *file = stdin; + hoedown_buffer *ib, *ob; + hoedown_renderer *renderer = NULL; + void (*renderer_free)(hoedown_renderer *) = NULL; + hoedown_document *document; - /* Parse options */ - data.basename = argv[0]; - data.done = 0; - data.show_time = 0; - data.iunit = DEF_IUNIT; - data.ounit = DEF_OUNIT; - data.filename = NULL; - data.renderer = RENDERER_HTML; - data.toc_level = 0; - data.html_flags = 0; - data.extensions = 0; - data.max_nesting = DEF_MAX_NESTING; + /* Parse options */ + data.basename = argv[0]; + data.done = 0; + data.show_time = 0; + data.iunit = DEF_IUNIT; + data.ounit = DEF_OUNIT; + data.filename = NULL; + data.renderer = RENDERER_HTML; + data.is_inline = 0; + data.max_nesting = DEF_MAX_NESTING; + data.features = presets_info[0].flags; - argc = parse_options(argc, argv, parse_short_option, parse_long_option, parse_argument, &data); - if (data.done) return 0; - if (!argc) return 1; + argc = parse_options(argc, argv, parse_short_option, parse_long_option, parse_argument, &data); + if (data.done) return 0; + if (!argc) return 1; - /* Open input file, if needed */ - if (data.filename) { - file = fopen(data.filename, "r"); - if (!file) { - fprintf(stderr, "Unable to open input file \"%s\": %s\n", data.filename, strerror(errno)); - return 5; - } - } + /* Open input file, if needed */ + if (data.filename) { + file = fopen(data.filename, "r"); + if (!file) { + fprintf(stderr, "Unable to open input file \"%s\": %s\n", data.filename, strerror(errno)); + return 5; + } + } - /* Read everything */ - ib = hoedown_buffer_new(data.iunit); + /* Read everything */ + ib = hoedown_buffer_new(data.iunit); - while (!feof(file)) { - if (ferror(file)) { - fprintf(stderr, "I/O errors found while reading input.\n"); - return 5; - } - hoedown_buffer_grow(ib, ib->size + data.iunit); - ib->size += fread(ib->data + ib->size, 1, data.iunit, file); - } + while (!feof(file)) { + if (ferror(file)) { + fprintf(stderr, "I/O errors found while reading input.\n"); + return 5; + } + hoedown_buffer_grow(ib, ib->size + data.iunit); + ib->size += fread(ib->data + ib->size, 1, data.iunit, file); + } - if (file != stdin) fclose(file); + if (file != stdin) fclose(file); - /* Create the renderer */ - switch (data.renderer) { - case RENDERER_HTML: - renderer = hoedown_html_renderer_new(data.html_flags, data.toc_level); - renderer_free = hoedown_html_renderer_free; - break; - case RENDERER_HTML_TOC: - renderer = hoedown_html_toc_renderer_new(data.toc_level); - renderer_free = hoedown_html_renderer_free; - break; - }; + /* Create the renderer */ + switch (data.renderer) { + case RENDERER_HTML: + renderer = hoedown_html_renderer_new(); + renderer_free = hoedown_html_renderer_free; + break; + case RENDERER_NOOP: + renderer = hoedown_noop_renderer_new(); + renderer_free = hoedown_noop_renderer_free; + break; + }; - /* Perform Markdown rendering */ - ob = hoedown_buffer_new(data.ounit); - document = hoedown_document_new(renderer, data.extensions, data.max_nesting); + /* Perform Markdown rendering */ + ob = hoedown_buffer_new(data.ounit); + document = hoedown_document_new(renderer, data.features, data.max_nesting); - /*clock_gettime(CLOCK_MONOTONIC, &start);*/ - hoedown_document_render(document, ob, ib->data, ib->size); - /*clock_gettime(CLOCK_MONOTONIC, &end);*/ + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); + hoedown_document_render(document, ob, ib->data, ib->size, data.is_inline); + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end); - /* Write the result to stdout */ - (void)fwrite(ob->data, 1, ob->size, stdout); + /* Write the result to stdout */ + (void)fwrite(ob->data, 1, ob->size, stdout); - /* Show rendering time */ - if (data.show_time) { - /*TODO: enable this - long long elapsed = (end.tv_sec - start.tv_sec)*1e9 + (end.tv_nsec - start.tv_nsec); - if (elapsed < 1e9) - fprintf(stderr, "Time spent on rendering: %.2f ms.\n", ((double)elapsed)/1e6); - else - fprintf(stderr, "Time spent on rendering: %.3f s.\n", ((double)elapsed)/1e9); - */ - } + /* Show rendering time */ + if (data.show_time) { + long long elapsed = (end.tv_sec - start.tv_sec)*1e9 + (end.tv_nsec - start.tv_nsec); + if (elapsed < 1e9) + fprintf(stderr, "Time spent on rendering: %.2f ms.\n", ((double)elapsed)/1e6); + else + fprintf(stderr, "Time spent on rendering: %.3f s.\n", ((double)elapsed)/1e9); + } - /* Cleanup */ - hoedown_buffer_free(ib); - hoedown_buffer_free(ob); + /* Cleanup */ + hoedown_buffer_free(ib); + hoedown_buffer_free(ob); - hoedown_document_free(document); - renderer_free(renderer); + hoedown_document_free(document); + renderer_free(renderer); - if (ferror(stdout)) { - fprintf(stderr, "I/O errors found while writing output.\n"); - return 5; - } + if (ferror(stdout)) { + fprintf(stderr, "I/O errors found while writing output.\n"); + return 5; + } - return 0; + return 0; } diff --git a/bin/noop.c b/bin/noop.c new file mode 100644 index 0000000..3425881 --- /dev/null +++ b/bin/noop.c @@ -0,0 +1,82 @@ +#include "noop.h" + +#include + +/* Block constructs */ +static void rndr_paragraph(void *target, void *content, int is_tight, const hoedown_renderer_data *data) {} +static void rndr_indented_code_block(void *target, const hoedown_buffer *code, const hoedown_renderer_data *data) {} +static void rndr_fenced_code_block(void *target, const hoedown_buffer *code, const hoedown_buffer *info, const hoedown_renderer_data *data) {} +static void rndr_horizontal_rule(void *target, const hoedown_renderer_data *data) {} +static void rndr_atx_header(void *target, void *content, size_t level, const hoedown_renderer_data *data) {} +static void rndr_setext_header(void *target, void *content, int is_double, const hoedown_renderer_data *data) {} +static void rndr_list(void *target, void *content, int is_ordered, int is_tight, int start, const hoedown_renderer_data *data) {} +static void rndr_list_item(void *target, void *content, int is_ordered, int is_tight, const hoedown_renderer_data *data) {} +static void rndr_quote_block(void *target, void *content, const hoedown_renderer_data *data) {} +static void rndr_html_block(void *target, const hoedown_buffer *html, const hoedown_renderer_data *data) {} + +/* Inline constructs */ +static void rndr_string(void *target, const hoedown_buffer *text, const hoedown_renderer_data *data) {} +static void rndr_escape(void *target, uint8_t character, const hoedown_renderer_data *data) {} +static void rndr_hard_linebreak(void *target, const hoedown_renderer_data *data) {} +static void rndr_linebreak(void *target, const hoedown_renderer_data *data) {} +static void rndr_uri_autolink(void *target, const hoedown_buffer *uri, const hoedown_renderer_data *data) {} +static void rndr_email_autolink(void *target, const hoedown_buffer *email, const hoedown_renderer_data *data) {} +static void rndr_html(void *target, const hoedown_buffer *html, const hoedown_renderer_data *data) {} +static void rndr_entity(void *target, const hoedown_buffer *character, const hoedown_renderer_data *data) {} +static void rndr_code_span(void *target, const hoedown_buffer *code, const hoedown_renderer_data *data) {} +static void rndr_emphasis(void *target, void *content, size_t level, const hoedown_renderer_data *data) {} +static void rndr_link(void *target, void *content, const hoedown_buffer *dest, const hoedown_buffer *title, int is_image, const hoedown_renderer_data *data) {} + +/* Global callbacks */ +static void *object_get(int is_inline, const hoedown_renderer_data *data) { return NULL; } +static void object_merge(void *target, void *content, int is_inline, const hoedown_renderer_data *data) {} +static void object_pop(void *target, int is_inline, const hoedown_renderer_data *data) {} + +static void render_start(void *output, int is_inline, const hoedown_renderer_data *data) {} +static void render_end(void *output, void *target, int is_inline, const hoedown_renderer_data *data) {} + + +/* Exported API */ +hoedown_renderer *hoedown_noop_renderer_new() { + static const hoedown_renderer temp = { + NULL, + + rndr_paragraph, + rndr_indented_code_block, + rndr_fenced_code_block, + rndr_horizontal_rule, + rndr_atx_header, + rndr_setext_header, + rndr_list, + rndr_list_item, + rndr_quote_block, + rndr_html_block, + + rndr_string, + rndr_escape, + rndr_hard_linebreak, + rndr_linebreak, + rndr_uri_autolink, + rndr_email_autolink, + rndr_html, + rndr_entity, + rndr_code_span, + rndr_emphasis, + rndr_link, + + object_get, + object_merge, + object_pop, + + render_start, + render_end, + }; + + hoedown_renderer *rndr = hoedown_malloc(sizeof(hoedown_renderer)); + memcpy(rndr, &temp, sizeof(hoedown_renderer)); + return rndr; +} + +void hoedown_noop_renderer_free(hoedown_renderer *rndr) { + free(rndr); +} diff --git a/bin/noop.h b/bin/noop.h new file mode 100644 index 0000000..b8826b5 --- /dev/null +++ b/bin/noop.h @@ -0,0 +1,28 @@ +/* noop.h - dumb no-op renderer */ + +#ifndef HOEDOWN_NOOP_H +#define HOEDOWN_NOOP_H + +#include "document.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/************* + * FUNCTIONS * + *************/ + +/* hoedown_noop_renderer_new: allocate a new no-op renderer */ +hoedown_renderer *hoedown_noop_renderer_new() __attribute__((malloc)); + +/* hoedown_noop_renderer_free: deallocate a no-op renderer */ +void hoedown_noop_renderer_free(hoedown_renderer *rndr); + + +#ifdef __cplusplus +} +#endif + +#endif /** HOEDOWN_NOOP_H **/ diff --git a/bin/smartypants.c b/bin/smartypants.c deleted file mode 100644 index de0512e..0000000 --- a/bin/smartypants.c +++ /dev/null @@ -1,228 +0,0 @@ -#include "html.h" - -#include "common.h" -/*#include */ - - -/* FEATURES INFO / DEFAULTS */ - -#define DEF_IUNIT 1024 -#define DEF_OUNIT 64 - - -/* PRINT HELP */ - -void -print_help(const char *basename) -{ - /* usage */ - printf("Usage: %s [OPTION]... [FILE]\n\n", basename); - - /* description */ - printf("Apply SmartyPants smart punctuation to the HTML in FILE (or standard input), and output the resulting HTML to standard output.\n\n"); - - /* main options */ - printf("Main options:\n"); - print_option('T', "time", "Show time spent in SmartyPants processing."); - print_option('i', "input-unit=N", "Reading block size. Default is " str(DEF_IUNIT) "."); - print_option('o', "output-unit=N", "Writing block size. Default is " str(DEF_OUNIT) "."); - print_option('h', "help", "Print this help text."); - print_option('v', "version", "Print Hoedown version."); - printf("\n"); - - /* ending */ - printf("Options are processed in order, so in case of contradictory options the last specified stands.\n\n"); - - printf("When FILE is '-', read standard input. If no FILE was given, read standard input. Use '--' to signal end of option parsing. " - "Exit status is 0 if no errors occurred, 1 with option parsing errors, 4 with memory allocation errors or 5 with I/O errors.\n\n"); -} - - -/* OPTION PARSING */ - -struct option_data { - char *basename; - int done; - - /* time reporting */ - int show_time; - - /* I/O */ - size_t iunit; - size_t ounit; - const char *filename; -}; - -int -parse_short_option(char opt, char *next, void *opaque) -{ - struct option_data *data = opaque; - long int num; - int isNum = next ? parseint(next, &num) : 0; - - if (opt == 'h') { - print_help(data->basename); - data->done = 1; - return 0; - } - - if (opt == 'v') { - print_version(); - data->done = 1; - return 0; - } - - if (opt == 'T') { - data->show_time = 1; - return 1; - } - - /* options requiring value */ - /* FIXME: add validation */ - - if (opt == 'i' && isNum) { - data->iunit = num; - return 2; - } - - if (opt == 'o' && isNum) { - data->ounit = num; - return 2; - } - - fprintf(stderr, "Wrong option '-%c' found.\n", opt); - return 0; -} - -int -parse_long_option(char *opt, char *next, void *opaque) -{ - struct option_data *data = opaque; - long int num; - int isNum = next ? parseint(next, &num) : 0; - - if (strcmp(opt, "help")==0) { - print_help(data->basename); - data->done = 1; - return 0; - } - - if (strcmp(opt, "version")==0) { - print_version(); - data->done = 1; - return 0; - } - - if (strcmp(opt, "time")==0) { - data->show_time = 1; - return 1; - } - - /* FIXME: validation */ - - if (strcmp(opt, "input-unit")==0 && isNum) { - data->iunit = num; - return 2; - } - if (strcmp(opt, "output-unit")==0 && isNum) { - data->ounit = num; - return 2; - } - - fprintf(stderr, "Wrong option '--%s' found.\n", opt); - return 0; -} - -int -parse_argument(int argn, char *arg, int is_forced, void *opaque) -{ - struct option_data *data = opaque; - - if (argn == 0) { - /* Input file */ - if (strcmp(arg, "-")!=0 || is_forced) data->filename = arg; - return 1; - } - - fprintf(stderr, "Too many arguments.\n"); - return 0; -} - - -/* MAIN LOGIC */ - -int -main(int argc, char **argv) -{ - struct option_data data; - /*struct timespec start, end;*/ - FILE *file = stdin; - hoedown_buffer *ib, *ob; - - /* Parse options */ - data.basename = argv[0]; - data.done = 0; - data.show_time = 0; - data.iunit = DEF_IUNIT; - data.ounit = DEF_OUNIT; - data.filename = NULL; - - argc = parse_options(argc, argv, parse_short_option, parse_long_option, parse_argument, &data); - if (data.done) return 0; - if (!argc) return 1; - - /* Open input file, if needed */ - if (data.filename) { - file = fopen(data.filename, "r"); - if (!file) { - fprintf(stderr, "Unable to open input file \"%s\": %s\n", data.filename, strerror(errno)); - return 5; - } - } - - /* Read everything */ - ib = hoedown_buffer_new(data.iunit); - - while (!feof(file)) { - if (ferror(file)) { - fprintf(stderr, "I/O errors found while reading input.\n"); - return 5; - } - hoedown_buffer_grow(ib, ib->size + data.iunit); - ib->size += fread(ib->data + ib->size, 1, data.iunit, file); - } - - if (file != stdin) fclose(file); - - /* Perform SmartyPants processing */ - ob = hoedown_buffer_new(data.ounit); - - /*clock_gettime(CLOCK_MONOTONIC, &start);*/ - hoedown_html_smartypants(ob, ib->data, ib->size); - /*clock_gettime(CLOCK_MONOTONIC, &end);*/ - - /* Write the result to stdout */ - (void)fwrite(ob->data, 1, ob->size, stdout); - - /* Show rendering time */ - if (data.show_time) { - /*TODO: enable this - long long elapsed = (end.tv_sec - start.tv_sec)*1e9 + (end.tv_nsec - start.tv_nsec); - if (elapsed < 1e9) - fprintf(stderr, "Time spent on rendering: %.2f ms.\n", ((double)elapsed)/1e6); - else - fprintf(stderr, "Time spent on rendering: %.3f s.\n", ((double)elapsed)/1e9); - */ - } - - /* Cleanup */ - hoedown_buffer_free(ib); - hoedown_buffer_free(ob); - - if (ferror(stdout)) { - fprintf(stderr, "I/O errors found while writing output.\n"); - return 5; - } - - return 0; -} diff --git a/data/autolink_schemes.gperf b/data/autolink_schemes.gperf new file mode 100644 index 0000000..dbd1205 --- /dev/null +++ b/data/autolink_schemes.gperf @@ -0,0 +1,166 @@ +# Keep this updated with CommonMark spec +# +coap +doi +javascript +aaa +aaas +about +acap +cap +cid +crid +data +dav +dict +dns +file +ftp +geo +go +gopher +h323 +http +https +iax +icap +im +imap +info +ipp +iris +iris.beep +iris.xpc +iris.xpcs +iris.lwz +ldap +mailto +mid +msrp +msrps +mtqp +mupdate +news +nfs +ni +nih +nntp +opaquelocktoken +pop +pres +rtsp +service +session +shttp +sieve +sip +sips +sms +snmp +soap.beep +soap.beeps +tag +tel +telnet +tftp +thismessage +tn3270 +tip +tv +urn +vemmi +ws +wss +xcon +xcon-userid +xmlrpc.beep +xmlrpc.beeps +xmpp +z39.50r +z39.50s +adiumxtra +afp +afs +aim +apt +attachment +aw +beshare +bitcoin +bolo +callto +chrome +chrome-extension +com-eventbrite-attendee +content +cvs +dlna-playsingle +dlna-playcontainer +dtn +dvb +ed2k +facetime +feed +finger +fish +gg +git +gizmoproject +gtalk +hcp +icon +ipn +irc +irc6 +ircs +itms +jar +jms +keyparc +lastfm +ldaps +magnet +maps +market +message +mms +ms-help +msnim +mumble +mvn +notes +oid +palm +paparazzi +platform +proxy +psyc +query +res +resource +rmi +rsync +rtmp +secondlife +sftp +sgn +skype +smb +soldat +spotify +ssh +steam +svn +teamspeak +things +udp +unreal +ut2004 +ventrilo +view-source +webcal +wtai +wyciwyg +xfire +xri +ymsgr diff --git a/data/html_blocks.gperf b/data/html_blocks.gperf new file mode 100644 index 0000000..25c3ea4 --- /dev/null +++ b/data/html_blocks.gperf @@ -0,0 +1,52 @@ +# Keep this updated with CommonMark spec +# +article +header +aside +hgroup +blockquote +hr +iframe +body +li +map +button +object +canvas +ol +caption +output +col +p +colgroup +pre +dd +progress +div +section +dl +table +td +dt +tbody +embed +textarea +fieldset +tfoot +figcaption +th +figure +thead +footer +tr +form +ul +h1 +h2 +h3 +h4 +h5 +h6 +video +script +style diff --git a/hoedown.def b/hoedown.def deleted file mode 100644 index 3b2c69f..0000000 --- a/hoedown.def +++ /dev/null @@ -1,40 +0,0 @@ -LIBRARY HOEDOWN -EXPORTS - hoedown_autolink_is_safe - hoedown_autolink__www - hoedown_autolink__email - hoedown_autolink__url - hoedown_buffer_init - hoedown_buffer_new - hoedown_buffer_reset - hoedown_buffer_grow - hoedown_buffer_put - hoedown_buffer_puts - hoedown_buffer_putc - hoedown_buffer_set - hoedown_buffer_sets - hoedown_buffer_eq - hoedown_buffer_eqs - hoedown_buffer_prefix - hoedown_buffer_slurp - hoedown_buffer_cstr - hoedown_buffer_printf - hoedown_buffer_free - hoedown_document_new - hoedown_document_render - hoedown_document_render_inline - hoedown_document_free - hoedown_escape_href - hoedown_escape_html - hoedown_html_smartypants - hoedown_html_is_tag - hoedown_html_renderer_new - hoedown_html_toc_renderer_new - hoedown_html_renderer_free - hoedown_stack_init - hoedown_stack_uninit - hoedown_stack_grow - hoedown_stack_push - hoedown_stack_pop - hoedown_stack_top - hoedown_version diff --git a/html_block_names.gperf b/html_block_names.gperf deleted file mode 100644 index a316d5c..0000000 --- a/html_block_names.gperf +++ /dev/null @@ -1,24 +0,0 @@ -p -dl -h1 -h2 -h3 -h4 -h5 -h6 -ol -ul -del -div -ins -pre -form -math -style -table -figure -iframe -script -fieldset -noscript -blockquote diff --git a/src/_autolink_schemes.c b/src/_autolink_schemes.c new file mode 100644 index 0000000..12d9621 --- /dev/null +++ b/src/_autolink_schemes.c @@ -0,0 +1,1319 @@ +/* ANSI-C code produced by gperf version 3.0.4 */ +/* Command-line: gperf -L ANSI-C -N hoedown_find_autolink_scheme -l -c -C -E -S 1 --ignore-case -m100 data/autolink_schemes.gperf */ +/* Computed positions: -k'1-3,$' */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#endif + +/* maximum key range = 274, duplicates = 0 */ + +#ifndef GPERF_DOWNCASE +#define GPERF_DOWNCASE 1 +static unsigned char gperf_downcase[256] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255 + }; +#endif + +#ifndef GPERF_CASE_MEMCMP +#define GPERF_CASE_MEMCMP 1 +static int +gperf_case_memcmp (register const char *s1, register const char *s2, register unsigned int n) +{ + for (; n > 0;) + { + unsigned char c1 = gperf_downcase[(unsigned char)*s1++]; + unsigned char c2 = gperf_downcase[(unsigned char)*s2++]; + if (c1 == c2) + { + n--; + continue; + } + return (int)c1 - (int)c2; + } + return 0; +} +#endif + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +hash (register const char *str, register unsigned int len) +{ + static const unsigned short asso_values[] = + { + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 7, 296, 296, 12, 296, + 29, 6, 7, 296, 11, 296, 296, 6, 296, 296, + 296, 296, 296, 296, 296, 13, 68, 37, 41, 31, + 96, 45, 108, 12, 27, 27, 73, 9, 64, 59, + 9, 6, 22, 6, 29, 93, 93, 8, 90, 142, + 28, 296, 296, 296, 296, 296, 296, 13, 68, 37, + 41, 31, 96, 45, 108, 12, 27, 27, 73, 9, + 64, 59, 9, 6, 22, 6, 29, 93, 93, 8, + 90, 142, 28, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296 + }; + register int hval = len; + + switch (hval) + { + default: + hval += asso_values[(unsigned char)str[2]]; + /*FALLTHROUGH*/ + case 2: + hval += asso_values[(unsigned char)str[1]]; + /*FALLTHROUGH*/ + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return hval + asso_values[(unsigned char)str[len - 1]]; +} + +#ifdef __GNUC__ +__inline +#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__ +__attribute__ ((__gnu_inline__)) +#endif +#endif +const char * +hoedown_find_autolink_scheme (register const char *str, register unsigned int len) +{ + enum + { + TOTAL_KEYWORDS = 164, + MIN_WORD_LENGTH = 2, + MAX_WORD_LENGTH = 23, + MIN_HASH_VALUE = 22, + MAX_HASH_VALUE = 295 + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE) + { + register const char *resword; + + switch (key - 22) + { + case 0: + if (len == 2) + { + resword = "ws"; + goto compare; + } + break; + case 7: + if (len == 3) + { + resword = "wss"; + goto compare; + } + break; + case 8: + if (len == 3) + { + resword = "sms"; + goto compare; + } + break; + case 9: + if (len == 2) + { + resword = "aw"; + goto compare; + } + break; + case 10: + if (len == 2) + { + resword = "im"; + goto compare; + } + break; + case 11: + if (len == 3) + { + resword = "mms"; + goto compare; + } + break; + case 15: + if (len == 4) + { + resword = "sips"; + goto compare; + } + break; + case 16: + if (len == 7) + { + resword = "ms-help"; + goto compare; + } + break; + case 17: + if (len == 3) + { + resword = "sip"; + goto compare; + } + break; + case 19: + if (len == 4) + { + resword = "maps"; + goto compare; + } + break; + case 20: + if (len == 3) + { + resword = "ipp"; + goto compare; + } + break; + case 24: + if (len == 3) + { + resword = "aim"; + goto compare; + } + break; + case 25: + if (len == 4) + { + resword = "imap"; + goto compare; + } + break; + case 26: + if (len == 5) + { + resword = "msrps"; + goto compare; + } + break; + case 27: + if (len == 4) + { + resword = "aaas"; + goto compare; + } + break; + case 28: + if (len == 4) + { + resword = "msrp"; + goto compare; + } + break; + case 29: + if (len == 3) + { + resword = "jms"; + goto compare; + } + break; + case 30: + if (len == 9) + { + resword = "paparazzi"; + goto compare; + } + break; + case 31: + if (len == 7) + { + resword = "z39.50s"; + goto compare; + } + break; + case 33: + if (len == 3) + { + resword = "aaa"; + goto compare; + } + break; + case 34: + if (len == 4) + { + resword = "iris"; + goto compare; + } + break; + case 35: + if (len == 4) + { + resword = "mtqp"; + goto compare; + } + break; + case 36: + if (len == 3) + { + resword = "rmi"; + goto compare; + } + break; + case 38: + if (len == 4) + { + resword = "itms"; + goto compare; + } + break; + case 39: + if (len == 9) + { + resword = "iris.xpcs"; + goto compare; + } + break; + case 40: + if (len == 3) + { + resword = "tip"; + goto compare; + } + break; + case 42: + if (len == 9) + { + resword = "iris.beep"; + goto compare; + } + break; + case 44: + if (len == 4) + { + resword = "wtai"; + goto compare; + } + break; + case 46: + if (len == 3) + { + resword = "res"; + goto compare; + } + break; + case 47: + if (len == 7) + { + resword = "z39.50r"; + goto compare; + } + break; + case 48: + if (len == 4) + { + resword = "rtsp"; + goto compare; + } + break; + case 49: + if (len == 3) + { + resword = "cap"; + goto compare; + } + break; + case 50: + if (len == 4) + { + resword = "pres"; + goto compare; + } + break; + case 51: + if (len == 4) + { + resword = "rtmp"; + goto compare; + } + break; + case 53: + if (len == 4) + { + resword = "icap"; + goto compare; + } + break; + case 54: + if (len == 4) + { + resword = "acap"; + goto compare; + } + break; + case 57: + if (len == 6) + { + resword = "market"; + goto compare; + } + break; + case 58: + if (len == 5) + { + resword = "steam"; + goto compare; + } + break; + case 59: + if (len == 4) + { + resword = "ircs"; + goto compare; + } + break; + case 60: + if (len == 8) + { + resword = "iris.lwz"; + goto compare; + } + break; + case 61: + if (len == 3) + { + resword = "apt"; + goto compare; + } + break; + case 62: + if (len == 7) + { + resword = "message"; + goto compare; + } + break; + case 63: + if (len == 5) + { + resword = "sieve"; + goto compare; + } + break; + case 64: + if (len == 4) + { + resword = "irc6"; + goto compare; + } + break; + case 65: + if (len == 3) + { + resword = "jar"; + goto compare; + } + break; + case 66: + if (len == 9) + { + resword = "adiumxtra"; + goto compare; + } + break; + case 67: + if (len == 3) + { + resword = "pop"; + goto compare; + } + break; + case 68: + if (len == 2) + { + resword = "ni"; + goto compare; + } + break; + case 69: + if (len == 8) + { + resword = "iris.xpc"; + goto compare; + } + break; + case 70: + if (len == 4) + { + resword = "snmp"; + goto compare; + } + break; + case 71: + if (len == 5) + { + resword = "msnim"; + goto compare; + } + break; + case 72: + if (len == 10) + { + resword = "soap.beeps"; + goto compare; + } + break; + case 74: + if (len == 9) + { + resword = "soap.beep"; + goto compare; + } + break; + case 75: + if (len == 7) + { + resword = "service"; + goto compare; + } + break; + case 76: + if (len == 8) + { + resword = "resource"; + goto compare; + } + break; + case 77: + if (len == 6) + { + resword = "mailto"; + goto compare; + } + break; + case 78: + if (len == 4) + { + resword = "data"; + goto compare; + } + break; + case 80: + if (len == 6) + { + resword = "magnet"; + goto compare; + } + break; + case 84: + if (len == 3) + { + resword = "mid"; + goto compare; + } + break; + case 85: + if (len == 6) + { + resword = "lastfm"; + goto compare; + } + break; + case 86: + if (len == 4) + { + resword = "palm"; + goto compare; + } + break; + case 87: + if (len == 9) + { + resword = "teamspeak"; + goto compare; + } + break; + case 88: + if (len == 10) + { + resword = "attachment"; + goto compare; + } + break; + case 89: + if (len == 3) + { + resword = "irc"; + goto compare; + } + break; + case 90: + if (len == 8) + { + resword = "platform"; + goto compare; + } + break; + case 91: + if (len == 4) + { + resword = "news"; + goto compare; + } + break; + case 92: + if (len == 7) + { + resword = "session"; + goto compare; + } + break; + case 93: + if (len == 10) + { + resword = "secondlife"; + goto compare; + } + break; + case 94: + if (len == 4) + { + resword = "crid"; + goto compare; + } + break; + case 95: + if (len == 6) + { + resword = "tn3270"; + goto compare; + } + break; + case 96: + if (len == 3) + { + resword = "git"; + goto compare; + } + break; + case 97: + if (len == 5) + { + resword = "gtalk"; + goto compare; + } + break; + case 98: + if (len == 3) + { + resword = "dns"; + goto compare; + } + break; + case 99: + if (len == 4) + { + resword = "xmpp"; + goto compare; + } + break; + case 100: + if (len == 4) + { + resword = "coap"; + goto compare; + } + break; + case 101: + if (len == 4) + { + resword = "dict"; + goto compare; + } + break; + case 102: + if (len == 3) + { + resword = "afs"; + goto compare; + } + break; + case 104: + if (len == 12) + { + resword = "gizmoproject"; + goto compare; + } + break; + case 105: + if (len == 3) + { + resword = "doi"; + goto compare; + } + break; + case 108: + if (len == 3) + { + resword = "afp"; + goto compare; + } + break; + case 110: + if (len == 4) + { + resword = "ed2k"; + goto compare; + } + break; + case 112: + if (len == 3) + { + resword = "cid"; + goto compare; + } + break; + case 113: + if (len == 3) + { + resword = "tag"; + goto compare; + } + break; + case 115: + if (len == 2) + { + resword = "gg"; + goto compare; + } + break; + case 116: + if (len == 5) + { + resword = "ldaps"; + goto compare; + } + break; + case 117: + if (len == 3) + { + resword = "xri"; + goto compare; + } + break; + case 118: + if (len == 4) + { + resword = "ldap"; + goto compare; + } + break; + case 119: + if (len == 6) + { + resword = "gopher"; + goto compare; + } + break; + case 121: + if (len == 7) + { + resword = "beshare"; + goto compare; + } + break; + case 122: + if (len == 4) + { + resword = "sftp"; + goto compare; + } + break; + case 123: + if (len == 3) + { + resword = "cvs"; + goto compare; + } + break; + case 124: + if (len == 3) + { + resword = "ftp"; + goto compare; + } + break; + case 126: + if (len == 6) + { + resword = "mumble"; + goto compare; + } + break; + case 127: + if (len == 7) + { + resword = "mupdate"; + goto compare; + } + break; + case 128: + if (len == 5) + { + resword = "vemmi"; + goto compare; + } + break; + case 130: + if (len == 3) + { + resword = "ipn"; + goto compare; + } + break; + case 131: + if (len == 4) + { + resword = "h323"; + goto compare; + } + break; + case 132: + if (len == 3) + { + resword = "smb"; + goto compare; + } + break; + case 133: + if (len == 3) + { + resword = "udp"; + goto compare; + } + break; + case 134: + if (len == 3) + { + resword = "oid"; + goto compare; + } + break; + case 135: + if (len == 5) + { + resword = "shttp"; + goto compare; + } + break; + case 137: + if (len == 23) + { + resword = "com-eventbrite-attendee"; + goto compare; + } + break; + case 138: + if (len == 15) + { + resword = "opaquelocktoken"; + goto compare; + } + break; + case 139: + if (len == 6) + { + resword = "things"; + goto compare; + } + break; + case 141: + if (len == 5) + { + resword = "notes"; + goto compare; + } + break; + case 142: + if (len == 6) + { + resword = "ut2004"; + goto compare; + } + break; + case 143: + if (len == 2) + { + resword = "go"; + goto compare; + } + break; + case 144: + if (len == 3) + { + resword = "hcp"; + goto compare; + } + break; + case 145: + if (len == 4) + { + resword = "tftp"; + goto compare; + } + break; + case 146: + if (len == 6) + { + resword = "telnet"; + goto compare; + } + break; + case 148: + if (len == 4) + { + resword = "nntp"; + goto compare; + } + break; + case 150: + if (len == 10) + { + resword = "javascript"; + goto compare; + } + break; + case 151: + if (len == 6) + { + resword = "soldat"; + goto compare; + } + break; + case 152: + if (len == 5) + { + resword = "about"; + goto compare; + } + break; + case 153: + if (len == 3) + { + resword = "nfs"; + goto compare; + } + break; + case 154: + if (len == 4) + { + resword = "icon"; + goto compare; + } + break; + case 155: + if (len == 5) + { + resword = "https"; + goto compare; + } + break; + case 156: + if (len == 11) + { + resword = "view-source"; + goto compare; + } + break; + case 157: + if (len == 4) + { + resword = "http"; + goto compare; + } + break; + case 158: + if (len == 7) + { + resword = "bitcoin"; + goto compare; + } + break; + case 160: + if (len == 3) + { + resword = "sgn"; + goto compare; + } + break; + case 162: + if (len == 5) + { + resword = "ymsgr"; + goto compare; + } + break; + case 163: + if (len == 8) + { + resword = "facetime"; + goto compare; + } + break; + case 164: + if (len == 6) + { + resword = "webcal"; + goto compare; + } + break; + case 166: + if (len == 6) + { + resword = "callto"; + goto compare; + } + break; + case 168: + if (len == 12) + { + resword = "xmlrpc.beeps"; + goto compare; + } + break; + case 169: + if (len == 11) + { + resword = "thismessage"; + goto compare; + } + break; + case 170: + if (len == 11) + { + resword = "xmlrpc.beep"; + goto compare; + } + break; + case 174: + if (len == 7) + { + resword = "content"; + goto compare; + } + break; + case 175: + if (len == 3) + { + resword = "geo"; + goto compare; + } + break; + case 176: + if (len == 4) + { + resword = "psyc"; + goto compare; + } + break; + case 178: + if (len == 6) + { + resword = "finger"; + goto compare; + } + break; + case 179: + if (len == 3) + { + resword = "dtn"; + goto compare; + } + break; + case 181: + if (len == 4) + { + resword = "feed"; + goto compare; + } + break; + case 182: + if (len == 6) + { + resword = "chrome"; + goto compare; + } + break; + case 186: + if (len == 3) + { + resword = "iax"; + goto compare; + } + break; + case 187: + if (len == 3) + { + resword = "tel"; + goto compare; + } + break; + case 189: + if (len == 5) + { + resword = "skype"; + goto compare; + } + break; + case 190: + if (len == 5) + { + resword = "rsync"; + goto compare; + } + break; + case 194: + if (len == 4) + { + resword = "file"; + goto compare; + } + break; + case 195: + if (len == 2) + { + resword = "tv"; + goto compare; + } + break; + case 196: + if (len == 18) + { + resword = "dlna-playcontainer"; + goto compare; + } + break; + case 201: + if (len == 7) + { + resword = "spotify"; + goto compare; + } + break; + case 202: + if (len == 15) + { + resword = "dlna-playsingle"; + goto compare; + } + break; + case 204: + if (len == 4) + { + resword = "fish"; + goto compare; + } + break; + case 208: + if (len == 3) + { + resword = "svn"; + goto compare; + } + break; + case 209: + if (len == 3) + { + resword = "ssh"; + goto compare; + } + break; + case 211: + if (len == 3) + { + resword = "mvn"; + goto compare; + } + break; + case 212: + if (len == 5) + { + resword = "xfire"; + goto compare; + } + break; + case 213: + if (len == 4) + { + resword = "info"; + goto compare; + } + break; + case 215: + if (len == 5) + { + resword = "proxy"; + goto compare; + } + break; + case 216: + if (len == 11) + { + resword = "xcon-userid"; + goto compare; + } + break; + case 217: + if (len == 7) + { + resword = "wyciwyg"; + goto compare; + } + break; + case 221: + if (len == 3) + { + resword = "dav"; + goto compare; + } + break; + case 222: + if (len == 7) + { + resword = "keyparc"; + goto compare; + } + break; + case 224: + if (len == 3) + { + resword = "urn"; + goto compare; + } + break; + case 225: + if (len == 16) + { + resword = "chrome-extension"; + goto compare; + } + break; + case 232: + if (len == 4) + { + resword = "xcon"; + goto compare; + } + break; + case 233: + if (len == 8) + { + resword = "ventrilo"; + goto compare; + } + break; + case 236: + if (len == 6) + { + resword = "unreal"; + goto compare; + } + break; + case 241: + if (len == 4) + { + resword = "bolo"; + goto compare; + } + break; + case 251: + if (len == 3) + { + resword = "dvb"; + goto compare; + } + break; + case 255: + if (len == 5) + { + resword = "query"; + goto compare; + } + break; + case 273: + if (len == 3) + { + resword = "nih"; + goto compare; + } + break; + } + return 0; + compare: + if ((((unsigned char)*str ^ (unsigned char)*resword) & ~32) == 0 && !gperf_case_memcmp (str, resword, len)) + return resword; + } + } + return 0; +} diff --git a/src/html_blocks.c b/src/_html_blocks.c similarity index 66% rename from src/html_blocks.c rename to src/_html_blocks.c index f5e9dce..b8d333d 100644 --- a/src/html_blocks.c +++ b/src/_html_blocks.c @@ -1,5 +1,5 @@ -/* ANSI-C code produced by gperf version 3.0.3 */ -/* Command-line: gperf -L ANSI-C -N hoedown_find_block_tag -c -C -E -S 1 --ignore-case -m100 html_block_names.gperf */ +/* ANSI-C code produced by gperf version 3.0.4 */ +/* Command-line: gperf -L ANSI-C -N hoedown_find_block_tag -7 -c -C -E -S 1 --ignore-case -m100 data/html_blocks.gperf */ /* Computed positions: -k'1-2' */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ @@ -29,7 +29,7 @@ #error "gperf generated tables don't work with this execution character set. Please report a bug to ." #endif -/* maximum key range = 24, duplicates = 0 */ +/* maximum key range = 52, duplicates = 0 */ #ifndef GPERF_DOWNCASE #define GPERF_DOWNCASE 1 @@ -88,34 +88,21 @@ hash (register const char *str, register unsigned int len) { static const unsigned char asso_values[] = { - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 22, 21, 19, 18, 16, 0, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 1, 25, 0, 25, - 1, 0, 0, 13, 0, 25, 25, 11, 2, 1, - 0, 25, 25, 5, 0, 2, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 1, 25, - 0, 25, 1, 0, 0, 13, 0, 25, 25, 11, - 2, 1, 0, 25, 25, 5, 0, 2, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25 + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 25, 24, 21, 20, 19, 18, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 26, 8, 2, 20, 30, + 0, 22, 22, 23, 13, 53, 26, 0, 5, 29, + 0, 53, 53, 0, 7, 25, 11, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 26, 8, 2, + 20, 30, 0, 22, 22, 23, 13, 53, 26, 0, + 5, 29, 0, 53, 53, 0, 7, 25, 11, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53 }; - register int hval = (int)len; + register int hval = len; switch (hval) { @@ -131,7 +118,7 @@ hash (register const char *str, register unsigned int len) #ifdef __GNUC__ __inline -#ifdef __GNUC_STDC_INLINE__ +#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__ __attribute__ ((__gnu_inline__)) #endif #endif @@ -140,11 +127,11 @@ hoedown_find_block_tag (register const char *str, register unsigned int len) { enum { - TOTAL_KEYWORDS = 24, + TOTAL_KEYWORDS = 50, MIN_WORD_LENGTH = 1, MAX_WORD_LENGTH = 10, MIN_HASH_VALUE = 1, - MAX_HASH_VALUE = 24 + MAX_HASH_VALUE = 52 }; if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) @@ -160,75 +147,153 @@ hoedown_find_block_tag (register const char *str, register unsigned int len) case 0: resword = "p"; goto compare; - case 1: - resword = "h6"; - goto compare; case 2: - resword = "div"; - goto compare; - case 3: - resword = "del"; - goto compare; - case 4: - resword = "form"; - goto compare; - case 5: - resword = "table"; - goto compare; - case 6: - resword = "figure"; - goto compare; - case 7: resword = "pre"; goto compare; + case 3: + resword = "form"; + goto compare; + case 4: + resword = "col"; + goto compare; + case 5: + resword = "footer"; + goto compare; + case 6: + resword = "section"; + goto compare; + case 7: + resword = "progress"; + goto compare; case 8: - resword = "fieldset"; + resword = "tr"; goto compare; case 9: - resword = "noscript"; + resword = "colgroup"; goto compare; case 10: - resword = "script"; + resword = "map"; goto compare; case 11: - resword = "style"; - goto compare; - case 12: - resword = "dl"; + resword = "body"; goto compare; case 13: - resword = "ol"; + resword = "tbody"; goto compare; case 14: - resword = "ul"; + resword = "textarea"; goto compare; case 15: - resword = "math"; + resword = "canvas"; goto compare; case 16: - resword = "ins"; + resword = "caption"; goto compare; case 17: - resword = "h5"; - goto compare; - case 18: - resword = "iframe"; - goto compare; - case 19: - resword = "h4"; - goto compare; - case 20: - resword = "h3"; - goto compare; - case 21: resword = "blockquote"; goto compare; + case 18: + resword = "figure"; + goto compare; + case 19: + resword = "table"; + goto compare; + case 20: + resword = "fieldset"; + goto compare; + case 21: + resword = "dl"; + goto compare; case 22: - resword = "h2"; + resword = "figcaption"; goto compare; case 23: + resword = "hr"; + goto compare; + case 24: + resword = "button"; + goto compare; + case 25: + resword = "script"; + goto compare; + case 26: + resword = "ul"; + goto compare; + case 27: + resword = "header"; + goto compare; + case 28: + resword = "video"; + goto compare; + case 29: + resword = "style"; + goto compare; + case 30: + resword = "ol"; + goto compare; + case 31: + resword = "th"; + goto compare; + case 32: + resword = "article"; + goto compare; + case 33: + resword = "tfoot"; + goto compare; + case 34: + resword = "thead"; + goto compare; + case 35: + resword = "div"; + goto compare; + case 36: + resword = "object"; + goto compare; + case 37: + resword = "aside"; + goto compare; + case 38: + resword = "td"; + goto compare; + case 39: + resword = "embed"; + goto compare; + case 40: + resword = "li"; + goto compare; + case 41: + resword = "h6"; + goto compare; + case 42: + resword = "h5"; + goto compare; + case 43: + resword = "h4"; + goto compare; + case 44: + resword = "h3"; + goto compare; + case 45: + resword = "output"; + goto compare; + case 46: + resword = "dt"; + goto compare; + case 47: + resword = "h2"; + goto compare; + case 48: resword = "h1"; goto compare; + case 49: + resword = "hgroup"; + goto compare; + case 50: + resword = "iframe"; + goto compare; + case 51: + resword = "dd"; + goto compare; } return 0; compare: diff --git a/src/_html_entities.h b/src/_html_entities.h new file mode 100644 index 0000000..a477ab2 --- /dev/null +++ b/src/_html_entities.h @@ -0,0 +1,19287 @@ +/* C code produced by gperf version 3.0.3 */ +/* Command-line: gperf -S1 -m100 -l -C -N find_entity -t data/html_entities.gperf */ +/* Computed positions: -k'1-7,10,12,$' */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#endif + +#line 2 "data/html_entities.gperf" +struct html_entity { + const char *name; + uint8_t utf8 [6]; + size_t size; + }; + +#define TOTAL_KEYWORDS 2125 +#define MIN_WORD_LENGTH 2 +#define MAX_WORD_LENGTH 31 +#define MIN_HASH_VALUE 91 +#define MAX_HASH_VALUE 15711 +/* maximum key range = 15621, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +hash (str, len) + register const char *str; + register unsigned int len; +{ + static const unsigned short asso_values[] = + { + 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, + 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, + 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, + 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, + 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 18, + 31, 32, 18, 21, 19, 15712, 44, 15712, 15712, 15712, + 15712, 15712, 15712, 15712, 15712, 174, 395, 1127, 417, 670, + 233, 1928, 88, 136, 54, 137, 165, 188, 181, 1008, + 33, 48, 167, 59, 265, 253, 51, 108, 50, 232, + 41, 15712, 19, 15712, 20, 15712, 15712, 3078, 34, 2621, + 398, 22, 142, 1880, 2435, 336, 1762, 4050, 20, 644, + 31, 1233, 84, 199, 18, 21, 19, 27, 102, 985, + 3403, 4238, 865, 581, 157, 18, 18, 15712, 15712, 15712, + 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, + 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, + 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, + 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, + 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, + 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, + 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, + 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, + 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, + 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, + 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, + 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, + 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712, 15712 + }; + register int hval = len; + + switch (hval) + { + default: + hval += asso_values[(unsigned char)str[11]]; + /*FALLTHROUGH*/ + case 11: + case 10: + hval += asso_values[(unsigned char)str[9]]; + /*FALLTHROUGH*/ + case 9: + case 8: + case 7: + hval += asso_values[(unsigned char)str[6]]; + /*FALLTHROUGH*/ + case 6: + hval += asso_values[(unsigned char)str[5]]; + /*FALLTHROUGH*/ + case 5: + hval += asso_values[(unsigned char)str[4]+1]; + /*FALLTHROUGH*/ + case 4: + hval += asso_values[(unsigned char)str[3]+3]; + /*FALLTHROUGH*/ + case 3: + hval += asso_values[(unsigned char)str[2]+1]; + /*FALLTHROUGH*/ + case 2: + hval += asso_values[(unsigned char)str[1]+4]; + /*FALLTHROUGH*/ + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return hval + asso_values[(unsigned char)str[len - 1]]; +} + +#ifdef __GNUC__ +__inline +#ifdef __GNUC_STDC_INLINE__ +__attribute__ ((__gnu_inline__)) +#endif +#endif +const struct html_entity * +find_entity (str, len) + register const char *str; + register unsigned int len; +{ + static const struct html_entity wordlist[] = + { +#line 518 "data/html_entities.gperf" + {"lat", { 0xE2, 0xAA, 0xAB }, 3}, +#line 314 "data/html_entities.gperf" + {"npr", { 0xE2, 0x8A, 0x80 }, 3}, +#line 2061 "data/html_entities.gperf" + {"not", { 0xC2, 0xAC }, 2}, +#line 1174 "data/html_entities.gperf" + {"bot", { 0xE2, 0x8A, 0xA5 }, 3}, +#line 1073 "data/html_entities.gperf" + {"rarr", { 0xE2, 0x86, 0x92 }, 3}, +#line 865 "data/html_entities.gperf" + {"larr", { 0xE2, 0x86, 0x90 }, 3}, +#line 951 "data/html_entities.gperf" + {"nLt", { 0xE2, 0x89, 0xAA, 0xE2, 0x83, 0x92 }, 6}, +#line 957 "data/html_entities.gperf" + {"uarr", { 0xE2, 0x86, 0x91 }, 3}, +#line 259 "data/html_entities.gperf" + {"rpar", { 0x29 }, 1}, +#line 468 "data/html_entities.gperf" + {"lpar", { 0x28 }, 1}, +#line 1122 "data/html_entities.gperf" + {"spar", { 0xE2, 0x88, 0xA5 }, 3}, +#line 1647 "data/html_entities.gperf" + {"epar", { 0xE2, 0x8B, 0x95 }, 3}, +#line 1532 "data/html_entities.gperf" + {"ll", { 0xE2, 0x89, 0xAA }, 3}, +#line 934 "data/html_entities.gperf" + {"el", { 0xE2, 0xAA, 0x99 }, 3}, +#line 860 "data/html_entities.gperf" + {"npar", { 0xE2, 0x88, 0xA6 }, 3}, +#line 638 "data/html_entities.gperf" + {"roarr", { 0xE2, 0x87, 0xBE }, 3}, +#line 125 "data/html_entities.gperf" + {"loarr", { 0xE2, 0x87, 0xBD }, 3}, +#line 2095 "data/html_entities.gperf" + {"par", { 0xE2, 0x88, 0xA5 }, 3}, +#line 1795 "data/html_entities.gperf" + {"els", { 0xE2, 0xAA, 0x95 }, 3}, +#line 153 "data/html_entities.gperf" + {"uharr", { 0xE2, 0x86, 0xBE }, 3}, +#line 1546 "data/html_entities.gperf" + {"Pr", { 0xE2, 0xAA, 0xBB }, 3}, +#line 1931 "data/html_entities.gperf" + {"nharr", { 0xE2, 0x86, 0xAE }, 3}, +#line 647 "data/html_entities.gperf" + {"Hat", { 0x5E }, 1}, +#line 744 "data/html_entities.gperf" + {"tprime", { 0xE2, 0x80, 0xB4 }, 3}, +#line 1331 "data/html_entities.gperf" + {"rarrtl", { 0xE2, 0x86, 0xA3 }, 3}, +#line 2028 "data/html_entities.gperf" + {"npart", { 0xE2, 0x88, 0x82, 0xCC, 0xB8 }, 5}, +#line 45 "data/html_entities.gperf" + {"larrtl", { 0xE2, 0x86, 0xA2 }, 3}, +#line 1088 "data/html_entities.gperf" + {"nlt", { 0xE2, 0x89, 0xAE }, 3}, +#line 1559 "data/html_entities.gperf" + {"eparsl", { 0xE2, 0xA7, 0xA3 }, 3}, +#line 63 "data/html_entities.gperf" + {"ensp", { 0xE2, 0x80, 0x82 }, 3}, +#line 871 "data/html_entities.gperf" + {"tau", { 0xCF, 0x84 }, 2}, +#line 2120 "data/html_entities.gperf" + {"bprime", { 0xE2, 0x80, 0xB5 }, 3}, +#line 319 "data/html_entities.gperf" + {"nparsl", { 0xE2, 0xAB, 0xBD, 0xE2, 0x83, 0xA5 }, 6}, +#line 1225 "data/html_entities.gperf" + {"squ", { 0xE2, 0x96, 0xA1 }, 3}, +#line 1648 "data/html_entities.gperf" + {"lnap", { 0xE2, 0xAA, 0x89 }, 3}, +#line 1370 "data/html_entities.gperf" + {"nldr", { 0xE2, 0x80, 0xA5 }, 3}, +#line 628 "data/html_entities.gperf" + {"rotimes", { 0xE2, 0xA8, 0xB5 }, 3}, +#line 1799 "data/html_entities.gperf" + {"lotimes", { 0xE2, 0xA8, 0xB4 }, 3}, +#line 1497 "data/html_entities.gperf" + {"varr", { 0xE2, 0x86, 0x95 }, 3}, +#line 1712 "data/html_entities.gperf" + {"blk14", { 0xE2, 0x96, 0x91 }, 3}, +#line 481 "data/html_entities.gperf" + {"blk34", { 0xE2, 0x96, 0x93 }, 3}, +#line 1731 "data/html_entities.gperf" + {"Int", { 0xE2, 0x88, 0xAC }, 3}, +#line 2074 "data/html_entities.gperf" + {"lne", { 0xE2, 0xAA, 0x87 }, 3}, +#line 1631 "data/html_entities.gperf" + {"pr", { 0xE2, 0x89, 0xBA }, 3}, +#line 987 "data/html_entities.gperf" + {"rlarr", { 0xE2, 0x87, 0x84 }, 3}, +#line 22 "data/html_entities.gperf" + {"llarr", { 0xE2, 0x87, 0x87 }, 3}, +#line 842 "data/html_entities.gperf" + {"slarr", { 0xE2, 0x86, 0x90 }, 3}, +#line 944 "data/html_entities.gperf" + {"nparallel", { 0xE2, 0x88, 0xA6 }, 3}, +#line 100 "data/html_entities.gperf" + {"nGt", { 0xE2, 0x89, 0xAB, 0xE2, 0x83, 0x92 }, 6}, +#line 948 "data/html_entities.gperf" + {"bne", { 0x3D, 0xE2, 0x83, 0xA5 }, 4}, +#line 580 "data/html_entities.gperf" + {"nlarr", { 0xE2, 0x86, 0x9A }, 3}, +#line 523 "data/html_entities.gperf" + {"blk12", { 0xE2, 0x96, 0x92 }, 3}, +#line 496 "data/html_entities.gperf" + {"rrarr", { 0xE2, 0x87, 0x89 }, 3}, +#line 915 "data/html_entities.gperf" + {"lrarr", { 0xE2, 0x87, 0x86 }, 3}, +#line 1526 "data/html_entities.gperf" + {"srarr", { 0xE2, 0x86, 0x92 }, 3}, +#line 1666 "data/html_entities.gperf" + {"erarr", { 0xE2, 0xA5, 0xB1 }, 3}, +#line 1667 "data/html_entities.gperf" + {"rharu", { 0xE2, 0x87, 0x80 }, 3}, +#line 1019 "data/html_entities.gperf" + {"lharu", { 0xE2, 0x86, 0xBC }, 3}, +#line 2118 "data/html_entities.gperf" + {"nrarr", { 0xE2, 0x86, 0x9B }, 3}, +#line 256 "data/html_entities.gperf" + {"rharul", { 0xE2, 0xA5, 0xAC }, 3}, +#line 364 "data/html_entities.gperf" + {"lharul", { 0xE2, 0xA5, 0xAA }, 3}, +#line 885 "data/html_entities.gperf" + {"Not", { 0xE2, 0xAB, 0xAC }, 3}, +#line 69 "data/html_entities.gperf" + {"Larr", { 0xE2, 0x86, 0x9E }, 3}, +#line 592 "data/html_entities.gperf" + {"Rarr", { 0xE2, 0x86, 0xA0 }, 3}, +#line 281 "data/html_entities.gperf" + {"rbarr", { 0xE2, 0xA4, 0x8D }, 3}, +#line 1689 "data/html_entities.gperf" + {"rHar", { 0xE2, 0xA5, 0xA4 }, 3}, +#line 1402 "data/html_entities.gperf" + {"lbarr", { 0xE2, 0xA4, 0x8C }, 3}, +#line 1953 "data/html_entities.gperf" + {"lHar", { 0xE2, 0xA5, 0xA2 }, 3}, +#line 359 "data/html_entities.gperf" + {"smt", { 0xE2, 0xAA, 0xAA }, 3}, +#line 763 "data/html_entities.gperf" + {"Ll", { 0xE2, 0x8B, 0x98 }, 3}, +#line 1877 "data/html_entities.gperf" + {"uHar", { 0xE2, 0xA5, 0xA3 }, 3}, +#line 487 "data/html_entities.gperf" + {"Vbar", { 0xE2, 0xAB, 0xAB }, 3}, +#line 954 "data/html_entities.gperf" + {"nle", { 0xE2, 0x89, 0xB0 }, 3}, +#line 1043 "data/html_entities.gperf" + {"upuparrows", { 0xE2, 0x87, 0x88 }, 3}, +#line 208 "data/html_entities.gperf" + {"rarrap", { 0xE2, 0xA5, 0xB5 }, 3}, +#line 173 "data/html_entities.gperf" + {"phmmat", { 0xE2, 0x84, 0xB3 }, 3}, +#line 1348 "data/html_entities.gperf" + {"nbsp", { 0xC2, 0xA0 }, 2}, +#line 1337 "data/html_entities.gperf" + {"AMP", { 0x26 }, 1}, +#line 1513 "data/html_entities.gperf" + {"Rarrtl", { 0xE2, 0xA4, 0x96 }, 3}, +#line 327 "data/html_entities.gperf" + {"rbrkslu", { 0xE2, 0xA6, 0x90 }, 3}, +#line 343 "data/html_entities.gperf" + {"lbrkslu", { 0xE2, 0xA6, 0x8D }, 3}, +#line 1187 "data/html_entities.gperf" + {"napos", { 0xC5, 0x89 }, 2}, +#line 1553 "data/html_entities.gperf" + {"top", { 0xE2, 0x8A, 0xA4 }, 3}, +#line 2033 "data/html_entities.gperf" + {"lap", { 0xE2, 0xAA, 0x85 }, 3}, +#line 1780 "data/html_entities.gperf" + {"prap", { 0xE2, 0xAA, 0xB7 }, 3}, +#line 1897 "data/html_entities.gperf" + {"rarrpl", { 0xE2, 0xA5, 0x85 }, 3}, +#line 1181 "data/html_entities.gperf" + {"emsp14", { 0xE2, 0x80, 0x85 }, 3}, +#line 74 "data/html_entities.gperf" + {"larrpl", { 0xE2, 0xA4, 0xB9 }, 3}, +#line 1441 "data/html_entities.gperf" + {"nap", { 0xE2, 0x89, 0x89 }, 3}, +#line 1478 "data/html_entities.gperf" + {"qprime", { 0xE2, 0x81, 0x97 }, 3}, +#line 1888 "data/html_entities.gperf" + {"Uarr", { 0xE2, 0x86, 0x9F }, 3}, +#line 1817 "data/html_entities.gperf" + {"emsp", { 0xE2, 0x80, 0x83 }, 3}, +#line 609 "data/html_entities.gperf" + {"pre", { 0xE2, 0xAA, 0xAF }, 3}, +#line 1256 "data/html_entities.gperf" + {"rBarr", { 0xE2, 0xA4, 0x8F }, 3}, +#line 268 "data/html_entities.gperf" + {"lBarr", { 0xE2, 0xA4, 0x8E }, 3}, +#line 1634 "data/html_entities.gperf" + {"emsp13", { 0xE2, 0x80, 0x84 }, 3}, +#line 1501 "data/html_entities.gperf" + {"nprcue", { 0xE2, 0x8B, 0xA0 }, 3}, +#line 919 "data/html_entities.gperf" + {"prop", { 0xE2, 0x88, 0x9D }, 3}, +#line 1946 "data/html_entities.gperf" + {"le", { 0xE2, 0x89, 0xA4 }, 3}, +#line 1379 "data/html_entities.gperf" + {"rbrke", { 0xE2, 0xA6, 0x8C }, 3}, +#line 1720 "data/html_entities.gperf" + {"ee", { 0xE2, 0x85, 0x87 }, 3}, +#line 1524 "data/html_entities.gperf" + {"lbrke", { 0xE2, 0xA6, 0x8B }, 3}, +#line 538 "data/html_entities.gperf" + {"nles", { 0xE2, 0xA9, 0xBD, 0xCC, 0xB8 }, 5}, +#line 1785 "data/html_entities.gperf" + {"in", { 0xE2, 0x88, 0x88 }, 3}, +#line 1465 "data/html_entities.gperf" + {"topbot", { 0xE2, 0x8C, 0xB6 }, 3}, +#line 1646 "data/html_entities.gperf" + {"sharp", { 0xE2, 0x99, 0xAF }, 3}, +#line 1107 "data/html_entities.gperf" + {"ne", { 0xE2, 0x89, 0xA0 }, 3}, +#line 1242 "data/html_entities.gperf" + {"there4", { 0xE2, 0x88, 0xB4 }, 3}, +#line 235 "data/html_entities.gperf" + {"plus", { 0x2B }, 1}, +#line 1519 "data/html_entities.gperf" + {"les", { 0xE2, 0xA9, 0xBD }, 3}, +#line 597 "data/html_entities.gperf" + {"lneq", { 0xE2, 0xAA, 0x87 }, 3}, +#line 1382 "data/html_entities.gperf" + {"int", { 0xE2, 0x88, 0xAB }, 3}, +#line 1624 "data/html_entities.gperf" + {"nless", { 0xE2, 0x89, 0xAE }, 3}, +#line 310 "data/html_entities.gperf" + {"looparrowleft", { 0xE2, 0x86, 0xAB }, 3}, +#line 2040 "data/html_entities.gperf" + {"vBar", { 0xE2, 0xAB, 0xA8 }, 3}, +#line 657 "data/html_entities.gperf" + {"Tau", { 0xCE, 0xA4 }, 2}, +#line 1269 "data/html_entities.gperf" + {"epsi", { 0xCE, 0xB5 }, 2}, +#line 1639 "data/html_entities.gperf" + {"lneqq", { 0xE2, 0x89, 0xA8 }, 3}, +#line 1227 "data/html_entities.gperf" + {"upsi", { 0xCF, 0x85 }, 2}, +#line 1385 "data/html_entities.gperf" + {"Proportion", { 0xE2, 0x88, 0xB7 }, 3}, +#line 1004 "data/html_entities.gperf" + {"blacktriangle", { 0xE2, 0x96, 0xB4 }, 3}, +#line 1110 "data/html_entities.gperf" + {"blacktriangleleft", { 0xE2, 0x97, 0x82 }, 3}, +#line 1329 "data/html_entities.gperf" + {"blacktriangleright", { 0xE2, 0x96, 0xB8 }, 3}, +#line 814 "data/html_entities.gperf" + {"emacr", { 0xC4, 0x93 }, 2}, +#line 782 "data/html_entities.gperf" + {"Proportional", { 0xE2, 0x88, 0x9D }, 3}, +#line 912 "data/html_entities.gperf" + {"umacr", { 0xC5, 0xAB }, 2}, +#line 297 "data/html_entities.gperf" + {"vprop", { 0xE2, 0x88, 0x9D }, 3}, +#line 781 "data/html_entities.gperf" + {"blacktriangledown", { 0xE2, 0x96, 0xBE }, 3}, +#line 822 "data/html_entities.gperf" + {"plusdu", { 0xE2, 0xA8, 0xA5 }, 3}, +#line 2069 "data/html_entities.gperf" + {"nedot", { 0xE2, 0x89, 0x90, 0xCC, 0xB8 }, 5}, +#line 1254 "data/html_entities.gperf" + {"searr", { 0xE2, 0x86, 0x98 }, 3}, +#line 606 "data/html_entities.gperf" + {"NotSubset", { 0xE2, 0x8A, 0x82, 0xE2, 0x83, 0x92 }, 6}, +#line 1000 "data/html_entities.gperf" + {"dot", { 0xCB, 0x99 }, 2}, +#line 1141 "data/html_entities.gperf" + {"plusmn", { 0xC2, 0xB1 }, 2}, +#line 260 "data/html_entities.gperf" + {"nearr", { 0xE2, 0x86, 0x97 }, 3}, +#line 858 "data/html_entities.gperf" + {"nleq", { 0xE2, 0x89, 0xB0 }, 3}, +#line 1942 "data/html_entities.gperf" + {"frac34", { 0xC2, 0xBE }, 2}, +#line 106 "data/html_entities.gperf" + {"LT", { 0x3C }, 1}, +#line 397 "data/html_entities.gperf" + {"frac56", { 0xE2, 0x85, 0x9A }, 3}, +#line 266 "data/html_entities.gperf" + {"smeparsl", { 0xE2, 0xA7, 0xA4 }, 3}, +#line 526 "data/html_entities.gperf" + {"frac35", { 0xE2, 0x85, 0x97 }, 3}, +#line 1934 "data/html_entities.gperf" + {"Dot", { 0xC2, 0xA8 }, 2}, +#line 1309 "data/html_entities.gperf" + {"frac45", { 0xE2, 0x85, 0x98 }, 3}, +#line 2104 "data/html_entities.gperf" + {"darr", { 0xE2, 0x86, 0x93 }, 3}, +#line 1904 "data/html_entities.gperf" + {"frac14", { 0xC2, 0xBC }, 2}, +#line 79 "data/html_entities.gperf" + {"frac16", { 0xE2, 0x85, 0x99 }, 3}, +#line 1734 "data/html_entities.gperf" + {"Map", { 0xE2, 0xA4, 0x85 }, 3}, +#line 649 "data/html_entities.gperf" + {"fltns", { 0xE2, 0x96, 0xB1 }, 3}, +#line 659 "data/html_entities.gperf" + {"nleqq", { 0xE2, 0x89, 0xA6, 0xCC, 0xB8 }, 5}, +#line 1763 "data/html_entities.gperf" + {"frac15", { 0xE2, 0x85, 0x95 }, 3}, +#line 1554 "data/html_entities.gperf" + {"frac25", { 0xE2, 0x85, 0x96 }, 3}, +#line 943 "data/html_entities.gperf" + {"prurel", { 0xE2, 0x8A, 0xB0 }, 3}, +#line 500 "data/html_entities.gperf" + {"RBarr", { 0xE2, 0xA4, 0x90 }, 3}, +#line 784 "data/html_entities.gperf" + {"Verbar", { 0xE2, 0x80, 0x96 }, 3}, +#line 1315 "data/html_entities.gperf" + {"Darr", { 0xE2, 0x86, 0xA1 }, 3}, +#line 1787 "data/html_entities.gperf" + {"rnmid", { 0xE2, 0xAB, 0xAE }, 3}, +#line 789 "data/html_entities.gperf" + {"nhArr", { 0xE2, 0x87, 0x8E }, 3}, +#line 710 "data/html_entities.gperf" + {"frac12", { 0xC2, 0xBD }, 2}, +#line 565 "data/html_entities.gperf" + {"frac13", { 0xE2, 0x85, 0x93 }, 3}, +#line 1903 "data/html_entities.gperf" + {"frac23", { 0xE2, 0x85, 0x94 }, 3}, +#line 38 "data/html_entities.gperf" + {"dharr", { 0xE2, 0x87, 0x82 }, 3}, +#line 1535 "data/html_entities.gperf" + {"rhard", { 0xE2, 0x87, 0x81 }, 3}, +#line 890 "data/html_entities.gperf" + {"lhard", { 0xE2, 0x86, 0xBD }, 3}, +#line 551 "data/html_entities.gperf" + {"Re", { 0xE2, 0x84, 0x9C }, 3}, +#line 61 "data/html_entities.gperf" + {"frac38", { 0xE2, 0x85, 0x9C }, 3}, +#line 401 "data/html_entities.gperf" + {"frac58", { 0xE2, 0x85, 0x9D }, 3}, +#line 540 "data/html_entities.gperf" + {"NotSuperset", { 0xE2, 0x8A, 0x83, 0xE2, 0x83, 0x92 }, 6}, +#line 1523 "data/html_entities.gperf" + {"pluse", { 0xE2, 0xA9, 0xB2 }, 3}, +#line 1600 "data/html_entities.gperf" + {"frac18", { 0xE2, 0x85, 0x9B }, 3}, +#line 1063 "data/html_entities.gperf" + {"perp", { 0xE2, 0x8A, 0xA5 }, 3}, +#line 980 "data/html_entities.gperf" + {"Vee", { 0xE2, 0x8B, 0x81 }, 3}, +#line 1872 "data/html_entities.gperf" + {"Imacr", { 0xC4, 0xAA }, 2}, +#line 716 "data/html_entities.gperf" + {"phone", { 0xE2, 0x98, 0x8E }, 3}, +#line 936 "data/html_entities.gperf" + {"verbar", { 0x7C }, 1}, +#line 1022 "data/html_entities.gperf" + {"frac78", { 0xE2, 0x85, 0x9E }, 3}, +#line 1209 "data/html_entities.gperf" + {"leq", { 0xE2, 0x89, 0xA4 }, 3}, +#line 920 "data/html_entities.gperf" + {"nlArr", { 0xE2, 0x87, 0x8D }, 3}, +#line 642 "data/html_entities.gperf" + {"blacksquare", { 0xE2, 0x96, 0xAA }, 3}, +#line 530 "data/html_entities.gperf" + {"Amacr", { 0xC4, 0x80 }, 2}, +#line 1480 "data/html_entities.gperf" + {"leqq", { 0xE2, 0x89, 0xA6 }, 3}, +#line 972 "data/html_entities.gperf" + {"nrArr", { 0xE2, 0x87, 0x8F }, 3}, +#line 610 "data/html_entities.gperf" + {"intcal", { 0xE2, 0x8A, 0xBA }, 3}, +#line 644 "data/html_entities.gperf" + {"vee", { 0xE2, 0x88, 0xA8 }, 3}, +#line 524 "data/html_entities.gperf" + {"nbumpe", { 0xE2, 0x89, 0x8F, 0xCC, 0xB8 }, 5}, +#line 1007 "data/html_entities.gperf" + {"And", { 0xE2, 0xA9, 0x93 }, 3}, +#line 1440 "data/html_entities.gperf" + {"ulcorn", { 0xE2, 0x8C, 0x9C }, 3}, +#line 316 "data/html_entities.gperf" + {"square", { 0xE2, 0x96, 0xA1 }, 3}, +#line 1630 "data/html_entities.gperf" + {"llcorner", { 0xE2, 0x8C, 0x9E }, 3}, +#line 1332 "data/html_entities.gperf" + {"ulcorner", { 0xE2, 0x8C, 0x9C }, 3}, +#line 1082 "data/html_entities.gperf" + {"plankv", { 0xE2, 0x84, 0x8F }, 3}, +#line 1596 "data/html_entities.gperf" + {"squf", { 0xE2, 0x96, 0xAA }, 3}, +#line 216 "data/html_entities.gperf" + {"urcorn", { 0xE2, 0x8C, 0x9D }, 3}, +#line 1577 "data/html_entities.gperf" + {"lrcorner", { 0xE2, 0x8C, 0x9F }, 3}, +#line 1885 "data/html_entities.gperf" + {"fpartint", { 0xE2, 0xA8, 0x8D }, 3}, +#line 1444 "data/html_entities.gperf" + {"urcorner", { 0xE2, 0x8C, 0x9D }, 3}, +#line 1818 "data/html_entities.gperf" + {"dHar", { 0xE2, 0xA5, 0xA5 }, 3}, +#line 1018 "data/html_entities.gperf" + {"nbump", { 0xE2, 0x89, 0x8E, 0xCC, 0xB8 }, 5}, +#line 1490 "data/html_entities.gperf" + {"Upsi", { 0xCF, 0x92 }, 2}, +#line 8 "data/html_entities.gperf" + {"Square", { 0xE2, 0x96, 0xA1 }, 3}, +#line 590 "data/html_entities.gperf" + {"Umacr", { 0xC5, 0xAA }, 2}, +#line 128 "data/html_entities.gperf" + {"veebar", { 0xE2, 0x8A, 0xBB }, 3}, +#line 408 "data/html_entities.gperf" + {"ropar", { 0xE2, 0xA6, 0x86 }, 3}, +#line 2057 "data/html_entities.gperf" + {"lopar", { 0xE2, 0xA6, 0x85 }, 3}, +#line 505 "data/html_entities.gperf" + {"NotNestedLessLess", { 0xE2, 0xAA, 0xA1, 0xCC, 0xB8 }, 5}, +#line 1607 "data/html_entities.gperf" + {"QUOT", { 0x22 }, 1}, +#line 67 "data/html_entities.gperf" + {"nhpar", { 0xE2, 0xAB, 0xB2 }, 3}, +#line 869 "data/html_entities.gperf" + {"napid", { 0xE2, 0x89, 0x8B, 0xCC, 0xB8 }, 5}, +#line 1935 "data/html_entities.gperf" + {"swarr", { 0xE2, 0x86, 0x99 }, 3}, +#line 2011 "data/html_entities.gperf" + {"sol", { 0x2F }, 1}, +#line 718 "data/html_entities.gperf" + {"nwarr", { 0xE2, 0x86, 0x96 }, 3}, +#line 692 "data/html_entities.gperf" + {"nis", { 0xE2, 0x8B, 0xBC }, 3}, +#line 148 "data/html_entities.gperf" + {"ropf", { 0xF0, 0x9D, 0x95, 0xA3 }, 4}, +#line 625 "data/html_entities.gperf" + {"topf", { 0xF0, 0x9D, 0x95, 0xA5 }, 4}, +#line 1743 "data/html_entities.gperf" + {"lopf", { 0xF0, 0x9D, 0x95, 0x9D }, 4}, +#line 1234 "data/html_entities.gperf" + {"sopf", { 0xF0, 0x9D, 0x95, 0xA4 }, 4}, +#line 1819 "data/html_entities.gperf" + {"eopf", { 0xF0, 0x9D, 0x95, 0x96 }, 4}, +#line 600 "data/html_entities.gperf" + {"fnof", { 0xC6, 0x92 }, 2}, +#line 1861 "data/html_entities.gperf" + {"uopf", { 0xF0, 0x9D, 0x95, 0xA6 }, 4}, +#line 1597 "data/html_entities.gperf" + {"nLl", { 0xE2, 0x8B, 0x98, 0xCC, 0xB8 }, 5}, +#line 1341 "data/html_entities.gperf" + {"nopf", { 0xF0, 0x9D, 0x95, 0x9F }, 4}, +#line 950 "data/html_entities.gperf" + {"bernou", { 0xE2, 0x84, 0xAC }, 3}, +#line 620 "data/html_entities.gperf" + {"Popf", { 0xE2, 0x84, 0x99 }, 3}, +#line 1750 "data/html_entities.gperf" + {"bopf", { 0xF0, 0x9D, 0x95, 0x93 }, 4}, +#line 108 "data/html_entities.gperf" + {"Zopf", { 0xE2, 0x84, 0xA4 }, 3}, +#line 678 "data/html_entities.gperf" + {"thkap", { 0xE2, 0x89, 0x88 }, 3}, +#line 726 "data/html_entities.gperf" + {"solb", { 0xE2, 0xA7, 0x84 }, 3}, +#line 1629 "data/html_entities.gperf" + {"semi", { 0x3B }, 1}, +#line 896 "data/html_entities.gperf" + {"mp", { 0xE2, 0x88, 0x93 }, 3}, +#line 1155 "data/html_entities.gperf" + {"Qopf", { 0xE2, 0x84, 0x9A }, 3}, +#line 1585 "data/html_entities.gperf" + {"Xopf", { 0xF0, 0x9D, 0x95, 0x8F }, 4}, +#line 870 "data/html_entities.gperf" + {"Vopf", { 0xF0, 0x9D, 0x95, 0x8D }, 4}, +#line 573 "data/html_entities.gperf" + {"imacr", { 0xC4, 0xAB }, 2}, +#line 344 "data/html_entities.gperf" + {"Jopf", { 0xF0, 0x9D, 0x95, 0x81 }, 4}, +#line 398 "data/html_entities.gperf" + {"lnsim", { 0xE2, 0x8B, 0xA6 }, 3}, +#line 907 "data/html_entities.gperf" + {"rArr", { 0xE2, 0x87, 0x92 }, 3}, +#line 968 "data/html_entities.gperf" + {"SquareSubset", { 0xE2, 0x8A, 0x8F }, 3}, +#line 535 "data/html_entities.gperf" + {"lArr", { 0xE2, 0x87, 0x90 }, 3}, +#line 2015 "data/html_entities.gperf" + {"Sopf", { 0xF0, 0x9D, 0x95, 0x8A }, 4}, +#line 850 "data/html_entities.gperf" + {"SquareSuperset", { 0xE2, 0x8A, 0x90 }, 3}, +#line 234 "data/html_entities.gperf" + {"SquareSubsetEqual", { 0xE2, 0x8A, 0x91 }, 3}, +#line 472 "data/html_entities.gperf" + {"uArr", { 0xE2, 0x87, 0x91 }, 3}, +#line 2067 "data/html_entities.gperf" + {"eqsim", { 0xE2, 0x89, 0x82 }, 3}, +#line 1662 "data/html_entities.gperf" + {"SquareSupersetEqual", { 0xE2, 0x8A, 0x92 }, 3}, +#line 1913 "data/html_entities.gperf" + {"ell", { 0xE2, 0x84, 0x93 }, 3}, +#line 1917 "data/html_entities.gperf" + {"uharl", { 0xE2, 0x86, 0xBF }, 3}, +#line 417 "data/html_entities.gperf" + {"rlm", { 0xE2, 0x80, 0x8F }, 3}, +#line 1565 "data/html_entities.gperf" + {"solbar", { 0xE2, 0x8C, 0xBF }, 3}, +#line 1103 "data/html_entities.gperf" + {"popf", { 0xF0, 0x9D, 0x95, 0xA1 }, 4}, +#line 2112 "data/html_entities.gperf" + {"lparlt", { 0xE2, 0xA6, 0x93 }, 3}, +#line 1040 "data/html_entities.gperf" + {"Hopf", { 0xE2, 0x84, 0x8D }, 3}, +#line 1879 "data/html_entities.gperf" + {"rAarr", { 0xE2, 0x87, 0x9B }, 3}, +#line 1727 "data/html_entities.gperf" + {"ulcrop", { 0xE2, 0x8C, 0x8F }, 3}, +#line 1842 "data/html_entities.gperf" + {"lAarr", { 0xE2, 0x87, 0x9A }, 3}, +#line 1200 "data/html_entities.gperf" + {"mldr", { 0xE2, 0x80, 0xA6 }, 3}, +#line 695 "data/html_entities.gperf" + {"lrm", { 0xE2, 0x80, 0x8E }, 3}, +#line 341 "data/html_entities.gperf" + {"LessGreater", { 0xE2, 0x89, 0xB6 }, 3}, +#line 1560 "data/html_entities.gperf" + {"vopf", { 0xF0, 0x9D, 0x95, 0xA7 }, 4}, +#line 1868 "data/html_entities.gperf" + {"Wopf", { 0xF0, 0x9D, 0x95, 0x8E }, 4}, +#line 732 "data/html_entities.gperf" + {"urcrop", { 0xE2, 0x8C, 0x8E }, 3}, +#line 1419 "data/html_entities.gperf" + {"simrarr", { 0xE2, 0xA5, 0xB2 }, 3}, +#line 2081 "data/html_entities.gperf" + {"iprod", { 0xE2, 0xA8, 0xBC }, 3}, +#line 779 "data/html_entities.gperf" + {"profsurf", { 0xE2, 0x8C, 0x93 }, 3}, +#line 102 "data/html_entities.gperf" + {"seArr", { 0xE2, 0x87, 0x98 }, 3}, +#line 1487 "data/html_entities.gperf" + {"NotReverseElement", { 0xE2, 0x88, 0x8C }, 3}, +#line 1415 "data/html_entities.gperf" + {"lE", { 0xE2, 0x89, 0xA6 }, 3}, +#line 507 "data/html_entities.gperf" + {"pound", { 0xC2, 0xA3 }, 2}, +#line 1411 "data/html_entities.gperf" + {"neArr", { 0xE2, 0x87, 0x97 }, 3}, +#line 1153 "data/html_entities.gperf" + {"nlsim", { 0xE2, 0x89, 0xB4 }, 3}, +#line 71 "data/html_entities.gperf" + {"Iopf", { 0xF0, 0x9D, 0x95, 0x80 }, 4}, +#line 1578 "data/html_entities.gperf" + {"Kopf", { 0xF0, 0x9D, 0x95, 0x82 }, 4}, +#line 532 "data/html_entities.gperf" + {"vArr", { 0xE2, 0x87, 0x95 }, 3}, +#line 1286 "data/html_entities.gperf" + {"fopf", { 0xF0, 0x9D, 0x95, 0x97 }, 4}, +#line 230 "data/html_entities.gperf" + {"varsubsetneq", { 0xE2, 0x8A, 0x8A, 0xEF, 0xB8, 0x80 }, 6}, +#line 889 "data/html_entities.gperf" + {"varsubsetneqq", { 0xE2, 0xAB, 0x8B, 0xEF, 0xB8, 0x80 }, 6}, +#line 581 "data/html_entities.gperf" + {"eDDot", { 0xE2, 0xA9, 0xB7 }, 3}, +#line 1746 "data/html_entities.gperf" + {"SquareIntersection", { 0xE2, 0x8A, 0x93 }, 3}, +#line 1977 "data/html_entities.gperf" + {"squarf", { 0xE2, 0x96, 0xAA }, 3}, +#line 591 "data/html_entities.gperf" + {"bnequiv", { 0xE2, 0x89, 0xA1, 0xE2, 0x83, 0xA5 }, 6}, +#line 365 "data/html_entities.gperf" + {"erDot", { 0xE2, 0x89, 0x93 }, 3}, +#line 1704 "data/html_entities.gperf" + {"smashp", { 0xE2, 0xA8, 0xB3 }, 3}, +#line 925 "data/html_entities.gperf" + {"Lopf", { 0xF0, 0x9D, 0x95, 0x83 }, 4}, +#line 1214 "data/html_entities.gperf" + {"Ropf", { 0xE2, 0x84, 0x9D }, 3}, +#line 185 "data/html_entities.gperf" + {"Aopf", { 0xF0, 0x9D, 0x94, 0xB8 }, 4}, +#line 1075 "data/html_entities.gperf" + {"rlhar", { 0xE2, 0x87, 0x8C }, 3}, +#line 831 "data/html_entities.gperf" + {"LessLess", { 0xE2, 0xAA, 0xA1 }, 3}, +#line 1150 "data/html_entities.gperf" + {"Nopf", { 0xE2, 0x84, 0x95 }, 3}, +#line 2043 "data/html_entities.gperf" + {"Mopf", { 0xF0, 0x9D, 0x95, 0x84 }, 4}, +#line 976 "data/html_entities.gperf" + {"uml", { 0xC2, 0xA8 }, 2}, +#line 130 "data/html_entities.gperf" + {"varsupsetneq", { 0xE2, 0x8A, 0x8B, 0xEF, 0xB8, 0x80 }, 6}, +#line 1530 "data/html_entities.gperf" + {"varsupsetneqq", { 0xE2, 0xAB, 0x8C, 0xEF, 0xB8, 0x80 }, 6}, +#line 1836 "data/html_entities.gperf" + {"parsl", { 0xE2, 0xAB, 0xBD }, 3}, +#line 1125 "data/html_entities.gperf" + {"PlusMinus", { 0xC2, 0xB1 }, 2}, +#line 1026 "data/html_entities.gperf" + {"lrhar", { 0xE2, 0x87, 0x8B }, 3}, +#line 14 "data/html_entities.gperf" + {"qopf", { 0xF0, 0x9D, 0x95, 0xA2 }, 4}, +#line 486 "data/html_entities.gperf" + {"marker", { 0xE2, 0x96, 0xAE }, 3}, +#line 1575 "data/html_entities.gperf" + {"prsim", { 0xE2, 0x89, 0xBE }, 3}, +#line 1289 "data/html_entities.gperf" + {"rarrlp", { 0xE2, 0x86, 0xAC }, 3}, +#line 1981 "data/html_entities.gperf" + {"larrlp", { 0xE2, 0x86, 0xAB }, 3}, +#line 1675 "data/html_entities.gperf" + {"DD", { 0xE2, 0x85, 0x85 }, 3}, +#line 302 "data/html_entities.gperf" + {"pm", { 0xC2, 0xB1 }, 2}, +#line 1612 "data/html_entities.gperf" + {"Yopf", { 0xF0, 0x9D, 0x95, 0x90 }, 4}, +#line 1725 "data/html_entities.gperf" + {"Fopf", { 0xF0, 0x9D, 0x94, 0xBD }, 4}, +#line 1543 "data/html_entities.gperf" + {"lnE", { 0xE2, 0x89, 0xA8 }, 3}, +#line 1215 "data/html_entities.gperf" + {"ETH", { 0xC3, 0x90 }, 2}, +#line 1384 "data/html_entities.gperf" + {"map", { 0xE2, 0x86, 0xA6 }, 3}, +#line 874 "data/html_entities.gperf" + {"Uopf", { 0xF0, 0x9D, 0x95, 0x8C }, 4}, +#line 2050 "data/html_entities.gperf" + {"Topf", { 0xF0, 0x9D, 0x95, 0x8B }, 4}, +#line 1263 "data/html_entities.gperf" + {"Im", { 0xE2, 0x84, 0x91 }, 3}, +#line 2021 "data/html_entities.gperf" + {"dlcorn", { 0xE2, 0x8C, 0x9E }, 3}, +#line 594 "data/html_entities.gperf" + {"drcorn", { 0xE2, 0x8C, 0x9F }, 3}, +#line 1226 "data/html_entities.gperf" + {"Precedes", { 0xE2, 0x89, 0xBA }, 3}, +#line 768 "data/html_entities.gperf" + {"ni", { 0xE2, 0x88, 0x8B }, 3}, +#line 1149 "data/html_entities.gperf" + {"napE", { 0xE2, 0xA9, 0xB0, 0xCC, 0xB8 }, 5}, +#line 482 "data/html_entities.gperf" + {"Pi", { 0xCE, 0xA0 }, 2}, +#line 1430 "data/html_entities.gperf" + {"preceq", { 0xE2, 0xAA, 0xAF }, 3}, +#line 1533 "data/html_entities.gperf" + {"nlE", { 0xE2, 0x89, 0xA6, 0xCC, 0xB8 }, 5}, +#line 2054 "data/html_entities.gperf" + {"rbrace", { 0x7D }, 1}, +#line 212 "data/html_entities.gperf" + {"lbrace", { 0x7B }, 1}, +#line 1351 "data/html_entities.gperf" + {"Xi", { 0xCE, 0x9E }, 2}, +#line 733 "data/html_entities.gperf" + {"iopf", { 0xF0, 0x9D, 0x95, 0x9A }, 4}, +#line 10 "data/html_entities.gperf" + {"nvap", { 0xE2, 0x89, 0x8D, 0xE2, 0x83, 0x92 }, 6}, +#line 566 "data/html_entities.gperf" + {"frasl", { 0xE2, 0x81, 0x84 }, 3}, +#line 340 "data/html_entities.gperf" + {"rbrksld", { 0xE2, 0xA6, 0x8E }, 3}, +#line 2025 "data/html_entities.gperf" + {"lbrksld", { 0xE2, 0xA6, 0x8F }, 3}, +#line 1381 "data/html_entities.gperf" + {"lesseqqgtr", { 0xE2, 0xAA, 0x8B }, 3}, +#line 463 "data/html_entities.gperf" + {"simne", { 0xE2, 0x89, 0x86 }, 3}, +#line 895 "data/html_entities.gperf" + {"pi", { 0xCF, 0x80 }, 2}, +#line 1002 "data/html_entities.gperf" + {"swArr", { 0xE2, 0x87, 0x99 }, 3}, +#line 969 "data/html_entities.gperf" + {"backprime", { 0xE2, 0x80, 0xB5 }, 3}, +#line 1705 "data/html_entities.gperf" + {"PrecedesSlantEqual", { 0xE2, 0x89, 0xBC }, 3}, +#line 1690 "data/html_entities.gperf" + {"nwArr", { 0xE2, 0x87, 0x96 }, 3}, +#line 1555 "data/html_entities.gperf" + {"rsqb", { 0x5D }, 1}, +#line 288 "data/html_entities.gperf" + {"lsqb", { 0x5B }, 1}, +#line 956 "data/html_entities.gperf" + {"nesim", { 0xE2, 0x89, 0x82, 0xCC, 0xB8 }, 5}, +#line 2087 "data/html_entities.gperf" + {"Emacr", { 0xC4, 0x92 }, 2}, +#line 1318 "data/html_entities.gperf" + {"wp", { 0xE2, 0x84, 0x98 }, 3}, +#line 1496 "data/html_entities.gperf" + {"sqcaps", { 0xE2, 0x8A, 0x93, 0xEF, 0xB8, 0x80 }, 6}, +#line 305 "data/html_entities.gperf" + {"prE", { 0xE2, 0xAA, 0xB3 }, 3}, +#line 966 "data/html_entities.gperf" + {"Bopf", { 0xF0, 0x9D, 0x94, 0xB9 }, 4}, +#line 665 "data/html_entities.gperf" + {"esdot", { 0xE2, 0x89, 0x90 }, 3}, +#line 913 "data/html_entities.gperf" + {"dopf", { 0xF0, 0x9D, 0x95, 0x95 }, 4}, +#line 1308 "data/html_entities.gperf" + {"imof", { 0xE2, 0x8A, 0xB7 }, 3}, +#line 1754 "data/html_entities.gperf" + {"lozf", { 0xE2, 0xA7, 0xAB }, 3}, +#line 1854 "data/html_entities.gperf" + {"wr", { 0xE2, 0x89, 0x80 }, 3}, +#line 787 "data/html_entities.gperf" + {"macr", { 0xC2, 0xAF }, 2}, +#line 1030 "data/html_entities.gperf" + {"Sqrt", { 0xE2, 0x88, 0x9A }, 3}, +#line 82 "data/html_entities.gperf" + {"Dopf", { 0xF0, 0x9D, 0x94, 0xBB }, 4}, +#line 836 "data/html_entities.gperf" + {"Or", { 0xE2, 0xA9, 0x94 }, 3}, +#line 2076 "data/html_entities.gperf" + {"sqcap", { 0xE2, 0x8A, 0x93 }, 3}, +#line 1013 "data/html_entities.gperf" + {"Bernoullis", { 0xE2, 0x84, 0xAC }, 3}, +#line 533 "data/html_entities.gperf" + {"part", { 0xE2, 0x88, 0x82 }, 3}, +#line 1169 "data/html_entities.gperf" + {"dArr", { 0xE2, 0x87, 0x93 }, 3}, +#line 1657 "data/html_entities.gperf" + {"bnot", { 0xE2, 0x8C, 0x90 }, 3}, +#line 311 "data/html_entities.gperf" + {"preccurlyeq", { 0xE2, 0x89, 0xBC }, 3}, +#line 1922 "data/html_entities.gperf" + {"dharl", { 0xE2, 0x87, 0x83 }, 3}, +#line 1683 "data/html_entities.gperf" + {"pluscir", { 0xE2, 0xA8, 0xA2 }, 3}, +#line 792 "data/html_entities.gperf" + {"eqvparsl", { 0xE2, 0xA7, 0xA5 }, 3}, +#line 1671 "data/html_entities.gperf" + {"dlcrop", { 0xE2, 0x8C, 0x8D }, 3}, +#line 1576 "data/html_entities.gperf" + {"NotSubsetEqual", { 0xE2, 0x8A, 0x88 }, 3}, +#line 448 "data/html_entities.gperf" + {"epsiv", { 0xCF, 0xB5 }, 2}, +#line 276 "data/html_entities.gperf" + {"nsub", { 0xE2, 0x8A, 0x84 }, 3}, +#line 563 "data/html_entities.gperf" + {"varphi", { 0xCF, 0x95 }, 2}, +#line 1610 "data/html_entities.gperf" + {"drcrop", { 0xE2, 0x8C, 0x8C }, 3}, +#line 403 "data/html_entities.gperf" + {"dotplus", { 0xE2, 0x88, 0x94 }, 3}, +#line 2012 "data/html_entities.gperf" + {"Element", { 0xE2, 0x88, 0x88 }, 3}, +#line 1617 "data/html_entities.gperf" + {"eDot", { 0xE2, 0x89, 0x91 }, 3}, +#line 682 "data/html_entities.gperf" + {"diams", { 0xE2, 0x99, 0xA6 }, 3}, +#line 2090 "data/html_entities.gperf" + {"die", { 0xC2, 0xA8 }, 2}, +#line 395 "data/html_entities.gperf" + {"NotSupersetEqual", { 0xE2, 0x8A, 0x89 }, 3}, +#line 335 "data/html_entities.gperf" + {"brvbar", { 0xC2, 0xA6 }, 2}, +#line 880 "data/html_entities.gperf" + {"incare", { 0xE2, 0x84, 0x85 }, 3}, +#line 2116 "data/html_entities.gperf" + {"nsupset", { 0xE2, 0x8A, 0x83, 0xE2, 0x83, 0x92 }, 6}, +#line 1609 "data/html_entities.gperf" + {"nsubset", { 0xE2, 0x8A, 0x82, 0xE2, 0x83, 0x92 }, 6}, +#line 263 "data/html_entities.gperf" + {"nsup", { 0xE2, 0x8A, 0x85 }, 3}, +#line 1274 "data/html_entities.gperf" + {"easter", { 0xE2, 0xA9, 0xAE }, 3}, +#line 369 "data/html_entities.gperf" + {"mlcp", { 0xE2, 0xAB, 0x9B }, 3}, +#line 614 "data/html_entities.gperf" + {"parallel", { 0xE2, 0x88, 0xA5 }, 3}, +#line 1079 "data/html_entities.gperf" + {"equals", { 0x3D }, 1}, +#line 1761 "data/html_entities.gperf" + {"LessTilde", { 0xE2, 0x89, 0xB2 }, 3}, +#line 1825 "data/html_entities.gperf" + {"equiv", { 0xE2, 0x89, 0xA1 }, 3}, +#line 508 "data/html_entities.gperf" + {"flat", { 0xE2, 0x99, 0xAD }, 3}, +#line 111 "data/html_entities.gperf" + {"forall", { 0xE2, 0x88, 0x80 }, 3}, +#line 1992 "data/html_entities.gperf" + {"NotHumpEqual", { 0xE2, 0x89, 0x8F, 0xCC, 0xB8 }, 5}, +#line 379 "data/html_entities.gperf" + {"rppolint", { 0xE2, 0xA8, 0x92 }, 3}, +#line 1804 "data/html_entities.gperf" + {"bNot", { 0xE2, 0xAB, 0xAD }, 3}, +#line 126 "data/html_entities.gperf" + {"forkv", { 0xE2, 0xAB, 0x99 }, 3}, +#line 1281 "data/html_entities.gperf" + {"nsupe", { 0xE2, 0x8A, 0x89 }, 3}, +#line 1170 "data/html_entities.gperf" + {"nsube", { 0xE2, 0x8A, 0x88 }, 3}, +#line 1178 "data/html_entities.gperf" + {"becaus", { 0xE2, 0x88, 0xB5 }, 3}, +#line 228 "data/html_entities.gperf" + {"seswar", { 0xE2, 0xA4, 0xA9 }, 3}, +#line 734 "data/html_entities.gperf" + {"ii", { 0xE2, 0x85, 0x88 }, 3}, +#line 1426 "data/html_entities.gperf" + {"nsqsube", { 0xE2, 0x8B, 0xA2 }, 3}, +#line 1398 "data/html_entities.gperf" + {"opar", { 0xE2, 0xA6, 0xB7 }, 3}, +#line 680 "data/html_entities.gperf" + {"because", { 0xE2, 0x88, 0xB5 }, 3}, +#line 1121 "data/html_entities.gperf" + {"lvertneqq", { 0xE2, 0x89, 0xA8, 0xEF, 0xB8, 0x80 }, 6}, +#line 324 "data/html_entities.gperf" + {"sim", { 0xE2, 0x88, 0xBC }, 3}, +#line 1173 "data/html_entities.gperf" + {"measuredangle", { 0xE2, 0x88, 0xA1 }, 3}, +#line 380 "data/html_entities.gperf" + {"mopf", { 0xF0, 0x9D, 0x95, 0x9E }, 4}, +#line 1923 "data/html_entities.gperf" + {"period", { 0x2E }, 1}, +#line 903 "data/html_entities.gperf" + {"or", { 0xE2, 0x88, 0xA8 }, 3}, +#line 1297 "data/html_entities.gperf" + {"rho", { 0xCF, 0x81 }, 2}, +#line 1687 "data/html_entities.gperf" + {"olt", { 0xE2, 0xA7, 0x80 }, 3}, +#line 1232 "data/html_entities.gperf" + {"notin", { 0xE2, 0x88, 0x89 }, 3}, +#line 1350 "data/html_entities.gperf" + {"Eopf", { 0xF0, 0x9D, 0x94, 0xBC }, 4}, +#line 1433 "data/html_entities.gperf" + {"nsqsupe", { 0xE2, 0x8B, 0xA3 }, 3}, +#line 621 "data/html_entities.gperf" + {"ForAll", { 0xE2, 0x88, 0x80 }, 3}, +#line 684 "data/html_entities.gperf" + {"nvrArr", { 0xE2, 0xA4, 0x83 }, 3}, +#line 210 "data/html_entities.gperf" + {"oS", { 0xE2, 0x93, 0x88 }, 3}, +#line 562 "data/html_entities.gperf" + {"nsupseteq", { 0xE2, 0x8A, 0x89 }, 3}, +#line 634 "data/html_entities.gperf" + {"nsubseteq", { 0xE2, 0x8A, 0x88 }, 3}, +#line 284 "data/html_entities.gperf" + {"ratio", { 0xE2, 0x88, 0xB6 }, 3}, +#line 1285 "data/html_entities.gperf" + {"thetav", { 0xCF, 0x91 }, 2}, +#line 908 "data/html_entities.gperf" + {"Vert", { 0xE2, 0x80, 0x96 }, 3}, +#line 1393 "data/html_entities.gperf" + {"thorn", { 0xC3, 0xBE }, 2}, +#line 717 "data/html_entities.gperf" + {"Del", { 0xE2, 0x88, 0x87 }, 3}, +#line 572 "data/html_entities.gperf" + {"olarr", { 0xE2, 0x86, 0xBA }, 3}, +#line 1005 "data/html_entities.gperf" + {"Omacr", { 0xC5, 0x8C }, 2}, +#line 821 "data/html_entities.gperf" + {"eqslantgtr", { 0xE2, 0xAA, 0x96 }, 3}, +#line 651 "data/html_entities.gperf" + {"Cap", { 0xE2, 0x8B, 0x92 }, 3}, +#line 1857 "data/html_entities.gperf" + {"simplus", { 0xE2, 0xA8, 0xA4 }, 3}, +#line 1747 "data/html_entities.gperf" + {"eqslantless", { 0xE2, 0xAA, 0x95 }, 3}, +#line 1333 "data/html_entities.gperf" + {"orarr", { 0xE2, 0x86, 0xBB }, 3}, +#line 1909 "data/html_entities.gperf" + {"wedbar", { 0xE2, 0xA9, 0x9F }, 3}, +#line 686 "data/html_entities.gperf" + {"NotLess", { 0xE2, 0x89, 0xAE }, 3}, +#line 447 "data/html_entities.gperf" + {"rscr", { 0xF0, 0x9D, 0x93, 0x87 }, 4}, +#line 677 "data/html_entities.gperf" + {"tscr", { 0xF0, 0x9D, 0x93, 0x89 }, 4}, +#line 1098 "data/html_entities.gperf" + {"lscr", { 0xF0, 0x9D, 0x93, 0x81 }, 4}, +#line 899 "data/html_entities.gperf" + {"sscr", { 0xF0, 0x9D, 0x93, 0x88 }, 4}, +#line 1603 "data/html_entities.gperf" + {"escr", { 0xE2, 0x84, 0xAF }, 3}, +#line 412 "data/html_entities.gperf" + {"uscr", { 0xF0, 0x9D, 0x93, 0x8A }, 4}, +#line 1824 "data/html_entities.gperf" + {"Cross", { 0xE2, 0xA8, 0xAF }, 3}, +#line 708 "data/html_entities.gperf" + {"nscr", { 0xF0, 0x9D, 0x93, 0x83 }, 4}, +#line 1323 "data/html_entities.gperf" + {"Pscr", { 0xF0, 0x9D, 0x92, 0xAB }, 4}, +#line 170 "data/html_entities.gperf" + {"bscr", { 0xF0, 0x9D, 0x92, 0xB7 }, 4}, +#line 1542 "data/html_entities.gperf" + {"vert", { 0x7C }, 1}, +#line 1541 "data/html_entities.gperf" + {"oror", { 0xE2, 0xA9, 0x96 }, 3}, +#line 736 "data/html_entities.gperf" + {"DoubleLeftTee", { 0xE2, 0xAB, 0xA4 }, 3}, +#line 1033 "data/html_entities.gperf" + {"mDDot", { 0xE2, 0x88, 0xBA }, 3}, +#line 636 "data/html_entities.gperf" + {"Zscr", { 0xF0, 0x9D, 0x92, 0xB5 }, 4}, +#line 195 "data/html_entities.gperf" + {"NotLessLess", { 0xE2, 0x89, 0xAA, 0xCC, 0xB8 }, 5}, +#line 1148 "data/html_entities.gperf" + {"Qscr", { 0xF0, 0x9D, 0x92, 0xAC }, 4}, +#line 1916 "data/html_entities.gperf" + {"Xscr", { 0xF0, 0x9D, 0x92, 0xB3 }, 4}, +#line 478 "data/html_entities.gperf" + {"Vscr", { 0xF0, 0x9D, 0x92, 0xB1 }, 4}, +#line 986 "data/html_entities.gperf" + {"Jscr", { 0xF0, 0x9D, 0x92, 0xA5 }, 4}, +#line 27 "data/html_entities.gperf" + {"vBarv", { 0xE2, 0xAB, 0xA9 }, 3}, +#line 146 "data/html_entities.gperf" + {"COPY", { 0xC2, 0xA9 }, 2}, +#line 493 "data/html_entities.gperf" + {"loz", { 0xE2, 0x97, 0x8A }, 3}, +#line 1399 "data/html_entities.gperf" + {"Sscr", { 0xF0, 0x9D, 0x92, 0xAE }, 4}, +#line 1104 "data/html_entities.gperf" + {"nsmid", { 0xE2, 0x88, 0xA4 }, 3}, +#line 433 "data/html_entities.gperf" + {"nvHarr", { 0xE2, 0xA4, 0x84 }, 3}, +#line 227 "data/html_entities.gperf" + {"NotLessGreater", { 0xE2, 0x89, 0xB8 }, 3}, +#line 1852 "data/html_entities.gperf" + {"between", { 0xE2, 0x89, 0xAC }, 3}, +#line 162 "data/html_entities.gperf" + {"NotLessTilde", { 0xE2, 0x89, 0xB4 }, 3}, +#line 357 "data/html_entities.gperf" + {"NotLessEqual", { 0xE2, 0x89, 0xB0 }, 3}, +#line 1644 "data/html_entities.gperf" + {"Rho", { 0xCE, 0xA1 }, 2}, +#line 1127 "data/html_entities.gperf" + {"notinvb", { 0xE2, 0x8B, 0xB7 }, 3}, +#line 298 "data/html_entities.gperf" + {"pscr", { 0xF0, 0x9D, 0x93, 0x85 }, 4}, +#line 1404 "data/html_entities.gperf" + {"Hscr", { 0xE2, 0x84, 0x8B }, 3}, +#line 1813 "data/html_entities.gperf" + {"vscr", { 0xF0, 0x9D, 0x93, 0x8B }, 4}, +#line 1192 "data/html_entities.gperf" + {"Wscr", { 0xF0, 0x9D, 0x92, 0xB2 }, 4}, +#line 184 "data/html_entities.gperf" + {"shortmid", { 0xE2, 0x88, 0xA3 }, 3}, +#line 879 "data/html_entities.gperf" + {"zopf", { 0xF0, 0x9D, 0x95, 0xAB }, 4}, +#line 392 "data/html_entities.gperf" + {"Iscr", { 0xE2, 0x84, 0x90 }, 3}, +#line 1230 "data/html_entities.gperf" + {"Kscr", { 0xF0, 0x9D, 0x92, 0xA6 }, 4}, +#line 1368 "data/html_entities.gperf" + {"fscr", { 0xF0, 0x9D, 0x92, 0xBB }, 4}, +#line 918 "data/html_entities.gperf" + {"ShortLeftArrow", { 0xE2, 0x86, 0x90 }, 3}, +#line 325 "data/html_entities.gperf" + {"Lscr", { 0xE2, 0x84, 0x92 }, 3}, +#line 1483 "data/html_entities.gperf" + {"Rscr", { 0xE2, 0x84, 0x9B }, 3}, +#line 522 "data/html_entities.gperf" + {"female", { 0xE2, 0x99, 0x80 }, 3}, +#line 338 "data/html_entities.gperf" + {"Ascr", { 0xF0, 0x9D, 0x92, 0x9C }, 4}, +#line 407 "data/html_entities.gperf" + {"nsupseteqq", { 0xE2, 0xAB, 0x86, 0xCC, 0xB8 }, 5}, +#line 1960 "data/html_entities.gperf" + {"nsubseteqq", { 0xE2, 0xAB, 0x85, 0xCC, 0xB8 }, 5}, +#line 1816 "data/html_entities.gperf" + {"Nscr", { 0xF0, 0x9D, 0x92, 0xA9 }, 4}, +#line 2130 "data/html_entities.gperf" + {"nvsim", { 0xE2, 0x88, 0xBC, 0xE2, 0x83, 0x92 }, 6}, +#line 1765 "data/html_entities.gperf" + {"Mscr", { 0xE2, 0x84, 0xB3 }, 3}, +#line 150 "data/html_entities.gperf" + {"roplus", { 0xE2, 0xA8, 0xAE }, 3}, +#line 155 "data/html_entities.gperf" + {"loplus", { 0xE2, 0xA8, 0xAD }, 3}, +#line 1930 "data/html_entities.gperf" + {"qscr", { 0xF0, 0x9D, 0x93, 0x86 }, 4}, +#line 646 "data/html_entities.gperf" + {"real", { 0xE2, 0x84, 0x9C }, 3}, +#line 1199 "data/html_entities.gperf" + {"profline", { 0xE2, 0x8C, 0x92 }, 3}, +#line 1386 "data/html_entities.gperf" + {"omacr", { 0xC5, 0x8D }, 2}, +#line 413 "data/html_entities.gperf" + {"blacklozenge", { 0xE2, 0xA7, 0xAB }, 3}, +#line 1376 "data/html_entities.gperf" + {"nspar", { 0xE2, 0x88, 0xA6 }, 3}, +#line 873 "data/html_entities.gperf" + {"llhard", { 0xE2, 0xA5, 0xAB }, 3}, +#line 856 "data/html_entities.gperf" + {"Yscr", { 0xF0, 0x9D, 0x92, 0xB4 }, 4}, +#line 561 "data/html_entities.gperf" + {"Fscr", { 0xE2, 0x84, 0xB1 }, 3}, +#line 389 "data/html_entities.gperf" + {"reals", { 0xE2, 0x84, 0x9D }, 3}, +#line 2046 "data/html_entities.gperf" + {"DoubleDot", { 0xC2, 0xA8 }, 2}, +#line 1231 "data/html_entities.gperf" + {"NotElement", { 0xE2, 0x88, 0x89 }, 3}, +#line 1461 "data/html_entities.gperf" + {"lrhard", { 0xE2, 0xA5, 0xAD }, 3}, +#line 1583 "data/html_entities.gperf" + {"RoundImplies", { 0xE2, 0xA5, 0xB0 }, 3}, +#line 2018 "data/html_entities.gperf" + {"UpEquilibrium", { 0xE2, 0xA5, 0xAE }, 3}, +#line 1380 "data/html_entities.gperf" + {"Uscr", { 0xF0, 0x9D, 0x92, 0xB0 }, 4}, +#line 571 "data/html_entities.gperf" + {"wopf", { 0xF0, 0x9D, 0x95, 0xA8 }, 4}, +#line 467 "data/html_entities.gperf" + {"backsimeq", { 0xE2, 0x8B, 0x8D }, 3}, +#line 2102 "data/html_entities.gperf" + {"Tscr", { 0xF0, 0x9D, 0x92, 0xAF }, 4}, +#line 560 "data/html_entities.gperf" + {"Because", { 0xE2, 0x88, 0xB5 }, 3}, +#line 1373 "data/html_entities.gperf" + {"nsccue", { 0xE2, 0x8B, 0xA1 }, 3}, +#line 1449 "data/html_entities.gperf" + {"operp", { 0xE2, 0xA6, 0xB9 }, 3}, +#line 1803 "data/html_entities.gperf" + {"Oopf", { 0xF0, 0x9D, 0x95, 0x86 }, 4}, +#line 1343 "data/html_entities.gperf" + {"mid", { 0xE2, 0x88, 0xA3 }, 3}, +#line 1204 "data/html_entities.gperf" + {"setmn", { 0xE2, 0x88, 0x96 }, 3}, +#line 405 "data/html_entities.gperf" + {"rarrsim", { 0xE2, 0xA5, 0xB4 }, 3}, +#line 292 "data/html_entities.gperf" + {"larrsim", { 0xE2, 0xA5, 0xB3 }, 3}, +#line 320 "data/html_entities.gperf" + {"sstarf", { 0xE2, 0x8B, 0x86 }, 3}, +#line 1322 "data/html_entities.gperf" + {"PrecedesTilde", { 0xE2, 0x89, 0xBE }, 3}, +#line 1775 "data/html_entities.gperf" + {"ssmile", { 0xE2, 0x8C, 0xA3 }, 3}, +#line 1889 "data/html_entities.gperf" + {"therefore", { 0xE2, 0x88, 0xB4 }, 3}, +#line 1273 "data/html_entities.gperf" + {"ShortRightArrow", { 0xE2, 0x86, 0x92 }, 3}, +#line 2084 "data/html_entities.gperf" + {"ord", { 0xE2, 0xA9, 0x9D }, 3}, +#line 1222 "data/html_entities.gperf" + {"rect", { 0xE2, 0x96, 0xAD }, 3}, +#line 1354 "data/html_entities.gperf" + {"sect", { 0xC2, 0xA7 }, 2}, +#line 252 "data/html_entities.gperf" + {"niv", { 0xE2, 0x88, 0x8B }, 3}, +#line 1042 "data/html_entities.gperf" + {"iscr", { 0xF0, 0x9D, 0x92, 0xBE }, 4}, +#line 1469 "data/html_entities.gperf" + {"midast", { 0x2A }, 1}, +#line 1709 "data/html_entities.gperf" + {"lessdot", { 0xE2, 0x8B, 0x96 }, 3}, +#line 1282 "data/html_entities.gperf" + {"olcir", { 0xE2, 0xA6, 0xBE }, 3}, +#line 2092 "data/html_entities.gperf" + {"diam", { 0xE2, 0x8B, 0x84 }, 3}, +#line 1467 "data/html_entities.gperf" + {"mstpos", { 0xE2, 0x88, 0xBE }, 3}, +#line 1936 "data/html_entities.gperf" + {"piv", { 0xCF, 0x96 }, 2}, +#line 1202 "data/html_entities.gperf" + {"rfr", { 0xF0, 0x9D, 0x94, 0xAF }, 4}, +#line 91 "data/html_entities.gperf" + {"tfr", { 0xF0, 0x9D, 0x94, 0xB1 }, 4}, +#line 139 "data/html_entities.gperf" + {"lfr", { 0xF0, 0x9D, 0x94, 0xA9 }, 4}, +#line 833 "data/html_entities.gperf" + {"sfr", { 0xF0, 0x9D, 0x94, 0xB0 }, 4}, +#line 1943 "data/html_entities.gperf" + {"efr", { 0xF0, 0x9D, 0x94, 0xA2 }, 4}, +#line 916 "data/html_entities.gperf" + {"Bscr", { 0xE2, 0x84, 0xAC }, 3}, +#line 2049 "data/html_entities.gperf" + {"Copf", { 0xE2, 0x84, 0x82 }, 3}, +#line 462 "data/html_entities.gperf" + {"dscr", { 0xF0, 0x9D, 0x92, 0xB9 }, 4}, +#line 1300 "data/html_entities.gperf" + {"ufr", { 0xF0, 0x9D, 0x94, 0xB2 }, 4}, +#line 1044 "data/html_entities.gperf" + {"excl", { 0x21 }, 1}, +#line 1716 "data/html_entities.gperf" + {"nfr", { 0xF0, 0x9D, 0x94, 0xAB }, 4}, +#line 2126 "data/html_entities.gperf" + {"Pfr", { 0xF0, 0x9D, 0x94, 0x93 }, 4}, +#line 1505 "data/html_entities.gperf" + {"bfr", { 0xF0, 0x9D, 0x94, 0x9F }, 4}, +#line 974 "data/html_entities.gperf" + {"ordf", { 0xC2, 0xAA }, 2}, +#line 1061 "data/html_entities.gperf" + {"Zfr", { 0xE2, 0x84, 0xA8 }, 3}, +#line 1591 "data/html_entities.gperf" + {"Dscr", { 0xF0, 0x9D, 0x92, 0x9F }, 4}, +#line 1160 "data/html_entities.gperf" + {"Qfr", { 0xF0, 0x9D, 0x94, 0x94 }, 4}, +#line 351 "data/html_entities.gperf" + {"Xfr", { 0xF0, 0x9D, 0x94, 0x9B }, 4}, +#line 2031 "data/html_entities.gperf" + {"Vfr", { 0xF0, 0x9D, 0x94, 0x99 }, 4}, +#line 451 "data/html_entities.gperf" + {"Jfr", { 0xF0, 0x9D, 0x94, 0x8D }, 4}, +#line 1182 "data/html_entities.gperf" + {"percnt", { 0x25 }, 1}, +#line 2083 "data/html_entities.gperf" + {"Sfr", { 0xF0, 0x9D, 0x94, 0x96 }, 4}, +#line 58 "data/html_entities.gperf" + {"Equal", { 0xE2, 0xA9, 0xB5 }, 3}, +#line 107 "data/html_entities.gperf" + {"NotCupCap", { 0xE2, 0x89, 0xAD }, 3}, +#line 1737 "data/html_entities.gperf" + {"barwed", { 0xE2, 0x8C, 0x85 }, 3}, +#line 1766 "data/html_entities.gperf" + {"pfr", { 0xF0, 0x9D, 0x94, 0xAD }, 4}, +#line 993 "data/html_entities.gperf" + {"Hfr", { 0xE2, 0x84, 0x8C }, 3}, +#line 1980 "data/html_entities.gperf" + {"olcross", { 0xE2, 0xA6, 0xBB }, 3}, +#line 1664 "data/html_entities.gperf" + {"vfr", { 0xF0, 0x9D, 0x94, 0xB3 }, 4}, +#line 1616 "data/html_entities.gperf" + {"THORN", { 0xC3, 0x9E }, 2}, +#line 470 "data/html_entities.gperf" + {"Coproduct", { 0xE2, 0x88, 0x90 }, 3}, +#line 1694 "data/html_entities.gperf" + {"Wfr", { 0xF0, 0x9D, 0x94, 0x9A }, 4}, +#line 866 "data/html_entities.gperf" + {"ohm", { 0xCE, 0xA9 }, 2}, +#line 164 "data/html_entities.gperf" + {"oopf", { 0xF0, 0x9D, 0x95, 0xA0 }, 4}, +#line 258 "data/html_entities.gperf" + {"Ifr", { 0xE2, 0x84, 0x91 }, 3}, +#line 1619 "data/html_entities.gperf" + {"Kfr", { 0xF0, 0x9D, 0x94, 0x8E }, 4}, +#line 1955 "data/html_entities.gperf" + {"NotLeftTriangleBar", { 0xE2, 0xA7, 0x8F, 0xCC, 0xB8 }, 5}, +#line 1521 "data/html_entities.gperf" + {"NotLeftTriangle", { 0xE2, 0x8B, 0xAA }, 3}, +#line 1947 "data/html_entities.gperf" + {"ffr", { 0xF0, 0x9D, 0x94, 0xA3 }, 4}, +#line 845 "data/html_entities.gperf" + {"NotLeftTriangleEqual", { 0xE2, 0x8B, 0xAC }, 3}, +#line 2038 "data/html_entities.gperf" + {"siml", { 0xE2, 0xAA, 0x9D }, 3}, +#line 933 "data/html_entities.gperf" + {"nLeftrightarrow", { 0xE2, 0x87, 0x8E }, 3}, +#line 26 "data/html_entities.gperf" + {"Lfr", { 0xF0, 0x9D, 0x94, 0x8F }, 4}, +#line 1550 "data/html_entities.gperf" + {"Rfr", { 0xE2, 0x84, 0x9C }, 3}, +#line 312 "data/html_entities.gperf" + {"Afr", { 0xF0, 0x9D, 0x94, 0x84 }, 4}, +#line 595 "data/html_entities.gperf" + {"nltrie", { 0xE2, 0x8B, 0xAC }, 3}, +#line 1778 "data/html_entities.gperf" + {"mho", { 0xE2, 0x84, 0xA7 }, 3}, +#line 360 "data/html_entities.gperf" + {"Nfr", { 0xF0, 0x9D, 0x94, 0x91 }, 4}, +#line 1894 "data/html_entities.gperf" + {"gl", { 0xE2, 0x89, 0xB7 }, 3}, +#line 169 "data/html_entities.gperf" + {"Mfr", { 0xF0, 0x9D, 0x94, 0x90 }, 4}, +#line 123 "data/html_entities.gperf" + {"nrtrie", { 0xE2, 0x8B, 0xAD }, 3}, +#line 30 "data/html_entities.gperf" + {"Therefore", { 0xE2, 0x88, 0xB4 }, 3}, +#line 1352 "data/html_entities.gperf" + {"qfr", { 0xF0, 0x9D, 0x94, 0xAE }, 4}, +#line 1642 "data/html_entities.gperf" + {"backepsilon", { 0xCF, 0xB6 }, 2}, +#line 1988 "data/html_entities.gperf" + {"target", { 0xE2, 0x8C, 0x96 }, 3}, +#line 1229 "data/html_entities.gperf" + {"nleftrightarrow", { 0xE2, 0x86, 0xAE }, 3}, +#line 1489 "data/html_entities.gperf" + {"rarrfs", { 0xE2, 0xA4, 0x9E }, 3}, +#line 1563 "data/html_entities.gperf" + {"larrfs", { 0xE2, 0xA4, 0x9D }, 3}, +#line 309 "data/html_entities.gperf" + {"nvlArr", { 0xE2, 0xA4, 0x82 }, 3}, +#line 1797 "data/html_entities.gperf" + {"plussim", { 0xE2, 0xA8, 0xA6 }, 3}, +#line 1522 "data/html_entities.gperf" + {"epsilon", { 0xCE, 0xB5 }, 2}, +#line 167 "data/html_entities.gperf" + {"upsilon", { 0xCF, 0x85 }, 2}, +#line 2080 "data/html_entities.gperf" + {"Yfr", { 0xF0, 0x9D, 0x94, 0x9C }, 4}, +#line 612 "data/html_entities.gperf" + {"Ffr", { 0xF0, 0x9D, 0x94, 0x89 }, 4}, +#line 375 "data/html_entities.gperf" + {"diamondsuit", { 0xE2, 0x99, 0xA6 }, 3}, +#line 778 "data/html_entities.gperf" + {"gnap", { 0xE2, 0xAA, 0x8A }, 3}, +#line 2125 "data/html_entities.gperf" + {"scap", { 0xE2, 0xAA, 0xB8 }, 3}, +#line 713 "data/html_entities.gperf" + {"nsupE", { 0xE2, 0xAB, 0x86, 0xCC, 0xB8 }, 5}, +#line 1717 "data/html_entities.gperf" + {"nsubE", { 0xE2, 0xAB, 0x85, 0xCC, 0xB8 }, 5}, +#line 1918 "data/html_entities.gperf" + {"ncap", { 0xE2, 0xA9, 0x83 }, 3}, +#line 118 "data/html_entities.gperf" + {"Ufr", { 0xF0, 0x9D, 0x94, 0x98 }, 4}, +#line 1821 "data/html_entities.gperf" + {"rcub", { 0x7D }, 1}, +#line 1377 "data/html_entities.gperf" + {"lcub", { 0x7B }, 1}, +#line 1637 "data/html_entities.gperf" + {"gne", { 0xE2, 0xAA, 0x88 }, 3}, +#line 2093 "data/html_entities.gperf" + {"sce", { 0xE2, 0xAA, 0xB0 }, 3}, +#line 442 "data/html_entities.gperf" + {"Tfr", { 0xF0, 0x9D, 0x94, 0x97 }, 4}, +#line 119 "data/html_entities.gperf" + {"mscr", { 0xF0, 0x9D, 0x93, 0x82 }, 4}, +#line 1344 "data/html_entities.gperf" + {"diamond", { 0xE2, 0x8B, 0x84 }, 3}, +#line 1091 "data/html_entities.gperf" + {"nsucceq", { 0xE2, 0xAA, 0xB0, 0xCC, 0xB8 }, 5}, +#line 1719 "data/html_entities.gperf" + {"ordm", { 0xC2, 0xBA }, 2}, +#line 1770 "data/html_entities.gperf" + {"exist", { 0xE2, 0x88, 0x83 }, 3}, +#line 1422 "data/html_entities.gperf" + {"Diamond", { 0xE2, 0x8B, 0x84 }, 3}, +#line 1112 "data/html_entities.gperf" + {"Escr", { 0xE2, 0x84, 0xB0 }, 3}, +#line 555 "data/html_entities.gperf" + {"prnap", { 0xE2, 0xAA, 0xB9 }, 3}, +#line 906 "data/html_entities.gperf" + {"rcaron", { 0xC5, 0x99 }, 2}, +#line 109 "data/html_entities.gperf" + {"tcaron", { 0xC5, 0xA5 }, 2}, +#line 582 "data/html_entities.gperf" + {"lcaron", { 0xC4, 0xBE }, 2}, +#line 1421 "data/html_entities.gperf" + {"scaron", { 0xC5, 0xA1 }, 2}, +#line 824 "data/html_entities.gperf" + {"ecaron", { 0xC4, 0x9B }, 2}, +#line 424 "data/html_entities.gperf" + {"divide", { 0xC3, 0xB7 }, 2}, +#line 1713 "data/html_entities.gperf" + {"precsim", { 0xE2, 0x89, 0xBE }, 3}, +#line 483 "data/html_entities.gperf" + {"ncup", { 0xE2, 0xA9, 0x82 }, 3}, +#line 648 "data/html_entities.gperf" + {"ncaron", { 0xC5, 0x88 }, 2}, +#line 1475 "data/html_entities.gperf" + {"lesssim", { 0xE2, 0x89, 0xB2 }, 3}, +#line 2078 "data/html_entities.gperf" + {"precneqq", { 0xE2, 0xAA, 0xB5 }, 3}, +#line 700 "data/html_entities.gperf" + {"div", { 0xC3, 0xB7 }, 2}, +#line 2056 "data/html_entities.gperf" + {"elsdot", { 0xE2, 0xAA, 0x97 }, 3}, +#line 1807 "data/html_entities.gperf" + {"Zcaron", { 0xC5, 0xBD }, 2}, +#line 1873 "data/html_entities.gperf" + {"backsim", { 0xE2, 0x88, 0xBD }, 3}, +#line 2032 "data/html_entities.gperf" + {"ifr", { 0xF0, 0x9D, 0x94, 0xA6 }, 4}, +#line 498 "data/html_entities.gperf" + {"spades", { 0xE2, 0x99, 0xA0 }, 3}, +#line 1661 "data/html_entities.gperf" + {"looparrowright", { 0xE2, 0x86, 0xAC }, 3}, +#line 1117 "data/html_entities.gperf" + {"Prime", { 0xE2, 0x80, 0xB3 }, 3}, +#line 735 "data/html_entities.gperf" + {"Scaron", { 0xC5, 0xA0 }, 2}, +#line 1349 "data/html_entities.gperf" + {"Phi", { 0xCE, 0xA6 }, 2}, +#line 725 "data/html_entities.gperf" + {"SquareUnion", { 0xE2, 0x8A, 0x94 }, 3}, +#line 721 "data/html_entities.gperf" + {"elinters", { 0xE2, 0x8F, 0xA7 }, 3}, +#line 1074 "data/html_entities.gperf" + {"spadesuit", { 0xE2, 0x99, 0xA0 }, 3}, +#line 455 "data/html_entities.gperf" + {"prnE", { 0xE2, 0xAA, 0xB5 }, 3}, +#line 1588 "data/html_entities.gperf" + {"topcir", { 0xE2, 0xAB, 0xB1 }, 3}, +#line 1978 "data/html_entities.gperf" + {"gap", { 0xE2, 0xAA, 0x86 }, 3}, +#line 2008 "data/html_entities.gperf" + {"nrarrw", { 0xE2, 0x86, 0x9D, 0xCC, 0xB8 }, 5}, +#line 1097 "data/html_entities.gperf" + {"thinsp", { 0xE2, 0x80, 0x89 }, 3}, +#line 113 "data/html_entities.gperf" + {"Bfr", { 0xF0, 0x9D, 0x94, 0x85 }, 4}, +#line 1064 "data/html_entities.gperf" + {"prime", { 0xE2, 0x80, 0xB2 }, 3}, +#line 135 "data/html_entities.gperf" + {"dfr", { 0xF0, 0x9D, 0x94, 0xA1 }, 4}, +#line 715 "data/html_entities.gperf" + {"trade", { 0xE2, 0x84, 0xA2 }, 3}, +#line 88 "data/html_entities.gperf" + {"phi", { 0xCF, 0x86 }, 2}, +#line 681 "data/html_entities.gperf" + {"notnivb", { 0xE2, 0x8B, 0xBE }, 3}, +#line 1076 "data/html_entities.gperf" + {"Dfr", { 0xF0, 0x9D, 0x94, 0x87 }, 4}, +#line 491 "data/html_entities.gperf" + {"primes", { 0xE2, 0x84, 0x99 }, 3}, +#line 639 "data/html_entities.gperf" + {"ssetmn", { 0xE2, 0x88, 0x96 }, 3}, +#line 837 "data/html_entities.gperf" + {"ge", { 0xE2, 0x89, 0xA5 }, 3}, +#line 1847 "data/html_entities.gperf" + {"mnplus", { 0xE2, 0x88, 0x93 }, 3}, +#line 277 "data/html_entities.gperf" + {"GT", { 0x3E }, 1}, +#line 1406 "data/html_entities.gperf" + {"Barwed", { 0xE2, 0x8C, 0x86 }, 3}, +#line 529 "data/html_entities.gperf" + {"Upsilon", { 0xCE, 0xA5 }, 2}, +#line 220 "data/html_entities.gperf" + {"Lcaron", { 0xC4, 0xBD }, 2}, +#line 935 "data/html_entities.gperf" + {"ges", { 0xE2, 0xA9, 0xBE }, 3}, +#line 1372 "data/html_entities.gperf" + {"Rcaron", { 0xC5, 0x98 }, 2}, +#line 98 "data/html_entities.gperf" + {"lltri", { 0xE2, 0x97, 0xBA }, 3}, +#line 1834 "data/html_entities.gperf" + {"gneq", { 0xE2, 0xAA, 0x88 }, 3}, +#line 1580 "data/html_entities.gperf" + {"ultri", { 0xE2, 0x97, 0xB8 }, 3}, +#line 643 "data/html_entities.gperf" + {"varpi", { 0xCF, 0x96 }, 2}, +#line 1168 "data/html_entities.gperf" + {"nltri", { 0xE2, 0x8B, 0xAA }, 3}, +#line 1700 "data/html_entities.gperf" + {"ratail", { 0xE2, 0xA4, 0x9A }, 3}, +#line 1566 "data/html_entities.gperf" + {"Ncaron", { 0xC5, 0x87 }, 2}, +#line 1006 "data/html_entities.gperf" + {"latail", { 0xE2, 0xA4, 0x99 }, 3}, +#line 2115 "data/html_entities.gperf" + {"lrtri", { 0xE2, 0x8A, 0xBF }, 3}, +#line 766 "data/html_entities.gperf" + {"gneqq", { 0xE2, 0x89, 0xA9 }, 3}, +#line 1165 "data/html_entities.gperf" + {"oast", { 0xE2, 0x8A, 0x9B }, 3}, +#line 441 "data/html_entities.gperf" + {"urtri", { 0xE2, 0x97, 0xB9 }, 3}, +#line 1527 "data/html_entities.gperf" + {"nrtri", { 0xE2, 0x8B, 0xAB }, 3}, +#line 1540 "data/html_entities.gperf" + {"mapstoleft", { 0xE2, 0x86, 0xA4 }, 3}, +#line 587 "data/html_entities.gperf" + {"zscr", { 0xF0, 0x9D, 0x93, 0x8F }, 4}, +#line 1726 "data/html_entities.gperf" + {"NestedLessLess", { 0xE2, 0x89, 0xAA }, 3}, +#line 1206 "data/html_entities.gperf" + {"nvrtrie", { 0xE2, 0x8A, 0xB5, 0xE2, 0x83, 0x92 }, 6}, +#line 1159 "data/html_entities.gperf" + {"upharpoonleft", { 0xE2, 0x86, 0xBF }, 3}, +#line 1065 "data/html_entities.gperf" + {"OpenCurlyDoubleQuote", { 0xE2, 0x80, 0x9C }, 3}, +#line 204 "data/html_entities.gperf" + {"setminus", { 0xE2, 0x88, 0x96 }, 3}, +#line 811 "data/html_entities.gperf" + {"malt", { 0xE2, 0x9C, 0xA0 }, 3}, +#line 1814 "data/html_entities.gperf" + {"REG", { 0xC2, 0xAE }, 2}, +#line 1366 "data/html_entities.gperf" + {"lesges", { 0xE2, 0xAA, 0x93 }, 3}, +#line 742 "data/html_entities.gperf" + {"permil", { 0xE2, 0x80, 0xB0 }, 3}, +#line 1310 "data/html_entities.gperf" + {"emptyset", { 0xE2, 0x88, 0x85 }, 3}, +#line 2085 "data/html_entities.gperf" + {"vltri", { 0xE2, 0x8A, 0xB2 }, 3}, +#line 42 "data/html_entities.gperf" + {"mapstoup", { 0xE2, 0x86, 0xA5 }, 3}, +#line 1041 "data/html_entities.gperf" + {"disin", { 0xE2, 0x8B, 0xB2 }, 3}, +#line 1312 "data/html_entities.gperf" + {"Tcaron", { 0xC5, 0xA4 }, 2}, +#line 1086 "data/html_entities.gperf" + {"bsol", { 0x5C }, 1}, +#line 1823 "data/html_entities.gperf" + {"vrtri", { 0xE2, 0x8A, 0xB3 }, 3}, +#line 1374 "data/html_entities.gperf" + {"NotHumpDownHump", { 0xE2, 0x89, 0x8E, 0xCC, 0xB8 }, 5}, +#line 1314 "data/html_entities.gperf" + {"dollar", { 0x24 }, 1}, +#line 1653 "data/html_entities.gperf" + {"dotminus", { 0xE2, 0x88, 0xB8 }, 3}, +#line 1702 "data/html_entities.gperf" + {"notni", { 0xE2, 0x88, 0x8C }, 3}, +#line 517 "data/html_entities.gperf" + {"lesdot", { 0xE2, 0xA9, 0xBF }, 3}, +#line 930 "data/html_entities.gperf" + {"HorizontalLine", { 0xE2, 0x94, 0x80 }, 3}, +#line 603 "data/html_entities.gperf" + {"Wedge", { 0xE2, 0x8B, 0x80 }, 3}, +#line 1859 "data/html_entities.gperf" + {"ThickSpace", { 0xE2, 0x81, 0x9F, 0xE2, 0x80, 0x8A }, 6}, +#line 1762 "data/html_entities.gperf" + {"NotDoubleVerticalBar", { 0xE2, 0x88, 0xA6 }, 3}, +#line 1396 "data/html_entities.gperf" + {"eqcolon", { 0xE2, 0x89, 0x95 }, 3}, +#line 1183 "data/html_entities.gperf" + {"equivDD", { 0xE2, 0xA9, 0xB8 }, 3}, +#line 1829 "data/html_entities.gperf" + {"wscr", { 0xF0, 0x9D, 0x93, 0x8C }, 4}, +#line 569 "data/html_entities.gperf" + {"orv", { 0xE2, 0xA9, 0x9B }, 3}, +#line 999 "data/html_entities.gperf" + {"DoubleLeftArrow", { 0xE2, 0x87, 0x90 }, 3}, +#line 1220 "data/html_entities.gperf" + {"geq", { 0xE2, 0x89, 0xA5 }, 3}, +#line 1699 "data/html_entities.gperf" + {"Oscr", { 0xF0, 0x9D, 0x92, 0xAA }, 4}, +#line 129 "data/html_entities.gperf" + {"DoubleContourIntegral", { 0xE2, 0x88, 0xAF }, 3}, +#line 2096 "data/html_entities.gperf" + {"bottom", { 0xE2, 0x8A, 0xA5 }, 3}, +#line 1831 "data/html_entities.gperf" + {"inodot", { 0xC4, 0xB1 }, 2}, +#line 1945 "data/html_entities.gperf" + {"mfr", { 0xF0, 0x9D, 0x94, 0xAA }, 4}, +#line 1456 "data/html_entities.gperf" + {"NotNestedGreaterGreater", { 0xE2, 0xAA, 0xA2, 0xCC, 0xB8 }, 5}, +#line 1146 "data/html_entities.gperf" + {"geqq", { 0xE2, 0x89, 0xA7 }, 3}, +#line 1311 "data/html_entities.gperf" + {"intprod", { 0xE2, 0xA8, 0xBC }, 3}, +#line 1858 "data/html_entities.gperf" + {"nshortmid", { 0xE2, 0x88, 0xA4 }, 3}, +#line 247 "data/html_entities.gperf" + {"frown", { 0xE2, 0x8C, 0xA2 }, 3}, +#line 1321 "data/html_entities.gperf" + {"jopf", { 0xF0, 0x9D, 0x95, 0x9B }, 4}, +#line 168 "data/html_entities.gperf" + {"Efr", { 0xF0, 0x9D, 0x94, 0x88 }, 4}, +#line 229 "data/html_entities.gperf" + {"Fouriertrf", { 0xE2, 0x84, 0xB1 }, 3}, +#line 1551 "data/html_entities.gperf" + {"emptyv", { 0xE2, 0x88, 0x85 }, 3}, +#line 183 "data/html_entities.gperf" + {"pointint", { 0xE2, 0xA8, 0x95 }, 3}, +#line 888 "data/html_entities.gperf" + {"dcaron", { 0xC4, 0x8F }, 2}, +#line 1781 "data/html_entities.gperf" + {"InvisibleTimes", { 0xE2, 0x81, 0xA2 }, 3}, +#line 222 "data/html_entities.gperf" + {"vsupne", { 0xE2, 0x8A, 0x8B, 0xEF, 0xB8, 0x80 }, 6}, +#line 688 "data/html_entities.gperf" + {"vsubne", { 0xE2, 0x8A, 0x8A, 0xEF, 0xB8, 0x80 }, 6}, +#line 1605 "data/html_entities.gperf" + {"EqualTilde", { 0xE2, 0x89, 0x82 }, 3}, +#line 1962 "data/html_entities.gperf" + {"image", { 0xE2, 0x84, 0x91 }, 3}, +#line 1120 "data/html_entities.gperf" + {"maltese", { 0xE2, 0x9C, 0xA0 }, 3}, +#line 1558 "data/html_entities.gperf" + {"Dcaron", { 0xC4, 0x8E }, 2}, +#line 799 "data/html_entities.gperf" + {"Equilibrium", { 0xE2, 0x87, 0x8C }, 3}, +#line 729 "data/html_entities.gperf" + {"DotDot", { 0xE2, 0x83, 0x9C }, 3}, +#line 1792 "data/html_entities.gperf" + {"efDot", { 0xE2, 0x89, 0x92 }, 3}, +#line 1733 "data/html_entities.gperf" + {"harr", { 0xE2, 0x86, 0x94 }, 3}, +#line 722 "data/html_entities.gperf" + {"NotCongruent", { 0xE2, 0x89, 0xA2 }, 3}, +#line 1319 "data/html_entities.gperf" + {"late", { 0xE2, 0xAA, 0xAD }, 3}, +#line 2086 "data/html_entities.gperf" + {"npre", { 0xE2, 0xAA, 0xAF, 0xCC, 0xB8 }, 5}, +#line 900 "data/html_entities.gperf" + {"NotTilde", { 0xE2, 0x89, 0x81 }, 3}, +#line 1140 "data/html_entities.gperf" + {"nvlt", { 0x3C, 0xE2, 0x83, 0x92 }, 4}, +#line 1598 "data/html_entities.gperf" + {"lates", { 0xE2, 0xAA, 0xAD, 0xEF, 0xB8, 0x80 }, 6}, +#line 59 "data/html_entities.gperf" + {"prod", { 0xE2, 0x88, 0x8F }, 3}, +#line 1010 "data/html_entities.gperf" + {"ShortUpArrow", { 0xE2, 0x86, 0x91 }, 3}, +#line 1129 "data/html_entities.gperf" + {"Cscr", { 0xF0, 0x9D, 0x92, 0x9E }, 4}, +#line 945 "data/html_entities.gperf" + {"hoarr", { 0xE2, 0x87, 0xBF }, 3}, +#line 1884 "data/html_entities.gperf" + {"udarr", { 0xE2, 0x87, 0x85 }, 3}, +#line 1929 "data/html_entities.gperf" + {"rfloor", { 0xE2, 0x8C, 0x8B }, 3}, +#line 2071 "data/html_entities.gperf" + {"lfloor", { 0xE2, 0x8C, 0x8A }, 3}, +#line 1072 "data/html_entities.gperf" + {"smallsetminus", { 0xE2, 0x88, 0x96 }, 3}, +#line 1534 "data/html_entities.gperf" + {"horbar", { 0xE2, 0x80, 0x95 }, 3}, +#line 719 "data/html_entities.gperf" + {"rpargt", { 0xE2, 0xA6, 0x94 }, 3}, +#line 605 "data/html_entities.gperf" + {"gopf", { 0xF0, 0x9D, 0x95, 0x98 }, 4}, +#line 2048 "data/html_entities.gperf" + {"NotTildeFullEqual", { 0xE2, 0x89, 0x87 }, 3}, +#line 1481 "data/html_entities.gperf" + {"lagran", { 0xE2, 0x84, 0x92 }, 3}, +#line 1299 "data/html_entities.gperf" + {"gnsim", { 0xE2, 0x8B, 0xA7 }, 3}, +#line 1106 "data/html_entities.gperf" + {"scsim", { 0xE2, 0x89, 0xBF }, 3}, +#line 1049 "data/html_entities.gperf" + {"triplus", { 0xE2, 0xA8, 0xB9 }, 3}, +#line 1925 "data/html_entities.gperf" + {"Gopf", { 0xF0, 0x9D, 0x94, 0xBE }, 4}, +#line 387 "data/html_entities.gperf" + {"zeetrf", { 0xE2, 0x84, 0xA8 }, 3}, +#line 1162 "data/html_entities.gperf" + {"equest", { 0xE2, 0x89, 0x9F }, 3}, +#line 87 "data/html_entities.gperf" + {"hbar", { 0xE2, 0x84, 0x8F }, 3}, +#line 226 "data/html_entities.gperf" + {"doublebarwedge", { 0xE2, 0x8C, 0x86 }, 3}, +#line 1131 "data/html_entities.gperf" + {"oscr", { 0xE2, 0x84, 0xB4 }, 3}, +#line 1552 "data/html_entities.gperf" + {"zfr", { 0xF0, 0x9D, 0x94, 0xB7 }, 4}, +#line 1217 "data/html_entities.gperf" + {"Epsilon", { 0xCE, 0x95 }, 2}, +#line 1890 "data/html_entities.gperf" + {"notinE", { 0xE2, 0x8B, 0xB9, 0xCC, 0xB8 }, 5}, +#line 1268 "data/html_entities.gperf" + {"gEl", { 0xE2, 0xAA, 0x8C }, 3}, +#line 674 "data/html_entities.gperf" + {"CirclePlus", { 0xE2, 0x8A, 0x95 }, 3}, +#line 1375 "data/html_entities.gperf" + {"gE", { 0xE2, 0x89, 0xA7 }, 3}, +#line 438 "data/html_entities.gperf" + {"GreaterLess", { 0xE2, 0x89, 0xB7 }, 3}, +#line 1674 "data/html_entities.gperf" + {"DoubleDownArrow", { 0xE2, 0x87, 0x93 }, 3}, +#line 346 "data/html_entities.gperf" + {"mapstodown", { 0xE2, 0x86, 0xA7 }, 3}, +#line 973 "data/html_entities.gperf" + {"simdot", { 0xE2, 0xA9, 0xAA }, 3}, +#line 859 "data/html_entities.gperf" + {"smte", { 0xE2, 0xAA, 0xAC }, 3}, +#line 758 "data/html_entities.gperf" + {"GreaterGreater", { 0xE2, 0xAA, 0xA2 }, 3}, +#line 1447 "data/html_entities.gperf" + {"precnsim", { 0xE2, 0x8B, 0xA8 }, 3}, +#line 1253 "data/html_entities.gperf" + {"GreaterTilde", { 0xE2, 0x89, 0xB3 }, 3}, +#line 1158 "data/html_entities.gperf" + {"GreaterEqual", { 0xE2, 0x89, 0xA5 }, 3}, +#line 953 "data/html_entities.gperf" + {"GreaterEqualLess", { 0xE2, 0x8B, 0x9B }, 3}, +#line 92 "data/html_entities.gperf" + {"dsol", { 0xE2, 0xA7, 0xB6 }, 3}, +#line 1172 "data/html_entities.gperf" + {"lesseqgtr", { 0xE2, 0x8B, 0x9A }, 3}, +#line 2064 "data/html_entities.gperf" + {"smtes", { 0xE2, 0xAA, 0xAC, 0xEF, 0xB8, 0x80 }, 6}, +#line 1244 "data/html_entities.gperf" + {"rceil", { 0xE2, 0x8C, 0x89 }, 3}, +#line 607 "data/html_entities.gperf" + {"lceil", { 0xE2, 0x8C, 0x88 }, 3}, +#line 1436 "data/html_entities.gperf" + {"varpropto", { 0xE2, 0x88, 0x9D }, 3}, +#line 1682 "data/html_entities.gperf" + {"rarrb", { 0xE2, 0x87, 0xA5 }, 3}, +#line 1094 "data/html_entities.gperf" + {"larrb", { 0xE2, 0x87, 0xA4 }, 3}, +#line 1789 "data/html_entities.gperf" + {"DoubleLeftRightArrow", { 0xE2, 0x87, 0x94 }, 3}, +#line 2063 "data/html_entities.gperf" + {"bsolhsub", { 0xE2, 0x9F, 0x88 }, 3}, +#line 997 "data/html_entities.gperf" + {"Ecaron", { 0xC4, 0x9A }, 2}, +#line 1711 "data/html_entities.gperf" + {"Exists", { 0xE2, 0x88, 0x83 }, 3}, +#line 390 "data/html_entities.gperf" + {"bepsi", { 0xCF, 0xB6 }, 2}, +#line 1853 "data/html_entities.gperf" + {"swnwar", { 0xE2, 0xA4, 0xAA }, 3}, +#line 18 "data/html_entities.gperf" + {"comp", { 0xE2, 0x88, 0x81 }, 3}, +#line 755 "data/html_entities.gperf" + {"wfr", { 0xF0, 0x9D, 0x94, 0xB4 }, 4}, +#line 450 "data/html_entities.gperf" + {"propto", { 0xE2, 0x88, 0x9D }, 3}, +#line 46 "data/html_entities.gperf" + {"gnE", { 0xE2, 0x89, 0xA9 }, 3}, +#line 332 "data/html_entities.gperf" + {"orslope", { 0xE2, 0xA9, 0x97 }, 3}, +#line 747 "data/html_entities.gperf" + {"scE", { 0xE2, 0xAA, 0xB4 }, 3}, +#line 1574 "data/html_entities.gperf" + {"Ofr", { 0xF0, 0x9D, 0x94, 0x92 }, 4}, +#line 1952 "data/html_entities.gperf" + {"crarr", { 0xE2, 0x86, 0xB5 }, 3}, +#line 761 "data/html_entities.gperf" + {"commat", { 0x40 }, 1}, +#line 645 "data/html_entities.gperf" + {"simlE", { 0xE2, 0xAA, 0x9F }, 3}, +#line 720 "data/html_entities.gperf" + {"CircleMinus", { 0xE2, 0x8A, 0x96 }, 3}, +#line 854 "data/html_entities.gperf" + {"gammad", { 0xCF, 0x9D }, 2}, +#line 1757 "data/html_entities.gperf" + {"ENG", { 0xC5, 0x8A }, 2}, +#line 406 "data/html_entities.gperf" + {"upsih", { 0xCF, 0x92 }, 2}, +#line 1998 "data/html_entities.gperf" + {"plusdo", { 0xE2, 0x88, 0x94 }, 3}, +#line 1844 "data/html_entities.gperf" + {"glE", { 0xE2, 0xAA, 0x92 }, 3}, +#line 635 "data/html_entities.gperf" + {"clubs", { 0xE2, 0x99, 0xA3 }, 3}, +#line 746 "data/html_entities.gperf" + {"lvnE", { 0xE2, 0x89, 0xA8, 0xEF, 0xB8, 0x80 }, 6}, +#line 1132 "data/html_entities.gperf" + {"gel", { 0xE2, 0x8B, 0x9B }, 3}, +#line 1228 "data/html_entities.gperf" + {"nesear", { 0xE2, 0xA4, 0xA8 }, 3}, +#line 2122 "data/html_entities.gperf" + {"race", { 0xE2, 0x88, 0xBD, 0xCC, 0xB1 }, 5}, +#line 1052 "data/html_entities.gperf" + {"rarrbfs", { 0xE2, 0xA4, 0xA0 }, 3}, +#line 1025 "data/html_entities.gperf" + {"Gammad", { 0xCF, 0x9C }, 2}, +#line 1811 "data/html_entities.gperf" + {"larrbfs", { 0xE2, 0xA4, 0x9F }, 3}, +#line 843 "data/html_entities.gperf" + {"tint", { 0xE2, 0x88, 0xAD }, 3}, +#line 32 "data/html_entities.gperf" + {"hearts", { 0xE2, 0x99, 0xA5 }, 3}, +#line 501 "data/html_entities.gperf" + {"CircleTimes", { 0xE2, 0x8A, 0x97 }, 3}, +#line 435 "data/html_entities.gperf" + {"rAtail", { 0xE2, 0xA4, 0x9C }, 3}, +#line 2027 "data/html_entities.gperf" + {"lAtail", { 0xE2, 0xA4, 0x9B }, 3}, +#line 1839 "data/html_entities.gperf" + {"cap", { 0xE2, 0x88, 0xA9 }, 3}, +#line 1902 "data/html_entities.gperf" + {"Cfr", { 0xE2, 0x84, 0xAD }, 3}, +#line 963 "data/html_entities.gperf" + {"nvltrie", { 0xE2, 0x8A, 0xB4, 0xE2, 0x83, 0x92 }, 6}, +#line 958 "data/html_entities.gperf" + {"heartsuit", { 0xE2, 0x99, 0xA5 }, 3}, +#line 1764 "data/html_entities.gperf" + {"ddarr", { 0xE2, 0x87, 0x8A }, 3}, +#line 795 "data/html_entities.gperf" + {"Tab", { 0x09 }, 1}, +#line 1635 "data/html_entities.gperf" + {"cross", { 0xE2, 0x9C, 0x97 }, 3}, +#line 62 "data/html_entities.gperf" + {"zcaron", { 0xC5, 0xBE }, 2}, +#line 762 "data/html_entities.gperf" + {"iquest", { 0xC2, 0xBF }, 2}, +#line 1849 "data/html_entities.gperf" + {"caps", { 0xE2, 0x88, 0xA9, 0xEF, 0xB8, 0x80 }, 6}, +#line 286 "data/html_entities.gperf" + {"thicksim", { 0xE2, 0x88, 0xBC }, 3}, +#line 1395 "data/html_entities.gperf" + {"lessgtr", { 0xE2, 0x89, 0xB6 }, 3}, +#line 619 "data/html_entities.gperf" + {"nisd", { 0xE2, 0x8B, 0xBA }, 3}, +#line 145 "data/html_entities.gperf" + {"UpArrowBar", { 0xE2, 0xA4, 0x92 }, 3}, +#line 753 "data/html_entities.gperf" + {"varrho", { 0xCF, 0xB1 }, 2}, +#line 1649 "data/html_entities.gperf" + {"notindot", { 0xE2, 0x8B, 0xB5, 0xCC, 0xB8 }, 5}, +#line 578 "data/html_entities.gperf" + {"iiint", { 0xE2, 0x88, 0xAD }, 3}, +#line 1774 "data/html_entities.gperf" + {"twixt", { 0xE2, 0x89, 0xAC }, 3}, +#line 2072 "data/html_entities.gperf" + {"Vdashl", { 0xE2, 0xAB, 0xA6 }, 3}, +#line 875 "data/html_entities.gperf" + {"NotPrecedes", { 0xE2, 0x8A, 0x80 }, 3}, +#line 1401 "data/html_entities.gperf" + {"lsime", { 0xE2, 0xAA, 0x8D }, 3}, +#line 368 "data/html_entities.gperf" + {"nsime", { 0xE2, 0x89, 0x84 }, 3}, +#line 285 "data/html_entities.gperf" + {"plusb", { 0xE2, 0x8A, 0x9E }, 3}, +#line 1636 "data/html_entities.gperf" + {"bsime", { 0xE2, 0x8B, 0x8D }, 3}, +#line 1360 "data/html_entities.gperf" + {"micro", { 0xC2, 0xB5 }, 2}, +#line 1177 "data/html_entities.gperf" + {"ofr", { 0xF0, 0x9D, 0x94, 0xAC }, 4}, +#line 291 "data/html_entities.gperf" + {"CircleDot", { 0xE2, 0x8A, 0x99 }, 3}, +#line 165 "data/html_entities.gperf" + {"VDash", { 0xE2, 0x8A, 0xAB }, 3}, +#line 1016 "data/html_entities.gperf" + {"ShortDownArrow", { 0xE2, 0x86, 0x93 }, 3}, +#line 1284 "data/html_entities.gperf" + {"copysr", { 0xE2, 0x84, 0x97 }, 3}, +#line 1684 "data/html_entities.gperf" + {"LessEqualGreater", { 0xE2, 0x8B, 0x9A }, 3}, +#line 248 "data/html_entities.gperf" + {"NotPrecedesSlantEqual", { 0xE2, 0x8B, 0xA0 }, 3}, +#line 1089 "data/html_entities.gperf" + {"Colon", { 0xE2, 0x88, 0xB7 }, 3}, +#line 1021 "data/html_entities.gperf" + {"qint", { 0xE2, 0xA8, 0x8C }, 3}, +#line 1123 "data/html_entities.gperf" + {"hercon", { 0xE2, 0x8A, 0xB9 }, 3}, +#line 1302 "data/html_entities.gperf" + {"Intersection", { 0xE2, 0x8B, 0x82 }, 3}, +#line 1506 "data/html_entities.gperf" + {"Colone", { 0xE2, 0xA9, 0xB4 }, 3}, +#line 790 "data/html_entities.gperf" + {"prec", { 0xE2, 0x89, 0xBA }, 3}, +#line 342 "data/html_entities.gperf" + {"vDash", { 0xE2, 0x8A, 0xA8 }, 3}, +#line 1417 "data/html_entities.gperf" + {"doteq", { 0xE2, 0x89, 0x90 }, 3}, +#line 1707 "data/html_entities.gperf" + {"radic", { 0xE2, 0x88, 0x9A }, 3}, +#line 1538 "data/html_entities.gperf" + {"rarrc", { 0xE2, 0xA4, 0xB3 }, 3}, +#line 1928 "data/html_entities.gperf" + {"Psi", { 0xCE, 0xA8 }, 2}, +#line 1145 "data/html_entities.gperf" + {"UpTee", { 0xE2, 0x8A, 0xA5 }, 3}, +#line 1869 "data/html_entities.gperf" + {"hopf", { 0xF0, 0x9D, 0x95, 0x99 }, 4}, +#line 770 "data/html_entities.gperf" + {"OpenCurlyQuote", { 0xE2, 0x80, 0x98 }, 3}, +#line 1081 "data/html_entities.gperf" + {"scpolint", { 0xE2, 0xA8, 0x93 }, 3}, +#line 1068 "data/html_entities.gperf" + {"sime", { 0xE2, 0x89, 0x83 }, 3}, +#line 1773 "data/html_entities.gperf" + {"psi", { 0xCF, 0x88 }, 2}, +#line 1645 "data/html_entities.gperf" + {"times", { 0xC3, 0x97 }, 2}, +#line 991 "data/html_entities.gperf" + {"hArr", { 0xE2, 0x87, 0x94 }, 3}, +#line 1632 "data/html_entities.gperf" + {"ap", { 0xE2, 0x89, 0x88 }, 3}, +#line 1751 "data/html_entities.gperf" + {"vangrt", { 0xE2, 0xA6, 0x9C }, 3}, +#line 1409 "data/html_entities.gperf" + {"capcap", { 0xE2, 0xA9, 0x8B }, 3}, +#line 1808 "data/html_entities.gperf" + {"jscr", { 0xF0, 0x9D, 0x92, 0xBF }, 4}, +#line 304 "data/html_entities.gperf" + {"hamilt", { 0xE2, 0x84, 0x8B }, 3}, +#line 1979 "data/html_entities.gperf" + {"gvertneqq", { 0xE2, 0x89, 0xA9, 0xEF, 0xB8, 0x80 }, 6}, +#line 1863 "data/html_entities.gperf" + {"range", { 0xE2, 0xA6, 0xA5 }, 3}, +#line 141 "data/html_entities.gperf" + {"npolint", { 0xE2, 0xA8, 0x94 }, 3}, +#line 444 "data/html_entities.gperf" + {"varepsilon", { 0xCF, 0xB5 }, 2}, +#line 679 "data/html_entities.gperf" + {"UnderBrace", { 0xE2, 0x8F, 0x9F }, 3}, +#line 955 "data/html_entities.gperf" + {"thksim", { 0xE2, 0x88, 0xBC }, 3}, +#line 177 "data/html_entities.gperf" + {"Ccaron", { 0xC4, 0x8C }, 2}, +#line 1730 "data/html_entities.gperf" + {"timesb", { 0xE2, 0x8A, 0xA0 }, 3}, +#line 995 "data/html_entities.gperf" + {"dd", { 0xE2, 0x85, 0x86 }, 3}, +#line 1485 "data/html_entities.gperf" + {"veeeq", { 0xE2, 0x89, 0x9A }, 3}, +#line 315 "data/html_entities.gperf" + {"clubsuit", { 0xE2, 0x99, 0xA3 }, 3}, +#line 675 "data/html_entities.gperf" + {"udhar", { 0xE2, 0xA5, 0xAE }, 3}, +#line 60 "data/html_entities.gperf" + {"Chi", { 0xCE, 0xA7 }, 2}, +#line 1595 "data/html_entities.gperf" + {"midcir", { 0xE2, 0xAB, 0xB0 }, 3}, +#line 55 "data/html_entities.gperf" + {"capcup", { 0xE2, 0xA9, 0x87 }, 3}, +#line 1668 "data/html_entities.gperf" + {"TripleDot", { 0xE2, 0x83, 0x9B }, 3}, +#line 1339 "data/html_entities.gperf" + {"ape", { 0xE2, 0x89, 0x8A }, 3}, +#line 329 "data/html_entities.gperf" + {"wedge", { 0xE2, 0x88, 0xA7 }, 3}, +#line 585 "data/html_entities.gperf" + {"harrcir", { 0xE2, 0xA5, 0x88 }, 3}, +#line 1462 "data/html_entities.gperf" + {"parsim", { 0xE2, 0xAB, 0xB3 }, 3}, +#line 1957 "data/html_entities.gperf" + {"NotTildeTilde", { 0xE2, 0x89, 0x89 }, 3}, +#line 1788 "data/html_entities.gperf" + {"cir", { 0xE2, 0x97, 0x8B }, 3}, +#line 1313 "data/html_entities.gperf" + {"apos", { 0x27 }, 1}, +#line 1305 "data/html_entities.gperf" + {"rationals", { 0xE2, 0x84, 0x9A }, 3}, +#line 1800 "data/html_entities.gperf" + {"gscr", { 0xE2, 0x84, 0x8A }, 3}, +#line 1092 "data/html_entities.gperf" + {"isin", { 0xE2, 0x88, 0x88 }, 3}, +#line 1895 "data/html_entities.gperf" + {"middot", { 0xC2, 0xB7 }, 2}, +#line 557 "data/html_entities.gperf" + {"Union", { 0xE2, 0x8B, 0x83 }, 3}, +#line 754 "data/html_entities.gperf" + {"copf", { 0xF0, 0x9D, 0x95, 0x94 }, 4}, +#line 272 "data/html_entities.gperf" + {"isins", { 0xE2, 0x8B, 0xB4 }, 3}, +#line 654 "data/html_entities.gperf" + {"npreceq", { 0xE2, 0xAA, 0xAF, 0xCC, 0xB8 }, 5}, +#line 550 "data/html_entities.gperf" + {"uparrow", { 0xE2, 0x86, 0x91 }, 3}, +#line 653 "data/html_entities.gperf" + {"uwangle", { 0xE2, 0xA6, 0xA7 }, 3}, +#line 1801 "data/html_entities.gperf" + {"bsemi", { 0xE2, 0x81, 0x8F }, 3}, +#line 149 "data/html_entities.gperf" + {"simeq", { 0xE2, 0x89, 0x83 }, 3}, +#line 1301 "data/html_entities.gperf" + {"tilde", { 0xCB, 0x9C }, 2}, +#line 807 "data/html_entities.gperf" + {"Gscr", { 0xF0, 0x9D, 0x92, 0xA2 }, 4}, +#line 39 "data/html_entities.gperf" + {"GreaterFullEqual", { 0xE2, 0x89, 0xA7 }, 3}, +#line 862 "data/html_entities.gperf" + {"simgE", { 0xE2, 0xAA, 0xA0 }, 3}, +#line 1458 "data/html_entities.gperf" + {"UnionPlus", { 0xE2, 0x8A, 0x8E }, 3}, +#line 691 "data/html_entities.gperf" + {"ecolon", { 0xE2, 0x89, 0x95 }, 3}, +#line 445 "data/html_entities.gperf" + {"imagline", { 0xE2, 0x84, 0x90 }, 3}, +#line 994 "data/html_entities.gperf" + {"smile", { 0xE2, 0x8C, 0xA3 }, 3}, +#line 1901 "data/html_entities.gperf" + {"bkarow", { 0xE2, 0xA4, 0x8D }, 3}, +#line 84 "data/html_entities.gperf" + {"plusacir", { 0xE2, 0xA8, 0xA3 }, 3}, +#line 1135 "data/html_entities.gperf" + {"Uarrocir", { 0xE2, 0xA5, 0x89 }, 3}, +#line 810 "data/html_entities.gperf" + {"barwedge", { 0xE2, 0x8C, 0x85 }, 3}, +#line 1367 "data/html_entities.gperf" + {"bigoplus", { 0xE2, 0xA8, 0x81 }, 3}, +#line 1568 "data/html_entities.gperf" + {"nsimeq", { 0xE2, 0x89, 0x84 }, 3}, +#line 2045 "data/html_entities.gperf" + {"shortparallel", { 0xE2, 0x88, 0xA5 }, 3}, +#line 2099 "data/html_entities.gperf" + {"nleqslant", { 0xE2, 0xA9, 0xBD, 0xCC, 0xB8 }, 5}, +#line 1387 "data/html_entities.gperf" + {"sigmav", { 0xCF, 0x82 }, 2}, +#line 1557 "data/html_entities.gperf" + {"lt", { 0x3C }, 1}, +#line 1748 "data/html_entities.gperf" + {"oline", { 0xE2, 0x80, 0xBE }, 3}, +#line 564 "data/html_entities.gperf" + {"NotGreater", { 0xE2, 0x89, 0xAF }, 3}, +#line 336 "data/html_entities.gperf" + {"ofcir", { 0xE2, 0xA6, 0xBF }, 3}, +#line 1714 "data/html_entities.gperf" + {"rangd", { 0xE2, 0xA6, 0x92 }, 3}, +#line 221 "data/html_entities.gperf" + {"langd", { 0xE2, 0xA6, 0x91 }, 3}, +#line 1031 "data/html_entities.gperf" + {"bigcap", { 0xE2, 0x8B, 0x82 }, 3}, +#line 1359 "data/html_entities.gperf" + {"varkappa", { 0xCF, 0xB0 }, 2}, +#line 101 "data/html_entities.gperf" + {"realine", { 0xE2, 0x84, 0x9B }, 3}, +#line 1473 "data/html_entities.gperf" + {"mapsto", { 0xE2, 0x86, 0xA6 }, 3}, +#line 819 "data/html_entities.gperf" + {"NotEqual", { 0xE2, 0x89, 0xA0 }, 3}, +#line 723 "data/html_entities.gperf" + {"FilledSmallSquare", { 0xE2, 0x97, 0xBC }, 3}, +#line 1706 "data/html_entities.gperf" + {"NotGreaterGreater", { 0xE2, 0x89, 0xAB, 0xCC, 0xB8 }, 5}, +#line 2111 "data/html_entities.gperf" + {"NotGreaterLess", { 0xE2, 0x89, 0xB9 }, 3}, +#line 771 "data/html_entities.gperf" + {"NotGreaterSlantEqual", { 0xE2, 0xA9, 0xBE, 0xCC, 0xB8 }, 5}, +#line 1975 "data/html_entities.gperf" + {"NotGreaterFullEqual", { 0xE2, 0x89, 0xA7, 0xCC, 0xB8 }, 5}, +#line 394 "data/html_entities.gperf" + {"gesl", { 0xE2, 0x8B, 0x9B, 0xEF, 0xB8, 0x80 }, 6}, +#line 1703 "data/html_entities.gperf" + {"Kappa", { 0xCE, 0x9A }, 2}, +#line 473 "data/html_entities.gperf" + {"amacr", { 0xC4, 0x81 }, 2}, +#line 1056 "data/html_entities.gperf" + {"lsim", { 0xE2, 0x89, 0xB2 }, 3}, +#line 531 "data/html_entities.gperf" + {"esim", { 0xE2, 0x89, 0x82 }, 3}, +#line 1221 "data/html_entities.gperf" + {"star", { 0xE2, 0x98, 0x86 }, 3}, +#line 1233 "data/html_entities.gperf" + {"sigmaf", { 0xCF, 0x82 }, 2}, +#line 714 "data/html_entities.gperf" + {"nsim", { 0xE2, 0x89, 0x81 }, 3}, +#line 72 "data/html_entities.gperf" + {"isinsv", { 0xE2, 0x8B, 0xB3 }, 3}, +#line 85 "data/html_entities.gperf" + {"bsim", { 0xE2, 0x88, 0xBD }, 3}, +#line 785 "data/html_entities.gperf" + {"ltdot", { 0xE2, 0x8B, 0x96 }, 3}, +#line 1288 "data/html_entities.gperf" + {"xodot", { 0xE2, 0xA8, 0x80 }, 3}, +#line 1347 "data/html_entities.gperf" + {"and", { 0xE2, 0x88, 0xA7 }, 3}, +#line 1507 "data/html_entities.gperf" + {"utdot", { 0xE2, 0x8B, 0xB0 }, 3}, +#line 2060 "data/html_entities.gperf" + {"infin", { 0xE2, 0x88, 0x9E }, 3}, +#line 378 "data/html_entities.gperf" + {"natur", { 0xE2, 0x99, 0xAE }, 3}, +#line 283 "data/html_entities.gperf" + {"xharr", { 0xE2, 0x9F, 0xB7 }, 3}, +#line 178 "data/html_entities.gperf" + {"NotSquareSubset", { 0xE2, 0x8A, 0x8F, 0xCC, 0xB8 }, 5}, +#line 1739 "data/html_entities.gperf" + {"bigcup", { 0xE2, 0x8B, 0x83 }, 3}, +#line 1157 "data/html_entities.gperf" + {"NotSquareSubsetEqual", { 0xE2, 0x8B, 0xA2 }, 3}, +#line 1476 "data/html_entities.gperf" + {"tosa", { 0xE2, 0xA4, 0xA9 }, 3}, +#line 608 "data/html_entities.gperf" + {"lescc", { 0xE2, 0xAA, 0xA8 }, 3}, +#line 511 "data/html_entities.gperf" + {"lowbar", { 0x5F }, 1}, +#line 952 "data/html_entities.gperf" + {"ominus", { 0xE2, 0x8A, 0x96 }, 3}, +#line 243 "data/html_entities.gperf" + {"Star", { 0xE2, 0x8B, 0x86 }, 3}, +#line 1424 "data/html_entities.gperf" + {"tdot", { 0xE2, 0x83, 0x9B }, 3}, +#line 262 "data/html_entities.gperf" + {"TRADE", { 0xE2, 0x84, 0xA2 }, 3}, +#line 867 "data/html_entities.gperf" + {"sdot", { 0xE2, 0x8B, 0x85 }, 3}, +#line 1949 "data/html_entities.gperf" + {"edot", { 0xC4, 0x97 }, 2}, +#line 1940 "data/html_entities.gperf" + {"xotime", { 0xE2, 0xA8, 0x82 }, 3}, +#line 938 "data/html_entities.gperf" + {"osol", { 0xE2, 0x8A, 0x98 }, 3}, +#line 2055 "data/html_entities.gperf" + {"amp", { 0x26 }, 1}, +#line 1011 "data/html_entities.gperf" + {"Uparrow", { 0xE2, 0x87, 0x91 }, 3}, +#line 1802 "data/html_entities.gperf" + {"jfr", { 0xF0, 0x9D, 0x94, 0xA7 }, 4}, +#line 1604 "data/html_entities.gperf" + {"Zdot", { 0xC5, 0xBB }, 2}, +#line 730 "data/html_entities.gperf" + {"ltrPar", { 0xE2, 0xA6, 0x96 }, 3}, +#line 1326 "data/html_entities.gperf" + {"rx", { 0xE2, 0x84, 0x9E }, 3}, +#line 1365 "data/html_entities.gperf" + {"NotSquareSuperset", { 0xE2, 0x8A, 0x90, 0xCC, 0xB8 }, 5}, +#line 664 "data/html_entities.gperf" + {"half", { 0xC2, 0xBD }, 2}, +#line 1001 "data/html_entities.gperf" + {"NotSquareSupersetEqual", { 0xE2, 0x8B, 0xA3 }, 3}, +#line 1407 "data/html_entities.gperf" + {"Lt", { 0xE2, 0x89, 0xAA }, 3}, +#line 115 "data/html_entities.gperf" + {"xlarr", { 0xE2, 0x9F, 0xB5 }, 3}, +#line 849 "data/html_entities.gperf" + {"imped", { 0xC6, 0xB5 }, 2}, +#line 841 "data/html_entities.gperf" + {"Implies", { 0xE2, 0x87, 0x92 }, 3}, +#line 499 "data/html_entities.gperf" + {"Tilde", { 0xE2, 0x88, 0xBC }, 3}, +#line 1245 "data/html_entities.gperf" + {"para", { 0xC2, 0xB6 }, 2}, +#line 886 "data/html_entities.gperf" + {"xrarr", { 0xE2, 0x9F, 0xB6 }, 3}, +#line 439 "data/html_entities.gperf" + {"lesdotor", { 0xE2, 0xAA, 0x83 }, 3}, +#line 631 "data/html_entities.gperf" + {"LeftUpVector", { 0xE2, 0x86, 0xBF }, 3}, +#line 2131 "data/html_entities.gperf" + {"LeftUpVectorBar", { 0xE2, 0xA5, 0x98 }, 3}, +#line 476 "data/html_entities.gperf" + {"rsaquo", { 0xE2, 0x80, 0xBA }, 3}, +#line 1939 "data/html_entities.gperf" + {"rtrie", { 0xE2, 0x8A, 0xB5 }, 3}, +#line 1932 "data/html_entities.gperf" + {"lsaquo", { 0xE2, 0x80, 0xB9 }, 3}, +#line 1060 "data/html_entities.gperf" + {"ltrie", { 0xE2, 0x8A, 0xB4 }, 3}, +#line 1265 "data/html_entities.gperf" + {"searrow", { 0xE2, 0x86, 0x98 }, 3}, +#line 2014 "data/html_entities.gperf" + {"wedgeq", { 0xE2, 0x89, 0x99 }, 3}, +#line 693 "data/html_entities.gperf" + {"NotGreaterEqual", { 0xE2, 0x89, 0xB1 }, 3}, +#line 946 "data/html_entities.gperf" + {"gesles", { 0xE2, 0xAA, 0x94 }, 3}, +#line 289 "data/html_entities.gperf" + {"nearrow", { 0xE2, 0x86, 0x97 }, 3}, +#line 2105 "data/html_entities.gperf" + {"ubreve", { 0xC5, 0xAD }, 2}, +#line 197 "data/html_entities.gperf" + {"toea", { 0xE2, 0xA4, 0xA8 }, 3}, +#line 1898 "data/html_entities.gperf" + {"Idot", { 0xC4, 0xB0 }, 2}, +#line 1692 "data/html_entities.gperf" + {"Iota", { 0xCE, 0x99 }, 2}, +#line 745 "data/html_entities.gperf" + {"cedil", { 0xC2, 0xB8 }, 2}, +#line 941 "data/html_entities.gperf" + {"Conint", { 0xE2, 0x88, 0xAF }, 3}, +#line 929 "data/html_entities.gperf" + {"leftarrowtail", { 0xE2, 0x86, 0xA2 }, 3}, +#line 1083 "data/html_entities.gperf" + {"NotPrecedesEqual", { 0xE2, 0xAA, 0xAF, 0xCC, 0xB8 }, 5}, +#line 1047 "data/html_entities.gperf" + {"gfr", { 0xF0, 0x9D, 0x94, 0xA4 }, 4}, +#line 1342 "data/html_entities.gperf" + {"SmallCircle", { 0xE2, 0x88, 0x98 }, 3}, +#line 1838 "data/html_entities.gperf" + {"strns", { 0xC2, 0xAF }, 2}, +#line 202 "data/html_entities.gperf" + {"LeftTee", { 0xE2, 0x8A, 0xA3 }, 3}, +#line 1987 "data/html_entities.gperf" + {"sdote", { 0xE2, 0xA9, 0xA6 }, 3}, +#line 140 "data/html_entities.gperf" + {"Assign", { 0xE2, 0x89, 0x94 }, 3}, +#line 1464 "data/html_entities.gperf" + {"dotsquare", { 0xE2, 0x8A, 0xA1 }, 3}, +#line 931 "data/html_entities.gperf" + {"DotEqual", { 0xE2, 0x89, 0x90 }, 3}, +#line 520 "data/html_entities.gperf" + {"ecir", { 0xE2, 0x89, 0x96 }, 3}, +#line 356 "data/html_entities.gperf" + {"divideontimes", { 0xE2, 0x8B, 0x87 }, 3}, +#line 2117 "data/html_entities.gperf" + {"dwangle", { 0xE2, 0xA6, 0xA6 }, 3}, +#line 615 "data/html_entities.gperf" + {"sqsupe", { 0xE2, 0x8A, 0x92 }, 3}, +#line 884 "data/html_entities.gperf" + {"rangle", { 0xE2, 0x9F, 0xA9 }, 3}, +#line 232 "data/html_entities.gperf" + {"DoubleUpArrow", { 0xE2, 0x87, 0x91 }, 3}, +#line 1260 "data/html_entities.gperf" + {"langle", { 0xE2, 0x9F, 0xA8 }, 3}, +#line 1608 "data/html_entities.gperf" + {"Gfr", { 0xF0, 0x9D, 0x94, 0x8A }, 4}, +#line 294 "data/html_entities.gperf" + {"sqsupset", { 0xE2, 0x8A, 0x90 }, 3}, +#line 1035 "data/html_entities.gperf" + {"xmap", { 0xE2, 0x9F, 0xBC }, 3}, +#line 443 "data/html_entities.gperf" + {"DoubleUpDownArrow", { 0xE2, 0x87, 0x95 }, 3}, +#line 1515 "data/html_entities.gperf" + {"coprod", { 0xE2, 0x88, 0x90 }, 3}, +#line 418 "data/html_entities.gperf" + {"sqsup", { 0xE2, 0x8A, 0x90 }, 3}, +#line 2121 "data/html_entities.gperf" + {"it", { 0xE2, 0x81, 0xA2 }, 3}, +#line 199 "data/html_entities.gperf" + {"profalar", { 0xE2, 0x8C, 0xAE }, 3}, +#line 1656 "data/html_entities.gperf" + {"eogon", { 0xC4, 0x99 }, 2}, +#line 1910 "data/html_entities.gperf" + {"rmoust", { 0xE2, 0x8E, 0xB1 }, 3}, +#line 2037 "data/html_entities.gperf" + {"csub", { 0xE2, 0xAB, 0x8F }, 3}, +#line 939 "data/html_entities.gperf" + {"lmoust", { 0xE2, 0x8E, 0xB0 }, 3}, +#line 160 "data/html_entities.gperf" + {"uogon", { 0xC5, 0xB3 }, 2}, +#line 712 "data/html_entities.gperf" + {"male", { 0xE2, 0x99, 0x82 }, 3}, +#line 1685 "data/html_entities.gperf" + {"rsh", { 0xE2, 0x86, 0xB1 }, 3}, +#line 2004 "data/html_entities.gperf" + {"lsh", { 0xE2, 0x86, 0xB0 }, 3}, +#line 1195 "data/html_entities.gperf" + {"aopf", { 0xF0, 0x9D, 0x95, 0x92 }, 4}, +#line 1996 "data/html_entities.gperf" + {"vsupnE", { 0xE2, 0xAB, 0x8C, 0xEF, 0xB8, 0x80 }, 6}, +#line 143 "data/html_entities.gperf" + {"vsubnE", { 0xE2, 0xAB, 0x8B, 0xEF, 0xB8, 0x80 }, 6}, +#line 1292 "data/html_entities.gperf" + {"NotGreaterTilde", { 0xE2, 0x89, 0xB5 }, 3}, +#line 1502 "data/html_entities.gperf" + {"rtri", { 0xE2, 0x96, 0xB9 }, 3}, +#line 2034 "data/html_entities.gperf" + {"ltri", { 0xE2, 0x97, 0x83 }, 3}, +#line 1166 "data/html_entities.gperf" + {"Abreve", { 0xC4, 0x82 }, 2}, +#line 1759 "data/html_entities.gperf" + {"utri", { 0xE2, 0x96, 0xB5 }, 3}, +#line 1983 "data/html_entities.gperf" + {"models", { 0xE2, 0x8A, 0xA7 }, 3}, +#line 1186 "data/html_entities.gperf" + {"triminus", { 0xE2, 0xA8, 0xBA }, 3}, +#line 2082 "data/html_entities.gperf" + {"csup", { 0xE2, 0xAB, 0x90 }, 3}, +#line 186 "data/html_entities.gperf" + {"scnap", { 0xE2, 0xAA, 0xBA }, 3}, +#line 820 "data/html_entities.gperf" + {"vnsup", { 0xE2, 0x8A, 0x83, 0xE2, 0x83, 0x92 }, 6}, +#line 1290 "data/html_entities.gperf" + {"order", { 0xE2, 0x84, 0xB4 }, 3}, +#line 461 "data/html_entities.gperf" + {"homtht", { 0xE2, 0x88, 0xBB }, 3}, +#line 1095 "data/html_entities.gperf" + {"plustwo", { 0xE2, 0xA8, 0xA7 }, 3}, +#line 13 "data/html_entities.gperf" + {"iota", { 0xCE, 0xB9 }, 2}, +#line 65 "data/html_entities.gperf" + {"hscr", { 0xF0, 0x9D, 0x92, 0xBD }, 4}, +#line 459 "data/html_entities.gperf" + {"infintie", { 0xE2, 0xA7, 0x9D }, 3}, +#line 1463 "data/html_entities.gperf" + {"nsce", { 0xE2, 0xAA, 0xB0, 0xCC, 0xB8 }, 5}, +#line 144 "data/html_entities.gperf" + {"beta", { 0xCE, 0xB2 }, 2}, +#line 1477 "data/html_entities.gperf" + {"EmptySmallSquare", { 0xE2, 0x97, 0xBB }, 3}, +#line 1769 "data/html_entities.gperf" + {"Iogon", { 0xC4, 0xAE }, 2}, +#line 328 "data/html_entities.gperf" + {"Zeta", { 0xCE, 0x96 }, 2}, +#line 1438 "data/html_entities.gperf" + {"ltcir", { 0xE2, 0xA9, 0xB9 }, 3}, +#line 317 "data/html_entities.gperf" + {"Ubreve", { 0xC5, 0xAC }, 2}, +#line 1208 "data/html_entities.gperf" + {"xhArr", { 0xE2, 0x9F, 0xBA }, 3}, +#line 1316 "data/html_entities.gperf" + {"tridot", { 0xE2, 0x97, 0xAC }, 3}, +#line 1235 "data/html_entities.gperf" + {"dtdot", { 0xE2, 0x8B, 0xB1 }, 3}, +#line 1676 "data/html_entities.gperf" + {"swarrow", { 0xE2, 0x86, 0x99 }, 3}, +#line 20 "data/html_entities.gperf" + {"scnE", { 0xE2, 0xAA, 0xB6 }, 3}, +#line 556 "data/html_entities.gperf" + {"csupe", { 0xE2, 0xAB, 0x92 }, 3}, +#line 1392 "data/html_entities.gperf" + {"csube", { 0xE2, 0xAB, 0x91 }, 3}, +#line 1974 "data/html_entities.gperf" + {"nwarrow", { 0xE2, 0x86, 0x96 }, 3}, +#line 1434 "data/html_entities.gperf" + {"lowast", { 0xE2, 0x88, 0x97 }, 3}, +#line 1193 "data/html_entities.gperf" + {"Aogon", { 0xC4, 0x84 }, 2}, +#line 1882 "data/html_entities.gperf" + {"racute", { 0xC5, 0x95 }, 2}, +#line 1460 "data/html_entities.gperf" + {"lacute", { 0xC4, 0xBA }, 2}, +#line 2110 "data/html_entities.gperf" + {"sacute", { 0xC5, 0x9B }, 2}, +#line 765 "data/html_entities.gperf" + {"eacute", { 0xC3, 0xA9 }, 2}, +#line 851 "data/html_entities.gperf" + {"Lsh", { 0xE2, 0x86, 0xB0 }, 3}, +#line 942 "data/html_entities.gperf" + {"UpArrow", { 0xE2, 0x86, 0x91 }, 3}, +#line 1830 "data/html_entities.gperf" + {"Rsh", { 0xE2, 0x86, 0xB1 }, 3}, +#line 1191 "data/html_entities.gperf" + {"uacute", { 0xC3, 0xBA }, 2}, +#line 1508 "data/html_entities.gperf" + {"nacute", { 0xC5, 0x84 }, 2}, +#line 1871 "data/html_entities.gperf" + {"Zacute", { 0xC5, 0xB9 }, 2}, +#line 1405 "data/html_entities.gperf" + {"timesd", { 0xE2, 0xA8, 0xB0 }, 3}, +#line 1615 "data/html_entities.gperf" + {"caron", { 0xCB, 0x87 }, 2}, +#line 36 "data/html_entities.gperf" + {"xlArr", { 0xE2, 0x9F, 0xB8 }, 3}, +#line 485 "data/html_entities.gperf" + {"DoubleVerticalBar", { 0xE2, 0x88, 0xA5 }, 3}, +#line 1223 "data/html_entities.gperf" + {"Sacute", { 0xC5, 0x9A }, 2}, +#line 2062 "data/html_entities.gperf" + {"xrArr", { 0xE2, 0x9F, 0xB9 }, 3}, +#line 1218 "data/html_entities.gperf" + {"circeq", { 0xE2, 0x89, 0x97 }, 3}, +#line 798 "data/html_entities.gperf" + {"rthree", { 0xE2, 0x8B, 0x8C }, 3}, +#line 1036 "data/html_entities.gperf" + {"lthree", { 0xE2, 0x8B, 0x8B }, 3}, +#line 1665 "data/html_entities.gperf" + {"ClockwiseContourIntegral", { 0xE2, 0x88, 0xB2 }, 3}, +#line 515 "data/html_entities.gperf" + {"lmidot", { 0xC5, 0x80 }, 2}, +#line 1058 "data/html_entities.gperf" + {"Uogon", { 0xC5, 0xB2 }, 2}, +#line 1579 "data/html_entities.gperf" + {"nvle", { 0xE2, 0x89, 0xA4, 0xE2, 0x83, 0x92 }, 6}, +#line 806 "data/html_entities.gperf" + {"apE", { 0xE2, 0xA9, 0xB0 }, 3}, +#line 1652 "data/html_entities.gperf" + {"LeftUpDownVector", { 0xE2, 0xA5, 0x91 }, 3}, +#line 1179 "data/html_entities.gperf" + {"lesg", { 0xE2, 0x8B, 0x9A, 0xEF, 0xB8, 0x80 }, 6}, +#line 756 "data/html_entities.gperf" + {"rfisht", { 0xE2, 0xA5, 0xBD }, 3}, +#line 1828 "data/html_entities.gperf" + {"MediumSpace", { 0xE2, 0x81, 0x9F }, 3}, +#line 546 "data/html_entities.gperf" + {"lfisht", { 0xE2, 0xA5, 0xBC }, 3}, +#line 1427 "data/html_entities.gperf" + {"ufisht", { 0xE2, 0xA5, 0xBE }, 3}, +#line 396 "data/html_entities.gperf" + {"backcong", { 0xE2, 0x89, 0x8C }, 3}, +#line 1696 "data/html_entities.gperf" + {"Iacute", { 0xC3, 0x8D }, 2}, +#line 1024 "data/html_entities.gperf" + {"nsc", { 0xE2, 0x8A, 0x81 }, 3}, +#line 75 "data/html_entities.gperf" + {"iiiint", { 0xE2, 0xA8, 0x8C }, 3}, +#line 516 "data/html_entities.gperf" + {"ApplyFunction", { 0xE2, 0x81, 0xA1 }, 3}, +#line 1020 "data/html_entities.gperf" + {"cirE", { 0xE2, 0xA7, 0x83 }, 3}, +#line 1130 "data/html_entities.gperf" + {"upharpoonright", { 0xE2, 0x86, 0xBE }, 3}, +#line 421 "data/html_entities.gperf" + {"complement", { 0xE2, 0x88, 0x81 }, 3}, +#line 430 "data/html_entities.gperf" + {"cscr", { 0xF0, 0x9D, 0x92, 0xB8 }, 4}, +#line 1450 "data/html_entities.gperf" + {"ReverseElement", { 0xE2, 0x88, 0x8B }, 3}, +#line 207 "data/html_entities.gperf" + {"Lacute", { 0xC4, 0xB9 }, 2}, +#line 818 "data/html_entities.gperf" + {"zigrarr", { 0xE2, 0x87, 0x9D }, 3}, +#line 1618 "data/html_entities.gperf" + {"Racute", { 0xC5, 0x94 }, 2}, +#line 1512 "data/html_entities.gperf" + {"Aacute", { 0xC3, 0x81 }, 2}, +#line 1090 "data/html_entities.gperf" + {"iogon", { 0xC4, 0xAF }, 2}, +#line 219 "data/html_entities.gperf" + {"Nacute", { 0xC5, 0x83 }, 2}, +#line 1028 "data/html_entities.gperf" + {"sqcups", { 0xE2, 0x8A, 0x94, 0xEF, 0xB8, 0x80 }, 6}, +#line 1250 "data/html_entities.gperf" + {"xopf", { 0xF0, 0x9D, 0x95, 0xA9 }, 4}, +#line 2068 "data/html_entities.gperf" + {"ast", { 0x2A }, 1}, +#line 1745 "data/html_entities.gperf" + {"egs", { 0xE2, 0xAA, 0x96 }, 3}, +#line 1835 "data/html_entities.gperf" + {"oint", { 0xE2, 0x88, 0xAE }, 3}, +#line 402 "data/html_entities.gperf" + {"sqsupseteq", { 0xE2, 0x8A, 0x92 }, 3}, +#line 1154 "data/html_entities.gperf" + {"iff", { 0xE2, 0x87, 0x94 }, 3}, +#line 250 "data/html_entities.gperf" + {"ngt", { 0xE2, 0x89, 0xAF }, 3}, +#line 1283 "data/html_entities.gperf" + {"DoubleRightTee", { 0xE2, 0x8A, 0xA8 }, 3}, +#line 1971 "data/html_entities.gperf" + {"Yacute", { 0xC3, 0x9D }, 2}, +#line 1032 "data/html_entities.gperf" + {"eplus", { 0xE2, 0xA9, 0xB1 }, 3}, +#line 1961 "data/html_entities.gperf" + {"Lmidot", { 0xC4, 0xBF }, 2}, +#line 743 "data/html_entities.gperf" + {"sqcup", { 0xE2, 0x8A, 0x94 }, 3}, +#line 961 "data/html_entities.gperf" + {"uplus", { 0xE2, 0x8A, 0x8E }, 3}, +#line 147 "data/html_entities.gperf" + {"NotVerticalBar", { 0xE2, 0x88, 0xA4 }, 3}, +#line 57 "data/html_entities.gperf" + {"Esim", { 0xE2, 0xA9, 0xB3 }, 3}, +#line 1334 "data/html_entities.gperf" + {"Uacute", { 0xC3, 0x9A }, 2}, +#line 1514 "data/html_entities.gperf" + {"prcue", { 0xE2, 0x89, 0xBC }, 3}, +#line 66 "data/html_entities.gperf" + {"ngtr", { 0xE2, 0x89, 0xAF }, 3}, +#line 200 "data/html_entities.gperf" + {"cirscir", { 0xE2, 0xA7, 0x82 }, 3}, +#line 536 "data/html_entities.gperf" + {"bigotimes", { 0xE2, 0xA8, 0x82 }, 3}, +#line 93 "data/html_entities.gperf" + {"dtri", { 0xE2, 0x96, 0xBF }, 3}, +#line 136 "data/html_entities.gperf" + {"dbkarow", { 0xE2, 0xA4, 0x8F }, 3}, +#line 1556 "data/html_entities.gperf" + {"isinE", { 0xE2, 0x8B, 0xB9 }, 3}, +#line 1504 "data/html_entities.gperf" + {"Edot", { 0xC4, 0x96 }, 2}, +#line 1681 "data/html_entities.gperf" + {"NotEqualTilde", { 0xE2, 0x89, 0x82, 0xCC, 0xB8 }, 5}, +#line 1003 "data/html_entities.gperf" + {"NegativeMediumSpace", { 0xE2, 0x80, 0x8B }, 3}, +#line 373 "data/html_entities.gperf" + {"TildeTilde", { 0xE2, 0x89, 0x88 }, 3}, +#line 1070 "data/html_entities.gperf" + {"iacute", { 0xC3, 0xAD }, 2}, +#line 1448 "data/html_entities.gperf" + {"Beta", { 0xCE, 0x92 }, 2}, +#line 48 "data/html_entities.gperf" + {"hfr", { 0xF0, 0x9D, 0x94, 0xA5 }, 4}, +#line 1457 "data/html_entities.gperf" + {"LeftArrowBar", { 0xE2, 0x87, 0xA4 }, 3}, +#line 1614 "data/html_entities.gperf" + {"Congruent", { 0xE2, 0x89, 0xA1 }, 3}, +#line 1715 "data/html_entities.gperf" + {"gesdot", { 0xE2, 0xAA, 0x80 }, 3}, +#line 239 "data/html_entities.gperf" + {"DifferentialD", { 0xE2, 0x85, 0x86 }, 3}, +#line 349 "data/html_entities.gperf" + {"nge", { 0xE2, 0x89, 0xB1 }, 3}, +#line 1956 "data/html_entities.gperf" + {"vellip", { 0xE2, 0x8B, 0xAE }, 3}, +#line 1355 "data/html_entities.gperf" + {"leqslant", { 0xE2, 0xA9, 0xBD }, 3}, +#line 171 "data/html_entities.gperf" + {"smid", { 0xE2, 0x88, 0xA3 }, 3}, +#line 1921 "data/html_entities.gperf" + {"tbrk", { 0xE2, 0x8E, 0xB4 }, 3}, +#line 205 "data/html_entities.gperf" + {"fork", { 0xE2, 0x8B, 0x94 }, 3}, +#line 1941 "data/html_entities.gperf" + {"nmid", { 0xE2, 0x88, 0xA4 }, 3}, +#line 1695 "data/html_entities.gperf" + {"bbrk", { 0xE2, 0x8E, 0xB5 }, 3}, +#line 1805 "data/html_entities.gperf" + {"theta", { 0xCE, 0xB8 }, 2}, +#line 1623 "data/html_entities.gperf" + {"nsucc", { 0xE2, 0x8A, 0x81 }, 3}, +#line 2108 "data/html_entities.gperf" + {"leftarrow", { 0xE2, 0x86, 0x90 }, 3}, +#line 1340 "data/html_entities.gperf" + {"CenterDot", { 0xC2, 0xB7 }, 2}, +#line 191 "data/html_entities.gperf" + {"PrecedesEqual", { 0xE2, 0xAA, 0xAF }, 3}, +#line 813 "data/html_entities.gperf" + {"nu", { 0xCE, 0xBD }, 2}, +#line 1180 "data/html_entities.gperf" + {"DoubleLongLeftArrow", { 0xE2, 0x9F, 0xB8 }, 3}, +#line 1271 "data/html_entities.gperf" + {"DoubleLongLeftRightArrow", { 0xE2, 0x9F, 0xBA }, 3}, +#line 1134 "data/html_entities.gperf" + {"UpperLeftArrow", { 0xE2, 0x86, 0x96 }, 3}, +#line 1571 "data/html_entities.gperf" + {"ohbar", { 0xE2, 0xA6, 0xB5 }, 3}, +#line 1294 "data/html_entities.gperf" + {"imath", { 0xC4, 0xB1 }, 2}, +#line 29 "data/html_entities.gperf" + {"nvgt", { 0x3E, 0xE2, 0x83, 0x92 }, 4}, +#line 1364 "data/html_entities.gperf" + {"simg", { 0xE2, 0xAA, 0x9E }, 3}, +#line 127 "data/html_entities.gperf" + {"trie", { 0xE2, 0x89, 0x9C }, 3}, +#line 927 "data/html_entities.gperf" + {"ddotseq", { 0xE2, 0xA9, 0xB7 }, 3}, +#line 1054 "data/html_entities.gperf" + {"nges", { 0xE2, 0xA9, 0xBE, 0xCC, 0xB8 }, 5}, +#line 152 "data/html_entities.gperf" + {"trpezium", { 0xE2, 0x8F, 0xA2 }, 3}, +#line 81 "data/html_entities.gperf" + {"nwnear", { 0xE2, 0xA4, 0xA7 }, 3}, +#line 2006 "data/html_entities.gperf" + {"eng", { 0xC5, 0x8B }, 2}, +#line 990 "data/html_entities.gperf" + {"Mellintrf", { 0xE2, 0x84, 0xB3 }, 3}, +#line 666 "data/html_entities.gperf" + {"bbrktbrk", { 0xE2, 0x8E, 0xB6 }, 3}, +#line 707 "data/html_entities.gperf" + {"DownTee", { 0xE2, 0x8A, 0xA4 }, 3}, +#line 883 "data/html_entities.gperf" + {"uuarr", { 0xE2, 0x87, 0x88 }, 3}, +#line 1161 "data/html_entities.gperf" + {"ZeroWidthSpace", { 0xE2, 0x80, 0x8B }, 3}, +#line 1008 "data/html_entities.gperf" + {"isinv", { 0xE2, 0x88, 0x88 }, 3}, +#line 702 "data/html_entities.gperf" + {"iinfin", { 0xE2, 0xA7, 0x9C }, 3}, +#line 1414 "data/html_entities.gperf" + {"xi", { 0xCE, 0xBE }, 2}, +#line 446 "data/html_entities.gperf" + {"boxUr", { 0xE2, 0x95, 0x99 }, 3}, +#line 132 "data/html_entities.gperf" + {"zdot", { 0xC5, 0xBC }, 2}, +#line 2103 "data/html_entities.gperf" + {"dfisht", { 0xE2, 0xA5, 0xBF }, 3}, +#line 797 "data/html_entities.gperf" + {"bump", { 0xE2, 0x89, 0x8E }, 3}, +#line 805 "data/html_entities.gperf" + {"Eogon", { 0xC4, 0x98 }, 2}, +#line 17 "data/html_entities.gperf" + {"block", { 0xE2, 0x96, 0x88 }, 3}, +#line 940 "data/html_entities.gperf" + {"cfr", { 0xF0, 0x9D, 0x94, 0xA0 }, 4}, +#line 544 "data/html_entities.gperf" + {"blank", { 0xE2, 0x90, 0xA3 }, 3}, +#line 475 "data/html_entities.gperf" + {"Leftarrow", { 0xE2, 0x87, 0x90 }, 3}, +#line 33 "data/html_entities.gperf" + {"bigodot", { 0xE2, 0xA8, 0x80 }, 3}, +#line 1059 "data/html_entities.gperf" + {"Omicron", { 0xCE, 0x9F }, 2}, +#line 2098 "data/html_entities.gperf" + {"nLtv", { 0xE2, 0x89, 0xAA, 0xCC, 0xB8 }, 5}, +#line 528 "data/html_entities.gperf" + {"hairsp", { 0xE2, 0x80, 0x8A }, 3}, +#line 759 "data/html_entities.gperf" + {"ngeq", { 0xE2, 0x89, 0xB1 }, 3}, +#line 965 "data/html_entities.gperf" + {"Nu", { 0xCE, 0x9D }, 2}, +#line 50 "data/html_entities.gperf" + {"Mu", { 0xCE, 0x9C }, 2}, +#line 1246 "data/html_entities.gperf" + {"ngeqq", { 0xE2, 0x89, 0xA7, 0xCC, 0xB8 }, 5}, +#line 910 "data/html_entities.gperf" + {"DownLeftVector", { 0xE2, 0x86, 0xBD }, 3}, +#line 832 "data/html_entities.gperf" + {"rhov", { 0xCF, 0xB1 }, 2}, +#line 1389 "data/html_entities.gperf" + {"UpperRightArrow", { 0xE2, 0x86, 0x97 }, 3}, +#line 1528 "data/html_entities.gperf" + {"DownLeftVectorBar", { 0xE2, 0xA5, 0x96 }, 3}, +#line 1257 "data/html_entities.gperf" + {"lEg", { 0xE2, 0xAA, 0x8B }, 3}, +#line 295 "data/html_entities.gperf" + {"rarrw", { 0xE2, 0x86, 0x9D }, 3}, +#line 548 "data/html_entities.gperf" + {"nGg", { 0xE2, 0x8B, 0x99, 0xCC, 0xB8 }, 5}, +#line 542 "data/html_entities.gperf" + {"rtriltri", { 0xE2, 0xA7, 0x8E }, 3}, +#line 769 "data/html_entities.gperf" + {"bumpe", { 0xE2, 0x89, 0x8F }, 3}, +#line 251 "data/html_entities.gperf" + {"TildeEqual", { 0xE2, 0x89, 0x83 }, 3}, +#line 1345 "data/html_entities.gperf" + {"sup1", { 0xC2, 0xB9 }, 2}, +#line 1247 "data/html_entities.gperf" + {"DownLeftTeeVector", { 0xE2, 0xA5, 0x9E }, 3}, +#line 28 "data/html_entities.gperf" + {"barvee", { 0xE2, 0x8A, 0xBD }, 3}, +#line 1758 "data/html_entities.gperf" + {"ascr", { 0xF0, 0x9D, 0x92, 0xB6 }, 4}, +#line 1057 "data/html_entities.gperf" + {"sup3", { 0xC2, 0xB3 }, 2}, +#line 911 "data/html_entities.gperf" + {"sup2", { 0xC2, 0xB2 }, 2}, +#line 166 "data/html_entities.gperf" + {"boxH", { 0xE2, 0x95, 0x90 }, 3}, +#line 1262 "data/html_entities.gperf" + {"sc", { 0xE2, 0x89, 0xBB }, 3}, +#line 301 "data/html_entities.gperf" + {"ltlarr", { 0xE2, 0xA5, 0xB6 }, 3}, +#line 949 "data/html_entities.gperf" + {"Theta", { 0xCE, 0x98 }, 2}, +#line 1561 "data/html_entities.gperf" + {"kappav", { 0xCF, 0xB0 }, 2}, +#line 640 "data/html_entities.gperf" + {"nGtv", { 0xE2, 0x89, 0xAB, 0xCC, 0xB8 }, 5}, +#line 1498 "data/html_entities.gperf" + {"circledast", { 0xE2, 0x8A, 0x9B }, 3}, +#line 474 "data/html_entities.gperf" + {"sup", { 0xE2, 0x8A, 0x83 }, 3}, +#line 1984 "data/html_entities.gperf" + {"rsquor", { 0xE2, 0x80, 0x99 }, 3}, +#line 1133 "data/html_entities.gperf" + {"lsquor", { 0xE2, 0x80, 0x9A }, 3}, +#line 970 "data/html_entities.gperf" + {"NotLessSlantEqual", { 0xE2, 0xA9, 0xBD, 0xCC, 0xB8 }, 5}, +#line 983 "data/html_entities.gperf" + {"doteqdot", { 0xE2, 0x89, 0x91 }, 3}, +#line 9 "data/html_entities.gperf" + {"circledS", { 0xE2, 0x93, 0x88 }, 3}, +#line 1999 "data/html_entities.gperf" + {"Sc", { 0xE2, 0xAA, 0xBC }, 3}, +#line 436 "data/html_entities.gperf" + {"boxHu", { 0xE2, 0x95, 0xA7 }, 3}, +#line 190 "data/html_entities.gperf" + {"TildeFullEqual", { 0xE2, 0x89, 0x85 }, 3}, +#line 711 "data/html_entities.gperf" + {"boxVr", { 0xE2, 0x95, 0x9F }, 3}, +#line 370 "data/html_entities.gperf" + {"Eacute", { 0xC3, 0x89 }, 2}, +#line 984 "data/html_entities.gperf" + {"colon", { 0x3A }, 1}, +#line 1777 "data/html_entities.gperf" + {"boxUR", { 0xE2, 0x95, 0x9A }, 3}, +#line 985 "data/html_entities.gperf" + {"prnsim", { 0xE2, 0x8B, 0xA8 }, 3}, +#line 749 "data/html_entities.gperf" + {"boxV", { 0xE2, 0x95, 0x91 }, 3}, +#line 513 "data/html_entities.gperf" + {"isindot", { 0xE2, 0x8B, 0xB5 }, 3}, +#line 34 "data/html_entities.gperf" + {"Sup", { 0xE2, 0x8B, 0x91 }, 3}, +#line 641 "data/html_entities.gperf" + {"colone", { 0xE2, 0x89, 0x94 }, 3}, +#line 1306 "data/html_entities.gperf" + {"Laplacetrf", { 0xE2, 0x84, 0x92 }, 3}, +#line 1798 "data/html_entities.gperf" + {"roang", { 0xE2, 0x9F, 0xAD }, 3}, +#line 1023 "data/html_entities.gperf" + {"vartheta", { 0xCF, 0x91 }, 2}, +#line 492 "data/html_entities.gperf" + {"loang", { 0xE2, 0x9F, 0xAC }, 3}, +#line 1394 "data/html_entities.gperf" + {"ccaps", { 0xE2, 0xA9, 0x8D }, 3}, +#line 1510 "data/html_entities.gperf" + {"dblac", { 0xCB, 0x9D }, 2}, +#line 1815 "data/html_entities.gperf" + {"DoubleLongRightArrow", { 0xE2, 0x9F, 0xB9 }, 3}, +#line 1625 "data/html_entities.gperf" + {"nshortparallel", { 0xE2, 0x88, 0xA6 }, 3}, +#line 752 "data/html_entities.gperf" + {"vartriangleright", { 0xE2, 0x8A, 0xB3 }, 3}, +#line 1045 "data/html_entities.gperf" + {"vartriangleleft", { 0xE2, 0x8A, 0xB2 }, 3}, +#line 1113 "data/html_entities.gperf" + {"compfn", { 0xE2, 0x88, 0x98 }, 3}, +#line 172 "data/html_entities.gperf" + {"risingdotseq", { 0xE2, 0x89, 0x93 }, 3}, +#line 1855 "data/html_entities.gperf" + {"trisb", { 0xE2, 0xA7, 0x8D }, 3}, +#line 2070 "data/html_entities.gperf" + {"Cdot", { 0xC4, 0x8A }, 2}, +#line 122 "data/html_entities.gperf" + {"omicron", { 0xCE, 0xBF }, 2}, +#line 1982 "data/html_entities.gperf" + {"circledR", { 0xC2, 0xAE }, 2}, +#line 1397 "data/html_entities.gperf" + {"ccups", { 0xE2, 0xA9, 0x8C }, 3}, +#line 791 "data/html_entities.gperf" + {"reg", { 0xC2, 0xAE }, 2}, +#line 1196 "data/html_entities.gperf" + {"leg", { 0xE2, 0x8B, 0x9A }, 3}, +#line 1968 "data/html_entities.gperf" + {"breve", { 0xCB, 0x98 }, 2}, +#line 937 "data/html_entities.gperf" + {"nexist", { 0xE2, 0x88, 0x84 }, 3}, +#line 1304 "data/html_entities.gperf" + {"numsp", { 0xE2, 0x80, 0x87 }, 3}, +#line 1537 "data/html_entities.gperf" + {"ReverseEquilibrium", { 0xE2, 0x87, 0x8B }, 3}, +#line 1327 "data/html_entities.gperf" + {"boxUL", { 0xE2, 0x95, 0x9D }, 3}, +#line 981 "data/html_entities.gperf" + {"zeta", { 0xCE, 0xB6 }, 2}, +#line 1531 "data/html_entities.gperf" + {"supmult", { 0xE2, 0xAB, 0x82 }, 3}, +#line 1841 "data/html_entities.gperf" + {"HilbertSpace", { 0xE2, 0x84, 0x8B }, 3}, +#line 257 "data/html_entities.gperf" + {"nexists", { 0xE2, 0x88, 0x84 }, 3}, +#line 1425 "data/html_entities.gperf" + {"ccaron", { 0xC4, 0x8D }, 2}, +#line 2013 "data/html_entities.gperf" + {"LessSlantEqual", { 0xE2, 0xA9, 0xBD }, 3}, +#line 593 "data/html_entities.gperf" + {"quest", { 0x3F }, 1}, +#line 514 "data/html_entities.gperf" + {"supsub", { 0xE2, 0xAB, 0x94 }, 3}, +#line 971 "data/html_entities.gperf" + {"boxHU", { 0xE2, 0x95, 0xA9 }, 3}, +#line 1266 "data/html_entities.gperf" + {"gvnE", { 0xE2, 0x89, 0xA9, 0xEF, 0xB8, 0x80 }, 6}, +#line 1051 "data/html_entities.gperf" + {"duarr", { 0xE2, 0x87, 0xB5 }, 3}, +#line 673 "data/html_entities.gperf" + {"chi", { 0xCF, 0x87 }, 2}, +#line 1878 "data/html_entities.gperf" + {"supset", { 0xE2, 0x8A, 0x83 }, 3}, +#line 138 "data/html_entities.gperf" + {"kopf", { 0xF0, 0x9D, 0x95, 0x9C }, 4}, +#line 64 "data/html_entities.gperf" + {"boxVH", { 0xE2, 0x95, 0xAC }, 3}, +#line 1243 "data/html_entities.gperf" + {"boxVR", { 0xE2, 0x95, 0xA0 }, 3}, +#line 454 "data/html_entities.gperf" + {"odot", { 0xE2, 0x8A, 0x99 }, 3}, +#line 626 "data/html_entities.gperf" + {"zacute", { 0xC5, 0xBA }, 2}, +#line 1459 "data/html_entities.gperf" + {"Barv", { 0xE2, 0xAB, 0xA7 }, 3}, +#line 812 "data/html_entities.gperf" + {"raquo", { 0xC2, 0xBB }, 2}, +#line 1768 "data/html_entities.gperf" + {"Supset", { 0xE2, 0x8B, 0x91 }, 3}, +#line 1264 "data/html_entities.gperf" + {"laquo", { 0xC2, 0xAB }, 2}, +#line 194 "data/html_entities.gperf" + {"LeftArrow", { 0xE2, 0x86, 0x90 }, 3}, +#line 214 "data/html_entities.gperf" + {"ngsim", { 0xE2, 0x89, 0xB5 }, 3}, +#line 1137 "data/html_entities.gperf" + {"dagger", { 0xE2, 0x80, 0xA0 }, 3}, +#line 1907 "data/html_entities.gperf" + {"exponentiale", { 0xE2, 0x85, 0x87 }, 3}, +#line 255 "data/html_entities.gperf" + {"Dagger", { 0xE2, 0x80, 0xA1 }, 3}, +#line 1827 "data/html_entities.gperf" + {"xsqcup", { 0xE2, 0xA8, 0x86 }, 3}, +#line 180 "data/html_entities.gperf" + {"supne", { 0xE2, 0x8A, 0x8B }, 3}, +#line 318 "data/html_entities.gperf" + {"lesdoto", { 0xE2, 0xAA, 0x81 }, 3}, +#line 35 "data/html_entities.gperf" + {"raemptyv", { 0xE2, 0xA6, 0xB3 }, 3}, +#line 704 "data/html_entities.gperf" + {"laemptyv", { 0xE2, 0xA6, 0xB4 }, 3}, +#line 893 "data/html_entities.gperf" + {"xscr", { 0xF0, 0x9D, 0x93, 0x8D }, 4}, +#line 1087 "data/html_entities.gperf" + {"supsup", { 0xE2, 0xAB, 0x96 }, 3}, +#line 1280 "data/html_entities.gperf" + {"shcy", { 0xD1, 0x88 }, 2}, +#line 1959 "data/html_entities.gperf" + {"ic", { 0xE2, 0x81, 0xA3 }, 3}, +#line 1908 "data/html_entities.gperf" + {"ljcy", { 0xD1, 0x99 }, 2}, +#line 588 "data/html_entities.gperf" + {"capdot", { 0xE2, 0xA9, 0x80 }, 3}, +#line 830 "data/html_entities.gperf" + {"boxHd", { 0xE2, 0x95, 0xA4 }, 3}, +#line 393 "data/html_entities.gperf" + {"njcy", { 0xD1, 0x9A }, 2}, +#line 1442 "data/html_entities.gperf" + {"HumpEqual", { 0xE2, 0x89, 0x8F }, 3}, +#line 362 "data/html_entities.gperf" + {"Product", { 0xE2, 0x88, 0x8F }, 3}, +#line 694 "data/html_entities.gperf" + {"bumpeq", { 0xE2, 0x89, 0x8F }, 3}, +#line 672 "data/html_entities.gperf" + {"gsime", { 0xE2, 0xAA, 0x8E }, 3}, +#line 1688 "data/html_entities.gperf" + {"afr", { 0xF0, 0x9D, 0x94, 0x9E }, 4}, +#line 670 "data/html_entities.gperf" + {"boxVL", { 0xE2, 0x95, 0xA3 }, 3}, +#line 1810 "data/html_entities.gperf" + {"bemptyv", { 0xE2, 0xA6, 0xB0 }, 3}, +#line 1509 "data/html_entities.gperf" + {"DiacriticalAcute", { 0xC2, 0xB4 }, 2}, +#line 97 "data/html_entities.gperf" + {"sbquo", { 0xE2, 0x80, 0x9A }, 3}, +#line 1870 "data/html_entities.gperf" + {"Oacute", { 0xC3, 0x93 }, 2}, +#line 110 "data/html_entities.gperf" + {"mu", { 0xCE, 0xBC }, 2}, +#line 1638 "data/html_entities.gperf" + {"DownArrowBar", { 0xE2, 0xA4, 0x93 }, 3}, +#line 1252 "data/html_entities.gperf" + {"rang", { 0xE2, 0x9F, 0xA9 }, 3}, +#line 1735 "data/html_entities.gperf" + {"lang", { 0xE2, 0x9F, 0xA8 }, 3}, +#line 1400 "data/html_entities.gperf" + {"ocir", { 0xE2, 0x8A, 0x9A }, 3}, +#line 156 "data/html_entities.gperf" + {"nang", { 0xE2, 0x88, 0xA0, 0xE2, 0x83, 0x92 }, 6}, +#line 11 "data/html_entities.gperf" + {"sum", { 0xE2, 0x88, 0x91 }, 3}, +#line 689 "data/html_entities.gperf" + {"yopf", { 0xF0, 0x9D, 0x95, 0xAA }, 4}, +#line 86 "data/html_entities.gperf" + {"NotExists", { 0xE2, 0x88, 0x84 }, 3}, +#line 1152 "data/html_entities.gperf" + {"realpart", { 0xE2, 0x84, 0x9C }, 3}, +#line 1356 "data/html_entities.gperf" + {"num", { 0x23 }, 1}, +#line 1840 "data/html_entities.gperf" + {"supseteq", { 0xE2, 0x8A, 0x87 }, 3}, +#line 2124 "data/html_entities.gperf" + {"supseteqq", { 0xE2, 0xAB, 0x86 }, 3}, +#line 741 "data/html_entities.gperf" + {"lnapprox", { 0xE2, 0xAA, 0x89 }, 3}, +#line 898 "data/html_entities.gperf" + {"supsetneq", { 0xE2, 0x8A, 0x8B }, 3}, +#line 1627 "data/html_entities.gperf" + {"coloneq", { 0xE2, 0x89, 0x94 }, 3}, +#line 992 "data/html_entities.gperf" + {"Sum", { 0xE2, 0x88, 0x91 }, 3}, +#line 1796 "data/html_entities.gperf" + {"lgE", { 0xE2, 0xAA, 0x91 }, 3}, +#line 690 "data/html_entities.gperf" + {"af", { 0xE2, 0x81, 0xA1 }, 3}, +#line 1924 "data/html_entities.gperf" + {"ngE", { 0xE2, 0x89, 0xA7, 0xCC, 0xB8 }, 5}, +#line 96 "data/html_entities.gperf" + {"IOcy", { 0xD0, 0x81 }, 2}, +#line 274 "data/html_entities.gperf" + {"DiacriticalTilde", { 0xCB, 0x9C }, 2}, +#line 2091 "data/html_entities.gperf" + {"bsolb", { 0xE2, 0xA7, 0x85 }, 3}, +#line 1880 "data/html_entities.gperf" + {"ZHcy", { 0xD0, 0x96 }, 2}, +#line 897 "data/html_entities.gperf" + {"DoubleRightArrow", { 0xE2, 0x87, 0x92 }, 3}, +#line 1102 "data/html_entities.gperf" + {"xoplus", { 0xE2, 0xA8, 0x81 }, 3}, +#line 796 "data/html_entities.gperf" + {"boxUl", { 0xE2, 0x95, 0x9C }, 3}, +#line 1429 "data/html_entities.gperf" + {"SHcy", { 0xD0, 0xA8 }, 2}, +#line 456 "data/html_entities.gperf" + {"szlig", { 0xC3, 0x9F }, 2}, +#line 1891 "data/html_entities.gperf" + {"Cacute", { 0xC4, 0x86 }, 2}, +#line 1439 "data/html_entities.gperf" + {"boxplus", { 0xE2, 0x8A, 0x9E }, 3}, +#line 163 "data/html_entities.gperf" + {"Breve", { 0xCB, 0x98 }, 2}, +#line 828 "data/html_entities.gperf" + {"deg", { 0xC2, 0xB0 }, 2}, +#line 739 "data/html_entities.gperf" + {"Lang", { 0xE2, 0x9F, 0xAA }, 3}, +#line 2023 "data/html_entities.gperf" + {"Rang", { 0xE2, 0x9F, 0xAB }, 3}, +#line 552 "data/html_entities.gperf" + {"IEcy", { 0xD0, 0x95 }, 2}, +#line 917 "data/html_entities.gperf" + {"apacir", { 0xE2, 0xA9, 0xAF }, 3}, +#line 2051 "data/html_entities.gperf" + {"gla", { 0xE2, 0xAA, 0xA5 }, 3}, +#line 868 "data/html_entities.gperf" + {"downarrow", { 0xE2, 0x86, 0x93 }, 3}, +#line 484 "data/html_entities.gperf" + {"zwnj", { 0xE2, 0x80, 0x8C }, 3}, +#line 1678 "data/html_entities.gperf" + {"UpArrowDownArrow", { 0xE2, 0x87, 0x85 }, 3}, +#line 1491 "data/html_entities.gperf" + {"CapitalDifferentialD", { 0xE2, 0x85, 0x85 }, 3}, +#line 685 "data/html_entities.gperf" + {"KHcy", { 0xD0, 0xA5 }, 2}, +#line 2053 "data/html_entities.gperf" + {"Downarrow", { 0xE2, 0x87, 0x93 }, 3}, +#line 477 "data/html_entities.gperf" + {"KJcy", { 0xD0, 0x8C }, 2}, +#line 964 "data/html_entities.gperf" + {"Cconint", { 0xE2, 0x88, 0xB0 }, 3}, +#line 1860 "data/html_entities.gperf" + {"oacute", { 0xC3, 0xB3 }, 2}, +#line 1791 "data/html_entities.gperf" + {"gamma", { 0xCE, 0xB3 }, 2}, +#line 857 "data/html_entities.gperf" + {"questeq", { 0xE2, 0x89, 0x9F }, 3}, +#line 1650 "data/html_entities.gperf" + {"DiacriticalDot", { 0xCB, 0x99 }, 2}, +#line 334 "data/html_entities.gperf" + {"nvinfin", { 0xE2, 0xA7, 0x9E }, 3}, +#line 1261 "data/html_entities.gperf" + {"LJcy", { 0xD0, 0x89 }, 2}, +#line 83 "data/html_entities.gperf" + {"shy", { 0xC2, 0xAD }, 2}, +#line 1241 "data/html_entities.gperf" + {"caret", { 0xE2, 0x81, 0x81 }, 3}, +#line 1259 "data/html_entities.gperf" + {"odsold", { 0xE2, 0xA6, 0xBC }, 3}, +#line 1906 "data/html_entities.gperf" + {"DiacriticalDoubleAcute", { 0xCB, 0x9D }, 2}, +#line 246 "data/html_entities.gperf" + {"iocy", { 0xD1, 0x91 }, 2}, +#line 1325 "data/html_entities.gperf" + {"fjlig", { 0x66, 0x6A }, 2}, +#line 2059 "data/html_entities.gperf" + {"NJcy", { 0xD0, 0x8A }, 2}, +#line 1933 "data/html_entities.gperf" + {"supsetneqq", { 0xE2, 0xAB, 0x8C }, 3}, +#line 213 "data/html_entities.gperf" + {"ovbar", { 0xE2, 0x8C, 0xBD }, 3}, +#line 1875 "data/html_entities.gperf" + {"iiota", { 0xE2, 0x84, 0xA9 }, 3}, +#line 1985 "data/html_entities.gperf" + {"TScy", { 0xD0, 0xA6 }, 2}, +#line 94 "data/html_entities.gperf" + {"conint", { 0xE2, 0x88, 0xAE }, 3}, +#line 1887 "data/html_entities.gperf" + {"Gamma", { 0xCE, 0x93 }, 2}, +#line 121 "data/html_entities.gperf" + {"boxVl", { 0xE2, 0x95, 0xA2 }, 3}, +#line 1071 "data/html_entities.gperf" + {"cent", { 0xC2, 0xA2 }, 2}, +#line 280 "data/html_entities.gperf" + {"supplus", { 0xE2, 0xAB, 0x80 }, 3}, +#line 2129 "data/html_entities.gperf" + {"xfr", { 0xF0, 0x9D, 0x94, 0xB5 }, 4}, +#line 901 "data/html_entities.gperf" + {"fllig", { 0xEF, 0xAC, 0x82 }, 3}, +#line 1237 "data/html_entities.gperf" + {"andslope", { 0xE2, 0xA9, 0x98 }, 3}, +#line 764 "data/html_entities.gperf" + {"dzcy", { 0xD1, 0x9F }, 2}, +#line 1663 "data/html_entities.gperf" + {"cwint", { 0xE2, 0x88, 0xB1 }, 3}, +#line 2029 "data/html_entities.gperf" + {"YIcy", { 0xD0, 0x87 }, 2}, +#line 480 "data/html_entities.gperf" + {"supE", { 0xE2, 0xAB, 0x86 }, 3}, +#line 882 "data/html_entities.gperf" + {"djcy", { 0xD1, 0x92 }, 2}, +#line 404 "data/html_entities.gperf" + {"Bumpeq", { 0xE2, 0x89, 0x8E }, 3}, +#line 223 "data/html_entities.gperf" + {"bumpE", { 0xE2, 0xAA, 0xAE }, 3}, +#line 705 "data/html_entities.gperf" + {"origof", { 0xE2, 0x8A, 0xB6 }, 3}, +#line 1128 "data/html_entities.gperf" + {"DZcy", { 0xD0, 0x8F }, 2}, +#line 731 "data/html_entities.gperf" + {"DownBreve", { 0xCC, 0x91 }, 2}, +#line 1295 "data/html_entities.gperf" + {"cwconint", { 0xE2, 0x88, 0xB2 }, 3}, +#line 457 "data/html_entities.gperf" + {"cirfnint", { 0xE2, 0xA8, 0x90 }, 3}, +#line 1067 "data/html_entities.gperf" + {"YUcy", { 0xD0, 0xAE }, 2}, +#line 371 "data/html_entities.gperf" + {"demptyv", { 0xE2, 0xA6, 0xB1 }, 3}, +#line 823 "data/html_entities.gperf" + {"OverParenthesis", { 0xE2, 0x8F, 0x9C }, 3}, +#line 1851 "data/html_entities.gperf" + {"UpTeeArrow", { 0xE2, 0x86, 0xA5 }, 3}, +#line 1779 "data/html_entities.gperf" + {"capand", { 0xE2, 0xA9, 0x84 }, 3}, +#line 909 "data/html_entities.gperf" + {"sfrown", { 0xE2, 0x8C, 0xA2 }, 3}, +#line 1012 "data/html_entities.gperf" + {"AElig", { 0xC3, 0x86 }, 2}, +#line 1641 "data/html_entities.gperf" + {"asymp", { 0xE2, 0x89, 0x88 }, 3}, +#line 1756 "data/html_entities.gperf" + {"IJlig", { 0xC4, 0xB2 }, 2}, +#line 701 "data/html_entities.gperf" + {"gt", { 0x3E }, 1}, +#line 347 "data/html_entities.gperf" + {"xnis", { 0xE2, 0x8B, 0xBB }, 3}, +#line 543 "data/html_entities.gperf" + {"leftleftarrows", { 0xE2, 0x87, 0x87 }, 3}, +#line 627 "data/html_entities.gperf" + {"integers", { 0xE2, 0x84, 0xA4 }, 3}, +#line 1446 "data/html_entities.gperf" + {"DScy", { 0xD0, 0x85 }, 2}, +#line 617 "data/html_entities.gperf" + {"tritime", { 0xE2, 0xA8, 0xBB }, 3}, +#line 238 "data/html_entities.gperf" + {"ogt", { 0xE2, 0xA7, 0x81 }, 3}, +#line 313 "data/html_entities.gperf" + {"orderof", { 0xE2, 0x84, 0xB4 }, 3}, +#line 2058 "data/html_entities.gperf" + {"oplus", { 0xE2, 0x8A, 0x95 }, 3}, +#line 2088 "data/html_entities.gperf" + {"succeq", { 0xE2, 0xAA, 0xB0 }, 3}, +#line 1686 "data/html_entities.gperf" + {"ReverseUpEquilibrium", { 0xE2, 0xA5, 0xAF }, 3}, +#line 1136 "data/html_entities.gperf" + {"ijlig", { 0xC4, 0xB3 }, 2}, +#line 840 "data/html_entities.gperf" + {"Gt", { 0xE2, 0x89, 0xAB }, 3}, +#line 1782 "data/html_entities.gperf" + {"NonBreakingSpace", { 0xC2, 0xA0 }, 2}, +#line 134 "data/html_entities.gperf" + {"gsim", { 0xE2, 0x89, 0xB3 }, 3}, +#line 519 "data/html_entities.gperf" + {"LeftDoubleBracket", { 0xE2, 0x9F, 0xA6 }, 3}, +#line 1479 "data/html_entities.gperf" + {"gtdot", { 0xE2, 0x8B, 0x97 }, 3}, +#line 241 "data/html_entities.gperf" + {"ndash", { 0xE2, 0x80, 0x93 }, 3}, +#line 1453 "data/html_entities.gperf" + {"gsiml", { 0xE2, 0xAA, 0x90 }, 3}, +#line 1964 "data/html_entities.gperf" + {"acd", { 0xE2, 0x88, 0xBF }, 3}, +#line 437 "data/html_entities.gperf" + {"nVdash", { 0xE2, 0x8A, 0xAE }, 3}, +#line 825 "data/html_entities.gperf" + {"DJcy", { 0xD0, 0x82 }, 2}, +#line 853 "data/html_entities.gperf" + {"Vdash", { 0xE2, 0x8A, 0xA9 }, 3}, +#line 1669 "data/html_entities.gperf" + {"andd", { 0xE2, 0xA9, 0x9C }, 3}, +#line 1567 "data/html_entities.gperf" + {"gescc", { 0xE2, 0xAA, 0xA9 }, 3}, +#line 1582 "data/html_entities.gperf" + {"gdot", { 0xC4, 0xA1 }, 2}, +#line 1970 "data/html_entities.gperf" + {"duhar", { 0xE2, 0xA5, 0xAF }, 3}, +#line 2128 "data/html_entities.gperf" + {"xcap", { 0xE2, 0x8B, 0x82 }, 3}, +#line 224 "data/html_entities.gperf" + {"Succeeds", { 0xE2, 0x89, 0xBB }, 3}, +#line 1760 "data/html_entities.gperf" + {"ContourIntegral", { 0xE2, 0x88, 0xAE }, 3}, +#line 1969 "data/html_entities.gperf" + {"drbkarow", { 0xE2, 0xA4, 0x90 }, 3}, +#line 425 "data/html_entities.gperf" + {"ubrcy", { 0xD1, 0x9E }, 2}, +#line 1037 "data/html_entities.gperf" + {"triangle", { 0xE2, 0x96, 0xB5 }, 3}, +#line 1672 "data/html_entities.gperf" + {"vdash", { 0xE2, 0x8A, 0xA2 }, 3}, +#line 196 "data/html_entities.gperf" + {"Gdot", { 0xC4, 0xA0 }, 2}, +#line 112 "data/html_entities.gperf" + {"rtimes", { 0xE2, 0x8B, 0x8A }, 3}, +#line 261 "data/html_entities.gperf" + {"ltimes", { 0xE2, 0x8B, 0x89 }, 3}, +#line 1708 "data/html_entities.gperf" + {"nrarrc", { 0xE2, 0xA4, 0xB3, 0xCC, 0xB8 }, 5}, +#line 1062 "data/html_entities.gperf" + {"DownArrow", { 0xE2, 0x86, 0x93 }, 3}, +#line 53 "data/html_entities.gperf" + {"iecy", { 0xD0, 0xB5 }, 2}, +#line 793 "data/html_entities.gperf" + {"succcurlyeq", { 0xE2, 0x89, 0xBD }, 3}, +#line 1994 "data/html_entities.gperf" + {"omid", { 0xE2, 0xA6, 0xB6 }, 3}, +#line 1677 "data/html_entities.gperf" + {"gesdotol", { 0xE2, 0xAA, 0x84 }, 3}, +#line 374 "data/html_entities.gperf" + {"delta", { 0xCE, 0xB4 }, 2}, +#line 1693 "data/html_entities.gperf" + {"kscr", { 0xF0, 0x9D, 0x93, 0x80 }, 4}, +#line 1586 "data/html_entities.gperf" + {"triangleleft", { 0xE2, 0x97, 0x83 }, 3}, +#line 308 "data/html_entities.gperf" + {"SucceedsSlantEqual", { 0xE2, 0x89, 0xBD }, 3}, +#line 271 "data/html_entities.gperf" + {"rtrif", { 0xE2, 0x96, 0xB8 }, 3}, +#line 923 "data/html_entities.gperf" + {"ltrif", { 0xE2, 0x97, 0x82 }, 3}, +#line 1050 "data/html_entities.gperf" + {"xcup", { 0xE2, 0x8B, 0x83 }, 3}, +#line 1673 "data/html_entities.gperf" + {"utrif", { 0xE2, 0x96, 0xB4 }, 3}, +#line 650 "data/html_entities.gperf" + {"Delta", { 0xCE, 0x94 }, 2}, +#line 1435 "data/html_entities.gperf" + {"starf", { 0xE2, 0x98, 0x85 }, 3}, +#line 872 "data/html_entities.gperf" + {"gbreve", { 0xC4, 0x9F }, 2}, +#line 1403 "data/html_entities.gperf" + {"boxHD", { 0xE2, 0x95, 0xA6 }, 3}, +#line 464 "data/html_entities.gperf" + {"egrave", { 0xC3, 0xA8 }, 2}, +#line 1581 "data/html_entities.gperf" + {"quot", { 0x22 }, 1}, +#line 68 "data/html_entities.gperf" + {"nprec", { 0xE2, 0x8A, 0x80 }, 3}, +#line 2109 "data/html_entities.gperf" + {"ugrave", { 0xC3, 0xB9 }, 2}, +#line 242 "data/html_entities.gperf" + {"euro", { 0xE2, 0x82, 0xAC }, 3}, +#line 1391 "data/html_entities.gperf" + {"ring", { 0xCB, 0x9A }, 2}, +#line 225 "data/html_entities.gperf" + {"euml", { 0xC3, 0xAB }, 2}, +#line 724 "data/html_entities.gperf" + {"andand", { 0xE2, 0xA9, 0x95 }, 3}, +#line 203 "data/html_entities.gperf" + {"uuml", { 0xC3, 0xBC }, 2}, +#line 586 "data/html_entities.gperf" + {"Gbreve", { 0xC4, 0x9E }, 2}, +#line 1736 "data/html_entities.gperf" + {"supnE", { 0xE2, 0xAB, 0x8C }, 3}, +#line 209 "data/html_entities.gperf" + {"MinusPlus", { 0xE2, 0x88, 0x93 }, 3}, +#line 878 "data/html_entities.gperf" + {"dashv", { 0xE2, 0x8A, 0xA3 }, 3}, +#line 772 "data/html_entities.gperf" + {"Poincareplane", { 0xE2, 0x84, 0x8C }, 3}, +#line 1445 "data/html_entities.gperf" + {"mumap", { 0xE2, 0x8A, 0xB8 }, 3}, +#line 559 "data/html_entities.gperf" + {"Dashv", { 0xE2, 0xAB, 0xA4 }, 3}, +#line 728 "data/html_entities.gperf" + {"ogon", { 0xCB, 0x9B }, 2}, +#line 1272 "data/html_entities.gperf" + {"sext", { 0xE2, 0x9C, 0xB6 }, 3}, +#line 1883 "data/html_entities.gperf" + {"angrt", { 0xE2, 0x88, 0x9F }, 3}, +#line 1164 "data/html_entities.gperf" + {"ntriangleleft", { 0xE2, 0x8B, 0xAA }, 3}, +#line 1219 "data/html_entities.gperf" + {"triangleq", { 0xE2, 0x89, 0x9C }, 3}, +#line 835 "data/html_entities.gperf" + {"capbrcup", { 0xE2, 0xA9, 0x89 }, 3}, +#line 1320 "data/html_entities.gperf" + {"hookleftarrow", { 0xE2, 0x86, 0xA9 }, 3}, +#line 629 "data/html_entities.gperf" + {"asympeq", { 0xE2, 0x89, 0x8D }, 3}, +#line 333 "data/html_entities.gperf" + {"Igrave", { 0xC3, 0x8C }, 2}, +#line 431 "data/html_entities.gperf" + {"angzarr", { 0xE2, 0x8D, 0xBC }, 3}, +#line 827 "data/html_entities.gperf" + {"nLeftarrow", { 0xE2, 0x87, 0x8D }, 3}, +#line 1420 "data/html_entities.gperf" + {"Cup", { 0xE2, 0x8B, 0x93 }, 3}, +#line 547 "data/html_entities.gperf" + {"imagpart", { 0xE2, 0x84, 0x91 }, 3}, +#line 415 "data/html_entities.gperf" + {"gimel", { 0xE2, 0x84, 0xB7 }, 3}, +#line 1291 "data/html_entities.gperf" + {"Iuml", { 0xC3, 0x8F }, 2}, +#line 1503 "data/html_entities.gperf" + {"LeftTeeArrow", { 0xE2, 0x86, 0xA4 }, 3}, +#line 124 "data/html_entities.gperf" + {"Ubrcy", { 0xD0, 0x8E }, 2}, +#line 1084 "data/html_entities.gperf" + {"trianglelefteq", { 0xE2, 0x8A, 0xB4 }, 3}, +#line 1643 "data/html_entities.gperf" + {"yscr", { 0xF0, 0x9D, 0x93, 0x8E }, 4}, +#line 947 "data/html_entities.gperf" + {"awint", { 0xE2, 0xA8, 0x91 }, 3}, +#line 1066 "data/html_entities.gperf" + {"Agrave", { 0xC3, 0x80 }, 2}, +#line 187 "data/html_entities.gperf" + {"zhcy", { 0xD0, 0xB6 }, 2}, +#line 1820 "data/html_entities.gperf" + {"angst", { 0xC3, 0x85 }, 2}, +#line 1371 "data/html_entities.gperf" + {"nleftarrow", { 0xE2, 0x86, 0x9A }, 3}, +#line 420 "data/html_entities.gperf" + {"YAcy", { 0xD0, 0xAF }, 2}, +#line 300 "data/html_entities.gperf" + {"Auml", { 0xC3, 0x84 }, 2}, +#line 2075 "data/html_entities.gperf" + {"awconint", { 0xE2, 0x88, 0xB3 }, 3}, +#line 2010 "data/html_entities.gperf" + {"ThinSpace", { 0xE2, 0x80, 0x89 }, 3}, +#line 1190 "data/html_entities.gperf" + {"quaternions", { 0xE2, 0x84, 0x8D }, 3}, +#line 1721 "data/html_entities.gperf" + {"weierp", { 0xE2, 0x84, 0x98 }, 3}, +#line 583 "data/html_entities.gperf" + {"iexcl", { 0xC2, 0xA1 }, 2}, +#line 808 "data/html_entities.gperf" + {"rcedil", { 0xC5, 0x97 }, 2}, +#line 1989 "data/html_entities.gperf" + {"tcedil", { 0xC5, 0xA3 }, 2}, +#line 1147 "data/html_entities.gperf" + {"lcedil", { 0xC4, 0xBC }, 2}, +#line 527 "data/html_entities.gperf" + {"scedil", { 0xC5, 0x9F }, 2}, +#line 137 "data/html_entities.gperf" + {"eqcirc", { 0xE2, 0x89, 0x96 }, 3}, +#line 1833 "data/html_entities.gperf" + {"ncedil", { 0xC5, 0x86 }, 2}, +#line 489 "data/html_entities.gperf" + {"gtcir", { 0xE2, 0xA9, 0xBA }, 3}, +#line 1432 "data/html_entities.gperf" + {"rsquo", { 0xE2, 0x80, 0x99 }, 3}, +#line 458 "data/html_entities.gperf" + {"cire", { 0xE2, 0x89, 0x97 }, 3}, +#line 56 "data/html_entities.gperf" + {"lsquo", { 0xE2, 0x80, 0x98 }, 3}, +#line 662 "data/html_entities.gperf" + {"jmath", { 0xC8, 0xB7 }, 2}, +#line 1740 "data/html_entities.gperf" + {"Ugrave", { 0xC3, 0x99 }, 2}, +#line 623 "data/html_entities.gperf" + {"Yuml", { 0xC5, 0xB8 }, 2}, +#line 1328 "data/html_entities.gperf" + {"TSHcy", { 0xD0, 0x8B }, 2}, +#line 703 "data/html_entities.gperf" + {"nequiv", { 0xE2, 0x89, 0xA2 }, 3}, +#line 1156 "data/html_entities.gperf" + {"centerdot", { 0xC2, 0xB7 }, 2}, +#line 2119 "data/html_entities.gperf" + {"angrtvb", { 0xE2, 0x8A, 0xBE }, 3}, +#line 330 "data/html_entities.gperf" + {"gtrarr", { 0xE2, 0xA5, 0xB8 }, 3}, +#line 1973 "data/html_entities.gperf" + {"Scedil", { 0xC5, 0x9E }, 2}, +#line 2113 "data/html_entities.gperf" + {"filig", { 0xEF, 0xAC, 0x81 }, 3}, +#line 348 "data/html_entities.gperf" + {"GreaterSlantEqual", { 0xE2, 0xA9, 0xBE }, 3}, +#line 1545 "data/html_entities.gperf" + {"Uuml", { 0xC3, 0x9C }, 2}, +#line 361 "data/html_entities.gperf" + {"gacute", { 0xC7, 0xB5 }, 2}, +#line 1100 "data/html_entities.gperf" + {"LongLeftArrow", { 0xE2, 0x9F, 0xB5 }, 3}, +#line 959 "data/html_entities.gperf" + {"suplarr", { 0xE2, 0xA5, 0xBB }, 3}, +#line 1732 "data/html_entities.gperf" + {"nvge", { 0xE2, 0x89, 0xA5, 0xE2, 0x83, 0x92 }, 6}, +#line 80 "data/html_entities.gperf" + {"ntrianglelefteq", { 0xE2, 0x8B, 0xAC }, 3}, +#line 1718 "data/html_entities.gperf" + {"tscy", { 0xD1, 0x86 }, 2}, +#line 1099 "data/html_entities.gperf" + {"NotTildeEqual", { 0xE2, 0x89, 0x84 }, 3}, +#line 95 "data/html_entities.gperf" + {"Lleftarrow", { 0xE2, 0x87, 0x9A }, 3}, +#line 326 "data/html_entities.gperf" + {"igrave", { 0xC3, 0xAC }, 2}, +#line 1046 "data/html_entities.gperf" + {"yen", { 0xC2, 0xA5 }, 2}, +#line 1601 "data/html_entities.gperf" + {"Kcedil", { 0xC4, 0xB6 }, 2}, +#line 1486 "data/html_entities.gperf" + {"kfr", { 0xF0, 0x9D, 0x94, 0xA8 }, 4}, +#line 1212 "data/html_entities.gperf" + {"iuml", { 0xC3, 0xAF }, 2}, +#line 1361 "data/html_entities.gperf" + {"acE", { 0xE2, 0x88, 0xBE, 0xCC, 0xB3 }, 5}, +#line 1728 "data/html_entities.gperf" + {"dtrif", { 0xE2, 0x96, 0xBE }, 3}, +#line 1845 "data/html_entities.gperf" + {"sccue", { 0xE2, 0x89, 0xBD }, 3}, +#line 1451 "data/html_entities.gperf" + {"comma", { 0x2C }, 1}, +#line 504 "data/html_entities.gperf" + {"Lcedil", { 0xC4, 0xBB }, 2}, +#line 988 "data/html_entities.gperf" + {"Rcedil", { 0xC5, 0x96 }, 2}, +#line 2005 "data/html_entities.gperf" + {"puncsp", { 0xE2, 0x80, 0x88 }, 3}, +#line 1296 "data/html_entities.gperf" + {"Ncedil", { 0xC5, 0x85 }, 2}, +#line 488 "data/html_entities.gperf" + {"DownArrowUpArrow", { 0xE2, 0x87, 0xB5 }, 3}, +#line 611 "data/html_entities.gperf" + {"LessFullEqual", { 0xE2, 0x89, 0xA6 }, 3}, +#line 1267 "data/html_entities.gperf" + {"LeftTriangleBar", { 0xE2, 0xA7, 0x8F }, 3}, +#line 293 "data/html_entities.gperf" + {"LeftTriangle", { 0xE2, 0x8A, 0xB2 }, 3}, +#line 337 "data/html_entities.gperf" + {"LeftTriangleEqual", { 0xE2, 0x8A, 0xB4 }, 3}, +#line 469 "data/html_entities.gperf" + {"cirmid", { 0xE2, 0xAB, 0xAF }, 3}, +#line 1660 "data/html_entities.gperf" + {"lg", { 0xE2, 0x89, 0xB6 }, 3}, +#line 1378 "data/html_entities.gperf" + {"eg", { 0xE2, 0xAA, 0x9A }, 3}, +#line 584 "data/html_entities.gperf" + {"ccupssm", { 0xE2, 0xA9, 0x90 }, 3}, +#line 253 "data/html_entities.gperf" + {"fallingdotseq", { 0xE2, 0x89, 0x92 }, 3}, +#line 1335 "data/html_entities.gperf" + {"minus", { 0xE2, 0x88, 0x92 }, 3}, +#line 244 "data/html_entities.gperf" + {"bigsqcup", { 0xE2, 0xA8, 0x86 }, 3}, +#line 54 "data/html_entities.gperf" + {"Tcedil", { 0xC5, 0xA2 }, 2}, +#line 1197 "data/html_entities.gperf" + {"mdash", { 0xE2, 0x80, 0x94 }, 3}, +#line 1966 "data/html_entities.gperf" + {"rdquor", { 0xE2, 0x80, 0x9D }, 3}, +#line 905 "data/html_entities.gperf" + {"ldquor", { 0xE2, 0x80, 0x9E }, 3}, +#line 2106 "data/html_entities.gperf" + {"CupCap", { 0xE2, 0x89, 0x8D }, 3}, +#line 2017 "data/html_entities.gperf" + {"minusb", { 0xE2, 0x8A, 0x9F }, 3}, +#line 1211 "data/html_entities.gperf" + {"nVDash", { 0xE2, 0x8A, 0xAF }, 3}, +#line 1111 "data/html_entities.gperf" + {"yfr", { 0xF0, 0x9D, 0x94, 0xB6 }, 4}, +#line 1369 "data/html_entities.gperf" + {"circ", { 0xCB, 0x86 }, 2}, +#line 233 "data/html_entities.gperf" + {"NotSucceeds", { 0xE2, 0x8A, 0x81 }, 3}, +#line 863 "data/html_entities.gperf" + {"gtlPar", { 0xE2, 0xA6, 0x95 }, 3}, +#line 1096 "data/html_entities.gperf" + {"LeftCeiling", { 0xE2, 0x8C, 0x88 }, 3}, +#line 282 "data/html_entities.gperf" + {"CHcy", { 0xD0, 0xA7 }, 2}, +#line 632 "data/html_entities.gperf" + {"longleftarrow", { 0xE2, 0x9F, 0xB5 }, 3}, +#line 804 "data/html_entities.gperf" + {"egsdot", { 0xE2, 0xAA, 0x98 }, 3}, +#line 864 "data/html_entities.gperf" + {"aleph", { 0xE2, 0x84, 0xB5 }, 3}, +#line 40 "data/html_entities.gperf" + {"thetasym", { 0xCF, 0x91 }, 2}, +#line 809 "data/html_entities.gperf" + {"ctdot", { 0xE2, 0x8B, 0xAF }, 3}, +#line 1915 "data/html_entities.gperf" + {"geqslant", { 0xE2, 0xA9, 0xBE }, 3}, +#line 887 "data/html_entities.gperf" + {"NotSucceedsSlantEqual", { 0xE2, 0x8B, 0xA1 }, 3}, +#line 1990 "data/html_entities.gperf" + {"angrtvbd", { 0xE2, 0xA6, 0x9D }, 3}, +#line 1416 "data/html_entities.gperf" + {"OElig", { 0xC5, 0x92 }, 2}, +#line 1976 "data/html_entities.gperf" + {"sqsub", { 0xE2, 0x8A, 0x8F }, 3}, +#line 1324 "data/html_entities.gperf" + {"sqsube", { 0xE2, 0x8A, 0x91 }, 3}, +#line 1362 "data/html_entities.gperf" + {"cdot", { 0xC4, 0x8B }, 2}, +#line 1651 "data/html_entities.gperf" + {"sqsubset", { 0xE2, 0x8A, 0x8F }, 3}, +#line 534 "data/html_entities.gperf" + {"LeftVector", { 0xE2, 0x86, 0xBC }, 3}, +#line 31 "data/html_entities.gperf" + {"SucceedsTilde", { 0xE2, 0x89, 0xBF }, 3}, +#line 1809 "data/html_entities.gperf" + {"EmptyVerySmallSquare", { 0xE2, 0x96, 0xAB }, 3}, +#line 760 "data/html_entities.gperf" + {"bull", { 0xE2, 0x80, 0xA2 }, 3}, +#line 24 "data/html_entities.gperf" + {"Egrave", { 0xC3, 0x88 }, 2}, +#line 1499 "data/html_entities.gperf" + {"dscy", { 0xD1, 0x95 }, 2}, +#line 44 "data/html_entities.gperf" + {"sdotb", { 0xE2, 0x8A, 0xA1 }, 3}, +#line 1862 "data/html_entities.gperf" + {"Euml", { 0xC3, 0x8B }, 2}, +#line 1484 "data/html_entities.gperf" + {"eth", { 0xC3, 0xB0 }, 2}, +#line 783 "data/html_entities.gperf" + {"vnsub", { 0xE2, 0x8A, 0x82, 0xE2, 0x83, 0x92 }, 6}, +#line 174 "data/html_entities.gperf" + {"phiv", { 0xCF, 0x95 }, 2}, +#line 1101 "data/html_entities.gperf" + {"nvdash", { 0xE2, 0x8A, 0xAC }, 3}, +#line 306 "data/html_entities.gperf" + {"acute", { 0xC2, 0xB4 }, 2}, +#line 323 "data/html_entities.gperf" + {"boxdr", { 0xE2, 0x94, 0x8C }, 3}, +#line 1899 "data/html_entities.gperf" + {"lozenge", { 0xE2, 0x97, 0x8A }, 3}, +#line 307 "data/html_entities.gperf" + {"boxminus", { 0xE2, 0x8A, 0x9F }, 3}, +#line 47 "data/html_entities.gperf" + {"Omega", { 0xCE, 0xA9 }, 2}, +#line 1468 "data/html_entities.gperf" + {"Vvdash", { 0xE2, 0x8A, 0xAA }, 3}, +#line 1358 "data/html_entities.gperf" + {"Longleftarrow", { 0xE2, 0x9F, 0xB8 }, 3}, +#line 926 "data/html_entities.gperf" + {"UnderBar", { 0x5F }, 1}, +#line 1138 "data/html_entities.gperf" + {"bowtie", { 0xE2, 0x8B, 0x88 }, 3}, +#line 466 "data/html_entities.gperf" + {"boxDr", { 0xE2, 0x95, 0x93 }, 3}, +#line 1105 "data/html_entities.gperf" + {"lambda", { 0xCE, 0xBB }, 2}, +#line 1822 "data/html_entities.gperf" + {"timesbar", { 0xE2, 0xA8, 0xB1 }, 3}, +#line 1599 "data/html_entities.gperf" + {"ncongdot", { 0xE2, 0xA9, 0xAD, 0xCC, 0xB8 }, 5}, +#line 613 "data/html_entities.gperf" + {"OverBar", { 0xE2, 0x80, 0xBE }, 3}, +#line 1896 "data/html_entities.gperf" + {"scnsim", { 0xE2, 0x8B, 0xA9 }, 3}, +#line 265 "data/html_entities.gperf" + {"OverBrace", { 0xE2, 0x8F, 0x9E }, 3}, +#line 2035 "data/html_entities.gperf" + {"sigma", { 0xCF, 0x83 }, 2}, +#line 2047 "data/html_entities.gperf" + {"OverBracket", { 0xE2, 0x8E, 0xB4 }, 3}, +#line 1670 "data/html_entities.gperf" + {"NegativeThinSpace", { 0xE2, 0x80, 0x8B }, 3}, +#line 471 "data/html_entities.gperf" + {"NotSucceedsTilde", { 0xE2, 0x89, 0xBF, 0xCC, 0xB8 }, 5}, +#line 372 "data/html_entities.gperf" + {"LeftDownVector", { 0xE2, 0x87, 0x83 }, 3}, +#line 21 "data/html_entities.gperf" + {"VeryThinSpace", { 0xE2, 0x80, 0x8A }, 3}, +#line 78 "data/html_entities.gperf" + {"LeftDownVectorBar", { 0xE2, 0xA5, 0x99 }, 3}, +#line 1986 "data/html_entities.gperf" + {"rdca", { 0xE2, 0xA4, 0xB7 }, 3}, +#line 861 "data/html_entities.gperf" + {"ldca", { 0xE2, 0xA4, 0xB6 }, 3}, +#line 1886 "data/html_entities.gperf" + {"bullet", { 0xE2, 0x80, 0xA2 }, 3}, +#line 1611 "data/html_entities.gperf" + {"DownTeeArrow", { 0xE2, 0x86, 0xA7 }, 3}, +#line 1753 "data/html_entities.gperf" + {"Sigma", { 0xCE, 0xA3 }, 2}, +#line 1418 "data/html_entities.gperf" + {"PartialD", { 0xE2, 0x88, 0x82 }, 3}, +#line 622 "data/html_entities.gperf" + {"LeftDownTeeVector", { 0xE2, 0xA5, 0xA1 }, 3}, +#line 914 "data/html_entities.gperf" + {"bigstar", { 0xE2, 0x98, 0x85 }, 3}, +#line 767 "data/html_entities.gperf" + {"leftthreetimes", { 0xE2, 0x8B, 0x8B }, 3}, +#line 273 "data/html_entities.gperf" + {"minusdu", { 0xE2, 0xA8, 0xAA }, 3}, +#line 892 "data/html_entities.gperf" + {"boxdR", { 0xE2, 0x95, 0x92 }, 3}, +#line 786 "data/html_entities.gperf" + {"Backslash", { 0xE2, 0x88, 0x96 }, 3}, +#line 549 "data/html_entities.gperf" + {"uring", { 0xC5, 0xAF }, 2}, +#line 176 "data/html_entities.gperf" + {"InvisibleComma", { 0xE2, 0x81, 0xA3 }, 3}, +#line 99 "data/html_entities.gperf" + {"telrec", { 0xE2, 0x8C, 0x95 }, 3}, +#line 816 "data/html_entities.gperf" + {"grave", { 0x60 }, 1}, +#line 175 "data/html_entities.gperf" + {"Lambda", { 0xCE, 0x9B }, 2}, +#line 1466 "data/html_entities.gperf" + {"bigwedge", { 0xE2, 0x8B, 0x80 }, 3}, +#line 1965 "data/html_entities.gperf" + {"angmsd", { 0xE2, 0x88, 0xA1 }, 3}, +#line 1248 "data/html_entities.gperf" + {"Otimes", { 0xE2, 0xA8, 0xB7 }, 3}, +#line 159 "data/html_entities.gperf" + {"succsim", { 0xE2, 0x89, 0xBF }, 3}, +#line 2002 "data/html_entities.gperf" + {"boxDR", { 0xE2, 0x95, 0x94 }, 3}, +#line 2123 "data/html_entities.gperf" + {"omega", { 0xCF, 0x89 }, 2}, +#line 384 "data/html_entities.gperf" + {"supdsub", { 0xE2, 0xAB, 0x98 }, 3}, +#line 1116 "data/html_entities.gperf" + {"succneqq", { 0xE2, 0xAA, 0xB6 }, 3}, +#line 367 "data/html_entities.gperf" + {"supdot", { 0xE2, 0xAA, 0xBE }, 3}, +#line 41 "data/html_entities.gperf" + {"LeftUpTeeVector", { 0xE2, 0xA5, 0xA0 }, 3}, +#line 245 "data/html_entities.gperf" + {"utilde", { 0xC5, 0xA9 }, 2}, +#line 1423 "data/html_entities.gperf" + {"ntilde", { 0xC3, 0xB1 }, 2}, +#line 1236 "data/html_entities.gperf" + {"leftrightsquigarrow", { 0xE2, 0x86, 0xAD }, 3}, +#line 2065 "data/html_entities.gperf" + {"Ograve", { 0xC3, 0x92 }, 2}, +#line 1205 "data/html_entities.gperf" + {"empty", { 0xE2, 0x88, 0x85 }, 3}, +#line 1772 "data/html_entities.gperf" + {"ncong", { 0xE2, 0x89, 0x87 }, 3}, +#line 383 "data/html_entities.gperf" + {"bcong", { 0xE2, 0x89, 0x8C }, 3}, +#line 465 "data/html_entities.gperf" + {"cacute", { 0xC4, 0x87 }, 2}, +#line 1239 "data/html_entities.gperf" + {"wreath", { 0xE2, 0x89, 0x80 }, 3}, +#line 2114 "data/html_entities.gperf" + {"boxdL", { 0xE2, 0x95, 0x95 }, 3}, +#line 2019 "data/html_entities.gperf" + {"Ouml", { 0xC3, 0x96 }, 2}, +#line 780 "data/html_entities.gperf" + {"eta", { 0xCE, 0xB7 }, 2}, +#line 1912 "data/html_entities.gperf" + {"sqsubseteq", { 0xE2, 0x8A, 0x91 }, 3}, +#line 1741 "data/html_entities.gperf" + {"oelig", { 0xC5, 0x93 }, 2}, +#line 652 "data/html_entities.gperf" + {"Aring", { 0xC3, 0x85 }, 2}, +#line 1029 "data/html_entities.gperf" + {"LeftFloor", { 0xE2, 0x8C, 0x8A }, 3}, +#line 1115 "data/html_entities.gperf" + {"boxDL", { 0xE2, 0x95, 0x97 }, 3}, +#line 989 "data/html_entities.gperf" + {"odash", { 0xE2, 0x8A, 0x9D }, 3}, +#line 193 "data/html_entities.gperf" + {"hellip", { 0xE2, 0x80, 0xA6 }, 3}, +#line 839 "data/html_entities.gperf" + {"ltcc", { 0xE2, 0xAA, 0xA6 }, 3}, +#line 77 "data/html_entities.gperf" + {"tshcy", { 0xD1, 0x9B }, 2}, +#line 376 "data/html_entities.gperf" + {"Itilde", { 0xC4, 0xA8 }, 2}, +#line 1474 "data/html_entities.gperf" + {"natural", { 0xE2, 0x99, 0xAE }, 3}, +#line 1492 "data/html_entities.gperf" + {"naturals", { 0xE2, 0x84, 0x95 }, 3}, +#line 215 "data/html_entities.gperf" + {"Uring", { 0xC5, 0xAE }, 2}, +#line 1482 "data/html_entities.gperf" + {"DownRightTeeVector", { 0xE2, 0xA5, 0x9F }, 3}, +#line 192 "data/html_entities.gperf" + {"Atilde", { 0xC3, 0x83 }, 2}, +#line 89 "data/html_entities.gperf" + {"LongRightArrow", { 0xE2, 0x9F, 0xB6 }, 3}, +#line 774 "data/html_entities.gperf" + {"Ntilde", { 0xC3, 0x91 }, 2}, +#line 660 "data/html_entities.gperf" + {"varnothing", { 0xE2, 0x88, 0x85 }, 3}, +#line 750 "data/html_entities.gperf" + {"DiacriticalGrave", { 0x60 }, 1}, +#line 1275 "data/html_entities.gperf" + {"pitchfork", { 0xE2, 0x8B, 0x94 }, 3}, +#line 1303 "data/html_entities.gperf" + {"otimes", { 0xE2, 0x8A, 0x97 }, 3}, +#line 1270 "data/html_entities.gperf" + {"notinvc", { 0xE2, 0x8B, 0xB6 }, 3}, +#line 1790 "data/html_entities.gperf" + {"gesdoto", { 0xE2, 0xAA, 0x82 }, 3}, +#line 521 "data/html_entities.gperf" + {"gjcy", { 0xD1, 0x93 }, 2}, +#line 829 "data/html_entities.gperf" + {"abreve", { 0xC4, 0x83 }, 2}, +#line 299 "data/html_entities.gperf" + {"scirc", { 0xC5, 0x9D }, 2}, +#line 737 "data/html_entities.gperf" + {"ecirc", { 0xC3, 0xAA }, 2}, +#line 1249 "data/html_entities.gperf" + {"ucirc", { 0xC3, 0xBB }, 2}, +#line 1255 "data/html_entities.gperf" + {"triangledown", { 0xE2, 0x96, 0xBF }, 3}, +#line 1078 "data/html_entities.gperf" + {"Utilde", { 0xC5, 0xA8 }, 2}, +#line 19 "data/html_entities.gperf" + {"NotSucceedsEqual", { 0xE2, 0xAA, 0xB0, 0xCC, 0xB8 }, 5}, +#line 1865 "data/html_entities.gperf" + {"ograve", { 0xC3, 0xB2 }, 2}, +#line 1697 "data/html_entities.gperf" + {"minusd", { 0xE2, 0x88, 0xB8 }, 3}, +#line 1346 "data/html_entities.gperf" + {"Jcirc", { 0xC4, 0xB4 }, 2}, +#line 1729 "data/html_entities.gperf" + {"gtrless", { 0xE2, 0x89, 0xB7 }, 3}, +#line 574 "data/html_entities.gperf" + {"Scirc", { 0xC5, 0x9C }, 2}, +#line 354 "data/html_entities.gperf" + {"ouml", { 0xC3, 0xB6 }, 2}, +#line 2007 "data/html_entities.gperf" + {"ExponentialE", { 0xE2, 0x85, 0x87 }, 3}, +#line 2097 "data/html_entities.gperf" + {"robrk", { 0xE2, 0x9F, 0xA7 }, 3}, +#line 1562 "data/html_entities.gperf" + {"lobrk", { 0xE2, 0x9F, 0xA6 }, 3}, +#line 322 "data/html_entities.gperf" + {"NewLine", { 0x0A }, 1}, +#line 1744 "data/html_entities.gperf" + {"Hcirc", { 0xC4, 0xA4 }, 2}, +#line 1633 "data/html_entities.gperf" + {"biguplus", { 0xE2, 0xA8, 0x84 }, 3}, +#line 894 "data/html_entities.gperf" + {"complexes", { 0xE2, 0x84, 0x82 }, 3}, +#line 928 "data/html_entities.gperf" + {"UpDownArrow", { 0xE2, 0x86, 0x95 }, 3}, +#line 788 "data/html_entities.gperf" + {"Wcirc", { 0xC5, 0xB4 }, 2}, +#line 1950 "data/html_entities.gperf" + {"itilde", { 0xC4, 0xA9 }, 2}, +#line 502 "data/html_entities.gperf" + {"gnapprox", { 0xE2, 0xAA, 0x8A }, 3}, +#line 932 "data/html_entities.gperf" + {"aogon", { 0xC4, 0x85 }, 2}, +#line 1893 "data/html_entities.gperf" + {"Icirc", { 0xC3, 0x8E }, 2}, +#line 1298 "data/html_entities.gperf" + {"hkswarow", { 0xE2, 0xA4, 0xA6 }, 3}, +#line 1472 "data/html_entities.gperf" + {"LeftRightArrow", { 0xE2, 0x86, 0x94 }, 3}, +#line 727 "data/html_entities.gperf" + {"Ccedil", { 0xC3, 0x87 }, 2}, +#line 1549 "data/html_entities.gperf" + {"boxdl", { 0xE2, 0x94, 0x90 }, 3}, +#line 12 "data/html_entities.gperf" + {"LeftArrowRightArrow", { 0xE2, 0x87, 0x86 }, 3}, +#line 1317 "data/html_entities.gperf" + {"CounterClockwiseContourIntegral", { 0xE2, 0x88, 0xB3 }, 3}, +#line 453 "data/html_entities.gperf" + {"nvDash", { 0xE2, 0x8A, 0xAD }, 3}, +#line 1139 "data/html_entities.gperf" + {"Acirc", { 0xC3, 0x82 }, 2}, +#line 1213 "data/html_entities.gperf" + {"xvee", { 0xE2, 0x8B, 0x81 }, 3}, +#line 120 "data/html_entities.gperf" + {"rmoustache", { 0xE2, 0x8E, 0xB1 }, 3}, +#line 826 "data/html_entities.gperf" + {"lmoustache", { 0xE2, 0x8E, 0xB0 }, 3}, +#line 1516 "data/html_entities.gperf" + {"rbbrk", { 0xE2, 0x9D, 0xB3 }, 3}, +#line 1151 "data/html_entities.gperf" + {"lbbrk", { 0xE2, 0x9D, 0xB2 }, 3}, +#line 1488 "data/html_entities.gperf" + {"beth", { 0xE2, 0x84, 0xB6 }, 3}, +#line 1431 "data/html_entities.gperf" + {"fflig", { 0xEF, 0xAC, 0x80 }, 3}, +#line 1691 "data/html_entities.gperf" + {"boxDl", { 0xE2, 0x95, 0x96 }, 3}, +#line 852 "data/html_entities.gperf" + {"harrw", { 0xE2, 0x86, 0xAD }, 3}, +#line 881 "data/html_entities.gperf" + {"GJcy", { 0xD0, 0x83 }, 2}, +#line 1357 "data/html_entities.gperf" + {"hyphen", { 0xE2, 0x80, 0x90 }, 3}, +#line 1658 "data/html_entities.gperf" + {"sub", { 0xE2, 0x8A, 0x82 }, 3}, +#line 2022 "data/html_entities.gperf" + {"supe", { 0xE2, 0x8A, 0x87 }, 3}, +#line 1621 "data/html_entities.gperf" + {"Ycirc", { 0xC5, 0xB6 }, 2}, +#line 1142 "data/html_entities.gperf" + {"dash", { 0xE2, 0x80, 0x90 }, 3}, +#line 800 "data/html_entities.gperf" + {"angle", { 0xE2, 0x88, 0xA0 }, 3}, +#line 630 "data/html_entities.gperf" + {"congdot", { 0xE2, 0xA9, 0xAD }, 3}, +#line 1536 "data/html_entities.gperf" + {"Ucirc", { 0xC3, 0x9B }, 2}, +#line 848 "data/html_entities.gperf" + {"Sub", { 0xE2, 0x8B, 0x90 }, 3}, +#line 1109 "data/html_entities.gperf" + {"circleddash", { 0xE2, 0x8A, 0x9D }, 3}, +#line 676 "data/html_entities.gperf" + {"aacute", { 0xC3, 0xA1 }, 2}, +#line 2026 "data/html_entities.gperf" + {"CloseCurlyQuote", { 0xE2, 0x80, 0x99 }, 3}, +#line 37 "data/html_entities.gperf" + {"check", { 0xE2, 0x9C, 0x93 }, 3}, +#line 545 "data/html_entities.gperf" + {"subrarr", { 0xE2, 0xA5, 0xB9 }, 3}, +#line 1080 "data/html_entities.gperf" + {"rcy", { 0xD1, 0x80 }, 2}, +#line 1408 "data/html_entities.gperf" + {"tcy", { 0xD1, 0x82 }, 2}, +#line 1547 "data/html_entities.gperf" + {"lcy", { 0xD0, 0xBB }, 2}, +#line 1093 "data/html_entities.gperf" + {"scy", { 0xD1, 0x81 }, 2}, +#line 2042 "data/html_entities.gperf" + {"ecy", { 0xD1, 0x8D }, 2}, +#line 960 "data/html_entities.gperf" + {"ucy", { 0xD1, 0x83 }, 2}, +#line 1602 "data/html_entities.gperf" + {"ncy", { 0xD0, 0xBD }, 2}, +#line 161 "data/html_entities.gperf" + {"Hacek", { 0xCB, 0x87 }, 2}, +#line 1680 "data/html_entities.gperf" + {"Pcy", { 0xD0, 0x9F }, 2}, +#line 1997 "data/html_entities.gperf" + {"bcy", { 0xD0, 0xB1 }, 2}, +#line 599 "data/html_entities.gperf" + {"Superset", { 0xE2, 0x8A, 0x83 }, 3}, +#line 877 "data/html_entities.gperf" + {"nabla", { 0xE2, 0x88, 0x87 }, 3}, +#line 1710 "data/html_entities.gperf" + {"Zcy", { 0xD0, 0x97 }, 2}, +#line 1144 "data/html_entities.gperf" + {"icirc", { 0xC3, 0xAE }, 2}, +#line 1606 "data/html_entities.gperf" + {"Vcy", { 0xD0, 0x92 }, 2}, +#line 479 "data/html_entities.gperf" + {"approxeq", { 0xE2, 0x89, 0x8A }, 3}, +#line 264 "data/html_entities.gperf" + {"Jcy", { 0xD0, 0x99 }, 2}, +#line 1143 "data/html_entities.gperf" + {"succnsim", { 0xE2, 0x8B, 0xA9 }, 3}, +#line 2024 "data/html_entities.gperf" + {"Scy", { 0xD0, 0xA1 }, 2}, +#line 503 "data/html_entities.gperf" + {"ltquest", { 0xE2, 0xA9, 0xBB }, 3}, +#line 1014 "data/html_entities.gperf" + {"cuepr", { 0xE2, 0x8B, 0x9E }, 3}, +#line 1338 "data/html_entities.gperf" + {"pcy", { 0xD0, 0xBF }, 2}, +#line 182 "data/html_entities.gperf" + {"dzigrarr", { 0xE2, 0x9F, 0xBF }, 3}, +#line 236 "data/html_entities.gperf" + {"vcy", { 0xD0, 0xB2 }, 2}, +#line 1856 "data/html_entities.gperf" + {"curren", { 0xC2, 0xA4 }, 2}, +#line 1189 "data/html_entities.gperf" + {"cupor", { 0xE2, 0xA9, 0x85 }, 3}, +#line 460 "data/html_entities.gperf" + {"Icy", { 0xD0, 0x98 }, 2}, +#line 240 "data/html_entities.gperf" + {"Kcy", { 0xD0, 0x9A }, 2}, +#line 339 "data/html_entities.gperf" + {"ntgl", { 0xE2, 0x89, 0xB9 }, 3}, +#line 1659 "data/html_entities.gperf" + {"NestedGreaterGreater", { 0xE2, 0x89, 0xAB }, 3}, +#line 1564 "data/html_entities.gperf" + {"fcy", { 0xD1, 0x84 }, 2}, +#line 1963 "data/html_entities.gperf" + {"ddagger", { 0xE2, 0x80, 0xA1 }, 3}, +#line 73 "data/html_entities.gperf" + {"submult", { 0xE2, 0xAB, 0x81 }, 3}, +#line 876 "data/html_entities.gperf" + {"apid", { 0xE2, 0x89, 0x8B }, 3}, +#line 618 "data/html_entities.gperf" + {"circledcirc", { 0xE2, 0x8A, 0x9A }, 3}, +#line 656 "data/html_entities.gperf" + {"cup", { 0xE2, 0x88, 0xAA }, 3}, +#line 391 "data/html_entities.gperf" + {"Lcy", { 0xD0, 0x9B }, 2}, +#line 1454 "data/html_entities.gperf" + {"Rcy", { 0xD0, 0xA0 }, 2}, +#line 416 "data/html_entities.gperf" + {"subsub", { 0xE2, 0xAB, 0x95 }, 3}, +#line 452 "data/html_entities.gperf" + {"Acy", { 0xD0, 0x90 }, 2}, +#line 419 "data/html_entities.gperf" + {"Ncy", { 0xD0, 0x9D }, 2}, +#line 1900 "data/html_entities.gperf" + {"subset", { 0xE2, 0x8A, 0x82 }, 3}, +#line 1701 "data/html_entities.gperf" + {"lsimg", { 0xE2, 0xAA, 0x8F }, 3}, +#line 353 "data/html_entities.gperf" + {"Mcy", { 0xD0, 0x9C }, 2}, +#line 1905 "data/html_entities.gperf" + {"cups", { 0xE2, 0x88, 0xAA, 0xEF, 0xB8, 0x80 }, 6}, +#line 287 "data/html_entities.gperf" + {"Eta", { 0xCE, 0x97 }, 2}, +#line 776 "data/html_entities.gperf" + {"rdquo", { 0xE2, 0x80, 0x9D }, 3}, +#line 1188 "data/html_entities.gperf" + {"ldquo", { 0xE2, 0x80, 0x9C }, 3}, +#line 1881 "data/html_entities.gperf" + {"DownLeftRightVector", { 0xE2, 0xA5, 0x90 }, 3}, +#line 1207 "data/html_entities.gperf" + {"Subset", { 0xE2, 0x8B, 0x90 }, 3}, +#line 142 "data/html_entities.gperf" + {"bdquo", { 0xE2, 0x80, 0x9E }, 3}, +#line 157 "data/html_entities.gperf" + {"Ycy", { 0xD0, 0xAB }, 2}, +#line 411 "data/html_entities.gperf" + {"Fcy", { 0xD0, 0xA4 }, 2}, +#line 217 "data/html_entities.gperf" + {"Ucy", { 0xD0, 0xA3 }, 2}, +#line 267 "data/html_entities.gperf" + {"copy", { 0xC2, 0xA9 }, 2}, +#line 90 "data/html_entities.gperf" + {"subne", { 0xE2, 0x8A, 0x8A }, 3}, +#line 1584 "data/html_entities.gperf" + {"Tcy", { 0xD0, 0xA2 }, 2}, +#line 410 "data/html_entities.gperf" + {"subsup", { 0xE2, 0xAB, 0x93 }, 3}, +#line 637 "data/html_entities.gperf" + {"zwj", { 0xE2, 0x80, 0x8D }, 3}, +#line 1184 "data/html_entities.gperf" + {"UnderBracket", { 0xE2, 0x8E, 0xB5 }, 3}, +#line 1698 "data/html_entities.gperf" + {"ImaginaryI", { 0xE2, 0x85, 0x88 }, 3}, +#line 962 "data/html_entities.gperf" + {"quatint", { 0xE2, 0xA8, 0x96 }, 3}, +#line 1654 "data/html_entities.gperf" + {"boxVh", { 0xE2, 0x95, 0xAB }, 3}, +#line 1991 "data/html_entities.gperf" + {"LongLeftRightArrow", { 0xE2, 0x9F, 0xB7 }, 3}, +#line 2094 "data/html_entities.gperf" + {"gtrdot", { 0xE2, 0x8B, 0x97 }, 3}, +#line 105 "data/html_entities.gperf" + {"icy", { 0xD0, 0xB8 }, 2}, +#line 801 "data/html_entities.gperf" + {"curarr", { 0xE2, 0x86, 0xB7 }, 3}, +#line 751 "data/html_entities.gperf" + {"ntriangleright", { 0xE2, 0x8B, 0xAB }, 3}, +#line 1518 "data/html_entities.gperf" + {"cudarrr", { 0xE2, 0xA4, 0xB5 }, 3}, +#line 2001 "data/html_entities.gperf" + {"Ecirc", { 0xC3, 0x8A }, 2}, +#line 154 "data/html_entities.gperf" + {"cudarrl", { 0xE2, 0xA4, 0xB8 }, 3}, +#line 757 "data/html_entities.gperf" + {"subseteq", { 0xE2, 0x8A, 0x86 }, 3}, +#line 409 "data/html_entities.gperf" + {"subseteqq", { 0xE2, 0xAB, 0x85 }, 3}, +#line 1251 "data/html_entities.gperf" + {"Bcy", { 0xD0, 0x91 }, 2}, +#line 363 "data/html_entities.gperf" + {"subsetneq", { 0xE2, 0x8A, 0x8A }, 3}, +#line 1494 "data/html_entities.gperf" + {"dcy", { 0xD0, 0xB4 }, 2}, +#line 352 "data/html_entities.gperf" + {"ngeqslant", { 0xE2, 0xA9, 0xBE, 0xCC, 0xB8 }, 5}, +#line 815 "data/html_entities.gperf" + {"notnivc", { 0xE2, 0x8B, 0xBD }, 3}, +#line 1738 "data/html_entities.gperf" + {"Dcy", { 0xD0, 0x94 }, 2}, +#line 624 "data/html_entities.gperf" + {"cupcap", { 0xE2, 0xA9, 0x86 }, 3}, +#line 449 "data/html_entities.gperf" + {"kappa", { 0xCE, 0xBA }, 2}, +#line 385 "data/html_entities.gperf" + {"ang", { 0xE2, 0x88, 0xA0 }, 3}, +#line 1240 "data/html_entities.gperf" + {"LowerLeftArrow", { 0xE2, 0x86, 0x99 }, 3}, +#line 1794 "data/html_entities.gperf" + {"succ", { 0xE2, 0x89, 0xBB }, 3}, +#line 2030 "data/html_entities.gperf" + {"chcy", { 0xD1, 0x87 }, 2}, +#line 1620 "data/html_entities.gperf" + {"andv", { 0xE2, 0xA9, 0x9A }, 3}, +#line 399 "data/html_entities.gperf" + {"HumpDownHump", { 0xE2, 0x89, 0x8E }, 3}, +#line 1806 "data/html_entities.gperf" + {"cupcup", { 0xE2, 0xA9, 0x8A }, 3}, +#line 1048 "data/html_entities.gperf" + {"Otilde", { 0xC3, 0x95 }, 2}, +#line 616 "data/html_entities.gperf" + {"cemptyv", { 0xE2, 0xA6, 0xB2 }, 3}, +#line 1108 "data/html_entities.gperf" + {"precapprox", { 0xE2, 0xAA, 0xB7 }, 3}, +#line 1500 "data/html_entities.gperf" + {"lessapprox", { 0xE2, 0xAA, 0x85 }, 3}, +#line 748 "data/html_entities.gperf" + {"DDotrahd", { 0xE2, 0xA4, 0x91 }, 3}, +#line 1053 "data/html_entities.gperf" + {"cong", { 0xE2, 0x89, 0x85 }, 3}, +#line 434 "data/html_entities.gperf" + {"ntrianglerighteq", { 0xE2, 0x8B, 0xAD }, 3}, +#line 982 "data/html_entities.gperf" + {"bigvee", { 0xE2, 0x8B, 0x81 }, 3}, +#line 967 "data/html_entities.gperf" + {"downdownarrows", { 0xE2, 0x87, 0x8A }, 3}, +#line 1038 "data/html_entities.gperf" + {"LeftTeeVector", { 0xE2, 0xA5, 0x9A }, 3}, +#line 1723 "data/html_entities.gperf" + {"ac", { 0xE2, 0x88, 0xBE }, 3}, +#line 1783 "data/html_entities.gperf" + {"subsetneqq", { 0xE2, 0xAB, 0x8B }, 3}, +#line 1039 "data/html_entities.gperf" + {"expectation", { 0xE2, 0x84, 0xB0 }, 3}, +#line 834 "data/html_entities.gperf" + {"LowerRightArrow", { 0xE2, 0x86, 0x98 }, 3}, +#line 1569 "data/html_entities.gperf" + {"notinva", { 0xE2, 0x88, 0x89 }, 3}, +#line 510 "data/html_entities.gperf" + {"rightrightarrows", { 0xE2, 0x87, 0x89 }, 3}, +#line 494 "data/html_entities.gperf" + {"RightAngleBracket", { 0xE2, 0x9F, 0xA9 }, 3}, +#line 1548 "data/html_entities.gperf" + {"supsim", { 0xE2, 0xAB, 0x88 }, 3}, +#line 2073 "data/html_entities.gperf" + {"longleftrightarrow", { 0xE2, 0x9F, 0xB7 }, 3}, +#line 803 "data/html_entities.gperf" + {"varsigma", { 0xCF, 0x82 }, 2}, +#line 1919 "data/html_entities.gperf" + {"subplus", { 0xE2, 0xAA, 0xBF }, 3}, +#line 440 "data/html_entities.gperf" + {"RightFloor", { 0xE2, 0x8C, 0x8B }, 3}, +#line 1864 "data/html_entities.gperf" + {"Alpha", { 0xCE, 0x91 }, 2}, +#line 2132 "data/html_entities.gperf" + {"mcy", { 0xD0, 0xBC }, 2}, +#line 382 "data/html_entities.gperf" + {"Gcedil", { 0xC4, 0xA2 }, 2}, +#line 355 "data/html_entities.gperf" + {"RightTee", { 0xE2, 0x8A, 0xA2 }, 3}, +#line 377 "data/html_entities.gperf" + {"subE", { 0xE2, 0xAB, 0x85 }, 3}, +#line 303 "data/html_entities.gperf" + {"Ecy", { 0xD0, 0xAD }, 2}, +#line 579 "data/html_entities.gperf" + {"Cayleys", { 0xE2, 0x84, 0xAD }, 3}, +#line 661 "data/html_entities.gperf" + {"bigtriangleup", { 0xE2, 0x96, 0xB3 }, 3}, +#line 1027 "data/html_entities.gperf" + {"wcirc", { 0xC5, 0xB5 }, 2}, +#line 1573 "data/html_entities.gperf" + {"RightTeeVector", { 0xE2, 0xA5, 0x9B }, 3}, +#line 1622 "data/html_entities.gperf" + {"RightTriangleBar", { 0xE2, 0xA7, 0x90 }, 3}, +#line 1539 "data/html_entities.gperf" + {"RightTriangle", { 0xE2, 0x8A, 0xB3 }, 3}, +#line 1967 "data/html_entities.gperf" + {"RightTriangleEqual", { 0xE2, 0x8A, 0xB5 }, 3}, +#line 1995 "data/html_entities.gperf" + {"Ocirc", { 0xC3, 0x94 }, 2}, +#line 554 "data/html_entities.gperf" + {"otilde", { 0xC3, 0xB5 }, 2}, +#line 2016 "data/html_entities.gperf" + {"ntlg", { 0xE2, 0x89, 0xB8 }, 3}, +#line 495 "data/html_entities.gperf" + {"boxtimes", { 0xE2, 0x8A, 0xA0 }, 3}, +#line 658 "data/html_entities.gperf" + {"RightUpTeeVector", { 0xE2, 0xA5, 0x9C }, 3}, +#line 509 "data/html_entities.gperf" + {"boxur", { 0xE2, 0x94, 0x94 }, 3}, +#line 1944 "data/html_entities.gperf" + {"Longleftrightarrow", { 0xE2, 0x9F, 0xBA }, 3}, +#line 2052 "data/html_entities.gperf" + {"glj", { 0xE2, 0xAA, 0xA4 }, 3}, +#line 553 "data/html_entities.gperf" + {"gg", { 0xE2, 0x89, 0xAB }, 3}, +#line 1495 "data/html_entities.gperf" + {"ldrdhar", { 0xE2, 0xA5, 0xA7 }, 3}, +#line 1353 "data/html_entities.gperf" + {"Ccirc", { 0xC4, 0x88 }, 2}, +#line 104 "data/html_entities.gperf" + {"gtreqless", { 0xE2, 0x8B, 0x9B }, 3}, +#line 1363 "data/html_entities.gperf" + {"zcy", { 0xD0, 0xB7 }, 2}, +#line 655 "data/html_entities.gperf" + {"Gg", { 0xE2, 0x8B, 0x99 }, 3}, +#line 699 "data/html_entities.gperf" + {"ocirc", { 0xC3, 0xB4 }, 2}, +#line 2079 "data/html_entities.gperf" + {"boxuR", { 0xE2, 0x95, 0x98 }, 3}, +#line 924 "data/html_entities.gperf" + {"Oslash", { 0xC3, 0x98 }, 2}, +#line 1114 "data/html_entities.gperf" + {"leftrightharpoons", { 0xE2, 0x87, 0x8B }, 3}, +#line 427 "data/html_entities.gperf" + {"cularr", { 0xE2, 0x86, 0xB6 }, 3}, +#line 1176 "data/html_entities.gperf" + {"lhblk", { 0xE2, 0x96, 0x84 }, 3}, +#line 1124 "data/html_entities.gperf" + {"uhblk", { 0xE2, 0x96, 0x80 }, 3}, +#line 1640 "data/html_entities.gperf" + {"subnE", { 0xE2, 0xAB, 0x8B }, 3}, +#line 567 "data/html_entities.gperf" + {"ange", { 0xE2, 0xA6, 0xA4 }, 3}, +#line 432 "data/html_entities.gperf" + {"Ocy", { 0xD0, 0x9E }, 2}, +#line 1993 "data/html_entities.gperf" + {"xdtri", { 0xE2, 0x96, 0xBD }, 3}, +#line 1786 "data/html_entities.gperf" + {"bigtriangledown", { 0xE2, 0x96, 0xBD }, 3}, +#line 51 "data/html_entities.gperf" + {"leftharpoonup", { 0xE2, 0x86, 0xBC }, 3}, +#line 1126 "data/html_entities.gperf" + {"gtreqqless", { 0xE2, 0xAA, 0x8C }, 3}, +#line 321 "data/html_entities.gperf" + {"boxuL", { 0xE2, 0x95, 0x9B }, 3}, +#line 904 "data/html_entities.gperf" + {"cularrp", { 0xE2, 0xA4, 0xBD }, 3}, +#line 206 "data/html_entities.gperf" + {"NegativeVeryThinSpace", { 0xE2, 0x80, 0x8B }, 3}, +#line 1812 "data/html_entities.gperf" + {"yacute", { 0xC3, 0xBD }, 2}, +#line 740 "data/html_entities.gperf" + {"oslash", { 0xC3, 0xB8 }, 2}, +#line 1850 "data/html_entities.gperf" + {"intlarhk", { 0xE2, 0xA8, 0x97 }, 3}, +#line 1203 "data/html_entities.gperf" + {"Integral", { 0xE2, 0x88, 0xAB }, 3}, +#line 279 "data/html_entities.gperf" + {"supedot", { 0xE2, 0xAB, 0x84 }, 3}, +#line 1655 "data/html_entities.gperf" + {"CloseCurlyDoubleQuote", { 0xE2, 0x80, 0x9D }, 3}, +#line 117 "data/html_entities.gperf" + {"triangleright", { 0xE2, 0x96, 0xB9 }, 3}, +#line 43 "data/html_entities.gperf" + {"ocy", { 0xD0, 0xBE }, 2}, +#line 133 "data/html_entities.gperf" + {"FilledVerySmallSquare", { 0xE2, 0x96, 0xAA }, 3}, +#line 537 "data/html_entities.gperf" + {"notniva", { 0xE2, 0x88, 0x8C }, 3}, +#line 2009 "data/html_entities.gperf" + {"leftharpoondown", { 0xE2, 0x86, 0xBD }, 3}, +#line 1171 "data/html_entities.gperf" + {"ccedil", { 0xC3, 0xA7 }, 2}, +#line 506 "data/html_entities.gperf" + {"Cedilla", { 0xC2, 0xB8 }, 2}, +#line 1544 "data/html_entities.gperf" + {"napprox", { 0xE2, 0x89, 0x89 }, 3}, +#line 1034 "data/html_entities.gperf" + {"LeftRightVector", { 0xE2, 0xA5, 0x8E }, 3}, +#line 1920 "data/html_entities.gperf" + {"UnderParenthesis", { 0xE2, 0x8F, 0x9D }, 3}, +#line 846 "data/html_entities.gperf" + {"boxul", { 0xE2, 0x94, 0x98 }, 3}, +#line 2039 "data/html_entities.gperf" + {"aelig", { 0xC3, 0xA6 }, 2}, +#line 1926 "data/html_entities.gperf" + {"trianglerighteq", { 0xE2, 0x8A, 0xB5 }, 3}, +#line 290 "data/html_entities.gperf" + {"hksearow", { 0xE2, 0xA4, 0xA5 }, 3}, +#line 1517 "data/html_entities.gperf" + {"daleth", { 0xE2, 0x84, 0xB8 }, 3}, +#line 817 "data/html_entities.gperf" + {"rdldhar", { 0xE2, 0xA5, 0xA9 }, 3}, +#line 802 "data/html_entities.gperf" + {"gtcc", { 0xE2, 0xAA, 0xA7 }, 3}, +#line 1238 "data/html_entities.gperf" + {"jcirc", { 0xC4, 0xB5 }, 2}, +#line 1055 "data/html_entities.gperf" + {"circlearrowright", { 0xE2, 0x86, 0xBB }, 3}, +#line 1626 "data/html_entities.gperf" + {"circlearrowleft", { 0xE2, 0x86, 0xBA }, 3}, +#line 1742 "data/html_entities.gperf" + {"gtrsim", { 0xE2, 0x89, 0xB3 }, 3}, +#line 497 "data/html_entities.gperf" + {"boxhu", { 0xE2, 0x94, 0xB4 }, 3}, +#line 1525 "data/html_entities.gperf" + {"xwedge", { 0xE2, 0x8B, 0x80 }, 3}, +#line 902 "data/html_entities.gperf" + {"rarrhk", { 0xE2, 0x86, 0xAA }, 3}, +#line 1278 "data/html_entities.gperf" + {"larrhk", { 0xE2, 0x86, 0xA9 }, 3}, +#line 1163 "data/html_entities.gperf" + {"intercal", { 0xE2, 0x8A, 0xBA }, 3}, +#line 1590 "data/html_entities.gperf" + {"gcirc", { 0xC4, 0x9D }, 2}, +#line 576 "data/html_entities.gperf" + {"boxvr", { 0xE2, 0x94, 0x9C }, 3}, +#line 198 "data/html_entities.gperf" + {"agrave", { 0xC3, 0xA0 }, 2}, +#line 249 "data/html_entities.gperf" + {"leftrightarrows", { 0xE2, 0x87, 0x86 }, 3}, +#line 1279 "data/html_entities.gperf" + {"auml", { 0xC3, 0xA4 }, 2}, +#line 151 "data/html_entities.gperf" + {"curarrm", { 0xE2, 0xA4, 0xBC }, 3}, +#line 1866 "data/html_entities.gperf" + {"Gcirc", { 0xC4, 0x9C }, 2}, +#line 2077 "data/html_entities.gperf" + {"RuleDelayed", { 0xE2, 0xA7, 0xB4 }, 3}, +#line 2000 "data/html_entities.gperf" + {"suphsub", { 0xE2, 0xAB, 0x97 }, 3}, +#line 211 "data/html_entities.gperf" + {"boxv", { 0xE2, 0x94, 0x82 }, 3}, +#line 2066 "data/html_entities.gperf" + {"boxhU", { 0xE2, 0x95, 0xA8 }, 3}, +#line 1724 "data/html_entities.gperf" + {"RightVector", { 0xE2, 0x87, 0x80 }, 3}, +#line 1119 "data/html_entities.gperf" + {"longmapsto", { 0xE2, 0x9F, 0xBC }, 3}, +#line 414 "data/html_entities.gperf" + {"SucceedsEqual", { 0xE2, 0xAA, 0xB0 }, 3}, +#line 366 "data/html_entities.gperf" + {"RightUpDownVector", { 0xE2, 0xA5, 0x8F }, 3}, +#line 1452 "data/html_entities.gperf" + {"downharpoonright", { 0xE2, 0x87, 0x82 }, 3}, +#line 1587 "data/html_entities.gperf" + {"downharpoonleft", { 0xE2, 0x87, 0x83 }, 3}, +#line 1413 "data/html_entities.gperf" + {"jcy", { 0xD0, 0xB9 }, 2}, +#line 978 "data/html_entities.gperf" + {"boxvH", { 0xE2, 0x95, 0xAA }, 3}, +#line 23 "data/html_entities.gperf" + {"boxvR", { 0xE2, 0x95, 0x9E }, 3}, +#line 1210 "data/html_entities.gperf" + {"boxhd", { 0xE2, 0x94, 0xAC }, 3}, +#line 775 "data/html_entities.gperf" + {"topfork", { 0xE2, 0xAB, 0x9A }, 3}, +#line 2003 "data/html_entities.gperf" + {"updownarrow", { 0xE2, 0x86, 0x95 }, 3}, +#line 49 "data/html_entities.gperf" + {"searhk", { 0xE2, 0xA4, 0xA5 }, 3}, +#line 1336 "data/html_entities.gperf" + {"amalg", { 0xE2, 0xA8, 0xBF }, 3}, +#line 1572 "data/html_entities.gperf" + {"gcy", { 0xD0, 0xB3 }, 2}, +#line 400 "data/html_entities.gperf" + {"khcy", { 0xD1, 0x85 }, 2}, +#line 1175 "data/html_entities.gperf" + {"nearhk", { 0xE2, 0xA4, 0xA4 }, 3}, +#line 189 "data/html_entities.gperf" + {"kjcy", { 0xD1, 0x9C }, 2}, +#line 1722 "data/html_entities.gperf" + {"mcomma", { 0xE2, 0xA8, 0xA9 }, 3}, +#line 25 "data/html_entities.gperf" + {"subdot", { 0xE2, 0xAA, 0xBD }, 3}, +#line 1570 "data/html_entities.gperf" + {"boxvL", { 0xE2, 0x95, 0xA1 }, 3}, +#line 1077 "data/html_entities.gperf" + {"hookrightarrow", { 0xE2, 0x86, 0xAA }, 3}, +#line 633 "data/html_entities.gperf" + {"planck", { 0xE2, 0x84, 0x8F }, 3}, +#line 2107 "data/html_entities.gperf" + {"NegativeThickSpace", { 0xE2, 0x80, 0x8B }, 3}, +#line 490 "data/html_entities.gperf" + {"gtquest", { 0xE2, 0xA9, 0xBC }, 3}, +#line 386 "data/html_entities.gperf" + {"Gcy", { 0xD0, 0x93 }, 2}, +#line 1470 "data/html_entities.gperf" + {"rdsh", { 0xE2, 0x86, 0xB3 }, 3}, +#line 428 "data/html_entities.gperf" + {"ldsh", { 0xE2, 0x86, 0xB2 }, 3}, +#line 604 "data/html_entities.gperf" + {"DownRightVector", { 0xE2, 0x87, 0x81 }, 3}, +#line 1837 "data/html_entities.gperf" + {"DownRightVectorBar", { 0xE2, 0xA5, 0x97 }, 3}, +#line 1118 "data/html_entities.gperf" + {"Updownarrow", { 0xE2, 0x87, 0x95 }, 3}, +#line 15 "data/html_entities.gperf" + {"RightVectorBar", { 0xE2, 0xA5, 0x93 }, 3}, +#line 237 "data/html_entities.gperf" + {"yacy", { 0xD1, 0x8F }, 2}, +#line 388 "data/html_entities.gperf" + {"cupdot", { 0xE2, 0x8A, 0x8D }, 3}, +#line 1771 "data/html_entities.gperf" + {"rbrack", { 0x5D }, 1}, +#line 218 "data/html_entities.gperf" + {"lbrack", { 0x5B }, 1}, +#line 345 "data/html_entities.gperf" + {"swarhk", { 0xE2, 0xA4, 0xA6 }, 3}, +#line 2100 "data/html_entities.gperf" + {"nwarhk", { 0xE2, 0xA4, 0xA3 }, 3}, +#line 1493 "data/html_entities.gperf" + {"hcirc", { 0xC4, 0xA5 }, 2}, +#line 1307 "data/html_entities.gperf" + {"curlyvee", { 0xE2, 0x8B, 0x8E }, 3}, +#line 1198 "data/html_entities.gperf" + {"sung", { 0xE2, 0x99, 0xAA }, 3}, +#line 2089 "data/html_entities.gperf" + {"angmsdae", { 0xE2, 0xA6, 0xAC }, 3}, +#line 1749 "data/html_entities.gperf" + {"angmsdab", { 0xE2, 0xA6, 0xA9 }, 3}, +#line 975 "data/html_entities.gperf" + {"hybull", { 0xE2, 0x81, 0x83 }, 3}, +#line 1428 "data/html_entities.gperf" + {"LeftAngleBracket", { 0xE2, 0x9F, 0xA8 }, 3}, +#line 1848 "data/html_entities.gperf" + {"alefsym", { 0xE2, 0x84, 0xB5 }, 3}, +#line 2101 "data/html_entities.gperf" + {"boxvl", { 0xE2, 0x94, 0xA4 }, 3}, +#line 838 "data/html_entities.gperf" + {"xuplus", { 0xE2, 0xA8, 0x84 }, 3}, +#line 1958 "data/html_entities.gperf" + {"numero", { 0xE2, 0x84, 0x96 }, 3}, +#line 1914 "data/html_entities.gperf" + {"LeftVectorBar", { 0xE2, 0xA5, 0x92 }, 3}, +#line 777 "data/html_entities.gperf" + {"VerticalLine", { 0x7C }, 1}, +#line 254 "data/html_entities.gperf" + {"tstrok", { 0xC5, 0xA7 }, 2}, +#line 1009 "data/html_entities.gperf" + {"lstrok", { 0xC5, 0x82 }, 2}, +#line 422 "data/html_entities.gperf" + {"angmsdaf", { 0xE2, 0xA6, 0xAD }, 3}, +#line 188 "data/html_entities.gperf" + {"nRightarrow", { 0xE2, 0x87, 0x8F }, 3}, +#line 1826 "data/html_entities.gperf" + {"RightDownTeeVector", { 0xE2, 0xA5, 0x9D }, 3}, +#line 231 "data/html_entities.gperf" + {"ffllig", { 0xEF, 0xAC, 0x84 }, 3}, +#line 1085 "data/html_entities.gperf" + {"ccirc", { 0xC4, 0x89 }, 2}, +#line 76 "data/html_entities.gperf" + {"Hstrok", { 0xC4, 0xA6 }, 2}, +#line 1455 "data/html_entities.gperf" + {"nrightarrow", { 0xE2, 0x86, 0x9B }, 3}, +#line 922 "data/html_entities.gperf" + {"sube", { 0xE2, 0x8A, 0x86 }, 3}, +#line 663 "data/html_entities.gperf" + {"hslash", { 0xE2, 0x84, 0x8F }, 3}, +#line 1846 "data/html_entities.gperf" + {"longrightarrow", { 0xE2, 0x9F, 0xB6 }, 3}, +#line 158 "data/html_entities.gperf" + {"Lstrok", { 0xC5, 0x81 }, 2}, +#line 1390 "data/html_entities.gperf" + {"gtrapprox", { 0xE2, 0xAA, 0x86 }, 3}, +#line 381 "data/html_entities.gperf" + {"RightDoubleBracket", { 0xE2, 0x9F, 0xA7 }, 3}, +#line 350 "data/html_entities.gperf" + {"boxhD", { 0xE2, 0x95, 0xA5 }, 3}, +#line 2127 "data/html_entities.gperf" + {"Rrightarrow", { 0xE2, 0x87, 0x9B }, 3}, +#line 977 "data/html_entities.gperf" + {"aring", { 0xC3, 0xA5 }, 2}, +#line 921 "data/html_entities.gperf" + {"Tstrok", { 0xC5, 0xA6 }, 2}, +#line 794 "data/html_entities.gperf" + {"RightArrow", { 0xE2, 0x86, 0x92 }, 3}, +#line 1843 "data/html_entities.gperf" + {"precnapprox", { 0xE2, 0xAA, 0xB9 }, 3}, +#line 1911 "data/html_entities.gperf" + {"Longrightarrow", { 0xE2, 0x9F, 0xB9 }, 3}, +#line 114 "data/html_entities.gperf" + {"angmsdad", { 0xE2, 0xA6, 0xAB }, 3}, +#line 1948 "data/html_entities.gperf" + {"RightArrowLeftArrow", { 0xE2, 0x87, 0x84 }, 3}, +#line 16 "data/html_entities.gperf" + {"atilde", { 0xC3, 0xA3 }, 2}, +#line 696 "data/html_entities.gperf" + {"leftrightarrow", { 0xE2, 0x86, 0x94 }, 3}, +#line 2036 "data/html_entities.gperf" + {"Jukcy", { 0xD0, 0x84 }, 2}, +#line 1194 "data/html_entities.gperf" + {"VerticalTilde", { 0xE2, 0x89, 0x80 }, 3}, +#line 1201 "data/html_entities.gperf" + {"dstrok", { 0xC4, 0x91 }, 2}, +#line 541 "data/html_entities.gperf" + {"Iukcy", { 0xD0, 0x86 }, 2}, +#line 2041 "data/html_entities.gperf" + {"Dstrok", { 0xC4, 0x90 }, 2}, +#line 1412 "data/html_entities.gperf" + {"SHCHcy", { 0xD0, 0xA9 }, 2}, +#line 1954 "data/html_entities.gperf" + {"yicy", { 0xD1, 0x97 }, 2}, +#line 568 "data/html_entities.gperf" + {"NotRightTriangleBar", { 0xE2, 0xA7, 0x90, 0xCC, 0xB8 }, 5}, +#line 598 "data/html_entities.gperf" + {"NotRightTriangle", { 0xE2, 0x8B, 0xAB }, 3}, +#line 1876 "data/html_entities.gperf" + {"NotRightTriangleEqual", { 0xE2, 0x8B, 0xAD }, 3}, +#line 429 "data/html_entities.gperf" + {"Leftrightarrow", { 0xE2, 0x87, 0x94 }, 3}, +#line 1892 "data/html_entities.gperf" + {"pertenk", { 0xE2, 0x80, 0xB1 }, 3}, +#line 269 "data/html_entities.gperf" + {"rightleftharpoons", { 0xE2, 0x87, 0x8C }, 3}, +#line 1529 "data/html_entities.gperf" + {"planckh", { 0xE2, 0x84, 0x8E }, 3}, +#line 1767 "data/html_entities.gperf" + {"otimesas", { 0xE2, 0xA8, 0xB6 }, 3}, +#line 1594 "data/html_entities.gperf" + {"kcedil", { 0xC4, 0xB7 }, 2}, +#line 998 "data/html_entities.gperf" + {"yuml", { 0xC3, 0xBF }, 2}, +#line 1867 "data/html_entities.gperf" + {"acirc", { 0xC3, 0xA2 }, 2}, +#line 1784 "data/html_entities.gperf" + {"thickapprox", { 0xE2, 0x89, 0x88 }, 3}, +#line 131 "data/html_entities.gperf" + {"odiv", { 0xE2, 0xA8, 0xB8 }, 3}, +#line 668 "data/html_entities.gperf" + {"xutri", { 0xE2, 0x96, 0xB3 }, 3}, +#line 683 "data/html_entities.gperf" + {"suphsol", { 0xE2, 0x9F, 0x89 }, 3}, +#line 1972 "data/html_entities.gperf" + {"iukcy", { 0xD1, 0x96 }, 2}, +#line 709 "data/html_entities.gperf" + {"RightTeeArrow", { 0xE2, 0x86, 0xA6 }, 3}, +#line 1167 "data/html_entities.gperf" + {"rightthreetimes", { 0xE2, 0x8B, 0x8C }, 3}, +#line 1410 "data/html_entities.gperf" + {"subsim", { 0xE2, 0xAB, 0x87 }, 3}, +#line 2044 "data/html_entities.gperf" + {"curlywedge", { 0xE2, 0x8B, 0x8F }, 3}, +#line 1017 "data/html_entities.gperf" + {"acy", { 0xD0, 0xB0 }, 2}, +#line 601 "data/html_entities.gperf" + {"Jsercy", { 0xD0, 0x88 }, 2}, +#line 671 "data/html_entities.gperf" + {"divonx", { 0xE2, 0x8B, 0x87 }, 3}, +#line 738 "data/html_entities.gperf" + {"xcirc", { 0xE2, 0x97, 0xAF }, 3}, +#line 278 "data/html_entities.gperf" + {"cuesc", { 0xE2, 0x8B, 0x9F }, 3}, +#line 1592 "data/html_entities.gperf" + {"approx", { 0xE2, 0x89, 0x88 }, 3}, +#line 70 "data/html_entities.gperf" + {"ggg", { 0xE2, 0x8B, 0x99 }, 3}, +#line 1287 "data/html_entities.gperf" + {"bigcirc", { 0xE2, 0x97, 0xAF }, 3}, +#line 1015 "data/html_entities.gperf" + {"rightsquigarrow", { 0xE2, 0x86, 0x9D }, 3}, +#line 706 "data/html_entities.gperf" + {"SupersetEqual", { 0xE2, 0x8A, 0x87 }, 3}, +#line 667 "data/html_entities.gperf" + {"rightleftarrows", { 0xE2, 0x87, 0x84 }, 3}, +#line 358 "data/html_entities.gperf" + {"straightepsilon", { 0xCF, 0xB5 }, 2}, +#line 1383 "data/html_entities.gperf" + {"ffilig", { 0xEF, 0xAC, 0x83 }, 3}, +#line 669 "data/html_entities.gperf" + {"cuvee", { 0xE2, 0x8B, 0x8E }, 3}, +#line 1589 "data/html_entities.gperf" + {"alpha", { 0xCE, 0xB1 }, 2}, +#line 1471 "data/html_entities.gperf" + {"subedot", { 0xE2, 0xAB, 0x83 }, 3}, +#line 570 "data/html_entities.gperf" + {"angsph", { 0xE2, 0x88, 0xA2 }, 3}, +#line 697 "data/html_entities.gperf" + {"digamma", { 0xCF, 0x9D }, 2}, +#line 103 "data/html_entities.gperf" + {"checkmark", { 0xE2, 0x9C, 0x93 }, 3}, +#line 525 "data/html_entities.gperf" + {"kgreen", { 0xC4, 0xB8 }, 2}, +#line 1755 "data/html_entities.gperf" + {"boxh", { 0xE2, 0x94, 0x80 }, 3}, +#line 1613 "data/html_entities.gperf" + {"ycirc", { 0xC5, 0xB7 }, 2}, +#line 558 "data/html_entities.gperf" + {"SubsetEqual", { 0xE2, 0x8A, 0x86 }, 3}, +#line 275 "data/html_entities.gperf" + {"angmsdag", { 0xE2, 0xA6, 0xAE }, 3}, +#line 891 "data/html_entities.gperf" + {"SOFTcy", { 0xD0, 0xAC }, 2}, +#line 2020 "data/html_entities.gperf" + {"kcy", { 0xD0, 0xBA }, 2}, +#line 855 "data/html_entities.gperf" + {"vzigzag", { 0xE2, 0xA6, 0x9A }, 3}, +#line 687 "data/html_entities.gperf" + {"luruhar", { 0xE2, 0xA5, 0xA6 }, 3}, +#line 1293 "data/html_entities.gperf" + {"boxbox", { 0xE2, 0xA7, 0x89 }, 3}, +#line 1511 "data/html_entities.gperf" + {"ycy", { 0xD1, 0x8B }, 2}, +#line 589 "data/html_entities.gperf" + {"twoheadrightarrow", { 0xE2, 0x86, 0xA0 }, 3}, +#line 1776 "data/html_entities.gperf" + {"jukcy", { 0xD1, 0x94 }, 2}, +#line 1520 "data/html_entities.gperf" + {"boxvh", { 0xE2, 0x94, 0xBC }, 3}, +#line 181 "data/html_entities.gperf" + {"ldrushar", { 0xE2, 0xA5, 0x8B }, 3}, +#line 1388 "data/html_entities.gperf" + {"RightUpVector", { 0xE2, 0x86, 0xBE }, 3}, +#line 1752 "data/html_entities.gperf" + {"RightUpVectorBar", { 0xE2, 0xA5, 0x94 }, 3}, +#line 1927 "data/html_entities.gperf" + {"angmsdah", { 0xE2, 0xA6, 0xAF }, 3}, +#line 1628 "data/html_entities.gperf" + {"udblac", { 0xC5, 0xB1 }, 2}, +#line 1277 "data/html_entities.gperf" + {"RightArrowBar", { 0xE2, 0x87, 0xA5 }, 3}, +#line 52 "data/html_entities.gperf" + {"HARDcy", { 0xD0, 0xAA }, 2}, +#line 773 "data/html_entities.gperf" + {"hstrok", { 0xC4, 0xA7 }, 2}, +#line 1258 "data/html_entities.gperf" + {"RightDownVector", { 0xE2, 0x87, 0x82 }, 3}, +#line 1069 "data/html_entities.gperf" + {"RightDownVectorBar", { 0xE2, 0xA5, 0x95 }, 3}, +#line 539 "data/html_entities.gperf" + {"lurdshar", { 0xE2, 0xA5, 0x8A }, 3}, +#line 844 "data/html_entities.gperf" + {"angmsdac", { 0xE2, 0xA6, 0xAA }, 3}, +#line 296 "data/html_entities.gperf" + {"ruluhar", { 0xE2, 0xA5, 0xA8 }, 3}, +#line 426 "data/html_entities.gperf" + {"softcy", { 0xD1, 0x8C }, 2}, +#line 1832 "data/html_entities.gperf" + {"jsercy", { 0xD1, 0x98 }, 2}, +#line 1679 "data/html_entities.gperf" + {"succapprox", { 0xE2, 0xAA, 0xB8 }, 3}, +#line 979 "data/html_entities.gperf" + {"Udblac", { 0xC5, 0xB0 }, 2}, +#line 698 "data/html_entities.gperf" + {"curlyeqprec", { 0xE2, 0x8B, 0x9E }, 3}, +#line 1793 "data/html_entities.gperf" + {"cylcty", { 0xE2, 0x8C, 0xAD }, 3}, +#line 331 "data/html_entities.gperf" + {"VerticalBar", { 0xE2, 0x88, 0xA3 }, 3}, +#line 1330 "data/html_entities.gperf" + {"VerticalSeparator", { 0xE2, 0x9D, 0x98 }, 3}, +#line 1951 "data/html_entities.gperf" + {"multimap", { 0xE2, 0x8A, 0xB8 }, 3}, +#line 577 "data/html_entities.gperf" + {"angmsdaa", { 0xE2, 0xA6, 0xA8 }, 3}, +#line 1437 "data/html_entities.gperf" + {"rightarrow", { 0xE2, 0x86, 0x92 }, 3}, +#line 1276 "data/html_entities.gperf" + {"Rightarrow", { 0xE2, 0x87, 0x92 }, 3}, +#line 575 "data/html_entities.gperf" + {"twoheadleftarrow", { 0xE2, 0x86, 0x9E }, 3}, +#line 270 "data/html_entities.gperf" + {"Odblac", { 0xC5, 0x90 }, 2}, +#line 1185 "data/html_entities.gperf" + {"RightCeiling", { 0xE2, 0x8C, 0x89 }, 3}, +#line 179 "data/html_entities.gperf" + {"NoBreak", { 0xE2, 0x81, 0xA0 }, 3}, +#line 602 "data/html_entities.gperf" + {"straightphi", { 0xCF, 0x95 }, 2}, +#line 1216 "data/html_entities.gperf" + {"odblac", { 0xC5, 0x91 }, 2}, +#line 423 "data/html_entities.gperf" + {"cupbrcap", { 0xE2, 0xA9, 0x88 }, 3}, +#line 512 "data/html_entities.gperf" + {"cuwed", { 0xE2, 0x8B, 0x8F }, 3}, +#line 596 "data/html_entities.gperf" + {"hardcy", { 0xD1, 0x8A }, 2}, +#line 1593 "data/html_entities.gperf" + {"yucy", { 0xD1, 0x8E }, 2}, +#line 1937 "data/html_entities.gperf" + {"shchcy", { 0xD1, 0x89 }, 2}, +#line 996 "data/html_entities.gperf" + {"succnapprox", { 0xE2, 0xAA, 0xBA }, 3}, +#line 1874 "data/html_entities.gperf" + {"rightharpoondown", { 0xE2, 0x87, 0x81 }, 3}, +#line 201 "data/html_entities.gperf" + {"rightharpoonup", { 0xE2, 0x87, 0x80 }, 3}, +#line 847 "data/html_entities.gperf" + {"rightarrowtail", { 0xE2, 0x86, 0xA3 }, 3}, +#line 1224 "data/html_entities.gperf" + {"curlyeqsucc", { 0xE2, 0x8B, 0x9F }, 3}, +#line 1938 "data/html_entities.gperf" + {"SuchThat", { 0xE2, 0x88, 0x8B }, 3}, +#line 116 "data/html_entities.gperf" + {"curvearrowleft", { 0xE2, 0x86, 0xB6 }, 3}, +#line 1443 "data/html_entities.gperf" + {"curvearrowright", { 0xE2, 0x86, 0xB7 }, 3} + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE) + { + register const struct html_entity *resword; + + switch (key - 91) + { + case 0: + if (len == 3) + { + resword = &wordlist[0]; + goto compare; + } + break; + case 1: + if (len == 3) + { + resword = &wordlist[1]; + goto compare; + } + break; + case 10: + if (len == 3) + { + resword = &wordlist[2]; + goto compare; + } + break; + case 13: + if (len == 3) + { + resword = &wordlist[3]; + goto compare; + } + break; + case 19: + if (len == 4) + { + resword = &wordlist[4]; + goto compare; + } + break; + case 21: + if (len == 4) + { + resword = &wordlist[5]; + goto compare; + } + break; + case 22: + if (len == 3) + { + resword = &wordlist[6]; + goto compare; + } + break; + case 28: + if (len == 4) + { + resword = &wordlist[7]; + goto compare; + } + break; + case 29: + if (len == 4) + { + resword = &wordlist[8]; + goto compare; + } + break; + case 31: + if (len == 4) + { + resword = &wordlist[9]; + goto compare; + } + break; + case 32: + if (len == 4) + { + resword = &wordlist[10]; + goto compare; + } + break; + case 33: + if (len == 4) + { + resword = &wordlist[11]; + goto compare; + } + break; + case 35: + if (len == 2) + { + resword = &wordlist[12]; + goto compare; + } + break; + case 37: + if (len == 2) + { + resword = &wordlist[13]; + goto compare; + } + break; + case 42: + if (len == 4) + { + resword = &wordlist[14]; + goto compare; + } + break; + case 53: + if (len == 5) + { + resword = &wordlist[15]; + goto compare; + } + break; + case 55: + if (len == 5) + { + resword = &wordlist[16]; + goto compare; + } + break; + case 57: + if (len == 3) + { + resword = &wordlist[17]; + goto compare; + } + break; + case 58: + if (len == 3) + { + resword = &wordlist[18]; + goto compare; + } + break; + case 61: + if (len == 5) + { + resword = &wordlist[19]; + goto compare; + } + break; + case 64: + if (len == 2) + { + resword = &wordlist[20]; + goto compare; + } + break; + case 65: + if (len == 5) + { + resword = &wordlist[21]; + goto compare; + } + break; + case 68: + if (len == 3) + { + resword = &wordlist[22]; + goto compare; + } + break; + case 69: + if (len == 6) + { + resword = &wordlist[23]; + goto compare; + } + break; + case 70: + if (len == 6) + { + resword = &wordlist[24]; + goto compare; + } + break; + case 71: + if (len == 5) + { + resword = &wordlist[25]; + goto compare; + } + break; + case 72: + if (len == 6) + { + resword = &wordlist[26]; + goto compare; + } + break; + case 73: + if (len == 3) + { + resword = &wordlist[27]; + goto compare; + } + break; + case 76: + if (len == 6) + { + resword = &wordlist[28]; + goto compare; + } + break; + case 77: + if (len == 4) + { + resword = &wordlist[29]; + goto compare; + } + break; + case 82: + if (len == 3) + { + resword = &wordlist[30]; + goto compare; + } + break; + case 84: + if (len == 6) + { + resword = &wordlist[31]; + goto compare; + } + break; + case 85: + if (len == 6) + { + resword = &wordlist[32]; + goto compare; + } + break; + case 89: + if (len == 3) + { + resword = &wordlist[33]; + goto compare; + } + break; + case 90: + if (len == 4) + { + resword = &wordlist[34]; + goto compare; + } + break; + case 95: + if (len == 4) + { + resword = &wordlist[35]; + goto compare; + } + break; + case 97: + if (len == 7) + { + resword = &wordlist[36]; + goto compare; + } + break; + case 99: + if (len == 7) + { + resword = &wordlist[37]; + goto compare; + } + break; + case 103: + if (len == 4) + { + resword = &wordlist[38]; + goto compare; + } + break; + case 109: + if (len == 5) + { + resword = &wordlist[39]; + goto compare; + } + break; + case 110: + if (len == 5) + { + resword = &wordlist[40]; + goto compare; + } + break; + case 112: + if (len == 3) + { + resword = &wordlist[41]; + goto compare; + } + break; + case 114: + if (len == 3) + { + resword = &wordlist[42]; + goto compare; + } + break; + case 115: + if (len == 2) + { + resword = &wordlist[43]; + goto compare; + } + break; + case 116: + if (len == 5) + { + resword = &wordlist[44]; + goto compare; + } + break; + case 118: + if (len == 5) + { + resword = &wordlist[45]; + goto compare; + } + break; + case 119: + if (len == 5) + { + resword = &wordlist[46]; + goto compare; + } + break; + case 123: + if (len == 9) + { + resword = &wordlist[47]; + goto compare; + } + break; + case 126: + if (len == 3) + { + resword = &wordlist[48]; + goto compare; + } + break; + case 128: + if (len == 3) + { + resword = &wordlist[49]; + goto compare; + } + break; + case 129: + if (len == 5) + { + resword = &wordlist[50]; + goto compare; + } + break; + case 133: + if (len == 5) + { + resword = &wordlist[51]; + goto compare; + } + break; + case 134: + if (len == 5) + { + resword = &wordlist[52]; + goto compare; + } + break; + case 136: + if (len == 5) + { + resword = &wordlist[53]; + goto compare; + } + break; + case 137: + if (len == 5) + { + resword = &wordlist[54]; + goto compare; + } + break; + case 138: + if (len == 5) + { + resword = &wordlist[55]; + goto compare; + } + break; + case 142: + if (len == 5) + { + resword = &wordlist[56]; + goto compare; + } + break; + case 144: + if (len == 5) + { + resword = &wordlist[57]; + goto compare; + } + break; + case 147: + if (len == 5) + { + resword = &wordlist[58]; + goto compare; + } + break; + case 156: + if (len == 6) + { + resword = &wordlist[59]; + goto compare; + } + break; + case 158: + if (len == 6) + { + resword = &wordlist[60]; + goto compare; + } + break; + case 160: + if (len == 3) + { + resword = &wordlist[61]; + goto compare; + } + break; + case 166: + if (len == 4) + { + resword = &wordlist[62]; + goto compare; + } + break; + case 168: + if (len == 4) + { + resword = &wordlist[63]; + goto compare; + } + break; + case 174: + if (len == 5) + { + resword = &wordlist[64]; + goto compare; + } + break; + case 175: + if (len == 4) + { + resword = &wordlist[65]; + goto compare; + } + break; + case 176: + if (len == 5) + { + resword = &wordlist[66]; + goto compare; + } + break; + case 177: + if (len == 4) + { + resword = &wordlist[67]; + goto compare; + } + break; + case 178: + if (len == 3) + { + resword = &wordlist[68]; + goto compare; + } + break; + case 180: + if (len == 2) + { + resword = &wordlist[69]; + goto compare; + } + break; + case 184: + if (len == 4) + { + resword = &wordlist[70]; + goto compare; + } + break; + case 185: + if (len == 4) + { + resword = &wordlist[71]; + goto compare; + } + break; + case 191: + if (len == 3) + { + resword = &wordlist[72]; + goto compare; + } + break; + case 200: + if (len == 10) + { + resword = &wordlist[73]; + goto compare; + } + break; + case 205: + if (len == 6) + { + resword = &wordlist[74]; + goto compare; + } + break; + case 206: + if (len == 6) + { + resword = &wordlist[75]; + goto compare; + } + break; + case 210: + if (len == 4) + { + resword = &wordlist[76]; + goto compare; + } + break; + case 215: + if (len == 3) + { + resword = &wordlist[77]; + goto compare; + } + break; + case 219: + if (len == 6) + { + resword = &wordlist[78]; + goto compare; + } + break; + case 221: + if (len == 7) + { + resword = &wordlist[79]; + goto compare; + } + break; + case 223: + if (len == 7) + { + resword = &wordlist[80]; + goto compare; + } + break; + case 224: + if (len == 5) + { + resword = &wordlist[81]; + goto compare; + } + break; + case 235: + if (len == 3) + { + resword = &wordlist[82]; + goto compare; + } + break; + case 237: + if (len == 3) + { + resword = &wordlist[83]; + goto compare; + } + break; + case 238: + if (len == 4) + { + resword = &wordlist[84]; + goto compare; + } + break; + case 242: + if (len == 6) + { + resword = &wordlist[85]; + goto compare; + } + break; + case 243: + if (len == 6) + { + resword = &wordlist[86]; + goto compare; + } + break; + case 244: + if (len == 6) + { + resword = &wordlist[87]; + goto compare; + } + break; + case 248: + if (len == 3) + { + resword = &wordlist[88]; + goto compare; + } + break; + case 249: + if (len == 6) + { + resword = &wordlist[89]; + goto compare; + } + break; + case 254: + if (len == 4) + { + resword = &wordlist[90]; + goto compare; + } + break; + case 258: + if (len == 4) + { + resword = &wordlist[91]; + goto compare; + } + break; + case 262: + if (len == 3) + { + resword = &wordlist[92]; + goto compare; + } + break; + case 265: + if (len == 5) + { + resword = &wordlist[93]; + goto compare; + } + break; + case 267: + if (len == 5) + { + resword = &wordlist[94]; + goto compare; + } + break; + case 271: + if (len == 6) + { + resword = &wordlist[95]; + goto compare; + } + break; + case 274: + if (len == 6) + { + resword = &wordlist[96]; + goto compare; + } + break; + case 288: + if (len == 4) + { + resword = &wordlist[97]; + goto compare; + } + break; + case 289: + if (len == 2) + { + resword = &wordlist[98]; + goto compare; + } + break; + case 290: + if (len == 5) + { + resword = &wordlist[99]; + goto compare; + } + break; + case 291: + if (len == 2) + { + resword = &wordlist[100]; + goto compare; + } + break; + case 292: + if (len == 5) + { + resword = &wordlist[101]; + goto compare; + } + break; + case 293: + if (len == 4) + { + resword = &wordlist[102]; + goto compare; + } + break; + case 296: + if (len == 2) + { + resword = &wordlist[103]; + goto compare; + } + break; + case 298: + if (len == 6) + { + resword = &wordlist[104]; + goto compare; + } + break; + case 299: + if (len == 5) + { + resword = &wordlist[105]; + goto compare; + } + break; + case 300: + if (len == 2) + { + resword = &wordlist[106]; + goto compare; + } + break; + case 301: + if (len == 6) + { + resword = &wordlist[107]; + goto compare; + } + break; + case 306: + if (len == 4) + { + resword = &wordlist[108]; + goto compare; + } + break; + case 308: + if (len == 3) + { + resword = &wordlist[109]; + goto compare; + } + break; + case 311: + if (len == 4) + { + resword = &wordlist[110]; + goto compare; + } + break; + case 312: + if (len == 3) + { + resword = &wordlist[111]; + goto compare; + } + break; + case 313: + if (len == 5) + { + resword = &wordlist[112]; + goto compare; + } + break; + case 319: + if (len == 13) + { + resword = &wordlist[113]; + goto compare; + } + break; + case 327: + if (len == 4) + { + resword = &wordlist[114]; + goto compare; + } + break; + case 328: + if (len == 3) + { + resword = &wordlist[115]; + goto compare; + } + break; + case 329: + if (len == 4) + { + resword = &wordlist[116]; + goto compare; + } + break; + case 330: + if (len == 5) + { + resword = &wordlist[117]; + goto compare; + } + break; + case 334: + if (len == 4) + { + resword = &wordlist[118]; + goto compare; + } + break; + case 342: + if (len == 10) + { + resword = &wordlist[119]; + goto compare; + } + break; + case 346: + if (len == 13) + { + resword = &wordlist[120]; + goto compare; + } + break; + case 347: + if (len == 17) + { + resword = &wordlist[121]; + goto compare; + } + break; + case 348: + if (len == 18) + { + resword = &wordlist[122]; + goto compare; + } + break; + case 350: + if (len == 5) + { + resword = &wordlist[123]; + goto compare; + } + break; + case 353: + if (len == 12) + { + resword = &wordlist[124]; + goto compare; + } + break; + case 355: + if (len == 5) + { + resword = &wordlist[125]; + goto compare; + } + break; + case 357: + if (len == 5) + { + resword = &wordlist[126]; + goto compare; + } + break; + case 359: + if (len == 17) + { + resword = &wordlist[127]; + goto compare; + } + break; + case 363: + if (len == 6) + { + resword = &wordlist[128]; + goto compare; + } + break; + case 367: + if (len == 5) + { + resword = &wordlist[129]; + goto compare; + } + break; + case 371: + if (len == 5) + { + resword = &wordlist[130]; + goto compare; + } + break; + case 374: + if (len == 9) + { + resword = &wordlist[131]; + goto compare; + } + break; + case 377: + if (len == 3) + { + resword = &wordlist[132]; + goto compare; + } + break; + case 380: + if (len == 6) + { + resword = &wordlist[133]; + goto compare; + } + break; + case 381: + if (len == 5) + { + resword = &wordlist[134]; + goto compare; + } + break; + case 388: + if (len == 4) + { + resword = &wordlist[135]; + goto compare; + } + break; + case 389: + if (len == 6) + { + resword = &wordlist[136]; + goto compare; + } + break; + case 391: + if (len == 2) + { + resword = &wordlist[137]; + goto compare; + } + break; + case 392: + if (len == 6) + { + resword = &wordlist[138]; + goto compare; + } + break; + case 393: + if (len == 8) + { + resword = &wordlist[139]; + goto compare; + } + break; + case 395: + if (len == 6) + { + resword = &wordlist[140]; + goto compare; + } + break; + case 396: + if (len == 3) + { + resword = &wordlist[141]; + goto compare; + } + break; + case 398: + if (len == 6) + { + resword = &wordlist[142]; + goto compare; + } + break; + case 399: + if (len == 4) + { + resword = &wordlist[143]; + goto compare; + } + break; + case 402: + if (len == 6) + { + resword = &wordlist[144]; + goto compare; + } + break; + case 404: + if (len == 6) + { + resword = &wordlist[145]; + goto compare; + } + break; + case 405: + if (len == 3) + { + resword = &wordlist[146]; + goto compare; + } + break; + case 406: + if (len == 5) + { + resword = &wordlist[147]; + goto compare; + } + break; + case 407: + if (len == 5) + { + resword = &wordlist[148]; + goto compare; + } + break; + case 408: + if (len == 6) + { + resword = &wordlist[149]; + goto compare; + } + break; + case 409: + if (len == 6) + { + resword = &wordlist[150]; + goto compare; + } + break; + case 412: + if (len == 6) + { + resword = &wordlist[151]; + goto compare; + } + break; + case 414: + if (len == 5) + { + resword = &wordlist[152]; + goto compare; + } + break; + case 415: + if (len == 6) + { + resword = &wordlist[153]; + goto compare; + } + break; + case 418: + if (len == 4) + { + resword = &wordlist[154]; + goto compare; + } + break; + case 421: + if (len == 5) + { + resword = &wordlist[155]; + goto compare; + } + break; + case 426: + if (len == 5) + { + resword = &wordlist[156]; + goto compare; + } + break; + case 428: + if (len == 6) + { + resword = &wordlist[157]; + goto compare; + } + break; + case 430: + if (len == 6) + { + resword = &wordlist[158]; + goto compare; + } + break; + case 431: + if (len == 6) + { + resword = &wordlist[159]; + goto compare; + } + break; + case 432: + if (len == 5) + { + resword = &wordlist[160]; + goto compare; + } + break; + case 433: + if (len == 5) + { + resword = &wordlist[161]; + goto compare; + } + break; + case 435: + if (len == 5) + { + resword = &wordlist[162]; + goto compare; + } + break; + case 436: + if (len == 2) + { + resword = &wordlist[163]; + goto compare; + } + break; + case 441: + if (len == 6) + { + resword = &wordlist[164]; + goto compare; + } + break; + case 442: + if (len == 6) + { + resword = &wordlist[165]; + goto compare; + } + break; + case 449: + if (len == 11) + { + resword = &wordlist[166]; + goto compare; + } + break; + case 450: + if (len == 5) + { + resword = &wordlist[167]; + goto compare; + } + break; + case 454: + if (len == 6) + { + resword = &wordlist[168]; + goto compare; + } + break; + case 459: + if (len == 4) + { + resword = &wordlist[169]; + goto compare; + } + break; + case 463: + if (len == 3) + { + resword = &wordlist[170]; + goto compare; + } + break; + case 464: + if (len == 5) + { + resword = &wordlist[171]; + goto compare; + } + break; + case 465: + if (len == 5) + { + resword = &wordlist[172]; + goto compare; + } + break; + case 466: + if (len == 6) + { + resword = &wordlist[173]; + goto compare; + } + break; + case 467: + if (len == 6) + { + resword = &wordlist[174]; + goto compare; + } + break; + case 485: + if (len == 3) + { + resword = &wordlist[175]; + goto compare; + } + break; + case 490: + if (len == 5) + { + resword = &wordlist[176]; + goto compare; + } + break; + case 494: + if (len == 11) + { + resword = &wordlist[177]; + goto compare; + } + break; + case 502: + if (len == 5) + { + resword = &wordlist[178]; + goto compare; + } + break; + case 505: + if (len == 4) + { + resword = &wordlist[179]; + goto compare; + } + break; + case 508: + if (len == 5) + { + resword = &wordlist[180]; + goto compare; + } + break; + case 512: + if (len == 6) + { + resword = &wordlist[181]; + goto compare; + } + break; + case 514: + if (len == 3) + { + resword = &wordlist[182]; + goto compare; + } + break; + case 517: + if (len == 6) + { + resword = &wordlist[183]; + goto compare; + } + break; + case 524: + if (len == 3) + { + resword = &wordlist[184]; + goto compare; + } + break; + case 525: + if (len == 6) + { + resword = &wordlist[185]; + goto compare; + } + break; + case 528: + if (len == 6) + { + resword = &wordlist[186]; + goto compare; + } + break; + case 529: + if (len == 8) + { + resword = &wordlist[187]; + goto compare; + } + break; + case 536: + if (len == 8) + { + resword = &wordlist[188]; + goto compare; + } + break; + case 540: + if (len == 6) + { + resword = &wordlist[189]; + goto compare; + } + break; + case 541: + if (len == 4) + { + resword = &wordlist[190]; + goto compare; + } + break; + case 543: + if (len == 6) + { + resword = &wordlist[191]; + goto compare; + } + break; + case 547: + if (len == 8) + { + resword = &wordlist[192]; + goto compare; + } + break; + case 552: + if (len == 8) + { + resword = &wordlist[193]; + goto compare; + } + break; + case 554: + if (len == 8) + { + resword = &wordlist[194]; + goto compare; + } + break; + case 555: + if (len == 4) + { + resword = &wordlist[195]; + goto compare; + } + break; + case 556: + if (len == 5) + { + resword = &wordlist[196]; + goto compare; + } + break; + case 560: + if (len == 4) + { + resword = &wordlist[197]; + goto compare; + } + break; + case 566: + if (len == 6) + { + resword = &wordlist[198]; + goto compare; + } + break; + case 581: + if (len == 5) + { + resword = &wordlist[199]; + goto compare; + } + break; + case 587: + if (len == 6) + { + resword = &wordlist[200]; + goto compare; + } + break; + case 589: + if (len == 5) + { + resword = &wordlist[201]; + goto compare; + } + break; + case 591: + if (len == 5) + { + resword = &wordlist[202]; + goto compare; + } + break; + case 592: + if (len == 17) + { + resword = &wordlist[203]; + goto compare; + } + break; + case 599: + if (len == 4) + { + resword = &wordlist[204]; + goto compare; + } + break; + case 601: + if (len == 5) + { + resword = &wordlist[205]; + goto compare; + } + break; + case 606: + if (len == 5) + { + resword = &wordlist[206]; + goto compare; + } + break; + case 616: + if (len == 5) + { + resword = &wordlist[207]; + goto compare; + } + break; + case 618: + if (len == 3) + { + resword = &wordlist[208]; + goto compare; + } + break; + case 626: + if (len == 5) + { + resword = &wordlist[209]; + goto compare; + } + break; + case 627: + if (len == 3) + { + resword = &wordlist[210]; + goto compare; + } + break; + case 629: + if (len == 4) + { + resword = &wordlist[211]; + goto compare; + } + break; + case 630: + if (len == 4) + { + resword = &wordlist[212]; + goto compare; + } + break; + case 631: + if (len == 4) + { + resword = &wordlist[213]; + goto compare; + } + break; + case 632: + if (len == 4) + { + resword = &wordlist[214]; + goto compare; + } + break; + case 633: + if (len == 4) + { + resword = &wordlist[215]; + goto compare; + } + break; + case 635: + if (len == 4) + { + resword = &wordlist[216]; + goto compare; + } + break; + case 638: + if (len == 4) + { + resword = &wordlist[217]; + goto compare; + } + break; + case 640: + if (len == 3) + { + resword = &wordlist[218]; + goto compare; + } + break; + case 642: + if (len == 4) + { + resword = &wordlist[219]; + goto compare; + } + break; + case 643: + if (len == 6) + { + resword = &wordlist[220]; + goto compare; + } + break; + case 644: + if (len == 4) + { + resword = &wordlist[221]; + goto compare; + } + break; + case 645: + if (len == 4) + { + resword = &wordlist[222]; + goto compare; + } + break; + case 652: + if (len == 4) + { + resword = &wordlist[223]; + goto compare; + } + break; + case 654: + if (len == 5) + { + resword = &wordlist[224]; + goto compare; + } + break; + case 655: + if (len == 4) + { + resword = &wordlist[225]; + goto compare; + } + break; + case 657: + if (len == 4) + { + resword = &wordlist[226]; + goto compare; + } + break; + case 658: + if (len == 2) + { + resword = &wordlist[227]; + goto compare; + } + break; + case 659: + if (len == 4) + { + resword = &wordlist[228]; + goto compare; + } + break; + case 661: + if (len == 4) + { + resword = &wordlist[229]; + goto compare; + } + break; + case 662: + if (len == 4) + { + resword = &wordlist[230]; + goto compare; + } + break; + case 664: + if (len == 5) + { + resword = &wordlist[231]; + goto compare; + } + break; + case 665: + if (len == 4) + { + resword = &wordlist[232]; + goto compare; + } + break; + case 666: + if (len == 5) + { + resword = &wordlist[233]; + goto compare; + } + break; + case 667: + if (len == 4) + { + resword = &wordlist[234]; + goto compare; + } + break; + case 668: + if (len == 12) + { + resword = &wordlist[235]; + goto compare; + } + break; + case 669: + if (len == 4) + { + resword = &wordlist[236]; + goto compare; + } + break; + case 670: + if (len == 4) + { + resword = &wordlist[237]; + goto compare; + } + break; + case 673: + if (len == 14) + { + resword = &wordlist[238]; + goto compare; + } + break; + case 674: + if (len == 17) + { + resword = &wordlist[239]; + goto compare; + } + break; + case 676: + if (len == 4) + { + resword = &wordlist[240]; + goto compare; + } + break; + case 677: + if (len == 5) + { + resword = &wordlist[241]; + goto compare; + } + break; + case 679: + if (len == 19) + { + resword = &wordlist[242]; + goto compare; + } + break; + case 682: + if (len == 3) + { + resword = &wordlist[243]; + goto compare; + } + break; + case 686: + if (len == 5) + { + resword = &wordlist[244]; + goto compare; + } + break; + case 689: + if (len == 3) + { + resword = &wordlist[245]; + goto compare; + } + break; + case 693: + if (len == 6) + { + resword = &wordlist[246]; + goto compare; + } + break; + case 695: + if (len == 4) + { + resword = &wordlist[247]; + goto compare; + } + break; + case 697: + if (len == 6) + { + resword = &wordlist[248]; + goto compare; + } + break; + case 699: + if (len == 4) + { + resword = &wordlist[249]; + goto compare; + } + break; + case 702: + if (len == 5) + { + resword = &wordlist[250]; + goto compare; + } + break; + case 703: + if (len == 6) + { + resword = &wordlist[251]; + goto compare; + } + break; + case 704: + if (len == 5) + { + resword = &wordlist[252]; + goto compare; + } + break; + case 708: + if (len == 4) + { + resword = &wordlist[253]; + goto compare; + } + break; + case 709: + if (len == 3) + { + resword = &wordlist[254]; + goto compare; + } + break; + case 710: + if (len == 11) + { + resword = &wordlist[255]; + goto compare; + } + break; + case 713: + if (len == 4) + { + resword = &wordlist[256]; + goto compare; + } + break; + case 719: + if (len == 4) + { + resword = &wordlist[257]; + goto compare; + } + break; + case 721: + if (len == 6) + { + resword = &wordlist[258]; + goto compare; + } + break; + case 727: + if (len == 7) + { + resword = &wordlist[259]; + goto compare; + } + break; + case 728: + if (len == 5) + { + resword = &wordlist[260]; + goto compare; + } + break; + case 729: + if (len == 8) + { + resword = &wordlist[261]; + goto compare; + } + break; + case 732: + if (len == 5) + { + resword = &wordlist[262]; + goto compare; + } + break; + case 735: + if (len == 17) + { + resword = &wordlist[263]; + goto compare; + } + break; + case 737: + if (len == 2) + { + resword = &wordlist[264]; + goto compare; + } + break; + case 740: + if (len == 5) + { + resword = &wordlist[265]; + goto compare; + } + break; + case 742: + if (len == 5) + { + resword = &wordlist[266]; + goto compare; + } + break; + case 743: + if (len == 5) + { + resword = &wordlist[267]; + goto compare; + } + break; + case 747: + if (len == 4) + { + resword = &wordlist[268]; + goto compare; + } + break; + case 748: + if (len == 4) + { + resword = &wordlist[269]; + goto compare; + } + break; + case 751: + if (len == 4) + { + resword = &wordlist[270]; + goto compare; + } + break; + case 753: + if (len == 4) + { + resword = &wordlist[271]; + goto compare; + } + break; + case 754: + if (len == 12) + { + resword = &wordlist[272]; + goto compare; + } + break; + case 755: + if (len == 13) + { + resword = &wordlist[273]; + goto compare; + } + break; + case 758: + if (len == 5) + { + resword = &wordlist[274]; + goto compare; + } + break; + case 766: + if (len == 18) + { + resword = &wordlist[275]; + goto compare; + } + break; + case 768: + if (len == 6) + { + resword = &wordlist[276]; + goto compare; + } + break; + case 771: + if (len == 7) + { + resword = &wordlist[277]; + goto compare; + } + break; + case 772: + if (len == 5) + { + resword = &wordlist[278]; + goto compare; + } + break; + case 775: + if (len == 6) + { + resword = &wordlist[279]; + goto compare; + } + break; + case 776: + if (len == 4) + { + resword = &wordlist[280]; + goto compare; + } + break; + case 778: + if (len == 4) + { + resword = &wordlist[281]; + goto compare; + } + break; + case 785: + if (len == 4) + { + resword = &wordlist[282]; + goto compare; + } + break; + case 789: + if (len == 5) + { + resword = &wordlist[283]; + goto compare; + } + break; + case 791: + if (len == 8) + { + resword = &wordlist[284]; + goto compare; + } + break; + case 792: + if (len == 4) + { + resword = &wordlist[285]; + goto compare; + } + break; + case 799: + if (len == 4) + { + resword = &wordlist[286]; + goto compare; + } + break; + case 802: + if (len == 3) + { + resword = &wordlist[287]; + goto compare; + } + break; + case 804: + if (len == 12) + { + resword = &wordlist[288]; + goto compare; + } + break; + case 805: + if (len == 13) + { + resword = &wordlist[289]; + goto compare; + } + break; + case 807: + if (len == 5) + { + resword = &wordlist[290]; + goto compare; + } + break; + case 808: + if (len == 9) + { + resword = &wordlist[291]; + goto compare; + } + break; + case 809: + if (len == 5) + { + resword = &wordlist[292]; + goto compare; + } + break; + case 810: + if (len == 4) + { + resword = &wordlist[293]; + goto compare; + } + break; + case 811: + if (len == 6) + { + resword = &wordlist[294]; + goto compare; + } + break; + case 814: + if (len == 5) + { + resword = &wordlist[295]; + goto compare; + } + break; + case 815: + if (len == 6) + { + resword = &wordlist[296]; + goto compare; + } + break; + case 817: + if (len == 6) + { + resword = &wordlist[297]; + goto compare; + } + break; + case 833: + if (len == 2) + { + resword = &wordlist[298]; + goto compare; + } + break; + case 838: + if (len == 2) + { + resword = &wordlist[299]; + goto compare; + } + break; + case 843: + if (len == 4) + { + resword = &wordlist[300]; + goto compare; + } + break; + case 844: + if (len == 4) + { + resword = &wordlist[301]; + goto compare; + } + break; + case 853: + if (len == 3) + { + resword = &wordlist[302]; + goto compare; + } + break; + case 856: + if (len == 3) + { + resword = &wordlist[303]; + goto compare; + } + break; + case 861: + if (len == 3) + { + resword = &wordlist[304]; + goto compare; + } + break; + case 864: + if (len == 4) + { + resword = &wordlist[305]; + goto compare; + } + break; + case 876: + if (len == 4) + { + resword = &wordlist[306]; + goto compare; + } + break; + case 890: + if (len == 2) + { + resword = &wordlist[307]; + goto compare; + } + break; + case 896: + if (len == 6) + { + resword = &wordlist[308]; + goto compare; + } + break; + case 914: + if (len == 6) + { + resword = &wordlist[309]; + goto compare; + } + break; + case 919: + if (len == 8) + { + resword = &wordlist[310]; + goto compare; + } + break; + case 922: + if (len == 2) + { + resword = &wordlist[311]; + goto compare; + } + break; + case 923: + if (len == 4) + { + resword = &wordlist[312]; + goto compare; + } + break; + case 924: + if (len == 2) + { + resword = &wordlist[313]; + goto compare; + } + break; + case 925: + if (len == 6) + { + resword = &wordlist[314]; + goto compare; + } + break; + case 930: + if (len == 3) + { + resword = &wordlist[315]; + goto compare; + } + break; + case 936: + if (len == 6) + { + resword = &wordlist[316]; + goto compare; + } + break; + case 938: + if (len == 6) + { + resword = &wordlist[317]; + goto compare; + } + break; + case 941: + if (len == 2) + { + resword = &wordlist[318]; + goto compare; + } + break; + case 947: + if (len == 4) + { + resword = &wordlist[319]; + goto compare; + } + break; + case 948: + if (len == 4) + { + resword = &wordlist[320]; + goto compare; + } + break; + case 958: + if (len == 5) + { + resword = &wordlist[321]; + goto compare; + } + break; + case 963: + if (len == 7) + { + resword = &wordlist[322]; + goto compare; + } + break; + case 965: + if (len == 7) + { + resword = &wordlist[323]; + goto compare; + } + break; + case 972: + if (len == 10) + { + resword = &wordlist[324]; + goto compare; + } + break; + case 973: + if (len == 5) + { + resword = &wordlist[325]; + goto compare; + } + break; + case 975: + if (len == 2) + { + resword = &wordlist[326]; + goto compare; + } + break; + case 977: + if (len == 5) + { + resword = &wordlist[327]; + goto compare; + } + break; + case 978: + if (len == 9) + { + resword = &wordlist[328]; + goto compare; + } + break; + case 979: + if (len == 18) + { + resword = &wordlist[329]; + goto compare; + } + break; + case 987: + if (len == 5) + { + resword = &wordlist[330]; + goto compare; + } + break; + case 990: + if (len == 4) + { + resword = &wordlist[331]; + goto compare; + } + break; + case 992: + if (len == 4) + { + resword = &wordlist[332]; + goto compare; + } + break; + case 995: + if (len == 5) + { + resword = &wordlist[333]; + goto compare; + } + break; + case 998: + if (len == 5) + { + resword = &wordlist[334]; + goto compare; + } + break; + case 999: + if (len == 2) + { + resword = &wordlist[335]; + goto compare; + } + break; + case 1000: + if (len == 6) + { + resword = &wordlist[336]; + goto compare; + } + break; + case 1001: + if (len == 3) + { + resword = &wordlist[337]; + goto compare; + } + break; + case 1006: + if (len == 4) + { + resword = &wordlist[338]; + goto compare; + } + break; + case 1007: + if (len == 5) + { + resword = &wordlist[339]; + goto compare; + } + break; + case 1009: + if (len == 4) + { + resword = &wordlist[340]; + goto compare; + } + break; + case 1010: + if (len == 4) + { + resword = &wordlist[341]; + goto compare; + } + break; + case 1013: + if (len == 4) + { + resword = &wordlist[342]; + goto compare; + } + break; + case 1016: + if (len == 2) + { + resword = &wordlist[343]; + goto compare; + } + break; + case 1022: + if (len == 4) + { + resword = &wordlist[344]; + goto compare; + } + break; + case 1024: + if (len == 4) + { + resword = &wordlist[345]; + goto compare; + } + break; + case 1028: + if (len == 4) + { + resword = &wordlist[346]; + goto compare; + } + break; + case 1039: + if (len == 2) + { + resword = &wordlist[347]; + goto compare; + } + break; + case 1041: + if (len == 5) + { + resword = &wordlist[348]; + goto compare; + } + break; + case 1043: + if (len == 10) + { + resword = &wordlist[349]; + goto compare; + } + break; + case 1044: + if (len == 4) + { + resword = &wordlist[350]; + goto compare; + } + break; + case 1047: + if (len == 4) + { + resword = &wordlist[351]; + goto compare; + } + break; + case 1053: + if (len == 4) + { + resword = &wordlist[352]; + goto compare; + } + break; + case 1054: + if (len == 11) + { + resword = &wordlist[353]; + goto compare; + } + break; + case 1057: + if (len == 5) + { + resword = &wordlist[354]; + goto compare; + } + break; + case 1058: + if (len == 7) + { + resword = &wordlist[355]; + goto compare; + } + break; + case 1065: + if (len == 8) + { + resword = &wordlist[356]; + goto compare; + } + break; + case 1074: + if (len == 6) + { + resword = &wordlist[357]; + goto compare; + } + break; + case 1077: + if (len == 14) + { + resword = &wordlist[358]; + goto compare; + } + break; + case 1081: + if (len == 5) + { + resword = &wordlist[359]; + goto compare; + } + break; + case 1087: + if (len == 4) + { + resword = &wordlist[360]; + goto compare; + } + break; + case 1089: + if (len == 6) + { + resword = &wordlist[361]; + goto compare; + } + break; + case 1092: + if (len == 6) + { + resword = &wordlist[362]; + goto compare; + } + break; + case 1096: + if (len == 7) + { + resword = &wordlist[363]; + goto compare; + } + break; + case 1107: + if (len == 7) + { + resword = &wordlist[364]; + goto compare; + } + break; + case 1111: + if (len == 4) + { + resword = &wordlist[365]; + goto compare; + } + break; + case 1114: + if (len == 5) + { + resword = &wordlist[366]; + goto compare; + } + break; + case 1118: + if (len == 3) + { + resword = &wordlist[367]; + goto compare; + } + break; + case 1125: + if (len == 16) + { + resword = &wordlist[368]; + goto compare; + } + break; + case 1128: + if (len == 6) + { + resword = &wordlist[369]; + goto compare; + } + break; + case 1130: + if (len == 6) + { + resword = &wordlist[370]; + goto compare; + } + break; + case 1134: + if (len == 7) + { + resword = &wordlist[371]; + goto compare; + } + break; + case 1135: + if (len == 7) + { + resword = &wordlist[372]; + goto compare; + } + break; + case 1136: + if (len == 4) + { + resword = &wordlist[373]; + goto compare; + } + break; + case 1141: + if (len == 6) + { + resword = &wordlist[374]; + goto compare; + } + break; + case 1144: + if (len == 4) + { + resword = &wordlist[375]; + goto compare; + } + break; + case 1148: + if (len == 8) + { + resword = &wordlist[376]; + goto compare; + } + break; + case 1150: + if (len == 6) + { + resword = &wordlist[377]; + goto compare; + } + break; + case 1171: + if (len == 9) + { + resword = &wordlist[378]; + goto compare; + } + break; + case 1172: + if (len == 5) + { + resword = &wordlist[379]; + goto compare; + } + break; + case 1177: + if (len == 4) + { + resword = &wordlist[380]; + goto compare; + } + break; + case 1181: + if (len == 6) + { + resword = &wordlist[381]; + goto compare; + } + break; + case 1184: + if (len == 12) + { + resword = &wordlist[382]; + goto compare; + } + break; + case 1201: + if (len == 8) + { + resword = &wordlist[383]; + goto compare; + } + break; + case 1202: + if (len == 4) + { + resword = &wordlist[384]; + goto compare; + } + break; + case 1216: + if (len == 5) + { + resword = &wordlist[385]; + goto compare; + } + break; + case 1217: + if (len == 5) + { + resword = &wordlist[386]; + goto compare; + } + break; + case 1218: + if (len == 5) + { + resword = &wordlist[387]; + goto compare; + } + break; + case 1225: + if (len == 6) + { + resword = &wordlist[388]; + goto compare; + } + break; + case 1226: + if (len == 6) + { + resword = &wordlist[389]; + goto compare; + } + break; + case 1227: + if (len == 2) + { + resword = &wordlist[390]; + goto compare; + } + break; + case 1232: + if (len == 7) + { + resword = &wordlist[391]; + goto compare; + } + break; + case 1244: + if (len == 4) + { + resword = &wordlist[392]; + goto compare; + } + break; + case 1249: + if (len == 7) + { + resword = &wordlist[393]; + goto compare; + } + break; + case 1251: + if (len == 9) + { + resword = &wordlist[394]; + goto compare; + } + break; + case 1252: + if (len == 3) + { + resword = &wordlist[395]; + goto compare; + } + break; + case 1253: + if (len == 13) + { + resword = &wordlist[396]; + goto compare; + } + break; + case 1255: + if (len == 4) + { + resword = &wordlist[397]; + goto compare; + } + break; + case 1256: + if (len == 6) + { + resword = &wordlist[398]; + goto compare; + } + break; + case 1264: + if (len == 2) + { + resword = &wordlist[399]; + goto compare; + } + break; + case 1267: + if (len == 3) + { + resword = &wordlist[400]; + goto compare; + } + break; + case 1275: + if (len == 3) + { + resword = &wordlist[401]; + goto compare; + } + break; + case 1277: + if (len == 5) + { + resword = &wordlist[402]; + goto compare; + } + break; + case 1281: + if (len == 4) + { + resword = &wordlist[403]; + goto compare; + } + break; + case 1282: + if (len == 7) + { + resword = &wordlist[404]; + goto compare; + } + break; + case 1291: + if (len == 6) + { + resword = &wordlist[405]; + goto compare; + } + break; + case 1306: + if (len == 6) + { + resword = &wordlist[406]; + goto compare; + } + break; + case 1311: + if (len == 2) + { + resword = &wordlist[407]; + goto compare; + } + break; + case 1316: + if (len == 9) + { + resword = &wordlist[408]; + goto compare; + } + break; + case 1317: + if (len == 9) + { + resword = &wordlist[409]; + goto compare; + } + break; + case 1318: + if (len == 5) + { + resword = &wordlist[410]; + goto compare; + } + break; + case 1319: + if (len == 6) + { + resword = &wordlist[411]; + goto compare; + } + break; + case 1325: + if (len == 4) + { + resword = &wordlist[412]; + goto compare; + } + break; + case 1328: + if (len == 5) + { + resword = &wordlist[413]; + goto compare; + } + break; + case 1329: + if (len == 3) + { + resword = &wordlist[414]; + goto compare; + } + break; + case 1331: + if (len == 5) + { + resword = &wordlist[415]; + goto compare; + } + break; + case 1336: + if (len == 5) + { + resword = &wordlist[416]; + goto compare; + } + break; + case 1340: + if (len == 10) + { + resword = &wordlist[417]; + goto compare; + } + break; + case 1344: + if (len == 3) + { + resword = &wordlist[418]; + goto compare; + } + break; + case 1346: + if (len == 7) + { + resword = &wordlist[419]; + goto compare; + } + break; + case 1347: + if (len == 11) + { + resword = &wordlist[420]; + goto compare; + } + break; + case 1349: + if (len == 5) + { + resword = &wordlist[421]; + goto compare; + } + break; + case 1350: + if (len == 6) + { + resword = &wordlist[422]; + goto compare; + } + break; + case 1358: + if (len == 7) + { + resword = &wordlist[423]; + goto compare; + } + break; + case 1359: + if (len == 4) + { + resword = &wordlist[424]; + goto compare; + } + break; + case 1360: + if (len == 4) + { + resword = &wordlist[425]; + goto compare; + } + break; + case 1361: + if (len == 4) + { + resword = &wordlist[426]; + goto compare; + } + break; + case 1362: + if (len == 4) + { + resword = &wordlist[427]; + goto compare; + } + break; + case 1363: + if (len == 4) + { + resword = &wordlist[428]; + goto compare; + } + break; + case 1368: + if (len == 4) + { + resword = &wordlist[429]; + goto compare; + } + break; + case 1369: + if (len == 5) + { + resword = &wordlist[430]; + goto compare; + } + break; + case 1372: + if (len == 4) + { + resword = &wordlist[431]; + goto compare; + } + break; + case 1374: + if (len == 4) + { + resword = &wordlist[432]; + goto compare; + } + break; + case 1375: + if (len == 4) + { + resword = &wordlist[433]; + goto compare; + } + break; + case 1376: + if (len == 4) + { + resword = &wordlist[434]; + goto compare; + } + break; + case 1377: + if (len == 4) + { + resword = &wordlist[435]; + goto compare; + } + break; + case 1378: + if (len == 13) + { + resword = &wordlist[436]; + goto compare; + } + break; + case 1380: + if (len == 5) + { + resword = &wordlist[437]; + goto compare; + } + break; + case 1382: + if (len == 4) + { + resword = &wordlist[438]; + goto compare; + } + break; + case 1383: + if (len == 11) + { + resword = &wordlist[439]; + goto compare; + } + break; + case 1389: + if (len == 4) + { + resword = &wordlist[440]; + goto compare; + } + break; + case 1391: + if (len == 4) + { + resword = &wordlist[441]; + goto compare; + } + break; + case 1392: + if (len == 4) + { + resword = &wordlist[442]; + goto compare; + } + break; + case 1395: + if (len == 4) + { + resword = &wordlist[443]; + goto compare; + } + break; + case 1397: + if (len == 5) + { + resword = &wordlist[444]; + goto compare; + } + break; + case 1398: + if (len == 4) + { + resword = &wordlist[445]; + goto compare; + } + break; + case 1399: + if (len == 3) + { + resword = &wordlist[446]; + goto compare; + } + break; + case 1400: + if (len == 4) + { + resword = &wordlist[447]; + goto compare; + } + break; + case 1401: + if (len == 5) + { + resword = &wordlist[448]; + goto compare; + } + break; + case 1402: + if (len == 6) + { + resword = &wordlist[449]; + goto compare; + } + break; + case 1403: + if (len == 14) + { + resword = &wordlist[450]; + goto compare; + } + break; + case 1404: + if (len == 7) + { + resword = &wordlist[451]; + goto compare; + } + break; + case 1406: + if (len == 12) + { + resword = &wordlist[452]; + goto compare; + } + break; + case 1409: + if (len == 12) + { + resword = &wordlist[453]; + goto compare; + } + break; + case 1416: + if (len == 3) + { + resword = &wordlist[454]; + goto compare; + } + break; + case 1418: + if (len == 7) + { + resword = &wordlist[455]; + goto compare; + } + break; + case 1425: + if (len == 4) + { + resword = &wordlist[456]; + goto compare; + } + break; + case 1429: + if (len == 4) + { + resword = &wordlist[457]; + goto compare; + } + break; + case 1443: + if (len == 4) + { + resword = &wordlist[458]; + goto compare; + } + break; + case 1449: + if (len == 4) + { + resword = &wordlist[459]; + goto compare; + } + break; + case 1474: + if (len == 8) + { + resword = &wordlist[460]; + goto compare; + } + break; + case 1476: + if (len == 4) + { + resword = &wordlist[461]; + goto compare; + } + break; + case 1477: + if (len == 4) + { + resword = &wordlist[462]; + goto compare; + } + break; + case 1478: + if (len == 4) + { + resword = &wordlist[463]; + goto compare; + } + break; + case 1483: + if (len == 4) + { + resword = &wordlist[464]; + goto compare; + } + break; + case 1504: + if (len == 14) + { + resword = &wordlist[465]; + goto compare; + } + break; + case 1506: + if (len == 4) + { + resword = &wordlist[466]; + goto compare; + } + break; + case 1508: + if (len == 4) + { + resword = &wordlist[467]; + goto compare; + } + break; + case 1510: + if (len == 6) + { + resword = &wordlist[468]; + goto compare; + } + break; + case 1515: + if (len == 4) + { + resword = &wordlist[469]; + goto compare; + } + break; + case 1516: + if (len == 10) + { + resword = &wordlist[470]; + goto compare; + } + break; + case 1517: + if (len == 10) + { + resword = &wordlist[471]; + goto compare; + } + break; + case 1522: + if (len == 4) + { + resword = &wordlist[472]; + goto compare; + } + break; + case 1524: + if (len == 5) + { + resword = &wordlist[473]; + goto compare; + } + break; + case 1529: + if (len == 4) + { + resword = &wordlist[474]; + goto compare; + } + break; + case 1530: + if (len == 6) + { + resword = &wordlist[475]; + goto compare; + } + break; + case 1532: + if (len == 6) + { + resword = &wordlist[476]; + goto compare; + } + break; + case 1540: + if (len == 4) + { + resword = &wordlist[477]; + goto compare; + } + break; + case 1554: + if (len == 4) + { + resword = &wordlist[478]; + goto compare; + } + break; + case 1556: + if (len == 8) + { + resword = &wordlist[479]; + goto compare; + } + break; + case 1561: + if (len == 5) + { + resword = &wordlist[480]; + goto compare; + } + break; + case 1563: + if (len == 12) + { + resword = &wordlist[481]; + goto compare; + } + break; + case 1566: + if (len == 5) + { + resword = &wordlist[482]; + goto compare; + } + break; + case 1570: + if (len == 6) + { + resword = &wordlist[483]; + goto compare; + } + break; + case 1573: + if (len == 4) + { + resword = &wordlist[484]; + goto compare; + } + break; + case 1574: + if (len == 4) + { + resword = &wordlist[485]; + goto compare; + } + break; + case 1575: + if (len == 5) + { + resword = &wordlist[486]; + goto compare; + } + break; + case 1582: + if (len == 9) + { + resword = &wordlist[487]; + goto compare; + } + break; + case 1584: + if (len == 10) + { + resword = &wordlist[488]; + goto compare; + } + break; + case 1588: + if (len == 6) + { + resword = &wordlist[489]; + goto compare; + } + break; + case 1590: + if (len == 12) + { + resword = &wordlist[490]; + goto compare; + } + break; + case 1593: + if (len == 13) + { + resword = &wordlist[491]; + goto compare; + } + break; + case 1594: + if (len == 4) + { + resword = &wordlist[492]; + goto compare; + } + break; + case 1596: + if (len == 4) + { + resword = &wordlist[493]; + goto compare; + } + break; + case 1601: + if (len == 9) + { + resword = &wordlist[494]; + goto compare; + } + break; + case 1606: + if (len == 4) + { + resword = &wordlist[495]; + goto compare; + } + break; + case 1610: + if (len == 7) + { + resword = &wordlist[496]; + goto compare; + } + break; + case 1617: + if (len == 6) + { + resword = &wordlist[497]; + goto compare; + } + break; + case 1618: + if (len == 5) + { + resword = &wordlist[498]; + goto compare; + } + break; + case 1619: + if (len == 4) + { + resword = &wordlist[499]; + goto compare; + } + break; + case 1620: + if (len == 3) + { + resword = &wordlist[500]; + goto compare; + } + break; + case 1646: + if (len == 5) + { + resword = &wordlist[501]; + goto compare; + } + break; + case 1647: + if (len == 7) + { + resword = &wordlist[502]; + goto compare; + } + break; + case 1649: + if (len == 7) + { + resword = &wordlist[503]; + goto compare; + } + break; + case 1651: + if (len == 6) + { + resword = &wordlist[504]; + goto compare; + } + break; + case 1659: + if (len == 13) + { + resword = &wordlist[505]; + goto compare; + } + break; + case 1660: + if (len == 6) + { + resword = &wordlist[506]; + goto compare; + } + break; + case 1665: + if (len == 9) + { + resword = &wordlist[507]; + goto compare; + } + break; + case 1666: + if (len == 15) + { + resword = &wordlist[508]; + goto compare; + } + break; + case 1667: + if (len == 3) + { + resword = &wordlist[509]; + goto compare; + } + break; + case 1669: + if (len == 4) + { + resword = &wordlist[510]; + goto compare; + } + break; + case 1672: + if (len == 4) + { + resword = &wordlist[511]; + goto compare; + } + break; + case 1674: + if (len == 3) + { + resword = &wordlist[512]; + goto compare; + } + break; + case 1677: + if (len == 4) + { + resword = &wordlist[513]; + goto compare; + } + break; + case 1680: + if (len == 6) + { + resword = &wordlist[514]; + goto compare; + } + break; + case 1686: + if (len == 7) + { + resword = &wordlist[515]; + goto compare; + } + break; + case 1688: + if (len == 5) + { + resword = &wordlist[516]; + goto compare; + } + break; + case 1717: + if (len == 4) + { + resword = &wordlist[517]; + goto compare; + } + break; + case 1718: + if (len == 6) + { + resword = &wordlist[518]; + goto compare; + } + break; + case 1727: + if (len == 3) + { + resword = &wordlist[519]; + goto compare; + } + break; + case 1731: + if (len == 3) + { + resword = &wordlist[520]; + goto compare; + } + break; + case 1732: + if (len == 3) + { + resword = &wordlist[521]; + goto compare; + } + break; + case 1733: + if (len == 3) + { + resword = &wordlist[522]; + goto compare; + } + break; + case 1734: + if (len == 3) + { + resword = &wordlist[523]; + goto compare; + } + break; + case 1735: + if (len == 3) + { + resword = &wordlist[524]; + goto compare; + } + break; + case 1736: + if (len == 4) + { + resword = &wordlist[525]; + goto compare; + } + break; + case 1738: + if (len == 4) + { + resword = &wordlist[526]; + goto compare; + } + break; + case 1739: + if (len == 4) + { + resword = &wordlist[527]; + goto compare; + } + break; + case 1740: + if (len == 3) + { + resword = &wordlist[528]; + goto compare; + } + break; + case 1743: + if (len == 4) + { + resword = &wordlist[529]; + goto compare; + } + break; + case 1744: + if (len == 3) + { + resword = &wordlist[530]; + goto compare; + } + break; + case 1746: + if (len == 3) + { + resword = &wordlist[531]; + goto compare; + } + break; + case 1747: + if (len == 3) + { + resword = &wordlist[532]; + goto compare; + } + break; + case 1748: + if (len == 4) + { + resword = &wordlist[533]; + goto compare; + } + break; + case 1754: + if (len == 3) + { + resword = &wordlist[534]; + goto compare; + } + break; + case 1758: + if (len == 4) + { + resword = &wordlist[535]; + goto compare; + } + break; + case 1761: + if (len == 3) + { + resword = &wordlist[536]; + goto compare; + } + break; + case 1763: + if (len == 3) + { + resword = &wordlist[537]; + goto compare; + } + break; + case 1764: + if (len == 3) + { + resword = &wordlist[538]; + goto compare; + } + break; + case 1767: + if (len == 3) + { + resword = &wordlist[539]; + goto compare; + } + break; + case 1769: + if (len == 6) + { + resword = &wordlist[540]; + goto compare; + } + break; + case 1772: + if (len == 3) + { + resword = &wordlist[541]; + goto compare; + } + break; + case 1775: + if (len == 5) + { + resword = &wordlist[542]; + goto compare; + } + break; + case 1777: + if (len == 9) + { + resword = &wordlist[543]; + goto compare; + } + break; + case 1795: + if (len == 6) + { + resword = &wordlist[544]; + goto compare; + } + break; + case 1797: + if (len == 3) + { + resword = &wordlist[545]; + goto compare; + } + break; + case 1801: + if (len == 3) + { + resword = &wordlist[546]; + goto compare; + } + break; + case 1805: + if (len == 7) + { + resword = &wordlist[547]; + goto compare; + } + break; + case 1815: + if (len == 3) + { + resword = &wordlist[548]; + goto compare; + } + break; + case 1819: + if (len == 5) + { + resword = &wordlist[549]; + goto compare; + } + break; + case 1820: + if (len == 9) + { + resword = &wordlist[550]; + goto compare; + } + break; + case 1821: + if (len == 3) + { + resword = &wordlist[551]; + goto compare; + } + break; + case 1840: + if (len == 3) + { + resword = &wordlist[552]; + goto compare; + } + break; + case 1844: + if (len == 4) + { + resword = &wordlist[553]; + goto compare; + } + break; + case 1849: + if (len == 3) + { + resword = &wordlist[554]; + goto compare; + } + break; + case 1850: + if (len == 3) + { + resword = &wordlist[555]; + goto compare; + } + break; + case 1852: + if (len == 18) + { + resword = &wordlist[556]; + goto compare; + } + break; + case 1853: + if (len == 15) + { + resword = &wordlist[557]; + goto compare; + } + break; + case 1855: + if (len == 3) + { + resword = &wordlist[558]; + goto compare; + } + break; + case 1856: + if (len == 20) + { + resword = &wordlist[559]; + goto compare; + } + break; + case 1862: + if (len == 4) + { + resword = &wordlist[560]; + goto compare; + } + break; + case 1869: + if (len == 15) + { + resword = &wordlist[561]; + goto compare; + } + break; + case 1878: + if (len == 3) + { + resword = &wordlist[562]; + goto compare; + } + break; + case 1880: + if (len == 3) + { + resword = &wordlist[563]; + goto compare; + } + break; + case 1887: + if (len == 3) + { + resword = &wordlist[564]; + goto compare; + } + break; + case 1890: + if (len == 6) + { + resword = &wordlist[565]; + goto compare; + } + break; + case 1893: + if (len == 3) + { + resword = &wordlist[566]; + goto compare; + } + break; + case 1894: + if (len == 3) + { + resword = &wordlist[567]; + goto compare; + } + break; + case 1895: + if (len == 2) + { + resword = &wordlist[568]; + goto compare; + } + break; + case 1901: + if (len == 3) + { + resword = &wordlist[569]; + goto compare; + } + break; + case 1908: + if (len == 6) + { + resword = &wordlist[570]; + goto compare; + } + break; + case 1911: + if (len == 9) + { + resword = &wordlist[571]; + goto compare; + } + break; + case 1912: + if (len == 3) + { + resword = &wordlist[572]; + goto compare; + } + break; + case 1916: + if (len == 11) + { + resword = &wordlist[573]; + goto compare; + } + break; + case 1919: + if (len == 6) + { + resword = &wordlist[574]; + goto compare; + } + break; + case 1920: + if (len == 15) + { + resword = &wordlist[575]; + goto compare; + } + break; + case 1925: + if (len == 6) + { + resword = &wordlist[576]; + goto compare; + } + break; + case 1927: + if (len == 6) + { + resword = &wordlist[577]; + goto compare; + } + break; + case 1929: + if (len == 6) + { + resword = &wordlist[578]; + goto compare; + } + break; + case 1931: + if (len == 7) + { + resword = &wordlist[579]; + goto compare; + } + break; + case 1935: + if (len == 7) + { + resword = &wordlist[580]; + goto compare; + } + break; + case 1940: + if (len == 7) + { + resword = &wordlist[581]; + goto compare; + } + break; + case 1945: + if (len == 3) + { + resword = &wordlist[582]; + goto compare; + } + break; + case 1946: + if (len == 3) + { + resword = &wordlist[583]; + goto compare; + } + break; + case 1948: + if (len == 11) + { + resword = &wordlist[584]; + goto compare; + } + break; + case 1950: + if (len == 4) + { + resword = &wordlist[585]; + goto compare; + } + break; + case 1953: + if (len == 4) + { + resword = &wordlist[586]; + goto compare; + } + break; + case 1956: + if (len == 5) + { + resword = &wordlist[587]; + goto compare; + } + break; + case 1957: + if (len == 5) + { + resword = &wordlist[588]; + goto compare; + } + break; + case 1963: + if (len == 4) + { + resword = &wordlist[589]; + goto compare; + } + break; + case 1966: + if (len == 3) + { + resword = &wordlist[590]; + goto compare; + } + break; + case 1969: + if (len == 4) + { + resword = &wordlist[591]; + goto compare; + } + break; + case 1971: + if (len == 4) + { + resword = &wordlist[592]; + goto compare; + } + break; + case 1974: + if (len == 3) + { + resword = &wordlist[593]; + goto compare; + } + break; + case 1977: + if (len == 3) + { + resword = &wordlist[594]; + goto compare; + } + break; + case 1978: + if (len == 3) + { + resword = &wordlist[595]; + goto compare; + } + break; + case 1985: + if (len == 4) + { + resword = &wordlist[596]; + goto compare; + } + break; + case 1987: + if (len == 7) + { + resword = &wordlist[597]; + goto compare; + } + break; + case 1994: + if (len == 7) + { + resword = &wordlist[598]; + goto compare; + } + break; + case 1998: + if (len == 4) + { + resword = &wordlist[599]; + goto compare; + } + break; + case 2003: + if (len == 5) + { + resword = &wordlist[600]; + goto compare; + } + break; + case 2006: + if (len == 7) + { + resword = &wordlist[601]; + goto compare; + } + break; + case 2011: + if (len == 4) + { + resword = &wordlist[602]; + goto compare; + } + break; + case 2014: + if (len == 5) + { + resword = &wordlist[603]; + goto compare; + } + break; + case 2020: + if (len == 6) + { + resword = &wordlist[604]; + goto compare; + } + break; + case 2021: + if (len == 6) + { + resword = &wordlist[605]; + goto compare; + } + break; + case 2022: + if (len == 6) + { + resword = &wordlist[606]; + goto compare; + } + break; + case 2023: + if (len == 6) + { + resword = &wordlist[607]; + goto compare; + } + break; + case 2024: + if (len == 6) + { + resword = &wordlist[608]; + goto compare; + } + break; + case 2028: + if (len == 6) + { + resword = &wordlist[609]; + goto compare; + } + break; + case 2029: + if (len == 7) + { + resword = &wordlist[610]; + goto compare; + } + break; + case 2031: + if (len == 4) + { + resword = &wordlist[611]; + goto compare; + } + break; + case 2033: + if (len == 6) + { + resword = &wordlist[612]; + goto compare; + } + break; + case 2036: + if (len == 7) + { + resword = &wordlist[613]; + goto compare; + } + break; + case 2040: + if (len == 8) + { + resword = &wordlist[614]; + goto compare; + } + break; + case 2041: + if (len == 3) + { + resword = &wordlist[615]; + goto compare; + } + break; + case 2042: + if (len == 6) + { + resword = &wordlist[616]; + goto compare; + } + break; + case 2043: + if (len == 6) + { + resword = &wordlist[617]; + goto compare; + } + break; + case 2044: + if (len == 7) + { + resword = &wordlist[618]; + goto compare; + } + break; + case 2049: + if (len == 3) + { + resword = &wordlist[619]; + goto compare; + } + break; + case 2053: + if (len == 6) + { + resword = &wordlist[620]; + goto compare; + } + break; + case 2056: + if (len == 14) + { + resword = &wordlist[621]; + goto compare; + } + break; + case 2059: + if (len == 5) + { + resword = &wordlist[622]; + goto compare; + } + break; + case 2061: + if (len == 6) + { + resword = &wordlist[623]; + goto compare; + } + break; + case 2063: + if (len == 3) + { + resword = &wordlist[624]; + goto compare; + } + break; + case 2066: + if (len == 11) + { + resword = &wordlist[625]; + goto compare; + } + break; + case 2072: + if (len == 8) + { + resword = &wordlist[626]; + goto compare; + } + break; + case 2081: + if (len == 9) + { + resword = &wordlist[627]; + goto compare; + } + break; + case 2090: + if (len == 4) + { + resword = &wordlist[628]; + goto compare; + } + break; + case 2094: + if (len == 6) + { + resword = &wordlist[629]; + goto compare; + } + break; + case 2097: + if (len == 3) + { + resword = &wordlist[630]; + goto compare; + } + break; + case 2100: + if (len == 6) + { + resword = &wordlist[631]; + goto compare; + } + break; + case 2102: + if (len == 6) + { + resword = &wordlist[632]; + goto compare; + } + break; + case 2108: + if (len == 3) + { + resword = &wordlist[633]; + goto compare; + } + break; + case 2110: + if (len == 5) + { + resword = &wordlist[634]; + goto compare; + } + break; + case 2111: + if (len == 3) + { + resword = &wordlist[635]; + goto compare; + } + break; + case 2113: + if (len == 5) + { + resword = &wordlist[636]; + goto compare; + } + break; + case 2114: + if (len == 3) + { + resword = &wordlist[637]; + goto compare; + } + break; + case 2126: + if (len == 7) + { + resword = &wordlist[638]; + goto compare; + } + break; + case 2130: + if (len == 3) + { + resword = &wordlist[639]; + goto compare; + } + break; + case 2131: + if (len == 6) + { + resword = &wordlist[640]; + goto compare; + } + break; + case 2141: + if (len == 6) + { + resword = &wordlist[641]; + goto compare; + } + break; + case 2149: + if (len == 2) + { + resword = &wordlist[642]; + goto compare; + } + break; + case 2153: + if (len == 6) + { + resword = &wordlist[643]; + goto compare; + } + break; + case 2154: + if (len == 2) + { + resword = &wordlist[644]; + goto compare; + } + break; + case 2156: + if (len == 6) + { + resword = &wordlist[645]; + goto compare; + } + break; + case 2166: + if (len == 7) + { + resword = &wordlist[646]; + goto compare; + } + break; + case 2167: + if (len == 6) + { + resword = &wordlist[647]; + goto compare; + } + break; + case 2168: + if (len == 3) + { + resword = &wordlist[648]; + goto compare; + } + break; + case 2169: + if (len == 6) + { + resword = &wordlist[649]; + goto compare; + } + break; + case 2170: + if (len == 5) + { + resword = &wordlist[650]; + goto compare; + } + break; + case 2171: + if (len == 4) + { + resword = &wordlist[651]; + goto compare; + } + break; + case 2177: + if (len == 5) + { + resword = &wordlist[652]; + goto compare; + } + break; + case 2178: + if (len == 5) + { + resword = &wordlist[653]; + goto compare; + } + break; + case 2181: + if (len == 5) + { + resword = &wordlist[654]; + goto compare; + } + break; + case 2182: + if (len == 6) + { + resword = &wordlist[655]; + goto compare; + } + break; + case 2183: + if (len == 6) + { + resword = &wordlist[656]; + goto compare; + } + break; + case 2184: + if (len == 6) + { + resword = &wordlist[657]; + goto compare; + } + break; + case 2188: + if (len == 5) + { + resword = &wordlist[658]; + goto compare; + } + break; + case 2190: + if (len == 5) + { + resword = &wordlist[659]; + goto compare; + } + break; + case 2191: + if (len == 4) + { + resword = &wordlist[660]; + goto compare; + } + break; + case 2195: + if (len == 5) + { + resword = &wordlist[661]; + goto compare; + } + break; + case 2199: + if (len == 5) + { + resword = &wordlist[662]; + goto compare; + } + break; + case 2204: + if (len == 10) + { + resword = &wordlist[663]; + goto compare; + } + break; + case 2206: + if (len == 4) + { + resword = &wordlist[664]; + goto compare; + } + break; + case 2213: + if (len == 14) + { + resword = &wordlist[665]; + goto compare; + } + break; + case 2219: + if (len == 7) + { + resword = &wordlist[666]; + goto compare; + } + break; + case 2221: + if (len == 13) + { + resword = &wordlist[667]; + goto compare; + } + break; + case 2225: + if (len == 20) + { + resword = &wordlist[668]; + goto compare; + } + break; + case 2226: + if (len == 8) + { + resword = &wordlist[669]; + goto compare; + } + break; + case 2227: + if (len == 4) + { + resword = &wordlist[670]; + goto compare; + } + break; + case 2231: + if (len == 3) + { + resword = &wordlist[671]; + goto compare; + } + break; + case 2236: + if (len == 6) + { + resword = &wordlist[672]; + goto compare; + } + break; + case 2242: + if (len == 6) + { + resword = &wordlist[673]; + goto compare; + } + break; + case 2249: + if (len == 8) + { + resword = &wordlist[674]; + goto compare; + } + break; + case 2252: + if (len == 5) + { + resword = &wordlist[675]; + goto compare; + } + break; + case 2255: + if (len == 8) + { + resword = &wordlist[676]; + goto compare; + } + break; + case 2259: + if (len == 5) + { + resword = &wordlist[677]; + goto compare; + } + break; + case 2267: + if (len == 6) + { + resword = &wordlist[678]; + goto compare; + } + break; + case 2269: + if (len == 4) + { + resword = &wordlist[679]; + goto compare; + } + break; + case 2270: + if (len == 5) + { + resword = &wordlist[680]; + goto compare; + } + break; + case 2277: + if (len == 15) + { + resword = &wordlist[681]; + goto compare; + } + break; + case 2281: + if (len == 6) + { + resword = &wordlist[682]; + goto compare; + } + break; + case 2288: + if (len == 8) + { + resword = &wordlist[683]; + goto compare; + } + break; + case 2290: + if (len == 5) + { + resword = &wordlist[684]; + goto compare; + } + break; + case 2292: + if (len == 6) + { + resword = &wordlist[685]; + goto compare; + } + break; + case 2296: + if (len == 14) + { + resword = &wordlist[686]; + goto compare; + } + break; + case 2306: + if (len == 5) + { + resword = &wordlist[687]; + goto compare; + } + break; + case 2315: + if (len == 10) + { + resword = &wordlist[688]; + goto compare; + } + break; + case 2318: + if (len == 20) + { + resword = &wordlist[689]; + goto compare; + } + break; + case 2320: + if (len == 7) + { + resword = &wordlist[690]; + goto compare; + } + break; + case 2323: + if (len == 7) + { + resword = &wordlist[691]; + goto compare; + } + break; + case 2326: + if (len == 4) + { + resword = &wordlist[692]; + goto compare; + } + break; + case 2334: + if (len == 3) + { + resword = &wordlist[693]; + goto compare; + } + break; + case 2339: + if (len == 15) + { + resword = &wordlist[694]; + goto compare; + } + break; + case 2345: + if (len == 3) + { + resword = &wordlist[695]; + goto compare; + } + break; + case 2349: + if (len == 4) + { + resword = &wordlist[696]; + goto compare; + } + break; + case 2351: + if (len == 21) + { + resword = &wordlist[697]; + goto compare; + } + break; + case 2354: + if (len == 6) + { + resword = &wordlist[698]; + goto compare; + } + break; + case 2355: + if (len == 6) + { + resword = &wordlist[699]; + goto compare; + } + break; + case 2357: + if (len == 3) + { + resword = &wordlist[700]; + goto compare; + } + break; + case 2359: + if (len == 23) + { + resword = &wordlist[701]; + goto compare; + } + break; + case 2365: + if (len == 4) + { + resword = &wordlist[702]; + goto compare; + } + break; + case 2368: + if (len == 7) + { + resword = &wordlist[703]; + goto compare; + } + break; + case 2370: + if (len == 9) + { + resword = &wordlist[704]; + goto compare; + } + break; + case 2371: + if (len == 5) + { + resword = &wordlist[705]; + goto compare; + } + break; + case 2373: + if (len == 4) + { + resword = &wordlist[706]; + goto compare; + } + break; + case 2383: + if (len == 3) + { + resword = &wordlist[707]; + goto compare; + } + break; + case 2388: + if (len == 10) + { + resword = &wordlist[708]; + goto compare; + } + break; + case 2389: + if (len == 6) + { + resword = &wordlist[709]; + goto compare; + } + break; + case 2396: + if (len == 8) + { + resword = &wordlist[710]; + goto compare; + } + break; + case 2400: + if (len == 6) + { + resword = &wordlist[711]; + goto compare; + } + break; + case 2401: + if (len == 14) + { + resword = &wordlist[712]; + goto compare; + } + break; + case 2402: + if (len == 6) + { + resword = &wordlist[713]; + goto compare; + } + break; + case 2403: + if (len == 6) + { + resword = &wordlist[714]; + goto compare; + } + break; + case 2405: + if (len == 10) + { + resword = &wordlist[715]; + goto compare; + } + break; + case 2409: + if (len == 5) + { + resword = &wordlist[716]; + goto compare; + } + break; + case 2418: + if (len == 7) + { + resword = &wordlist[717]; + goto compare; + } + break; + case 2419: + if (len == 6) + { + resword = &wordlist[718]; + goto compare; + } + break; + case 2424: + if (len == 11) + { + resword = &wordlist[719]; + goto compare; + } + break; + case 2430: + if (len == 6) + { + resword = &wordlist[720]; + goto compare; + } + break; + case 2432: + if (len == 5) + { + resword = &wordlist[721]; + goto compare; + } + break; + case 2436: + if (len == 4) + { + resword = &wordlist[722]; + goto compare; + } + break; + case 2438: + if (len == 12) + { + resword = &wordlist[723]; + goto compare; + } + break; + case 2439: + if (len == 4) + { + resword = &wordlist[724]; + goto compare; + } + break; + case 2441: + if (len == 4) + { + resword = &wordlist[725]; + goto compare; + } + break; + case 2456: + if (len == 8) + { + resword = &wordlist[726]; + goto compare; + } + break; + case 2457: + if (len == 4) + { + resword = &wordlist[727]; + goto compare; + } + break; + case 2458: + if (len == 5) + { + resword = &wordlist[728]; + goto compare; + } + break; + case 2461: + if (len == 4) + { + resword = &wordlist[729]; + goto compare; + } + break; + case 2463: + if (len == 12) + { + resword = &wordlist[730]; + goto compare; + } + break; + case 2468: + if (len == 4) + { + resword = &wordlist[731]; + goto compare; + } + break; + case 2470: + if (len == 5) + { + resword = &wordlist[732]; + goto compare; + } + break; + case 2476: + if (len == 5) + { + resword = &wordlist[733]; + goto compare; + } + break; + case 2477: + if (len == 6) + { + resword = &wordlist[734]; + goto compare; + } + break; + case 2479: + if (len == 6) + { + resword = &wordlist[735]; + goto compare; + } + break; + case 2480: + if (len == 13) + { + resword = &wordlist[736]; + goto compare; + } + break; + case 2484: + if (len == 6) + { + resword = &wordlist[737]; + goto compare; + } + break; + case 2486: + if (len == 6) + { + resword = &wordlist[738]; + goto compare; + } + break; + case 2491: + if (len == 4) + { + resword = &wordlist[739]; + goto compare; + } + break; + case 2510: + if (len == 17) + { + resword = &wordlist[740]; + goto compare; + } + break; + case 2515: + if (len == 6) + { + resword = &wordlist[741]; + goto compare; + } + break; + case 2526: + if (len == 5) + { + resword = &wordlist[742]; + goto compare; + } + break; + case 2529: + if (len == 5) + { + resword = &wordlist[743]; + goto compare; + } + break; + case 2533: + if (len == 7) + { + resword = &wordlist[744]; + goto compare; + } + break; + case 2539: + if (len == 4) + { + resword = &wordlist[745]; + goto compare; + } + break; + case 2548: + if (len == 6) + { + resword = &wordlist[746]; + goto compare; + } + break; + case 2558: + if (len == 6) + { + resword = &wordlist[747]; + goto compare; + } + break; + case 2569: + if (len == 4) + { + resword = &wordlist[748]; + goto compare; + } + break; + case 2571: + if (len == 14) + { + resword = &wordlist[749]; + goto compare; + } + break; + case 2574: + if (len == 4) + { + resword = &wordlist[750]; + goto compare; + } + break; + case 2578: + if (len == 3) + { + resword = &wordlist[751]; + goto compare; + } + break; + case 2583: + if (len == 7) + { + resword = &wordlist[752]; + goto compare; + } + break; + case 2587: + if (len == 6) + { + resword = &wordlist[753]; + goto compare; + } + break; + case 2592: + if (len == 3) + { + resword = &wordlist[754]; + goto compare; + } + break; + case 2594: + if (len == 10) + { + resword = &wordlist[755]; + goto compare; + } + break; + case 2597: + if (len == 2) + { + resword = &wordlist[756]; + goto compare; + } + break; + case 2599: + if (len == 11) + { + resword = &wordlist[757]; + goto compare; + } + break; + case 2603: + if (len == 15) + { + resword = &wordlist[758]; + goto compare; + } + break; + case 2606: + if (len == 10) + { + resword = &wordlist[759]; + goto compare; + } + break; + case 2613: + if (len == 6) + { + resword = &wordlist[760]; + goto compare; + } + break; + case 2617: + if (len == 4) + { + resword = &wordlist[761]; + goto compare; + } + break; + case 2619: + if (len == 14) + { + resword = &wordlist[762]; + goto compare; + } + break; + case 2621: + if (len == 8) + { + resword = &wordlist[763]; + goto compare; + } + break; + case 2622: + if (len == 12) + { + resword = &wordlist[764]; + goto compare; + } + break; + case 2625: + if (len == 12) + { + resword = &wordlist[765]; + goto compare; + } + break; + case 2630: + if (len == 16) + { + resword = &wordlist[766]; + goto compare; + } + break; + case 2633: + if (len == 4) + { + resword = &wordlist[767]; + goto compare; + } + break; + case 2634: + if (len == 9) + { + resword = &wordlist[768]; + goto compare; + } + break; + case 2636: + if (len == 5) + { + resword = &wordlist[769]; + goto compare; + } + break; + case 2638: + if (len == 5) + { + resword = &wordlist[770]; + goto compare; + } + break; + case 2640: + if (len == 5) + { + resword = &wordlist[771]; + goto compare; + } + break; + case 2655: + if (len == 9) + { + resword = &wordlist[772]; + goto compare; + } + break; + case 2657: + if (len == 5) + { + resword = &wordlist[773]; + goto compare; + } + break; + case 2659: + if (len == 5) + { + resword = &wordlist[774]; + goto compare; + } + break; + case 2662: + if (len == 20) + { + resword = &wordlist[775]; + goto compare; + } + break; + case 2671: + if (len == 8) + { + resword = &wordlist[776]; + goto compare; + } + break; + case 2672: + if (len == 6) + { + resword = &wordlist[777]; + goto compare; + } + break; + case 2675: + if (len == 6) + { + resword = &wordlist[778]; + goto compare; + } + break; + case 2683: + if (len == 5) + { + resword = &wordlist[779]; + goto compare; + } + break; + case 2685: + if (len == 6) + { + resword = &wordlist[780]; + goto compare; + } + break; + case 2691: + if (len == 4) + { + resword = &wordlist[781]; + goto compare; + } + break; + case 2698: + if (len == 3) + { + resword = &wordlist[782]; + goto compare; + } + break; + case 2699: + if (len == 6) + { + resword = &wordlist[783]; + goto compare; + } + break; + case 2713: + if (len == 3) + { + resword = &wordlist[784]; + goto compare; + } + break; + case 2715: + if (len == 7) + { + resword = &wordlist[785]; + goto compare; + } + break; + case 2716: + if (len == 3) + { + resword = &wordlist[786]; + goto compare; + } + break; + case 2721: + if (len == 3) + { + resword = &wordlist[787]; + goto compare; + } + break; + case 2737: + if (len == 5) + { + resword = &wordlist[788]; + goto compare; + } + break; + case 2744: + if (len == 6) + { + resword = &wordlist[789]; + goto compare; + } + break; + case 2746: + if (len == 5) + { + resword = &wordlist[790]; + goto compare; + } + break; + case 2756: + if (len == 11) + { + resword = &wordlist[791]; + goto compare; + } + break; + case 2762: + if (len == 6) + { + resword = &wordlist[792]; + goto compare; + } + break; + case 2765: + if (len == 3) + { + resword = &wordlist[793]; + goto compare; + } + break; + case 2770: + if (len == 5) + { + resword = &wordlist[794]; + goto compare; + } + break; + case 2775: + if (len == 6) + { + resword = &wordlist[795]; + goto compare; + } + break; + case 2779: + if (len == 3) + { + resword = &wordlist[796]; + goto compare; + } + break; + case 2783: + if (len == 5) + { + resword = &wordlist[797]; + goto compare; + } + break; + case 2789: + if (len == 4) + { + resword = &wordlist[798]; + goto compare; + } + break; + case 2792: + if (len == 3) + { + resword = &wordlist[799]; + goto compare; + } + break; + case 2806: + if (len == 6) + { + resword = &wordlist[800]; + goto compare; + } + break; + case 2808: + if (len == 4) + { + resword = &wordlist[801]; + goto compare; + } + break; + case 2809: + if (len == 7) + { + resword = &wordlist[802]; + goto compare; + } + break; + case 2810: + if (len == 6) + { + resword = &wordlist[803]; + goto compare; + } + break; + case 2811: + if (len == 7) + { + resword = &wordlist[804]; + goto compare; + } + break; + case 2813: + if (len == 4) + { + resword = &wordlist[805]; + goto compare; + } + break; + case 2816: + if (len == 6) + { + resword = &wordlist[806]; + goto compare; + } + break; + case 2828: + if (len == 11) + { + resword = &wordlist[807]; + goto compare; + } + break; + case 2830: + if (len == 6) + { + resword = &wordlist[808]; + goto compare; + } + break; + case 2832: + if (len == 6) + { + resword = &wordlist[809]; + goto compare; + } + break; + case 2838: + if (len == 3) + { + resword = &wordlist[810]; + goto compare; + } + break; + case 2840: + if (len == 3) + { + resword = &wordlist[811]; + goto compare; + } + break; + case 2842: + if (len == 7) + { + resword = &wordlist[812]; + goto compare; + } + break; + case 2844: + if (len == 9) + { + resword = &wordlist[813]; + goto compare; + } + break; + case 2847: + if (len == 5) + { + resword = &wordlist[814]; + goto compare; + } + break; + case 2854: + if (len == 3) + { + resword = &wordlist[815]; + goto compare; + } + break; + case 2863: + if (len == 5) + { + resword = &wordlist[816]; + goto compare; + } + break; + case 2867: + if (len == 6) + { + resword = &wordlist[817]; + goto compare; + } + break; + case 2872: + if (len == 6) + { + resword = &wordlist[818]; + goto compare; + } + break; + case 2878: + if (len == 4) + { + resword = &wordlist[819]; + goto compare; + } + break; + case 2881: + if (len == 8) + { + resword = &wordlist[820]; + goto compare; + } + break; + case 2883: + if (len == 7) + { + resword = &wordlist[821]; + goto compare; + } + break; + case 2885: + if (len == 4) + { + resword = &wordlist[822]; + goto compare; + } + break; + case 2888: + if (len == 10) + { + resword = &wordlist[823]; + goto compare; + } + break; + case 2889: + if (len == 6) + { + resword = &wordlist[824]; + goto compare; + } + break; + case 2899: + if (len == 8) + { + resword = &wordlist[825]; + goto compare; + } + break; + case 2901: + if (len == 5) + { + resword = &wordlist[826]; + goto compare; + } + break; + case 2903: + if (len == 5) + { + resword = &wordlist[827]; + goto compare; + } + break; + case 2913: + if (len == 6) + { + resword = &wordlist[828]; + goto compare; + } + break; + case 2915: + if (len == 11) + { + resword = &wordlist[829]; + goto compare; + } + break; + case 2929: + if (len == 5) + { + resword = &wordlist[830]; + goto compare; + } + break; + case 2940: + if (len == 5) + { + resword = &wordlist[831]; + goto compare; + } + break; + case 2941: + if (len == 5) + { + resword = &wordlist[832]; + goto compare; + } + break; + case 2943: + if (len == 5) + { + resword = &wordlist[833]; + goto compare; + } + break; + case 2944: + if (len == 5) + { + resword = &wordlist[834]; + goto compare; + } + break; + case 2946: + if (len == 3) + { + resword = &wordlist[835]; + goto compare; + } + break; + case 2954: + if (len == 9) + { + resword = &wordlist[836]; + goto compare; + } + break; + case 2960: + if (len == 5) + { + resword = &wordlist[837]; + goto compare; + } + break; + case 2967: + if (len == 14) + { + resword = &wordlist[838]; + goto compare; + } + break; + case 2968: + if (len == 6) + { + resword = &wordlist[839]; + goto compare; + } + break; + case 2974: + if (len == 16) + { + resword = &wordlist[840]; + goto compare; + } + break; + case 2983: + if (len == 21) + { + resword = &wordlist[841]; + goto compare; + } + break; + case 2988: + if (len == 5) + { + resword = &wordlist[842]; + goto compare; + } + break; + case 2993: + if (len == 4) + { + resword = &wordlist[843]; + goto compare; + } + break; + case 2995: + if (len == 6) + { + resword = &wordlist[844]; + goto compare; + } + break; + case 2999: + if (len == 12) + { + resword = &wordlist[845]; + goto compare; + } + break; + case 3002: + if (len == 6) + { + resword = &wordlist[846]; + goto compare; + } + break; + case 3004: + if (len == 4) + { + resword = &wordlist[847]; + goto compare; + } + break; + case 3011: + if (len == 5) + { + resword = &wordlist[848]; + goto compare; + } + break; + case 3012: + if (len == 5) + { + resword = &wordlist[849]; + goto compare; + } + break; + case 3015: + if (len == 5) + { + resword = &wordlist[850]; + goto compare; + } + break; + case 3021: + if (len == 5) + { + resword = &wordlist[851]; + goto compare; + } + break; + case 3028: + if (len == 3) + { + resword = &wordlist[852]; + goto compare; + } + break; + case 3038: + if (len == 5) + { + resword = &wordlist[853]; + goto compare; + } + break; + case 3046: + if (len == 4) + { + resword = &wordlist[854]; + goto compare; + } + break; + case 3056: + if (len == 14) + { + resword = &wordlist[855]; + goto compare; + } + break; + case 3065: + if (len == 8) + { + resword = &wordlist[856]; + goto compare; + } + break; + case 3066: + if (len == 4) + { + resword = &wordlist[857]; + goto compare; + } + break; + case 3079: + if (len == 3) + { + resword = &wordlist[858]; + goto compare; + } + break; + case 3083: + if (len == 5) + { + resword = &wordlist[859]; + goto compare; + } + break; + case 3084: + if (len == 4) + { + resword = &wordlist[860]; + goto compare; + } + break; + case 3092: + if (len == 2) + { + resword = &wordlist[861]; + goto compare; + } + break; + case 3093: + if (len == 6) + { + resword = &wordlist[862]; + goto compare; + } + break; + case 3101: + if (len == 6) + { + resword = &wordlist[863]; + goto compare; + } + break; + case 3103: + if (len == 4) + { + resword = &wordlist[864]; + goto compare; + } + break; + case 3105: + if (len == 6) + { + resword = &wordlist[865]; + goto compare; + } + break; + case 3111: + if (len == 9) + { + resword = &wordlist[866]; + goto compare; + } + break; + case 3113: + if (len == 5) + { + resword = &wordlist[867]; + goto compare; + } + break; + case 3114: + if (len == 7) + { + resword = &wordlist[868]; + goto compare; + } + break; + case 3117: + if (len == 10) + { + resword = &wordlist[869]; + goto compare; + } + break; + case 3125: + if (len == 10) + { + resword = &wordlist[870]; + goto compare; + } + break; + case 3126: + if (len == 6) + { + resword = &wordlist[871]; + goto compare; + } + break; + case 3129: + if (len == 6) + { + resword = &wordlist[872]; + goto compare; + } + break; + case 3131: + if (len == 6) + { + resword = &wordlist[873]; + goto compare; + } + break; + case 3142: + if (len == 2) + { + resword = &wordlist[874]; + goto compare; + } + break; + case 3146: + if (len == 5) + { + resword = &wordlist[875]; + goto compare; + } + break; + case 3147: + if (len == 8) + { + resword = &wordlist[876]; + goto compare; + } + break; + case 3149: + if (len == 5) + { + resword = &wordlist[877]; + goto compare; + } + break; + case 3157: + if (len == 3) + { + resword = &wordlist[878]; + goto compare; + } + break; + case 3165: + if (len == 6) + { + resword = &wordlist[879]; + goto compare; + } + break; + case 3169: + if (len == 6) + { + resword = &wordlist[880]; + goto compare; + } + break; + case 3170: + if (len == 9) + { + resword = &wordlist[881]; + goto compare; + } + break; + case 3173: + if (len == 3) + { + resword = &wordlist[882]; + goto compare; + } + break; + case 3183: + if (len == 5) + { + resword = &wordlist[883]; + goto compare; + } + break; + case 3191: + if (len == 7) + { + resword = &wordlist[884]; + goto compare; + } + break; + case 3194: + if (len == 6) + { + resword = &wordlist[885]; + goto compare; + } + break; + case 3195: + if (len == 13) + { + resword = &wordlist[886]; + goto compare; + } + break; + case 3216: + if (len == 3) + { + resword = &wordlist[887]; + goto compare; + } + break; + case 3217: + if (len == 4) + { + resword = &wordlist[888]; + goto compare; + } + break; + case 3219: + if (len == 9) + { + resword = &wordlist[889]; + goto compare; + } + break; + case 3221: + if (len == 4) + { + resword = &wordlist[890]; + goto compare; + } + break; + case 3226: + if (len == 4) + { + resword = &wordlist[891]; + goto compare; + } + break; + case 3227: + if (len == 6) + { + resword = &wordlist[892]; + goto compare; + } + break; + case 3229: + if (len == 5) + { + resword = &wordlist[893]; + goto compare; + } + break; + case 3232: + if (len == 4) + { + resword = &wordlist[894]; + goto compare; + } + break; + case 3236: + if (len == 5) + { + resword = &wordlist[895]; + goto compare; + } + break; + case 3240: + if (len == 7) + { + resword = &wordlist[896]; + goto compare; + } + break; + case 3247: + if (len == 7) + { + resword = &wordlist[897]; + goto compare; + } + break; + case 3256: + if (len == 7) + { + resword = &wordlist[898]; + goto compare; + } + break; + case 3257: + if (len == 5) + { + resword = &wordlist[899]; + goto compare; + } + break; + case 3262: + if (len == 5) + { + resword = &wordlist[900]; + goto compare; + } + break; + case 3265: + if (len == 5) + { + resword = &wordlist[901]; + goto compare; + } + break; + case 3269: + if (len == 4) + { + resword = &wordlist[902]; + goto compare; + } + break; + case 3272: + if (len == 16) + { + resword = &wordlist[903]; + goto compare; + } + break; + case 3275: + if (len == 5) + { + resword = &wordlist[904]; + goto compare; + } + break; + case 3276: + if (len == 9) + { + resword = &wordlist[905]; + goto compare; + } + break; + case 3280: + if (len == 6) + { + resword = &wordlist[906]; + goto compare; + } + break; + case 3281: + if (len == 8) + { + resword = &wordlist[907]; + goto compare; + } + break; + case 3293: + if (len == 5) + { + resword = &wordlist[908]; + goto compare; + } + break; + case 3297: + if (len == 6) + { + resword = &wordlist[909]; + goto compare; + } + break; + case 3298: + if (len == 8) + { + resword = &wordlist[910]; + goto compare; + } + break; + case 3299: + if (len == 8) + { + resword = &wordlist[911]; + goto compare; + } + break; + case 3301: + if (len == 8) + { + resword = &wordlist[912]; + goto compare; + } + break; + case 3315: + if (len == 8) + { + resword = &wordlist[913]; + goto compare; + } + break; + case 3317: + if (len == 6) + { + resword = &wordlist[914]; + goto compare; + } + break; + case 3325: + if (len == 13) + { + resword = &wordlist[915]; + goto compare; + } + break; + case 3330: + if (len == 9) + { + resword = &wordlist[916]; + goto compare; + } + break; + case 3337: + if (len == 6) + { + resword = &wordlist[917]; + goto compare; + } + break; + case 3353: + if (len == 2) + { + resword = &wordlist[918]; + goto compare; + } + break; + case 3356: + if (len == 5) + { + resword = &wordlist[919]; + goto compare; + } + break; + case 3359: + if (len == 10) + { + resword = &wordlist[920]; + goto compare; + } + break; + case 3366: + if (len == 5) + { + resword = &wordlist[921]; + goto compare; + } + break; + case 3369: + if (len == 5) + { + resword = &wordlist[922]; + goto compare; + } + break; + case 3371: + if (len == 5) + { + resword = &wordlist[923]; + goto compare; + } + break; + case 3372: + if (len == 6) + { + resword = &wordlist[924]; + goto compare; + } + break; + case 3373: + if (len == 8) + { + resword = &wordlist[925]; + goto compare; + } + break; + case 3374: + if (len == 7) + { + resword = &wordlist[926]; + goto compare; + } + break; + case 3375: + if (len == 6) + { + resword = &wordlist[927]; + goto compare; + } + break; + case 3377: + if (len == 8) + { + resword = &wordlist[928]; + goto compare; + } + break; + case 3380: + if (len == 17) + { + resword = &wordlist[929]; + goto compare; + } + break; + case 3384: + if (len == 17) + { + resword = &wordlist[930]; + goto compare; + } + break; + case 3388: + if (len == 14) + { + resword = &wordlist[931]; + goto compare; + } + break; + case 3391: + if (len == 20) + { + resword = &wordlist[932]; + goto compare; + } + break; + case 3397: + if (len == 19) + { + resword = &wordlist[933]; + goto compare; + } + break; + case 3401: + if (len == 4) + { + resword = &wordlist[934]; + goto compare; + } + break; + case 3405: + if (len == 5) + { + resword = &wordlist[935]; + goto compare; + } + break; + case 3406: + if (len == 5) + { + resword = &wordlist[936]; + goto compare; + } + break; + case 3408: + if (len == 4) + { + resword = &wordlist[937]; + goto compare; + } + break; + case 3410: + if (len == 4) + { + resword = &wordlist[938]; + goto compare; + } + break; + case 3416: + if (len == 4) + { + resword = &wordlist[939]; + goto compare; + } + break; + case 3417: + if (len == 6) + { + resword = &wordlist[940]; + goto compare; + } + break; + case 3419: + if (len == 4) + { + resword = &wordlist[941]; + goto compare; + } + break; + case 3420: + if (len == 6) + { + resword = &wordlist[942]; + goto compare; + } + break; + case 3422: + if (len == 4) + { + resword = &wordlist[943]; + goto compare; + } + break; + case 3423: + if (len == 5) + { + resword = &wordlist[944]; + goto compare; + } + break; + case 3424: + if (len == 5) + { + resword = &wordlist[945]; + goto compare; + } + break; + case 3428: + if (len == 3) + { + resword = &wordlist[946]; + goto compare; + } + break; + case 3430: + if (len == 5) + { + resword = &wordlist[947]; + goto compare; + } + break; + case 3432: + if (len == 5) + { + resword = &wordlist[948]; + goto compare; + } + break; + case 3436: + if (len == 5) + { + resword = &wordlist[949]; + goto compare; + } + break; + case 3437: + if (len == 5) + { + resword = &wordlist[950]; + goto compare; + } + break; + case 3439: + if (len == 15) + { + resword = &wordlist[951]; + goto compare; + } + break; + case 3440: + if (len == 6) + { + resword = &wordlist[952]; + goto compare; + } + break; + case 3445: + if (len == 20) + { + resword = &wordlist[953]; + goto compare; + } + break; + case 3448: + if (len == 4) + { + resword = &wordlist[954]; + goto compare; + } + break; + case 3450: + if (len == 5) + { + resword = &wordlist[955]; + goto compare; + } + break; + case 3451: + if (len == 6) + { + resword = &wordlist[956]; + goto compare; + } + break; + case 3452: + if (len == 6) + { + resword = &wordlist[957]; + goto compare; + } + break; + case 3454: + if (len == 4) + { + resword = &wordlist[958]; + goto compare; + } + break; + case 3455: + if (len == 4) + { + resword = &wordlist[959]; + goto compare; + } + break; + case 3456: + if (len == 5) + { + resword = &wordlist[960]; + goto compare; + } + break; + case 3457: + if (len == 4) + { + resword = &wordlist[961]; + goto compare; + } + break; + case 3458: + if (len == 4) + { + resword = &wordlist[962]; + goto compare; + } + break; + case 3461: + if (len == 6) + { + resword = &wordlist[963]; + goto compare; + } + break; + case 3468: + if (len == 4) + { + resword = &wordlist[964]; + goto compare; + } + break; + case 3472: + if (len == 3) + { + resword = &wordlist[965]; + goto compare; + } + break; + case 3473: + if (len == 7) + { + resword = &wordlist[966]; + goto compare; + } + break; + case 3475: + if (len == 3) + { + resword = &wordlist[967]; + goto compare; + } + break; + case 3477: + if (len == 4) + { + resword = &wordlist[968]; + goto compare; + } + break; + case 3488: + if (len == 6) + { + resword = &wordlist[969]; + goto compare; + } + break; + case 3489: + if (len == 2) + { + resword = &wordlist[970]; + goto compare; + } + break; + case 3491: + if (len == 17) + { + resword = &wordlist[971]; + goto compare; + } + break; + case 3492: + if (len == 4) + { + resword = &wordlist[972]; + goto compare; + } + break; + case 3497: + if (len == 22) + { + resword = &wordlist[973]; + goto compare; + } + break; + case 3498: + if (len == 2) + { + resword = &wordlist[974]; + goto compare; + } + break; + case 3501: + if (len == 5) + { + resword = &wordlist[975]; + goto compare; + } + break; + case 3503: + if (len == 5) + { + resword = &wordlist[976]; + goto compare; + } + break; + case 3509: + if (len == 7) + { + resword = &wordlist[977]; + goto compare; + } + break; + case 3511: + if (len == 5) + { + resword = &wordlist[978]; + goto compare; + } + break; + case 3516: + if (len == 4) + { + resword = &wordlist[979]; + goto compare; + } + break; + case 3519: + if (len == 5) + { + resword = &wordlist[980]; + goto compare; + } + break; + case 3526: + if (len == 8) + { + resword = &wordlist[981]; + goto compare; + } + break; + case 3528: + if (len == 12) + { + resword = &wordlist[982]; + goto compare; + } + break; + case 3531: + if (len == 15) + { + resword = &wordlist[983]; + goto compare; + } + break; + case 3539: + if (len == 6) + { + resword = &wordlist[984]; + goto compare; + } + break; + case 3540: + if (len == 5) + { + resword = &wordlist[985]; + goto compare; + } + break; + case 3541: + if (len == 6) + { + resword = &wordlist[986]; + goto compare; + } + break; + case 3542: + if (len == 5) + { + resword = &wordlist[987]; + goto compare; + } + break; + case 3558: + if (len == 7) + { + resword = &wordlist[988]; + goto compare; + } + break; + case 3560: + if (len == 6) + { + resword = &wordlist[989]; + goto compare; + } + break; + case 3565: + if (len == 15) + { + resword = &wordlist[990]; + goto compare; + } + break; + case 3567: + if (len == 6) + { + resword = &wordlist[991]; + goto compare; + } + break; + case 3568: + if (len == 7) + { + resword = &wordlist[992]; + goto compare; + } + break; + case 3569: + if (len == 6) + { + resword = &wordlist[993]; + goto compare; + } + break; + case 3571: + if (len == 4) + { + resword = &wordlist[994]; + goto compare; + } + break; + case 3572: + if (len == 4) + { + resword = &wordlist[995]; + goto compare; + } + break; + case 3573: + if (len == 4) + { + resword = &wordlist[996]; + goto compare; + } + break; + case 3577: + if (len == 5) + { + resword = &wordlist[997]; + goto compare; + } + break; + case 3587: + if (len == 6) + { + resword = &wordlist[998]; + goto compare; + } + break; + case 3588: + if (len == 13) + { + resword = &wordlist[999]; + goto compare; + } + break; + case 3589: + if (len == 16) + { + resword = &wordlist[1000]; + goto compare; + } + break; + case 3593: + if (len == 3) + { + resword = &wordlist[1001]; + goto compare; + } + break; + case 3594: + if (len == 11) + { + resword = &wordlist[1002]; + goto compare; + } + break; + case 3598: + if (len == 5) + { + resword = &wordlist[1003]; + goto compare; + } + break; + case 3601: + if (len == 7) + { + resword = &wordlist[1004]; + goto compare; + } + break; + case 3603: + if (len == 5) + { + resword = &wordlist[1005]; + goto compare; + } + break; + case 3610: + if (len == 6) + { + resword = &wordlist[1006]; + goto compare; + } + break; + case 3611: + if (len == 9) + { + resword = &wordlist[1007]; + goto compare; + } + break; + case 3613: + if (len == 8) + { + resword = &wordlist[1008]; + goto compare; + } + break; + case 3622: + if (len == 4) + { + resword = &wordlist[1009]; + goto compare; + } + break; + case 3625: + if (len == 13) + { + resword = &wordlist[1010]; + goto compare; + } + break; + case 3627: + if (len == 7) + { + resword = &wordlist[1011]; + goto compare; + } + break; + case 3628: + if (len == 6) + { + resword = &wordlist[1012]; + goto compare; + } + break; + case 3638: + if (len == 6) + { + resword = &wordlist[1013]; + goto compare; + } + break; + case 3639: + if (len == 13) + { + resword = &wordlist[1014]; + goto compare; + } + break; + case 3640: + if (len == 6) + { + resword = &wordlist[1015]; + goto compare; + } + break; + case 3641: + if (len == 3) + { + resword = &wordlist[1016]; + goto compare; + } + break; + case 3648: + if (len == 8) + { + resword = &wordlist[1017]; + goto compare; + } + break; + case 3654: + if (len == 4) + { + resword = &wordlist[1018]; + goto compare; + } + break; + case 3656: + if (len == 17) + { + resword = &wordlist[1019]; + goto compare; + } + break; + case 3663: + if (len == 6) + { + resword = &wordlist[1020]; + goto compare; + } + break; + case 3667: + if (len == 5) + { + resword = &wordlist[1021]; + goto compare; + } + break; + case 3669: + if (len == 2) + { + resword = &wordlist[1022]; + goto compare; + } + break; + case 3673: + if (len == 8) + { + resword = &wordlist[1023]; + goto compare; + } + break; + case 3674: + if (len == 5) + { + resword = &wordlist[1024]; + goto compare; + } + break; + case 3676: + if (len == 6) + { + resword = &wordlist[1025]; + goto compare; + } + break; + case 3677: + if (len == 4) + { + resword = &wordlist[1026]; + goto compare; + } + break; + case 3678: + if (len == 6) + { + resword = &wordlist[1027]; + goto compare; + } + break; + case 3679: + if (len == 5) + { + resword = &wordlist[1028]; + goto compare; + } + break; + case 3680: + if (len == 4) + { + resword = &wordlist[1029]; + goto compare; + } + break; + case 3686: + if (len == 3) + { + resword = &wordlist[1030]; + goto compare; + } + break; + case 3688: + if (len == 3) + { + resword = &wordlist[1031]; + goto compare; + } + break; + case 3689: + if (len == 4) + { + resword = &wordlist[1032]; + goto compare; + } + break; + case 3698: + if (len == 6) + { + resword = &wordlist[1033]; + goto compare; + } + break; + case 3699: + if (len == 6) + { + resword = &wordlist[1034]; + goto compare; + } + break; + case 3704: + if (len == 15) + { + resword = &wordlist[1035]; + goto compare; + } + break; + case 3711: + if (len == 4) + { + resword = &wordlist[1036]; + goto compare; + } + break; + case 3713: + if (len == 4) + { + resword = &wordlist[1037]; + goto compare; + } + break; + case 3716: + if (len == 6) + { + resword = &wordlist[1038]; + goto compare; + } + break; + case 3720: + if (len == 4) + { + resword = &wordlist[1039]; + goto compare; + } + break; + case 3723: + if (len == 6) + { + resword = &wordlist[1040]; + goto compare; + } + break; + case 3725: + if (len == 8) + { + resword = &wordlist[1041]; + goto compare; + } + break; + case 3726: + if (len == 4) + { + resword = &wordlist[1042]; + goto compare; + } + break; + case 3729: + if (len == 5) + { + resword = &wordlist[1043]; + goto compare; + } + break; + case 3739: + if (len == 5) + { + resword = &wordlist[1044]; + goto compare; + } + break; + case 3745: + if (len == 5) + { + resword = &wordlist[1045]; + goto compare; + } + break; + case 3761: + if (len == 6) + { + resword = &wordlist[1046]; + goto compare; + } + break; + case 3766: + if (len == 7) + { + resword = &wordlist[1047]; + goto compare; + } + break; + case 3773: + if (len == 4) + { + resword = &wordlist[1048]; + goto compare; + } + break; + case 3776: + if (len == 4) + { + resword = &wordlist[1049]; + goto compare; + } + break; + case 3781: + if (len == 8) + { + resword = &wordlist[1050]; + goto compare; + } + break; + case 3784: + if (len == 4) + { + resword = &wordlist[1051]; + goto compare; + } + break; + case 3786: + if (len == 4) + { + resword = &wordlist[1052]; + goto compare; + } + break; + case 3787: + if (len == 16) + { + resword = &wordlist[1053]; + goto compare; + } + break; + case 3788: + if (len == 5) + { + resword = &wordlist[1054]; + goto compare; + } + break; + case 3793: + if (len == 4) + { + resword = &wordlist[1055]; + goto compare; + } + break; + case 3794: + if (len == 5) + { + resword = &wordlist[1056]; + goto compare; + } + break; + case 3795: + if (len == 6) + { + resword = &wordlist[1057]; + goto compare; + } + break; + case 3798: + if (len == 5) + { + resword = &wordlist[1058]; + goto compare; + } + break; + case 3800: + if (len == 6) + { + resword = &wordlist[1059]; + goto compare; + } + break; + case 3801: + if (len == 5) + { + resword = &wordlist[1060]; + goto compare; + } + break; + case 3803: + if (len == 7) + { + resword = &wordlist[1061]; + goto compare; + } + break; + case 3805: + if (len == 4) + { + resword = &wordlist[1062]; + goto compare; + } + break; + case 3807: + if (len == 5) + { + resword = &wordlist[1063]; + goto compare; + } + break; + case 3808: + if (len == 5) + { + resword = &wordlist[1064]; + goto compare; + } + break; + case 3813: + if (len == 7) + { + resword = &wordlist[1065]; + goto compare; + } + break; + case 3814: + if (len == 6) + { + resword = &wordlist[1066]; + goto compare; + } + break; + case 3826: + if (len == 5) + { + resword = &wordlist[1067]; + goto compare; + } + break; + case 3827: + if (len == 6) + { + resword = &wordlist[1068]; + goto compare; + } + break; + case 3829: + if (len == 6) + { + resword = &wordlist[1069]; + goto compare; + } + break; + case 3830: + if (len == 6) + { + resword = &wordlist[1070]; + goto compare; + } + break; + case 3831: + if (len == 6) + { + resword = &wordlist[1071]; + goto compare; + } + break; + case 3833: + if (len == 3) + { + resword = &wordlist[1072]; + goto compare; + } + break; + case 3834: + if (len == 7) + { + resword = &wordlist[1073]; + goto compare; + } + break; + case 3835: + if (len == 3) + { + resword = &wordlist[1074]; + goto compare; + } + break; + case 3836: + if (len == 6) + { + resword = &wordlist[1075]; + goto compare; + } + break; + case 3840: + if (len == 6) + { + resword = &wordlist[1076]; + goto compare; + } + break; + case 3850: + if (len == 6) + { + resword = &wordlist[1077]; + goto compare; + } + break; + case 3859: + if (len == 6) + { + resword = &wordlist[1078]; + goto compare; + } + break; + case 3860: + if (len == 5) + { + resword = &wordlist[1079]; + goto compare; + } + break; + case 3862: + if (len == 5) + { + resword = &wordlist[1080]; + goto compare; + } + break; + case 3863: + if (len == 17) + { + resword = &wordlist[1081]; + goto compare; + } + break; + case 3868: + if (len == 6) + { + resword = &wordlist[1082]; + goto compare; + } + break; + case 3880: + if (len == 5) + { + resword = &wordlist[1083]; + goto compare; + } + break; + case 3883: + if (len == 6) + { + resword = &wordlist[1084]; + goto compare; + } + break; + case 3885: + if (len == 6) + { + resword = &wordlist[1085]; + goto compare; + } + break; + case 3887: + if (len == 6) + { + resword = &wordlist[1086]; + goto compare; + } + break; + case 3889: + if (len == 24) + { + resword = &wordlist[1087]; + goto compare; + } + break; + case 3898: + if (len == 6) + { + resword = &wordlist[1088]; + goto compare; + } + break; + case 3905: + if (len == 5) + { + resword = &wordlist[1089]; + goto compare; + } + break; + case 3910: + if (len == 4) + { + resword = &wordlist[1090]; + goto compare; + } + break; + case 3912: + if (len == 3) + { + resword = &wordlist[1091]; + goto compare; + } + break; + case 3914: + if (len == 16) + { + resword = &wordlist[1092]; + goto compare; + } + break; + case 3930: + if (len == 4) + { + resword = &wordlist[1093]; + goto compare; + } + break; + case 3933: + if (len == 6) + { + resword = &wordlist[1094]; + goto compare; + } + break; + case 3934: + if (len == 11) + { + resword = &wordlist[1095]; + goto compare; + } + break; + case 3935: + if (len == 6) + { + resword = &wordlist[1096]; + goto compare; + } + break; + case 3942: + if (len == 6) + { + resword = &wordlist[1097]; + goto compare; + } + break; + case 3944: + if (len == 8) + { + resword = &wordlist[1098]; + goto compare; + } + break; + case 3945: + if (len == 6) + { + resword = &wordlist[1099]; + goto compare; + } + break; + case 3947: + if (len == 3) + { + resword = &wordlist[1100]; + goto compare; + } + break; + case 3948: + if (len == 6) + { + resword = &wordlist[1101]; + goto compare; + } + break; + case 3955: + if (len == 13) + { + resword = &wordlist[1102]; + goto compare; + } + break; + case 3957: + if (len == 4) + { + resword = &wordlist[1103]; + goto compare; + } + break; + case 3958: + if (len == 14) + { + resword = &wordlist[1104]; + goto compare; + } + break; + case 3961: + if (len == 10) + { + resword = &wordlist[1105]; + goto compare; + } + break; + case 3962: + if (len == 4) + { + resword = &wordlist[1106]; + goto compare; + } + break; + case 3973: + if (len == 14) + { + resword = &wordlist[1107]; + goto compare; + } + break; + case 3974: + if (len == 6) + { + resword = &wordlist[1108]; + goto compare; + } + break; + case 3975: + if (len == 7) + { + resword = &wordlist[1109]; + goto compare; + } + break; + case 3976: + if (len == 6) + { + resword = &wordlist[1110]; + goto compare; + } + break; + case 3983: + if (len == 6) + { + resword = &wordlist[1111]; + goto compare; + } + break; + case 3988: + if (len == 5) + { + resword = &wordlist[1112]; + goto compare; + } + break; + case 3990: + if (len == 6) + { + resword = &wordlist[1113]; + goto compare; + } + break; + case 4005: + if (len == 6) + { + resword = &wordlist[1114]; + goto compare; + } + break; + case 4014: + if (len == 4) + { + resword = &wordlist[1115]; + goto compare; + } + break; + case 4021: + if (len == 3) + { + resword = &wordlist[1116]; + goto compare; + } + break; + case 4024: + if (len == 3) + { + resword = &wordlist[1117]; + goto compare; + } + break; + case 4027: + if (len == 4) + { + resword = &wordlist[1118]; + goto compare; + } + break; + case 4029: + if (len == 10) + { + resword = &wordlist[1119]; + goto compare; + } + break; + case 4032: + if (len == 3) + { + resword = &wordlist[1120]; + goto compare; + } + break; + case 4039: + if (len == 3) + { + resword = &wordlist[1121]; + goto compare; + } + break; + case 4040: + if (len == 14) + { + resword = &wordlist[1122]; + goto compare; + } + break; + case 4041: + if (len == 6) + { + resword = &wordlist[1123]; + goto compare; + } + break; + case 4042: + if (len == 5) + { + resword = &wordlist[1124]; + goto compare; + } + break; + case 4043: + if (len == 6) + { + resword = &wordlist[1125]; + goto compare; + } + break; + case 4046: + if (len == 5) + { + resword = &wordlist[1126]; + goto compare; + } + break; + case 4047: + if (len == 5) + { + resword = &wordlist[1127]; + goto compare; + } + break; + case 4054: + if (len == 14) + { + resword = &wordlist[1128]; + goto compare; + } + break; + case 4058: + if (len == 4) + { + resword = &wordlist[1129]; + goto compare; + } + break; + case 4062: + if (len == 6) + { + resword = &wordlist[1130]; + goto compare; + } + break; + case 4065: + if (len == 5) + { + resword = &wordlist[1131]; + goto compare; + } + break; + case 4066: + if (len == 4) + { + resword = &wordlist[1132]; + goto compare; + } + break; + case 4074: + if (len == 7) + { + resword = &wordlist[1133]; + goto compare; + } + break; + case 4077: + if (len == 9) + { + resword = &wordlist[1134]; + goto compare; + } + break; + case 4091: + if (len == 4) + { + resword = &wordlist[1135]; + goto compare; + } + break; + case 4098: + if (len == 7) + { + resword = &wordlist[1136]; + goto compare; + } + break; + case 4099: + if (len == 5) + { + resword = &wordlist[1137]; + goto compare; + } + break; + case 4106: + if (len == 4) + { + resword = &wordlist[1138]; + goto compare; + } + break; + case 4118: + if (len == 13) + { + resword = &wordlist[1139]; + goto compare; + } + break; + case 4123: + if (len == 19) + { + resword = &wordlist[1140]; + goto compare; + } + break; + case 4139: + if (len == 10) + { + resword = &wordlist[1141]; + goto compare; + } + break; + case 4145: + if (len == 6) + { + resword = &wordlist[1142]; + goto compare; + } + break; + case 4147: + if (len == 4) + { + resword = &wordlist[1143]; + goto compare; + } + break; + case 4148: + if (len == 3) + { + resword = &wordlist[1144]; + goto compare; + } + break; + case 4149: + if (len == 12) + { + resword = &wordlist[1145]; + goto compare; + } + break; + case 4150: + if (len == 9) + { + resword = &wordlist[1146]; + goto compare; + } + break; + case 4152: + if (len == 6) + { + resword = &wordlist[1147]; + goto compare; + } + break; + case 4154: + if (len == 13) + { + resword = &wordlist[1148]; + goto compare; + } + break; + case 4157: + if (len == 3) + { + resword = &wordlist[1149]; + goto compare; + } + break; + case 4160: + if (len == 6) + { + resword = &wordlist[1150]; + goto compare; + } + break; + case 4165: + if (len == 8) + { + resword = &wordlist[1151]; + goto compare; + } + break; + case 4173: + if (len == 4) + { + resword = &wordlist[1152]; + goto compare; + } + break; + case 4176: + if (len == 4) + { + resword = &wordlist[1153]; + goto compare; + } + break; + case 4178: + if (len == 4) + { + resword = &wordlist[1154]; + goto compare; + } + break; + case 4183: + if (len == 4) + { + resword = &wordlist[1155]; + goto compare; + } + break; + case 4191: + if (len == 4) + { + resword = &wordlist[1156]; + goto compare; + } + break; + case 4192: + if (len == 5) + { + resword = &wordlist[1157]; + goto compare; + } + break; + case 4193: + if (len == 5) + { + resword = &wordlist[1158]; + goto compare; + } + break; + case 4194: + if (len == 9) + { + resword = &wordlist[1159]; + goto compare; + } + break; + case 4195: + if (len == 9) + { + resword = &wordlist[1160]; + goto compare; + } + break; + case 4200: + if (len == 13) + { + resword = &wordlist[1161]; + goto compare; + } + break; + case 4207: + if (len == 2) + { + resword = &wordlist[1162]; + goto compare; + } + break; + case 4208: + if (len == 19) + { + resword = &wordlist[1163]; + goto compare; + } + break; + case 4213: + if (len == 24) + { + resword = &wordlist[1164]; + goto compare; + } + break; + case 4214: + if (len == 14) + { + resword = &wordlist[1165]; + goto compare; + } + break; + case 4225: + if (len == 5) + { + resword = &wordlist[1166]; + goto compare; + } + break; + case 4239: + if (len == 5) + { + resword = &wordlist[1167]; + goto compare; + } + break; + case 4248: + if (len == 4) + { + resword = &wordlist[1168]; + goto compare; + } + break; + case 4251: + if (len == 4) + { + resword = &wordlist[1169]; + goto compare; + } + break; + case 4253: + if (len == 4) + { + resword = &wordlist[1170]; + goto compare; + } + break; + case 4257: + if (len == 7) + { + resword = &wordlist[1171]; + goto compare; + } + break; + case 4259: + if (len == 4) + { + resword = &wordlist[1172]; + goto compare; + } + break; + case 4260: + if (len == 8) + { + resword = &wordlist[1173]; + goto compare; + } + break; + case 4265: + if (len == 6) + { + resword = &wordlist[1174]; + goto compare; + } + break; + case 4267: + if (len == 3) + { + resword = &wordlist[1175]; + goto compare; + } + break; + case 4273: + if (len == 9) + { + resword = &wordlist[1176]; + goto compare; + } + break; + case 4274: + if (len == 8) + { + resword = &wordlist[1177]; + goto compare; + } + break; + case 4275: + if (len == 7) + { + resword = &wordlist[1178]; + goto compare; + } + break; + case 4279: + if (len == 5) + { + resword = &wordlist[1179]; + goto compare; + } + break; + case 4282: + if (len == 14) + { + resword = &wordlist[1180]; + goto compare; + } + break; + case 4283: + if (len == 5) + { + resword = &wordlist[1181]; + goto compare; + } + break; + case 4288: + if (len == 6) + { + resword = &wordlist[1182]; + goto compare; + } + break; + case 4294: + if (len == 2) + { + resword = &wordlist[1183]; + goto compare; + } + break; + case 4296: + if (len == 5) + { + resword = &wordlist[1184]; + goto compare; + } + break; + case 4301: + if (len == 4) + { + resword = &wordlist[1185]; + goto compare; + } + break; + case 4313: + if (len == 6) + { + resword = &wordlist[1186]; + goto compare; + } + break; + case 4321: + if (len == 4) + { + resword = &wordlist[1187]; + goto compare; + } + break; + case 4322: + if (len == 5) + { + resword = &wordlist[1188]; + goto compare; + } + break; + case 4328: + if (len == 5) + { + resword = &wordlist[1189]; + goto compare; + } + break; + case 4334: + if (len == 3) + { + resword = &wordlist[1190]; + goto compare; + } + break; + case 4335: + if (len == 5) + { + resword = &wordlist[1191]; + goto compare; + } + break; + case 4339: + if (len == 9) + { + resword = &wordlist[1192]; + goto compare; + } + break; + case 4340: + if (len == 7) + { + resword = &wordlist[1193]; + goto compare; + } + break; + case 4343: + if (len == 7) + { + resword = &wordlist[1194]; + goto compare; + } + break; + case 4344: + if (len == 4) + { + resword = &wordlist[1195]; + goto compare; + } + break; + case 4348: + if (len == 6) + { + resword = &wordlist[1196]; + goto compare; + } + break; + case 4354: + if (len == 4) + { + resword = &wordlist[1197]; + goto compare; + } + break; + case 4357: + if (len == 2) + { + resword = &wordlist[1198]; + goto compare; + } + break; + case 4364: + if (len == 2) + { + resword = &wordlist[1199]; + goto compare; + } + break; + case 4373: + if (len == 5) + { + resword = &wordlist[1200]; + goto compare; + } + break; + case 4374: + if (len == 14) + { + resword = &wordlist[1201]; + goto compare; + } + break; + case 4375: + if (len == 4) + { + resword = &wordlist[1202]; + goto compare; + } + break; + case 4376: + if (len == 15) + { + resword = &wordlist[1203]; + goto compare; + } + break; + case 4377: + if (len == 17) + { + resword = &wordlist[1204]; + goto compare; + } + break; + case 4383: + if (len == 3) + { + resword = &wordlist[1205]; + goto compare; + } + break; + case 4390: + if (len == 5) + { + resword = &wordlist[1206]; + goto compare; + } + break; + case 4395: + if (len == 3) + { + resword = &wordlist[1207]; + goto compare; + } + break; + case 4396: + if (len == 8) + { + resword = &wordlist[1208]; + goto compare; + } + break; + case 4402: + if (len == 5) + { + resword = &wordlist[1209]; + goto compare; + } + break; + case 4403: + if (len == 10) + { + resword = &wordlist[1210]; + goto compare; + } + break; + case 4407: + if (len == 4) + { + resword = &wordlist[1211]; + goto compare; + } + break; + case 4409: + if (len == 17) + { + resword = &wordlist[1212]; + goto compare; + } + break; + case 4416: + if (len == 6) + { + resword = &wordlist[1213]; + goto compare; + } + break; + case 4419: + if (len == 4) + { + resword = &wordlist[1214]; + goto compare; + } + break; + case 4422: + if (len == 4) + { + resword = &wordlist[1215]; + goto compare; + } + break; + case 4423: + if (len == 4) + { + resword = &wordlist[1216]; + goto compare; + } + break; + case 4431: + if (len == 4) + { + resword = &wordlist[1217]; + goto compare; + } + break; + case 4433: + if (len == 2) + { + resword = &wordlist[1218]; + goto compare; + } + break; + case 4437: + if (len == 6) + { + resword = &wordlist[1219]; + goto compare; + } + break; + case 4438: + if (len == 5) + { + resword = &wordlist[1220]; + goto compare; + } + break; + case 4445: + if (len == 6) + { + resword = &wordlist[1221]; + goto compare; + } + break; + case 4448: + if (len == 4) + { + resword = &wordlist[1222]; + goto compare; + } + break; + case 4449: + if (len == 10) + { + resword = &wordlist[1223]; + goto compare; + } + break; + case 4454: + if (len == 3) + { + resword = &wordlist[1224]; + goto compare; + } + break; + case 4459: + if (len == 6) + { + resword = &wordlist[1225]; + goto compare; + } + break; + case 4461: + if (len == 6) + { + resword = &wordlist[1226]; + goto compare; + } + break; + case 4464: + if (len == 17) + { + resword = &wordlist[1227]; + goto compare; + } + break; + case 4466: + if (len == 8) + { + resword = &wordlist[1228]; + goto compare; + } + break; + case 4468: + if (len == 8) + { + resword = &wordlist[1229]; + goto compare; + } + break; + case 4471: + if (len == 2) + { + resword = &wordlist[1230]; + goto compare; + } + break; + case 4473: + if (len == 5) + { + resword = &wordlist[1231]; + goto compare; + } + break; + case 4475: + if (len == 14) + { + resword = &wordlist[1232]; + goto compare; + } + break; + case 4478: + if (len == 5) + { + resword = &wordlist[1233]; + goto compare; + } + break; + case 4479: + if (len == 6) + { + resword = &wordlist[1234]; + goto compare; + } + break; + case 4482: + if (len == 5) + { + resword = &wordlist[1235]; + goto compare; + } + break; + case 4483: + if (len == 5) + { + resword = &wordlist[1236]; + goto compare; + } + break; + case 4486: + if (len == 6) + { + resword = &wordlist[1237]; + goto compare; + } + break; + case 4489: + if (len == 4) + { + resword = &wordlist[1238]; + goto compare; + } + break; + case 4491: + if (len == 7) + { + resword = &wordlist[1239]; + goto compare; + } + break; + case 4492: + if (len == 3) + { + resword = &wordlist[1240]; + goto compare; + } + break; + case 4496: + if (len == 6) + { + resword = &wordlist[1241]; + goto compare; + } + break; + case 4499: + if (len == 10) + { + resword = &wordlist[1242]; + goto compare; + } + break; + case 4501: + if (len == 5) + { + resword = &wordlist[1243]; + goto compare; + } + break; + case 4502: + if (len == 8) + { + resword = &wordlist[1244]; + goto compare; + } + break; + case 4503: + if (len == 5) + { + resword = &wordlist[1245]; + goto compare; + } + break; + case 4510: + if (len == 5) + { + resword = &wordlist[1246]; + goto compare; + } + break; + case 4515: + if (len == 5) + { + resword = &wordlist[1247]; + goto compare; + } + break; + case 4523: + if (len == 20) + { + resword = &wordlist[1248]; + goto compare; + } + break; + case 4535: + if (len == 14) + { + resword = &wordlist[1249]; + goto compare; + } + break; + case 4547: + if (len == 16) + { + resword = &wordlist[1250]; + goto compare; + } + break; + case 4548: + if (len == 15) + { + resword = &wordlist[1251]; + goto compare; + } + break; + case 4551: + if (len == 6) + { + resword = &wordlist[1252]; + goto compare; + } + break; + case 4552: + if (len == 12) + { + resword = &wordlist[1253]; + goto compare; + } + break; + case 4554: + if (len == 5) + { + resword = &wordlist[1254]; + goto compare; + } + break; + case 4563: + if (len == 4) + { + resword = &wordlist[1255]; + goto compare; + } + break; + case 4568: + if (len == 7) + { + resword = &wordlist[1256]; + goto compare; + } + break; + case 4576: + if (len == 8) + { + resword = &wordlist[1257]; + goto compare; + } + break; + case 4578: + if (len == 5) + { + resword = &wordlist[1258]; + goto compare; + } + break; + case 4581: + if (len == 3) + { + resword = &wordlist[1259]; + goto compare; + } + break; + case 4583: + if (len == 3) + { + resword = &wordlist[1260]; + goto compare; + } + break; + case 4594: + if (len == 5) + { + resword = &wordlist[1261]; + goto compare; + } + break; + case 4597: + if (len == 6) + { + resword = &wordlist[1262]; + goto compare; + } + break; + case 4599: + if (len == 5) + { + resword = &wordlist[1263]; + goto compare; + } + break; + case 4605: + if (len == 18) + { + resword = &wordlist[1264]; + goto compare; + } + break; + case 4610: + if (len == 5) + { + resword = &wordlist[1265]; + goto compare; + } + break; + case 4617: + if (len == 4) + { + resword = &wordlist[1266]; + goto compare; + } + break; + case 4618: + if (len == 7) + { + resword = &wordlist[1267]; + goto compare; + } + break; + case 4620: + if (len == 12) + { + resword = &wordlist[1268]; + goto compare; + } + break; + case 4621: + if (len == 7) + { + resword = &wordlist[1269]; + goto compare; + } + break; + case 4623: + if (len == 6) + { + resword = &wordlist[1270]; + goto compare; + } + break; + case 4625: + if (len == 14) + { + resword = &wordlist[1271]; + goto compare; + } + break; + case 4641: + if (len == 5) + { + resword = &wordlist[1272]; + goto compare; + } + break; + case 4645: + if (len == 6) + { + resword = &wordlist[1273]; + goto compare; + } + break; + case 4648: + if (len == 5) + { + resword = &wordlist[1274]; + goto compare; + } + break; + case 4649: + if (len == 4) + { + resword = &wordlist[1275]; + goto compare; + } + break; + case 4650: + if (len == 5) + { + resword = &wordlist[1276]; + goto compare; + } + break; + case 4651: + if (len == 3) + { + resword = &wordlist[1277]; + goto compare; + } + break; + case 4655: + if (len == 6) + { + resword = &wordlist[1278]; + goto compare; + } + break; + case 4661: + if (len == 4) + { + resword = &wordlist[1279]; + goto compare; + } + break; + case 4663: + if (len == 5) + { + resword = &wordlist[1280]; + goto compare; + } + break; + case 4665: + if (len == 5) + { + resword = &wordlist[1281]; + goto compare; + } + break; + case 4669: + if (len == 4) + { + resword = &wordlist[1282]; + goto compare; + } + break; + case 4674: + if (len == 6) + { + resword = &wordlist[1283]; + goto compare; + } + break; + case 4691: + if (len == 4) + { + resword = &wordlist[1284]; + goto compare; + } + break; + case 4692: + if (len == 5) + { + resword = &wordlist[1285]; + goto compare; + } + break; + case 4693: + if (len == 6) + { + resword = &wordlist[1286]; + goto compare; + } + break; + case 4694: + if (len == 5) + { + resword = &wordlist[1287]; + goto compare; + } + break; + case 4700: + if (len == 9) + { + resword = &wordlist[1288]; + goto compare; + } + break; + case 4709: + if (len == 5) + { + resword = &wordlist[1289]; + goto compare; + } + break; + case 4710: + if (len == 6) + { + resword = &wordlist[1290]; + goto compare; + } + break; + case 4725: + if (len == 12) + { + resword = &wordlist[1291]; + goto compare; + } + break; + case 4729: + if (len == 6) + { + resword = &wordlist[1292]; + goto compare; + } + break; + case 4733: + if (len == 6) + { + resword = &wordlist[1293]; + goto compare; + } + break; + case 4735: + if (len == 5) + { + resword = &wordlist[1294]; + goto compare; + } + break; + case 4740: + if (len == 7) + { + resword = &wordlist[1295]; + goto compare; + } + break; + case 4741: + if (len == 8) + { + resword = &wordlist[1296]; + goto compare; + } + break; + case 4743: + if (len == 8) + { + resword = &wordlist[1297]; + goto compare; + } + break; + case 4744: + if (len == 4) + { + resword = &wordlist[1298]; + goto compare; + } + break; + case 4745: + if (len == 6) + { + resword = &wordlist[1299]; + goto compare; + } + break; + case 4747: + if (len == 4) + { + resword = &wordlist[1300]; + goto compare; + } + break; + case 4748: + if (len == 2) + { + resword = &wordlist[1301]; + goto compare; + } + break; + case 4757: + if (len == 4) + { + resword = &wordlist[1302]; + goto compare; + } + break; + case 4759: + if (len == 6) + { + resword = &wordlist[1303]; + goto compare; + } + break; + case 4764: + if (len == 5) + { + resword = &wordlist[1304]; + goto compare; + } + break; + case 4768: + if (len == 4) + { + resword = &wordlist[1305]; + goto compare; + } + break; + case 4775: + if (len == 9) + { + resword = &wordlist[1306]; + goto compare; + } + break; + case 4776: + if (len == 7) + { + resword = &wordlist[1307]; + goto compare; + } + break; + case 4779: + if (len == 6) + { + resword = &wordlist[1308]; + goto compare; + } + break; + case 4789: + if (len == 5) + { + resword = &wordlist[1309]; + goto compare; + } + break; + case 4791: + if (len == 3) + { + resword = &wordlist[1310]; + goto compare; + } + break; + case 4792: + if (len == 5) + { + resword = &wordlist[1311]; + goto compare; + } + break; + case 4807: + if (len == 7) + { + resword = &wordlist[1312]; + goto compare; + } + break; + case 4812: + if (len == 16) + { + resword = &wordlist[1313]; + goto compare; + } + break; + case 4815: + if (len == 5) + { + resword = &wordlist[1314]; + goto compare; + } + break; + case 4817: + if (len == 6) + { + resword = &wordlist[1315]; + goto compare; + } + break; + case 4820: + if (len == 2) + { + resword = &wordlist[1316]; + goto compare; + } + break; + case 4823: + if (len == 12) + { + resword = &wordlist[1317]; + goto compare; + } + break; + case 4828: + if (len == 4) + { + resword = &wordlist[1318]; + goto compare; + } + break; + case 4830: + if (len == 4) + { + resword = &wordlist[1319]; + goto compare; + } + break; + case 4833: + if (len == 4) + { + resword = &wordlist[1320]; + goto compare; + } + break; + case 4841: + if (len == 4) + { + resword = &wordlist[1321]; + goto compare; + } + break; + case 4846: + if (len == 3) + { + resword = &wordlist[1322]; + goto compare; + } + break; + case 4849: + if (len == 4) + { + resword = &wordlist[1323]; + goto compare; + } + break; + case 4851: + if (len == 9) + { + resword = &wordlist[1324]; + goto compare; + } + break; + case 4852: + if (len == 8) + { + resword = &wordlist[1325]; + goto compare; + } + break; + case 4856: + if (len == 3) + { + resword = &wordlist[1326]; + goto compare; + } + break; + case 4859: + if (len == 8) + { + resword = &wordlist[1327]; + goto compare; + } + break; + case 4860: + if (len == 9) + { + resword = &wordlist[1328]; + goto compare; + } + break; + case 4863: + if (len == 8) + { + resword = &wordlist[1329]; + goto compare; + } + break; + case 4869: + if (len == 9) + { + resword = &wordlist[1330]; + goto compare; + } + break; + case 4873: + if (len == 7) + { + resword = &wordlist[1331]; + goto compare; + } + break; + case 4884: + if (len == 3) + { + resword = &wordlist[1332]; + goto compare; + } + break; + case 4885: + if (len == 3) + { + resword = &wordlist[1333]; + goto compare; + } + break; + case 4893: + if (len == 2) + { + resword = &wordlist[1334]; + goto compare; + } + break; + case 4896: + if (len == 3) + { + resword = &wordlist[1335]; + goto compare; + } + break; + case 4901: + if (len == 4) + { + resword = &wordlist[1336]; + goto compare; + } + break; + case 4903: + if (len == 16) + { + resword = &wordlist[1337]; + goto compare; + } + break; + case 4905: + if (len == 5) + { + resword = &wordlist[1338]; + goto compare; + } + break; + case 4912: + if (len == 4) + { + resword = &wordlist[1339]; + goto compare; + } + break; + case 4914: + if (len == 16) + { + resword = &wordlist[1340]; + goto compare; + } + break; + case 4915: + if (len == 6) + { + resword = &wordlist[1341]; + goto compare; + } + break; + case 4921: + if (len == 5) + { + resword = &wordlist[1342]; + goto compare; + } + break; + case 4930: + if (len == 4) + { + resword = &wordlist[1343]; + goto compare; + } + break; + case 4932: + if (len == 5) + { + resword = &wordlist[1344]; + goto compare; + } + break; + case 4936: + if (len == 6) + { + resword = &wordlist[1345]; + goto compare; + } + break; + case 4943: + if (len == 7) + { + resword = &wordlist[1346]; + goto compare; + } + break; + case 4955: + if (len == 5) + { + resword = &wordlist[1347]; + goto compare; + } + break; + case 4961: + if (len == 3) + { + resword = &wordlist[1348]; + goto compare; + } + break; + case 4975: + if (len == 4) + { + resword = &wordlist[1349]; + goto compare; + } + break; + case 4977: + if (len == 4) + { + resword = &wordlist[1350]; + goto compare; + } + break; + case 4978: + if (len == 4) + { + resword = &wordlist[1351]; + goto compare; + } + break; + case 4986: + if (len == 6) + { + resword = &wordlist[1352]; + goto compare; + } + break; + case 4988: + if (len == 3) + { + resword = &wordlist[1353]; + goto compare; + } + break; + case 4994: + if (len == 9) + { + resword = &wordlist[1354]; + goto compare; + } + break; + case 4998: + if (len == 4) + { + resword = &wordlist[1355]; + goto compare; + } + break; + case 5002: + if (len == 16) + { + resword = &wordlist[1356]; + goto compare; + } + break; + case 5003: + if (len == 20) + { + resword = &wordlist[1357]; + goto compare; + } + break; + case 5008: + if (len == 4) + { + resword = &wordlist[1358]; + goto compare; + } + break; + case 5013: + if (len == 9) + { + resword = &wordlist[1359]; + goto compare; + } + break; + case 5024: + if (len == 4) + { + resword = &wordlist[1360]; + goto compare; + } + break; + case 5037: + if (len == 7) + { + resword = &wordlist[1361]; + goto compare; + } + break; + case 5042: + if (len == 6) + { + resword = &wordlist[1362]; + goto compare; + } + break; + case 5043: + if (len == 5) + { + resword = &wordlist[1363]; + goto compare; + } + break; + case 5044: + if (len == 7) + { + resword = &wordlist[1364]; + goto compare; + } + break; + case 5050: + if (len == 14) + { + resword = &wordlist[1365]; + goto compare; + } + break; + case 5051: + if (len == 7) + { + resword = &wordlist[1366]; + goto compare; + } + break; + case 5052: + if (len == 4) + { + resword = &wordlist[1367]; + goto compare; + } + break; + case 5056: + if (len == 3) + { + resword = &wordlist[1368]; + goto compare; + } + break; + case 5059: + if (len == 5) + { + resword = &wordlist[1369]; + goto compare; + } + break; + case 5060: + if (len == 6) + { + resword = &wordlist[1370]; + goto compare; + } + break; + case 5061: + if (len == 22) + { + resword = &wordlist[1371]; + goto compare; + } + break; + case 5063: + if (len == 4) + { + resword = &wordlist[1372]; + goto compare; + } + break; + case 5066: + if (len == 5) + { + resword = &wordlist[1373]; + goto compare; + } + break; + case 5068: + if (len == 4) + { + resword = &wordlist[1374]; + goto compare; + } + break; + case 5069: + if (len == 10) + { + resword = &wordlist[1375]; + goto compare; + } + break; + case 5070: + if (len == 5) + { + resword = &wordlist[1376]; + goto compare; + } + break; + case 5075: + if (len == 5) + { + resword = &wordlist[1377]; + goto compare; + } + break; + case 5079: + if (len == 4) + { + resword = &wordlist[1378]; + goto compare; + } + break; + case 5081: + if (len == 6) + { + resword = &wordlist[1379]; + goto compare; + } + break; + case 5091: + if (len == 5) + { + resword = &wordlist[1380]; + goto compare; + } + break; + case 5103: + if (len == 5) + { + resword = &wordlist[1381]; + goto compare; + } + break; + case 5107: + if (len == 4) + { + resword = &wordlist[1382]; + goto compare; + } + break; + case 5108: + if (len == 7) + { + resword = &wordlist[1383]; + goto compare; + } + break; + case 5116: + if (len == 3) + { + resword = &wordlist[1384]; + goto compare; + } + break; + case 5119: + if (len == 5) + { + resword = &wordlist[1385]; + goto compare; + } + break; + case 5120: + if (len == 8) + { + resword = &wordlist[1386]; + goto compare; + } + break; + case 5122: + if (len == 4) + { + resword = &wordlist[1387]; + goto compare; + } + break; + case 5123: + if (len == 5) + { + resword = &wordlist[1388]; + goto compare; + } + break; + case 5126: + if (len == 4) + { + resword = &wordlist[1389]; + goto compare; + } + break; + case 5129: + if (len == 4) + { + resword = &wordlist[1390]; + goto compare; + } + break; + case 5135: + if (len == 4) + { + resword = &wordlist[1391]; + goto compare; + } + break; + case 5140: + if (len == 6) + { + resword = &wordlist[1392]; + goto compare; + } + break; + case 5141: + if (len == 5) + { + resword = &wordlist[1393]; + goto compare; + } + break; + case 5142: + if (len == 6) + { + resword = &wordlist[1394]; + goto compare; + } + break; + case 5143: + if (len == 4) + { + resword = &wordlist[1395]; + goto compare; + } + break; + case 5147: + if (len == 9) + { + resword = &wordlist[1396]; + goto compare; + } + break; + case 5154: + if (len == 8) + { + resword = &wordlist[1397]; + goto compare; + } + break; + case 5158: + if (len == 8) + { + resword = &wordlist[1398]; + goto compare; + } + break; + case 5170: + if (len == 4) + { + resword = &wordlist[1399]; + goto compare; + } + break; + case 5171: + if (len == 7) + { + resword = &wordlist[1400]; + goto compare; + } + break; + case 5172: + if (len == 15) + { + resword = &wordlist[1401]; + goto compare; + } + break; + case 5183: + if (len == 10) + { + resword = &wordlist[1402]; + goto compare; + } + break; + case 5184: + if (len == 6) + { + resword = &wordlist[1403]; + goto compare; + } + break; + case 5202: + if (len == 6) + { + resword = &wordlist[1404]; + goto compare; + } + break; + case 5203: + if (len == 5) + { + resword = &wordlist[1405]; + goto compare; + } + break; + case 5209: + if (len == 5) + { + resword = &wordlist[1406]; + goto compare; + } + break; + case 5210: + if (len == 5) + { + resword = &wordlist[1407]; + goto compare; + } + break; + case 5213: + if (len == 2) + { + resword = &wordlist[1408]; + goto compare; + } + break; + case 5219: + if (len == 4) + { + resword = &wordlist[1409]; + goto compare; + } + break; + case 5224: + if (len == 14) + { + resword = &wordlist[1410]; + goto compare; + } + break; + case 5229: + if (len == 8) + { + resword = &wordlist[1411]; + goto compare; + } + break; + case 5231: + if (len == 4) + { + resword = &wordlist[1412]; + goto compare; + } + break; + case 5234: + if (len == 7) + { + resword = &wordlist[1413]; + goto compare; + } + break; + case 5241: + if (len == 3) + { + resword = &wordlist[1414]; + goto compare; + } + break; + case 5246: + if (len == 7) + { + resword = &wordlist[1415]; + goto compare; + } + break; + case 5253: + if (len == 5) + { + resword = &wordlist[1416]; + goto compare; + } + break; + case 5254: + if (len == 6) + { + resword = &wordlist[1417]; + goto compare; + } + break; + case 5257: + if (len == 20) + { + resword = &wordlist[1418]; + goto compare; + } + break; + case 5260: + if (len == 5) + { + resword = &wordlist[1419]; + goto compare; + } + break; + case 5261: + if (len == 2) + { + resword = &wordlist[1420]; + goto compare; + } + break; + case 5263: + if (len == 16) + { + resword = &wordlist[1421]; + goto compare; + } + break; + case 5268: + if (len == 4) + { + resword = &wordlist[1422]; + goto compare; + } + break; + case 5281: + if (len == 17) + { + resword = &wordlist[1423]; + goto compare; + } + break; + case 5283: + if (len == 5) + { + resword = &wordlist[1424]; + goto compare; + } + break; + case 5287: + if (len == 5) + { + resword = &wordlist[1425]; + goto compare; + } + break; + case 5289: + if (len == 5) + { + resword = &wordlist[1426]; + goto compare; + } + break; + case 5290: + if (len == 3) + { + resword = &wordlist[1427]; + goto compare; + } + break; + case 5296: + if (len == 6) + { + resword = &wordlist[1428]; + goto compare; + } + break; + case 5304: + if (len == 4) + { + resword = &wordlist[1429]; + goto compare; + } + break; + case 5307: + if (len == 5) + { + resword = &wordlist[1430]; + goto compare; + } + break; + case 5309: + if (len == 4) + { + resword = &wordlist[1431]; + goto compare; + } + break; + case 5310: + if (len == 5) + { + resword = &wordlist[1432]; + goto compare; + } + break; + case 5316: + if (len == 4) + { + resword = &wordlist[1433]; + goto compare; + } + break; + case 5323: + if (len == 5) + { + resword = &wordlist[1434]; + goto compare; + } + break; + case 5335: + if (len == 4) + { + resword = &wordlist[1435]; + goto compare; + } + break; + case 5337: + if (len == 8) + { + resword = &wordlist[1436]; + goto compare; + } + break; + case 5338: + if (len == 15) + { + resword = &wordlist[1437]; + goto compare; + } + break; + case 5339: + if (len == 8) + { + resword = &wordlist[1438]; + goto compare; + } + break; + case 5349: + if (len == 5) + { + resword = &wordlist[1439]; + goto compare; + } + break; + case 5353: + if (len == 8) + { + resword = &wordlist[1440]; + goto compare; + } + break; + case 5358: + if (len == 5) + { + resword = &wordlist[1441]; + goto compare; + } + break; + case 5364: + if (len == 4) + { + resword = &wordlist[1442]; + goto compare; + } + break; + case 5366: + if (len == 6) + { + resword = &wordlist[1443]; + goto compare; + } + break; + case 5368: + if (len == 6) + { + resword = &wordlist[1444]; + goto compare; + } + break; + case 5372: + if (len == 6) + { + resword = &wordlist[1445]; + goto compare; + } + break; + case 5374: + if (len == 9) + { + resword = &wordlist[1446]; + goto compare; + } + break; + case 5378: + if (len == 4) + { + resword = &wordlist[1447]; + goto compare; + } + break; + case 5383: + if (len == 11) + { + resword = &wordlist[1448]; + goto compare; + } + break; + case 5385: + if (len == 4) + { + resword = &wordlist[1449]; + goto compare; + } + break; + case 5388: + if (len == 8) + { + resword = &wordlist[1450]; + goto compare; + } + break; + case 5389: + if (len == 5) + { + resword = &wordlist[1451]; + goto compare; + } + break; + case 5391: + if (len == 4) + { + resword = &wordlist[1452]; + goto compare; + } + break; + case 5395: + if (len == 12) + { + resword = &wordlist[1453]; + goto compare; + } + break; + case 5397: + if (len == 18) + { + resword = &wordlist[1454]; + goto compare; + } + break; + case 5398: + if (len == 5) + { + resword = &wordlist[1455]; + goto compare; + } + break; + case 5400: + if (len == 5) + { + resword = &wordlist[1456]; + goto compare; + } + break; + case 5403: + if (len == 4) + { + resword = &wordlist[1457]; + goto compare; + } + break; + case 5407: + if (len == 5) + { + resword = &wordlist[1458]; + goto compare; + } + break; + case 5408: + if (len == 5) + { + resword = &wordlist[1459]; + goto compare; + } + break; + case 5421: + if (len == 5) + { + resword = &wordlist[1460]; + goto compare; + } + break; + case 5422: + if (len == 6) + { + resword = &wordlist[1461]; + goto compare; + } + break; + case 5431: + if (len == 5) + { + resword = &wordlist[1462]; + goto compare; + } + break; + case 5435: + if (len == 6) + { + resword = &wordlist[1463]; + goto compare; + } + break; + case 5438: + if (len == 4) + { + resword = &wordlist[1464]; + goto compare; + } + break; + case 5439: + if (len == 5) + { + resword = &wordlist[1465]; + goto compare; + } + break; + case 5440: + if (len == 6) + { + resword = &wordlist[1466]; + goto compare; + } + break; + case 5445: + if (len == 4) + { + resword = &wordlist[1467]; + goto compare; + } + break; + case 5450: + if (len == 4) + { + resword = &wordlist[1468]; + goto compare; + } + break; + case 5457: + if (len == 4) + { + resword = &wordlist[1469]; + goto compare; + } + break; + case 5460: + if (len == 6) + { + resword = &wordlist[1470]; + goto compare; + } + break; + case 5462: + if (len == 4) + { + resword = &wordlist[1471]; + goto compare; + } + break; + case 5470: + if (len == 6) + { + resword = &wordlist[1472]; + goto compare; + } + break; + case 5474: + if (len == 5) + { + resword = &wordlist[1473]; + goto compare; + } + break; + case 5479: + if (len == 9) + { + resword = &wordlist[1474]; + goto compare; + } + break; + case 5490: + if (len == 5) + { + resword = &wordlist[1475]; + goto compare; + } + break; + case 5504: + if (len == 13) + { + resword = &wordlist[1476]; + goto compare; + } + break; + case 5508: + if (len == 5) + { + resword = &wordlist[1477]; + goto compare; + } + break; + case 5509: + if (len == 5) + { + resword = &wordlist[1478]; + goto compare; + } + break; + case 5510: + if (len == 4) + { + resword = &wordlist[1479]; + goto compare; + } + break; + case 5512: + if (len == 4) + { + resword = &wordlist[1480]; + goto compare; + } + break; + case 5518: + if (len == 5) + { + resword = &wordlist[1481]; + goto compare; + } + break; + case 5523: + if (len == 13) + { + resword = &wordlist[1482]; + goto compare; + } + break; + case 5531: + if (len == 9) + { + resword = &wordlist[1483]; + goto compare; + } + break; + case 5534: + if (len == 8) + { + resword = &wordlist[1484]; + goto compare; + } + break; + case 5537: + if (len == 13) + { + resword = &wordlist[1485]; + goto compare; + } + break; + case 5547: + if (len == 7) + { + resword = &wordlist[1486]; + goto compare; + } + break; + case 5549: + if (len == 6) + { + resword = &wordlist[1487]; + goto compare; + } + break; + case 5553: + if (len == 7) + { + resword = &wordlist[1488]; + goto compare; + } + break; + case 5554: + if (len == 10) + { + resword = &wordlist[1489]; + goto compare; + } + break; + case 5560: + if (len == 3) + { + resword = &wordlist[1490]; + goto compare; + } + break; + case 5562: + if (len == 8) + { + resword = &wordlist[1491]; + goto compare; + } + break; + case 5568: + if (len == 5) + { + resword = &wordlist[1492]; + goto compare; + } + break; + case 5571: + if (len == 4) + { + resword = &wordlist[1493]; + goto compare; + } + break; + case 5572: + if (len == 12) + { + resword = &wordlist[1494]; + goto compare; + } + break; + case 5575: + if (len == 5) + { + resword = &wordlist[1495]; + goto compare; + } + break; + case 5577: + if (len == 14) + { + resword = &wordlist[1496]; + goto compare; + } + break; + case 5579: + if (len == 4) + { + resword = &wordlist[1497]; + goto compare; + } + break; + case 5580: + if (len == 5) + { + resword = &wordlist[1498]; + goto compare; + } + break; + case 5587: + if (len == 6) + { + resword = &wordlist[1499]; + goto compare; + } + break; + case 5591: + if (len == 4) + { + resword = &wordlist[1500]; + goto compare; + } + break; + case 5593: + if (len == 5) + { + resword = &wordlist[1501]; + goto compare; + } + break; + case 5605: + if (len == 10) + { + resword = &wordlist[1502]; + goto compare; + } + break; + case 5608: + if (len == 4) + { + resword = &wordlist[1503]; + goto compare; + } + break; + case 5609: + if (len == 4) + { + resword = &wordlist[1504]; + goto compare; + } + break; + case 5611: + if (len == 8) + { + resword = &wordlist[1505]; + goto compare; + } + break; + case 5613: + if (len == 9) + { + resword = &wordlist[1506]; + goto compare; + } + break; + case 5619: + if (len == 11) + { + resword = &wordlist[1507]; + goto compare; + } + break; + case 5622: + if (len == 6) + { + resword = &wordlist[1508]; + goto compare; + } + break; + case 5630: + if (len == 5) + { + resword = &wordlist[1509]; + goto compare; + } + break; + case 5637: + if (len == 6) + { + resword = &wordlist[1510]; + goto compare; + } + break; + case 5638: + if (len == 6) + { + resword = &wordlist[1511]; + goto compare; + } + break; + case 5639: + if (len == 6) + { + resword = &wordlist[1512]; + goto compare; + } + break; + case 5640: + if (len == 6) + { + resword = &wordlist[1513]; + goto compare; + } + break; + case 5645: + if (len == 6) + { + resword = &wordlist[1514]; + goto compare; + } + break; + case 5650: + if (len == 6) + { + resword = &wordlist[1515]; + goto compare; + } + break; + case 5654: + if (len == 5) + { + resword = &wordlist[1516]; + goto compare; + } + break; + case 5655: + if (len == 5) + { + resword = &wordlist[1517]; + goto compare; + } + break; + case 5656: + if (len == 4) + { + resword = &wordlist[1518]; + goto compare; + } + break; + case 5657: + if (len == 5) + { + resword = &wordlist[1519]; + goto compare; + } + break; + case 5665: + if (len == 5) + { + resword = &wordlist[1520]; + goto compare; + } + break; + case 5666: + if (len == 6) + { + resword = &wordlist[1521]; + goto compare; + } + break; + case 5667: + if (len == 4) + { + resword = &wordlist[1522]; + goto compare; + } + break; + case 5668: + if (len == 5) + { + resword = &wordlist[1523]; + goto compare; + } + break; + case 5669: + if (len == 6) + { + resword = &wordlist[1524]; + goto compare; + } + break; + case 5670: + if (len == 9) + { + resword = &wordlist[1525]; + goto compare; + } + break; + case 5671: + if (len == 7) + { + resword = &wordlist[1526]; + goto compare; + } + break; + case 5674: + if (len == 6) + { + resword = &wordlist[1527]; + goto compare; + } + break; + case 5678: + if (len == 6) + { + resword = &wordlist[1528]; + goto compare; + } + break; + case 5679: + if (len == 5) + { + resword = &wordlist[1529]; + goto compare; + } + break; + case 5680: + if (len == 17) + { + resword = &wordlist[1530]; + goto compare; + } + break; + case 5688: + if (len == 4) + { + resword = &wordlist[1531]; + goto compare; + } + break; + case 5689: + if (len == 6) + { + resword = &wordlist[1532]; + goto compare; + } + break; + case 5691: + if (len == 13) + { + resword = &wordlist[1533]; + goto compare; + } + break; + case 5695: + if (len == 7) + { + resword = &wordlist[1534]; + goto compare; + } + break; + case 5701: + if (len == 4) + { + resword = &wordlist[1535]; + goto compare; + } + break; + case 5705: + if (len == 15) + { + resword = &wordlist[1536]; + goto compare; + } + break; + case 5710: + if (len == 4) + { + resword = &wordlist[1537]; + goto compare; + } + break; + case 5736: + if (len == 13) + { + resword = &wordlist[1538]; + goto compare; + } + break; + case 5739: + if (len == 10) + { + resword = &wordlist[1539]; + goto compare; + } + break; + case 5749: + if (len == 6) + { + resword = &wordlist[1540]; + goto compare; + } + break; + case 5750: + if (len == 3) + { + resword = &wordlist[1541]; + goto compare; + } + break; + case 5756: + if (len == 6) + { + resword = &wordlist[1542]; + goto compare; + } + break; + case 5763: + if (len == 3) + { + resword = &wordlist[1543]; + goto compare; + } + break; + case 5771: + if (len == 4) + { + resword = &wordlist[1544]; + goto compare; + } + break; + case 5773: + if (len == 3) + { + resword = &wordlist[1545]; + goto compare; + } + break; + case 5778: + if (len == 5) + { + resword = &wordlist[1546]; + goto compare; + } + break; + case 5780: + if (len == 5) + { + resword = &wordlist[1547]; + goto compare; + } + break; + case 5783: + if (len == 5) + { + resword = &wordlist[1548]; + goto compare; + } + break; + case 5784: + if (len == 6) + { + resword = &wordlist[1549]; + goto compare; + } + break; + case 5786: + if (len == 6) + { + resword = &wordlist[1550]; + goto compare; + } + break; + case 5799: + if (len == 6) + { + resword = &wordlist[1551]; + goto compare; + } + break; + case 5800: + if (len == 6) + { + resword = &wordlist[1552]; + goto compare; + } + break; + case 5808: + if (len == 16) + { + resword = &wordlist[1553]; + goto compare; + } + break; + case 5816: + if (len == 13) + { + resword = &wordlist[1554]; + goto compare; + } + break; + case 5817: + if (len == 15) + { + resword = &wordlist[1555]; + goto compare; + } + break; + case 5818: + if (len == 12) + { + resword = &wordlist[1556]; + goto compare; + } + break; + case 5821: + if (len == 17) + { + resword = &wordlist[1557]; + goto compare; + } + break; + case 5843: + if (len == 6) + { + resword = &wordlist[1558]; + goto compare; + } + break; + case 5861: + if (len == 2) + { + resword = &wordlist[1559]; + goto compare; + } + break; + case 5863: + if (len == 2) + { + resword = &wordlist[1560]; + goto compare; + } + break; + case 5868: + if (len == 7) + { + resword = &wordlist[1561]; + goto compare; + } + break; + case 5876: + if (len == 13) + { + resword = &wordlist[1562]; + goto compare; + } + break; + case 5878: + if (len == 5) + { + resword = &wordlist[1563]; + goto compare; + } + break; + case 5882: + if (len == 8) + { + resword = &wordlist[1564]; + goto compare; + } + break; + case 5884: + if (len == 6) + { + resword = &wordlist[1565]; + goto compare; + } + break; + case 5900: + if (len == 5) + { + resword = &wordlist[1566]; + goto compare; + } + break; + case 5909: + if (len == 6) + { + resword = &wordlist[1567]; + goto compare; + } + break; + case 5911: + if (len == 6) + { + resword = &wordlist[1568]; + goto compare; + } + break; + case 5914: + if (len == 6) + { + resword = &wordlist[1569]; + goto compare; + } + break; + case 5926: + if (len == 6) + { + resword = &wordlist[1570]; + goto compare; + } + break; + case 5944: + if (len == 6) + { + resword = &wordlist[1571]; + goto compare; + } + break; + case 5951: + if (len == 3) + { + resword = &wordlist[1572]; + goto compare; + } + break; + case 5962: + if (len == 4) + { + resword = &wordlist[1573]; + goto compare; + } + break; + case 5963: + if (len == 11) + { + resword = &wordlist[1574]; + goto compare; + } + break; + case 5971: + if (len == 6) + { + resword = &wordlist[1575]; + goto compare; + } + break; + case 5972: + if (len == 11) + { + resword = &wordlist[1576]; + goto compare; + } + break; + case 5998: + if (len == 4) + { + resword = &wordlist[1577]; + goto compare; + } + break; + case 6002: + if (len == 13) + { + resword = &wordlist[1578]; + goto compare; + } + break; + case 6008: + if (len == 6) + { + resword = &wordlist[1579]; + goto compare; + } + break; + case 6010: + if (len == 5) + { + resword = &wordlist[1580]; + goto compare; + } + break; + case 6020: + if (len == 8) + { + resword = &wordlist[1581]; + goto compare; + } + break; + case 6024: + if (len == 5) + { + resword = &wordlist[1582]; + goto compare; + } + break; + case 6025: + if (len == 8) + { + resword = &wordlist[1583]; + goto compare; + } + break; + case 6031: + if (len == 21) + { + resword = &wordlist[1584]; + goto compare; + } + break; + case 6036: + if (len == 8) + { + resword = &wordlist[1585]; + goto compare; + } + break; + case 6037: + if (len == 5) + { + resword = &wordlist[1586]; + goto compare; + } + break; + case 6039: + if (len == 5) + { + resword = &wordlist[1587]; + goto compare; + } + break; + case 6050: + if (len == 6) + { + resword = &wordlist[1588]; + goto compare; + } + break; + case 6057: + if (len == 4) + { + resword = &wordlist[1589]; + goto compare; + } + break; + case 6070: + if (len == 8) + { + resword = &wordlist[1590]; + goto compare; + } + break; + case 6072: + if (len == 10) + { + resword = &wordlist[1591]; + goto compare; + } + break; + case 6077: + if (len == 13) + { + resword = &wordlist[1592]; + goto compare; + } + break; + case 6079: + if (len == 20) + { + resword = &wordlist[1593]; + goto compare; + } + break; + case 6082: + if (len == 4) + { + resword = &wordlist[1594]; + goto compare; + } + break; + case 6083: + if (len == 6) + { + resword = &wordlist[1595]; + goto compare; + } + break; + case 6089: + if (len == 4) + { + resword = &wordlist[1596]; + goto compare; + } + break; + case 6094: + if (len == 5) + { + resword = &wordlist[1597]; + goto compare; + } + break; + case 6105: + if (len == 4) + { + resword = &wordlist[1598]; + goto compare; + } + break; + case 6108: + if (len == 3) + { + resword = &wordlist[1599]; + goto compare; + } + break; + case 6111: + if (len == 5) + { + resword = &wordlist[1600]; + goto compare; + } + break; + case 6119: + if (len == 4) + { + resword = &wordlist[1601]; + goto compare; + } + break; + case 6120: + if (len == 6) + { + resword = &wordlist[1602]; + goto compare; + } + break; + case 6123: + if (len == 5) + { + resword = &wordlist[1603]; + goto compare; + } + break; + case 6126: + if (len == 5) + { + resword = &wordlist[1604]; + goto compare; + } + break; + case 6130: + if (len == 7) + { + resword = &wordlist[1605]; + goto compare; + } + break; + case 6135: + if (len == 8) + { + resword = &wordlist[1606]; + goto compare; + } + break; + case 6137: + if (len == 5) + { + resword = &wordlist[1607]; + goto compare; + } + break; + case 6140: + if (len == 6) + { + resword = &wordlist[1608]; + goto compare; + } + break; + case 6147: + if (len == 13) + { + resword = &wordlist[1609]; + goto compare; + } + break; + case 6157: + if (len == 8) + { + resword = &wordlist[1610]; + goto compare; + } + break; + case 6164: + if (len == 6) + { + resword = &wordlist[1611]; + goto compare; + } + break; + case 6174: + if (len == 5) + { + resword = &wordlist[1612]; + goto compare; + } + break; + case 6188: + if (len == 6) + { + resword = &wordlist[1613]; + goto compare; + } + break; + case 6195: + if (len == 8) + { + resword = &wordlist[1614]; + goto compare; + } + break; + case 6196: + if (len == 8) + { + resword = &wordlist[1615]; + goto compare; + } + break; + case 6199: + if (len == 7) + { + resword = &wordlist[1616]; + goto compare; + } + break; + case 6201: + if (len == 6) + { + resword = &wordlist[1617]; + goto compare; + } + break; + case 6205: + if (len == 9) + { + resword = &wordlist[1618]; + goto compare; + } + break; + case 6210: + if (len == 5) + { + resword = &wordlist[1619]; + goto compare; + } + break; + case 6226: + if (len == 11) + { + resword = &wordlist[1620]; + goto compare; + } + break; + case 6229: + if (len == 17) + { + resword = &wordlist[1621]; + goto compare; + } + break; + case 6234: + if (len == 16) + { + resword = &wordlist[1622]; + goto compare; + } + break; + case 6236: + if (len == 14) + { + resword = &wordlist[1623]; + goto compare; + } + break; + case 6238: + if (len == 13) + { + resword = &wordlist[1624]; + goto compare; + } + break; + case 6239: + if (len == 17) + { + resword = &wordlist[1625]; + goto compare; + } + break; + case 6240: + if (len == 4) + { + resword = &wordlist[1626]; + goto compare; + } + break; + case 6242: + if (len == 4) + { + resword = &wordlist[1627]; + goto compare; + } + break; + case 6244: + if (len == 6) + { + resword = &wordlist[1628]; + goto compare; + } + break; + case 6246: + if (len == 12) + { + resword = &wordlist[1629]; + goto compare; + } + break; + case 6248: + if (len == 5) + { + resword = &wordlist[1630]; + goto compare; + } + break; + case 6255: + if (len == 8) + { + resword = &wordlist[1631]; + goto compare; + } + break; + case 6271: + if (len == 17) + { + resword = &wordlist[1632]; + goto compare; + } + break; + case 6272: + if (len == 7) + { + resword = &wordlist[1633]; + goto compare; + } + break; + case 6308: + if (len == 14) + { + resword = &wordlist[1634]; + goto compare; + } + break; + case 6311: + if (len == 7) + { + resword = &wordlist[1635]; + goto compare; + } + break; + case 6313: + if (len == 5) + { + resword = &wordlist[1636]; + goto compare; + } + break; + case 6316: + if (len == 9) + { + resword = &wordlist[1637]; + goto compare; + } + break; + case 6319: + if (len == 5) + { + resword = &wordlist[1638]; + goto compare; + } + break; + case 6320: + if (len == 14) + { + resword = &wordlist[1639]; + goto compare; + } + break; + case 6325: + if (len == 6) + { + resword = &wordlist[1640]; + goto compare; + } + break; + case 6332: + if (len == 5) + { + resword = &wordlist[1641]; + goto compare; + } + break; + case 6333: + if (len == 6) + { + resword = &wordlist[1642]; + goto compare; + } + break; + case 6337: + if (len == 8) + { + resword = &wordlist[1643]; + goto compare; + } + break; + case 6345: + if (len == 6) + { + resword = &wordlist[1644]; + goto compare; + } + break; + case 6356: + if (len == 6) + { + resword = &wordlist[1645]; + goto compare; + } + break; + case 6358: + if (len == 7) + { + resword = &wordlist[1646]; + goto compare; + } + break; + case 6361: + if (len == 5) + { + resword = &wordlist[1647]; + goto compare; + } + break; + case 6362: + if (len == 5) + { + resword = &wordlist[1648]; + goto compare; + } + break; + case 6368: + if (len == 7) + { + resword = &wordlist[1649]; + goto compare; + } + break; + case 6369: + if (len == 8) + { + resword = &wordlist[1650]; + goto compare; + } + break; + case 6375: + if (len == 6) + { + resword = &wordlist[1651]; + goto compare; + } + break; + case 6380: + if (len == 15) + { + resword = &wordlist[1652]; + goto compare; + } + break; + case 6406: + if (len == 6) + { + resword = &wordlist[1653]; + goto compare; + } + break; + case 6410: + if (len == 6) + { + resword = &wordlist[1654]; + goto compare; + } + break; + case 6419: + if (len == 19) + { + resword = &wordlist[1655]; + goto compare; + } + break; + case 6421: + if (len == 6) + { + resword = &wordlist[1656]; + goto compare; + } + break; + case 6422: + if (len == 5) + { + resword = &wordlist[1657]; + goto compare; + } + break; + case 6423: + if (len == 5) + { + resword = &wordlist[1658]; + goto compare; + } + break; + case 6426: + if (len == 5) + { + resword = &wordlist[1659]; + goto compare; + } + break; + case 6430: + if (len == 6) + { + resword = &wordlist[1660]; + goto compare; + } + break; + case 6439: + if (len == 6) + { + resword = &wordlist[1661]; + goto compare; + } + break; + case 6440: + if (len == 5) + { + resword = &wordlist[1662]; + goto compare; + } + break; + case 6443: + if (len == 4) + { + resword = &wordlist[1663]; + goto compare; + } + break; + case 6449: + if (len == 3) + { + resword = &wordlist[1664]; + goto compare; + } + break; + case 6451: + if (len == 10) + { + resword = &wordlist[1665]; + goto compare; + } + break; + case 6462: + if (len == 5) + { + resword = &wordlist[1666]; + goto compare; + } + break; + case 6466: + if (len == 5) + { + resword = &wordlist[1667]; + goto compare; + } + break; + case 6483: + if (len == 9) + { + resword = &wordlist[1668]; + goto compare; + } + break; + case 6488: + if (len == 5) + { + resword = &wordlist[1669]; + goto compare; + } + break; + case 6489: + if (len == 5) + { + resword = &wordlist[1670]; + goto compare; + } + break; + case 6493: + if (len == 6) + { + resword = &wordlist[1671]; + goto compare; + } + break; + case 6497: + if (len == 4) + { + resword = &wordlist[1672]; + goto compare; + } + break; + case 6499: + if (len == 5) + { + resword = &wordlist[1673]; + goto compare; + } + break; + case 6515: + if (len == 6) + { + resword = &wordlist[1674]; + goto compare; + } + break; + case 6538: + if (len == 7) + { + resword = &wordlist[1675]; + goto compare; + } + break; + case 6540: + if (len == 8) + { + resword = &wordlist[1676]; + goto compare; + } + break; + case 6545: + if (len == 5) + { + resword = &wordlist[1677]; + goto compare; + } + break; + case 6547: + if (len == 18) + { + resword = &wordlist[1678]; + goto compare; + } + break; + case 6553: + if (len == 6) + { + resword = &wordlist[1679]; + goto compare; + } + break; + case 6556: + if (len == 14) + { + resword = &wordlist[1680]; + goto compare; + } + break; + case 6560: + if (len == 6) + { + resword = &wordlist[1681]; + goto compare; + } + break; + case 6561: + if (len == 10) + { + resword = &wordlist[1682]; + goto compare; + } + break; + case 6566: + if (len == 16) + { + resword = &wordlist[1683]; + goto compare; + } + break; + case 6576: + if (len == 9) + { + resword = &wordlist[1684]; + goto compare; + } + break; + case 6581: + if (len == 6) + { + resword = &wordlist[1685]; + goto compare; + } + break; + case 6592: + if (len == 7) + { + resword = &wordlist[1686]; + goto compare; + } + break; + case 6600: + if (len == 7) + { + resword = &wordlist[1687]; + goto compare; + } + break; + case 6617: + if (len == 4) + { + resword = &wordlist[1688]; + goto compare; + } + break; + case 6620: + if (len == 6) + { + resword = &wordlist[1689]; + goto compare; + } + break; + case 6623: + if (len == 5) + { + resword = &wordlist[1690]; + goto compare; + } + break; + case 6624: + if (len == 5) + { + resword = &wordlist[1691]; + goto compare; + } + break; + case 6629: + if (len == 5) + { + resword = &wordlist[1692]; + goto compare; + } + break; + case 6630: + if (len == 12) + { + resword = &wordlist[1693]; + goto compare; + } + break; + case 6632: + if (len == 6) + { + resword = &wordlist[1694]; + goto compare; + } + break; + case 6637: + if (len == 16) + { + resword = &wordlist[1695]; + goto compare; + } + break; + case 6646: + if (len == 6) + { + resword = &wordlist[1696]; + goto compare; + } + break; + case 6654: + if (len == 6) + { + resword = &wordlist[1697]; + goto compare; + } + break; + case 6656: + if (len == 5) + { + resword = &wordlist[1698]; + goto compare; + } + break; + case 6658: + if (len == 7) + { + resword = &wordlist[1699]; + goto compare; + } + break; + case 6661: + if (len == 5) + { + resword = &wordlist[1700]; + goto compare; + } + break; + case 6668: + if (len == 4) + { + resword = &wordlist[1701]; + goto compare; + } + break; + case 6669: + if (len == 12) + { + resword = &wordlist[1702]; + goto compare; + } + break; + case 6671: + if (len == 5) + { + resword = &wordlist[1703]; + goto compare; + } + break; + case 6673: + if (len == 5) + { + resword = &wordlist[1704]; + goto compare; + } + break; + case 6681: + if (len == 7) + { + resword = &wordlist[1705]; + goto compare; + } + break; + case 6690: + if (len == 5) + { + resword = &wordlist[1706]; + goto compare; + } + break; + case 6700: + if (len == 8) + { + resword = &wordlist[1707]; + goto compare; + } + break; + case 6702: + if (len == 9) + { + resword = &wordlist[1708]; + goto compare; + } + break; + case 6706: + if (len == 11) + { + resword = &wordlist[1709]; + goto compare; + } + break; + case 6710: + if (len == 5) + { + resword = &wordlist[1710]; + goto compare; + } + break; + case 6715: + if (len == 6) + { + resword = &wordlist[1711]; + goto compare; + } + break; + case 6723: + if (len == 8) + { + resword = &wordlist[1712]; + goto compare; + } + break; + case 6730: + if (len == 5) + { + resword = &wordlist[1713]; + goto compare; + } + break; + case 6738: + if (len == 5) + { + resword = &wordlist[1714]; + goto compare; + } + break; + case 6739: + if (len == 8) + { + resword = &wordlist[1715]; + goto compare; + } + break; + case 6741: + if (len == 14) + { + resword = &wordlist[1716]; + goto compare; + } + break; + case 6746: + if (len == 6) + { + resword = &wordlist[1717]; + goto compare; + } + break; + case 6751: + if (len == 5) + { + resword = &wordlist[1718]; + goto compare; + } + break; + case 6757: + if (len == 19) + { + resword = &wordlist[1719]; + goto compare; + } + break; + case 6759: + if (len == 31) + { + resword = &wordlist[1720]; + goto compare; + } + break; + case 6768: + if (len == 6) + { + resword = &wordlist[1721]; + goto compare; + } + break; + case 6776: + if (len == 5) + { + resword = &wordlist[1722]; + goto compare; + } + break; + case 6780: + if (len == 4) + { + resword = &wordlist[1723]; + goto compare; + } + break; + case 6783: + if (len == 10) + { + resword = &wordlist[1724]; + goto compare; + } + break; + case 6785: + if (len == 10) + { + resword = &wordlist[1725]; + goto compare; + } + break; + case 6792: + if (len == 5) + { + resword = &wordlist[1726]; + goto compare; + } + break; + case 6794: + if (len == 5) + { + resword = &wordlist[1727]; + goto compare; + } + break; + case 6795: + if (len == 4) + { + resword = &wordlist[1728]; + goto compare; + } + break; + case 6797: + if (len == 5) + { + resword = &wordlist[1729]; + goto compare; + } + break; + case 6799: + if (len == 5) + { + resword = &wordlist[1730]; + goto compare; + } + break; + case 6807: + if (len == 5) + { + resword = &wordlist[1731]; + goto compare; + } + break; + case 6815: + if (len == 4) + { + resword = &wordlist[1732]; + goto compare; + } + break; + case 6821: + if (len == 6) + { + resword = &wordlist[1733]; + goto compare; + } + break; + case 6826: + if (len == 3) + { + resword = &wordlist[1734]; + goto compare; + } + break; + case 6828: + if (len == 4) + { + resword = &wordlist[1735]; + goto compare; + } + break; + case 6834: + if (len == 5) + { + resword = &wordlist[1736]; + goto compare; + } + break; + case 6837: + if (len == 4) + { + resword = &wordlist[1737]; + goto compare; + } + break; + case 6842: + if (len == 5) + { + resword = &wordlist[1738]; + goto compare; + } + break; + case 6846: + if (len == 7) + { + resword = &wordlist[1739]; + goto compare; + } + break; + case 6855: + if (len == 5) + { + resword = &wordlist[1740]; + goto compare; + } + break; + case 6864: + if (len == 3) + { + resword = &wordlist[1741]; + goto compare; + } + break; + case 6868: + if (len == 11) + { + resword = &wordlist[1742]; + goto compare; + } + break; + case 6887: + if (len == 6) + { + resword = &wordlist[1743]; + goto compare; + } + break; + case 6904: + if (len == 15) + { + resword = &wordlist[1744]; + goto compare; + } + break; + case 6909: + if (len == 5) + { + resword = &wordlist[1745]; + goto compare; + } + break; + case 6911: + if (len == 7) + { + resword = &wordlist[1746]; + goto compare; + } + break; + case 6913: + if (len == 3) + { + resword = &wordlist[1747]; + goto compare; + } + break; + case 6914: + if (len == 3) + { + resword = &wordlist[1748]; + goto compare; + } + break; + case 6915: + if (len == 3) + { + resword = &wordlist[1749]; + goto compare; + } + break; + case 6916: + if (len == 3) + { + resword = &wordlist[1750]; + goto compare; + } + break; + case 6917: + if (len == 3) + { + resword = &wordlist[1751]; + goto compare; + } + break; + case 6922: + if (len == 3) + { + resword = &wordlist[1752]; + goto compare; + } + break; + case 6926: + if (len == 3) + { + resword = &wordlist[1753]; + goto compare; + } + break; + case 6927: + if (len == 5) + { + resword = &wordlist[1754]; + goto compare; + } + break; + case 6928: + if (len == 3) + { + resword = &wordlist[1755]; + goto compare; + } + break; + case 6929: + if (len == 3) + { + resword = &wordlist[1756]; + goto compare; + } + break; + case 6931: + if (len == 8) + { + resword = &wordlist[1757]; + goto compare; + } + break; + case 6933: + if (len == 5) + { + resword = &wordlist[1758]; + goto compare; + } + break; + case 6936: + if (len == 3) + { + resword = &wordlist[1759]; + goto compare; + } + break; + case 6938: + if (len == 5) + { + resword = &wordlist[1760]; + goto compare; + } + break; + case 6946: + if (len == 3) + { + resword = &wordlist[1761]; + goto compare; + } + break; + case 6948: + if (len == 8) + { + resword = &wordlist[1762]; + goto compare; + } + break; + case 6949: + if (len == 3) + { + resword = &wordlist[1763]; + goto compare; + } + break; + case 6950: + if (len == 8) + { + resword = &wordlist[1764]; + goto compare; + } + break; + case 6954: + if (len == 3) + { + resword = &wordlist[1765]; + goto compare; + } + break; + case 6961: + if (len == 7) + { + resword = &wordlist[1766]; + goto compare; + } + break; + case 6975: + if (len == 5) + { + resword = &wordlist[1767]; + goto compare; + } + break; + case 6979: + if (len == 3) + { + resword = &wordlist[1768]; + goto compare; + } + break; + case 6992: + if (len == 8) + { + resword = &wordlist[1769]; + goto compare; + } + break; + case 6997: + if (len == 3) + { + resword = &wordlist[1770]; + goto compare; + } + break; + case 7026: + if (len == 6) + { + resword = &wordlist[1771]; + goto compare; + } + break; + case 7029: + if (len == 5) + { + resword = &wordlist[1772]; + goto compare; + } + break; + case 7031: + if (len == 3) + { + resword = &wordlist[1773]; + goto compare; + } + break; + case 7032: + if (len == 3) + { + resword = &wordlist[1774]; + goto compare; + } + break; + case 7035: + if (len == 4) + { + resword = &wordlist[1775]; + goto compare; + } + break; + case 7036: + if (len == 20) + { + resword = &wordlist[1776]; + goto compare; + } + break; + case 7037: + if (len == 3) + { + resword = &wordlist[1777]; + goto compare; + } + break; + case 7038: + if (len == 7) + { + resword = &wordlist[1778]; + goto compare; + } + break; + case 7040: + if (len == 7) + { + resword = &wordlist[1779]; + goto compare; + } + break; + case 7050: + if (len == 4) + { + resword = &wordlist[1780]; + goto compare; + } + break; + case 7051: + if (len == 11) + { + resword = &wordlist[1781]; + goto compare; + } + break; + case 7054: + if (len == 3) + { + resword = &wordlist[1782]; + goto compare; + } + break; + case 7060: + if (len == 3) + { + resword = &wordlist[1783]; + goto compare; + } + break; + case 7062: + if (len == 3) + { + resword = &wordlist[1784]; + goto compare; + } + break; + case 7067: + if (len == 6) + { + resword = &wordlist[1785]; + goto compare; + } + break; + case 7069: + if (len == 3) + { + resword = &wordlist[1786]; + goto compare; + } + break; + case 7076: + if (len == 3) + { + resword = &wordlist[1787]; + goto compare; + } + break; + case 7077: + if (len == 6) + { + resword = &wordlist[1788]; + goto compare; + } + break; + case 7080: + if (len == 5) + { + resword = &wordlist[1789]; + goto compare; + } + break; + case 7083: + if (len == 3) + { + resword = &wordlist[1790]; + goto compare; + } + break; + case 7094: + if (len == 4) + { + resword = &wordlist[1791]; + goto compare; + } + break; + case 7097: + if (len == 3) + { + resword = &wordlist[1792]; + goto compare; + } + break; + case 7105: + if (len == 5) + { + resword = &wordlist[1793]; + goto compare; + } + break; + case 7107: + if (len == 5) + { + resword = &wordlist[1794]; + goto compare; + } + break; + case 7109: + if (len == 19) + { + resword = &wordlist[1795]; + goto compare; + } + break; + case 7115: + if (len == 6) + { + resword = &wordlist[1796]; + goto compare; + } + break; + case 7121: + if (len == 5) + { + resword = &wordlist[1797]; + goto compare; + } + break; + case 7127: + if (len == 3) + { + resword = &wordlist[1798]; + goto compare; + } + break; + case 7128: + if (len == 3) + { + resword = &wordlist[1799]; + goto compare; + } + break; + case 7148: + if (len == 3) + { + resword = &wordlist[1800]; + goto compare; + } + break; + case 7149: + if (len == 4) + { + resword = &wordlist[1801]; + goto compare; + } + break; + case 7157: + if (len == 5) + { + resword = &wordlist[1802]; + goto compare; + } + break; + case 7160: + if (len == 3) + { + resword = &wordlist[1803]; + goto compare; + } + break; + case 7167: + if (len == 6) + { + resword = &wordlist[1804]; + goto compare; + } + break; + case 7170: + if (len == 3) + { + resword = &wordlist[1805]; + goto compare; + } + break; + case 7171: + if (len == 12) + { + resword = &wordlist[1806]; + goto compare; + } + break; + case 7193: + if (len == 10) + { + resword = &wordlist[1807]; + goto compare; + } + break; + case 7203: + if (len == 7) + { + resword = &wordlist[1808]; + goto compare; + } + break; + case 7210: + if (len == 5) + { + resword = &wordlist[1809]; + goto compare; + } + break; + case 7216: + if (len == 18) + { + resword = &wordlist[1810]; + goto compare; + } + break; + case 7221: + if (len == 6) + { + resword = &wordlist[1811]; + goto compare; + } + break; + case 7231: + if (len == 3) + { + resword = &wordlist[1812]; + goto compare; + } + break; + case 7250: + if (len == 6) + { + resword = &wordlist[1813]; + goto compare; + } + break; + case 7260: + if (len == 14) + { + resword = &wordlist[1814]; + goto compare; + } + break; + case 7270: + if (len == 7) + { + resword = &wordlist[1815]; + goto compare; + } + break; + case 7272: + if (len == 5) + { + resword = &wordlist[1816]; + goto compare; + } + break; + case 7274: + if (len == 7) + { + resword = &wordlist[1817]; + goto compare; + } + break; + case 7281: + if (len == 8) + { + resword = &wordlist[1818]; + goto compare; + } + break; + case 7282: + if (len == 9) + { + resword = &wordlist[1819]; + goto compare; + } + break; + case 7290: + if (len == 3) + { + resword = &wordlist[1820]; + goto compare; + } + break; + case 7291: + if (len == 9) + { + resword = &wordlist[1821]; + goto compare; + } + break; + case 7293: + if (len == 3) + { + resword = &wordlist[1822]; + goto compare; + } + break; + case 7296: + if (len == 9) + { + resword = &wordlist[1823]; + goto compare; + } + break; + case 7300: + if (len == 7) + { + resword = &wordlist[1824]; + goto compare; + } + break; + case 7312: + if (len == 3) + { + resword = &wordlist[1825]; + goto compare; + } + break; + case 7317: + if (len == 6) + { + resword = &wordlist[1826]; + goto compare; + } + break; + case 7318: + if (len == 5) + { + resword = &wordlist[1827]; + goto compare; + } + break; + case 7323: + if (len == 3) + { + resword = &wordlist[1828]; + goto compare; + } + break; + case 7332: + if (len == 14) + { + resword = &wordlist[1829]; + goto compare; + } + break; + case 7333: + if (len == 4) + { + resword = &wordlist[1830]; + goto compare; + } + break; + case 7347: + if (len == 4) + { + resword = &wordlist[1831]; + goto compare; + } + break; + case 7371: + if (len == 4) + { + resword = &wordlist[1832]; + goto compare; + } + break; + case 7382: + if (len == 12) + { + resword = &wordlist[1833]; + goto compare; + } + break; + case 7385: + if (len == 6) + { + resword = &wordlist[1834]; + goto compare; + } + break; + case 7387: + if (len == 6) + { + resword = &wordlist[1835]; + goto compare; + } + break; + case 7394: + if (len == 7) + { + resword = &wordlist[1836]; + goto compare; + } + break; + case 7397: + if (len == 10) + { + resword = &wordlist[1837]; + goto compare; + } + break; + case 7404: + if (len == 10) + { + resword = &wordlist[1838]; + goto compare; + } + break; + case 7423: + if (len == 8) + { + resword = &wordlist[1839]; + goto compare; + } + break; + case 7430: + if (len == 4) + { + resword = &wordlist[1840]; + goto compare; + } + break; + case 7442: + if (len == 16) + { + resword = &wordlist[1841]; + goto compare; + } + break; + case 7452: + if (len == 6) + { + resword = &wordlist[1842]; + goto compare; + } + break; + case 7456: + if (len == 14) + { + resword = &wordlist[1843]; + goto compare; + } + break; + case 7457: + if (len == 13) + { + resword = &wordlist[1844]; + goto compare; + } + break; + case 7490: + if (len == 2) + { + resword = &wordlist[1845]; + goto compare; + } + break; + case 7491: + if (len == 10) + { + resword = &wordlist[1846]; + goto compare; + } + break; + case 7492: + if (len == 11) + { + resword = &wordlist[1847]; + goto compare; + } + break; + case 7494: + if (len == 15) + { + resword = &wordlist[1848]; + goto compare; + } + break; + case 7506: + if (len == 7) + { + resword = &wordlist[1849]; + goto compare; + } + break; + case 7511: + if (len == 16) + { + resword = &wordlist[1850]; + goto compare; + } + break; + case 7513: + if (len == 17) + { + resword = &wordlist[1851]; + goto compare; + } + break; + case 7525: + if (len == 6) + { + resword = &wordlist[1852]; + goto compare; + } + break; + case 7527: + if (len == 18) + { + resword = &wordlist[1853]; + goto compare; + } + break; + case 7528: + if (len == 8) + { + resword = &wordlist[1854]; + goto compare; + } + break; + case 7530: + if (len == 7) + { + resword = &wordlist[1855]; + goto compare; + } + break; + case 7531: + if (len == 10) + { + resword = &wordlist[1856]; + goto compare; + } + break; + case 7533: + if (len == 5) + { + resword = &wordlist[1857]; + goto compare; + } + break; + case 7539: + if (len == 3) + { + resword = &wordlist[1858]; + goto compare; + } + break; + case 7547: + if (len == 6) + { + resword = &wordlist[1859]; + goto compare; + } + break; + case 7549: + if (len == 8) + { + resword = &wordlist[1860]; + goto compare; + } + break; + case 7551: + if (len == 4) + { + resword = &wordlist[1861]; + goto compare; + } + break; + case 7565: + if (len == 3) + { + resword = &wordlist[1862]; + goto compare; + } + break; + case 7585: + if (len == 7) + { + resword = &wordlist[1863]; + goto compare; + } + break; + case 7586: + if (len == 13) + { + resword = &wordlist[1864]; + goto compare; + } + break; + case 7587: + if (len == 5) + { + resword = &wordlist[1865]; + goto compare; + } + break; + case 7592: + if (len == 14) + { + resword = &wordlist[1866]; + goto compare; + } + break; + case 7600: + if (len == 16) + { + resword = &wordlist[1867]; + goto compare; + } + break; + case 7601: + if (len == 13) + { + resword = &wordlist[1868]; + goto compare; + } + break; + case 7604: + if (len == 18) + { + resword = &wordlist[1869]; + goto compare; + } + break; + case 7610: + if (len == 5) + { + resword = &wordlist[1870]; + goto compare; + } + break; + case 7612: + if (len == 6) + { + resword = &wordlist[1871]; + goto compare; + } + break; + case 7633: + if (len == 4) + { + resword = &wordlist[1872]; + goto compare; + } + break; + case 7644: + if (len == 8) + { + resword = &wordlist[1873]; + goto compare; + } + break; + case 7647: + if (len == 16) + { + resword = &wordlist[1874]; + goto compare; + } + break; + case 7649: + if (len == 5) + { + resword = &wordlist[1875]; + goto compare; + } + break; + case 7672: + if (len == 18) + { + resword = &wordlist[1876]; + goto compare; + } + break; + case 7688: + if (len == 3) + { + resword = &wordlist[1877]; + goto compare; + } + break; + case 7721: + if (len == 2) + { + resword = &wordlist[1878]; + goto compare; + } + break; + case 7722: + if (len == 7) + { + resword = &wordlist[1879]; + goto compare; + } + break; + case 7729: + if (len == 5) + { + resword = &wordlist[1880]; + goto compare; + } + break; + case 7738: + if (len == 9) + { + resword = &wordlist[1881]; + goto compare; + } + break; + case 7760: + if (len == 3) + { + resword = &wordlist[1882]; + goto compare; + } + break; + case 7769: + if (len == 2) + { + resword = &wordlist[1883]; + goto compare; + } + break; + case 7835: + if (len == 5) + { + resword = &wordlist[1884]; + goto compare; + } + break; + case 7836: + if (len == 5) + { + resword = &wordlist[1885]; + goto compare; + } + break; + case 7839: + if (len == 6) + { + resword = &wordlist[1886]; + goto compare; + } + break; + case 7858: + if (len == 17) + { + resword = &wordlist[1887]; + goto compare; + } + break; + case 7873: + if (len == 6) + { + resword = &wordlist[1888]; + goto compare; + } + break; + case 7878: + if (len == 5) + { + resword = &wordlist[1889]; + goto compare; + } + break; + case 7885: + if (len == 5) + { + resword = &wordlist[1890]; + goto compare; + } + break; + case 7896: + if (len == 5) + { + resword = &wordlist[1891]; + goto compare; + } + break; + case 7901: + if (len == 4) + { + resword = &wordlist[1892]; + goto compare; + } + break; + case 7903: + if (len == 3) + { + resword = &wordlist[1893]; + goto compare; + } + break; + case 7904: + if (len == 5) + { + resword = &wordlist[1894]; + goto compare; + } + break; + case 7906: + if (len == 15) + { + resword = &wordlist[1895]; + goto compare; + } + break; + case 7919: + if (len == 13) + { + resword = &wordlist[1896]; + goto compare; + } + break; + case 7937: + if (len == 10) + { + resword = &wordlist[1897]; + goto compare; + } + break; + case 7963: + if (len == 5) + { + resword = &wordlist[1898]; + goto compare; + } + break; + case 8024: + if (len == 7) + { + resword = &wordlist[1899]; + goto compare; + } + break; + case 8027: + if (len == 21) + { + resword = &wordlist[1900]; + goto compare; + } + break; + case 8047: + if (len == 6) + { + resword = &wordlist[1901]; + goto compare; + } + break; + case 8064: + if (len == 6) + { + resword = &wordlist[1902]; + goto compare; + } + break; + case 8068: + if (len == 8) + { + resword = &wordlist[1903]; + goto compare; + } + break; + case 8084: + if (len == 8) + { + resword = &wordlist[1904]; + goto compare; + } + break; + case 8102: + if (len == 7) + { + resword = &wordlist[1905]; + goto compare; + } + break; + case 8116: + if (len == 21) + { + resword = &wordlist[1906]; + goto compare; + } + break; + case 8126: + if (len == 13) + { + resword = &wordlist[1907]; + goto compare; + } + break; + case 8128: + if (len == 3) + { + resword = &wordlist[1908]; + goto compare; + } + break; + case 8179: + if (len == 21) + { + resword = &wordlist[1909]; + goto compare; + } + break; + case 8214: + if (len == 7) + { + resword = &wordlist[1910]; + goto compare; + } + break; + case 8239: + if (len == 15) + { + resword = &wordlist[1911]; + goto compare; + } + break; + case 8240: + if (len == 6) + { + resword = &wordlist[1912]; + goto compare; + } + break; + case 8241: + if (len == 7) + { + resword = &wordlist[1913]; + goto compare; + } + break; + case 8249: + if (len == 7) + { + resword = &wordlist[1914]; + goto compare; + } + break; + case 8255: + if (len == 15) + { + resword = &wordlist[1915]; + goto compare; + } + break; + case 8272: + if (len == 16) + { + resword = &wordlist[1916]; + goto compare; + } + break; + case 8274: + if (len == 5) + { + resword = &wordlist[1917]; + goto compare; + } + break; + case 8307: + if (len == 5) + { + resword = &wordlist[1918]; + goto compare; + } + break; + case 8308: + if (len == 15) + { + resword = &wordlist[1919]; + goto compare; + } + break; + case 8309: + if (len == 8) + { + resword = &wordlist[1920]; + goto compare; + } + break; + case 8311: + if (len == 6) + { + resword = &wordlist[1921]; + goto compare; + } + break; + case 8343: + if (len == 7) + { + resword = &wordlist[1922]; + goto compare; + } + break; + case 8357: + if (len == 4) + { + resword = &wordlist[1923]; + goto compare; + } + break; + case 8364: + if (len == 5) + { + resword = &wordlist[1924]; + goto compare; + } + break; + case 8367: + if (len == 16) + { + resword = &wordlist[1925]; + goto compare; + } + break; + case 8368: + if (len == 15) + { + resword = &wordlist[1926]; + goto compare; + } + break; + case 8371: + if (len == 6) + { + resword = &wordlist[1927]; + goto compare; + } + break; + case 8386: + if (len == 5) + { + resword = &wordlist[1928]; + goto compare; + } + break; + case 8400: + if (len == 6) + { + resword = &wordlist[1929]; + goto compare; + } + break; + case 8439: + if (len == 6) + { + resword = &wordlist[1930]; + goto compare; + } + break; + case 8441: + if (len == 6) + { + resword = &wordlist[1931]; + goto compare; + } + break; + case 8473: + if (len == 8) + { + resword = &wordlist[1932]; + goto compare; + } + break; + case 8482: + if (len == 5) + { + resword = &wordlist[1933]; + goto compare; + } + break; + case 8484: + if (len == 5) + { + resword = &wordlist[1934]; + goto compare; + } + break; + case 8491: + if (len == 6) + { + resword = &wordlist[1935]; + goto compare; + } + break; + case 8499: + if (len == 15) + { + resword = &wordlist[1936]; + goto compare; + } + break; + case 8513: + if (len == 4) + { + resword = &wordlist[1937]; + goto compare; + } + break; + case 8521: + if (len == 7) + { + resword = &wordlist[1938]; + goto compare; + } + break; + case 8530: + if (len == 5) + { + resword = &wordlist[1939]; + goto compare; + } + break; + case 8536: + if (len == 11) + { + resword = &wordlist[1940]; + goto compare; + } + break; + case 8538: + if (len == 7) + { + resword = &wordlist[1941]; + goto compare; + } + break; + case 8546: + if (len == 4) + { + resword = &wordlist[1942]; + goto compare; + } + break; + case 8561: + if (len == 5) + { + resword = &wordlist[1943]; + goto compare; + } + break; + case 8567: + if (len == 11) + { + resword = &wordlist[1944]; + goto compare; + } + break; + case 8614: + if (len == 10) + { + resword = &wordlist[1945]; + goto compare; + } + break; + case 8618: + if (len == 13) + { + resword = &wordlist[1946]; + goto compare; + } + break; + case 8640: + if (len == 17) + { + resword = &wordlist[1947]; + goto compare; + } + break; + case 8648: + if (len == 16) + { + resword = &wordlist[1948]; + goto compare; + } + break; + case 8649: + if (len == 15) + { + resword = &wordlist[1949]; + goto compare; + } + break; + case 8657: + if (len == 3) + { + resword = &wordlist[1950]; + goto compare; + } + break; + case 8669: + if (len == 5) + { + resword = &wordlist[1951]; + goto compare; + } + break; + case 8671: + if (len == 5) + { + resword = &wordlist[1952]; + goto compare; + } + break; + case 8677: + if (len == 5) + { + resword = &wordlist[1953]; + goto compare; + } + break; + case 8693: + if (len == 7) + { + resword = &wordlist[1954]; + goto compare; + } + break; + case 8736: + if (len == 11) + { + resword = &wordlist[1955]; + goto compare; + } + break; + case 8769: + if (len == 6) + { + resword = &wordlist[1956]; + goto compare; + } + break; + case 8773: + if (len == 5) + { + resword = &wordlist[1957]; + goto compare; + } + break; + case 8775: + if (len == 3) + { + resword = &wordlist[1958]; + goto compare; + } + break; + case 8776: + if (len == 4) + { + resword = &wordlist[1959]; + goto compare; + } + break; + case 8779: + if (len == 6) + { + resword = &wordlist[1960]; + goto compare; + } + break; + case 8787: + if (len == 4) + { + resword = &wordlist[1961]; + goto compare; + } + break; + case 8794: + if (len == 6) + { + resword = &wordlist[1962]; + goto compare; + } + break; + case 8797: + if (len == 6) + { + resword = &wordlist[1963]; + goto compare; + } + break; + case 8798: + if (len == 5) + { + resword = &wordlist[1964]; + goto compare; + } + break; + case 8812: + if (len == 14) + { + resword = &wordlist[1965]; + goto compare; + } + break; + case 8814: + if (len == 6) + { + resword = &wordlist[1966]; + goto compare; + } + break; + case 8820: + if (len == 18) + { + resword = &wordlist[1967]; + goto compare; + } + break; + case 8821: + if (len == 7) + { + resword = &wordlist[1968]; + goto compare; + } + break; + case 8823: + if (len == 3) + { + resword = &wordlist[1969]; + goto compare; + } + break; + case 8870: + if (len == 4) + { + resword = &wordlist[1970]; + goto compare; + } + break; + case 8872: + if (len == 4) + { + resword = &wordlist[1971]; + goto compare; + } + break; + case 8929: + if (len == 15) + { + resword = &wordlist[1972]; + goto compare; + } + break; + case 8932: + if (len == 18) + { + resword = &wordlist[1973]; + goto compare; + } + break; + case 8962: + if (len == 11) + { + resword = &wordlist[1974]; + goto compare; + } + break; + case 8965: + if (len == 14) + { + resword = &wordlist[1975]; + goto compare; + } + break; + case 8966: + if (len == 4) + { + resword = &wordlist[1976]; + goto compare; + } + break; + case 8975: + if (len == 6) + { + resword = &wordlist[1977]; + goto compare; + } + break; + case 8992: + if (len == 6) + { + resword = &wordlist[1978]; + goto compare; + } + break; + case 8994: + if (len == 6) + { + resword = &wordlist[1979]; + goto compare; + } + break; + case 9014: + if (len == 6) + { + resword = &wordlist[1980]; + goto compare; + } + break; + case 9024: + if (len == 6) + { + resword = &wordlist[1981]; + goto compare; + } + break; + case 9037: + if (len == 5) + { + resword = &wordlist[1982]; + goto compare; + } + break; + case 9041: + if (len == 8) + { + resword = &wordlist[1983]; + goto compare; + } + break; + case 9047: + if (len == 4) + { + resword = &wordlist[1984]; + goto compare; + } + break; + case 9049: + if (len == 8) + { + resword = &wordlist[1985]; + goto compare; + } + break; + case 9061: + if (len == 8) + { + resword = &wordlist[1986]; + goto compare; + } + break; + case 9076: + if (len == 6) + { + resword = &wordlist[1987]; + goto compare; + } + break; + case 9089: + if (len == 16) + { + resword = &wordlist[1988]; + goto compare; + } + break; + case 9101: + if (len == 7) + { + resword = &wordlist[1989]; + goto compare; + } + break; + case 9109: + if (len == 5) + { + resword = &wordlist[1990]; + goto compare; + } + break; + case 9132: + if (len == 6) + { + resword = &wordlist[1991]; + goto compare; + } + break; + case 9137: + if (len == 6) + { + resword = &wordlist[1992]; + goto compare; + } + break; + case 9153: + if (len == 13) + { + resword = &wordlist[1993]; + goto compare; + } + break; + case 9155: + if (len == 12) + { + resword = &wordlist[1994]; + goto compare; + } + break; + case 9157: + if (len == 6) + { + resword = &wordlist[1995]; + goto compare; + } + break; + case 9158: + if (len == 6) + { + resword = &wordlist[1996]; + goto compare; + } + break; + case 9169: + if (len == 8) + { + resword = &wordlist[1997]; + goto compare; + } + break; + case 9177: + if (len == 11) + { + resword = &wordlist[1998]; + goto compare; + } + break; + case 9205: + if (len == 18) + { + resword = &wordlist[1999]; + goto compare; + } + break; + case 9218: + if (len == 6) + { + resword = &wordlist[2000]; + goto compare; + } + break; + case 9223: + if (len == 5) + { + resword = &wordlist[2001]; + goto compare; + } + break; + case 9226: + if (len == 6) + { + resword = &wordlist[2002]; + goto compare; + } + break; + case 9228: + if (len == 11) + { + resword = &wordlist[2003]; + goto compare; + } + break; + case 9250: + if (len == 4) + { + resword = &wordlist[2004]; + goto compare; + } + break; + case 9266: + if (len == 6) + { + resword = &wordlist[2005]; + goto compare; + } + break; + case 9277: + if (len == 14) + { + resword = &wordlist[2006]; + goto compare; + } + break; + case 9303: + if (len == 6) + { + resword = &wordlist[2007]; + goto compare; + } + break; + case 9324: + if (len == 9) + { + resword = &wordlist[2008]; + goto compare; + } + break; + case 9334: + if (len == 18) + { + resword = &wordlist[2009]; + goto compare; + } + break; + case 9344: + if (len == 5) + { + resword = &wordlist[2010]; + goto compare; + } + break; + case 9364: + if (len == 11) + { + resword = &wordlist[2011]; + goto compare; + } + break; + case 9370: + if (len == 5) + { + resword = &wordlist[2012]; + goto compare; + } + break; + case 9403: + if (len == 6) + { + resword = &wordlist[2013]; + goto compare; + } + break; + case 9404: + if (len == 10) + { + resword = &wordlist[2014]; + goto compare; + } + break; + case 9421: + if (len == 11) + { + resword = &wordlist[2015]; + goto compare; + } + break; + case 9422: + if (len == 14) + { + resword = &wordlist[2016]; + goto compare; + } + break; + case 9425: + if (len == 8) + { + resword = &wordlist[2017]; + goto compare; + } + break; + case 9435: + if (len == 19) + { + resword = &wordlist[2018]; + goto compare; + } + break; + case 9457: + if (len == 6) + { + resword = &wordlist[2019]; + goto compare; + } + break; + case 9462: + if (len == 14) + { + resword = &wordlist[2020]; + goto compare; + } + break; + case 9471: + if (len == 5) + { + resword = &wordlist[2021]; + goto compare; + } + break; + case 9532: + if (len == 13) + { + resword = &wordlist[2022]; + goto compare; + } + break; + case 9536: + if (len == 6) + { + resword = &wordlist[2023]; + goto compare; + } + break; + case 9553: + if (len == 5) + { + resword = &wordlist[2024]; + goto compare; + } + break; + case 9555: + if (len == 6) + { + resword = &wordlist[2025]; + goto compare; + } + break; + case 9567: + if (len == 6) + { + resword = &wordlist[2026]; + goto compare; + } + break; + case 9588: + if (len == 4) + { + resword = &wordlist[2027]; + goto compare; + } + break; + case 9601: + if (len == 19) + { + resword = &wordlist[2028]; + goto compare; + } + break; + case 9602: + if (len == 16) + { + resword = &wordlist[2029]; + goto compare; + } + break; + case 9605: + if (len == 21) + { + resword = &wordlist[2030]; + goto compare; + } + break; + case 9607: + if (len == 14) + { + resword = &wordlist[2031]; + goto compare; + } + break; + case 9615: + if (len == 7) + { + resword = &wordlist[2032]; + goto compare; + } + break; + case 9616: + if (len == 17) + { + resword = &wordlist[2033]; + goto compare; + } + break; + case 9635: + if (len == 7) + { + resword = &wordlist[2034]; + goto compare; + } + break; + case 9661: + if (len == 8) + { + resword = &wordlist[2035]; + goto compare; + } + break; + case 9669: + if (len == 6) + { + resword = &wordlist[2036]; + goto compare; + } + break; + case 9673: + if (len == 4) + { + resword = &wordlist[2037]; + goto compare; + } + break; + case 9680: + if (len == 5) + { + resword = &wordlist[2038]; + goto compare; + } + break; + case 9681: + if (len == 11) + { + resword = &wordlist[2039]; + goto compare; + } + break; + case 9683: + if (len == 4) + { + resword = &wordlist[2040]; + goto compare; + } + break; + case 9707: + if (len == 5) + { + resword = &wordlist[2041]; + goto compare; + } + break; + case 9716: + if (len == 7) + { + resword = &wordlist[2042]; + goto compare; + } + break; + case 9753: + if (len == 5) + { + resword = &wordlist[2043]; + goto compare; + } + break; + case 9768: + if (len == 13) + { + resword = &wordlist[2044]; + goto compare; + } + break; + case 9931: + if (len == 15) + { + resword = &wordlist[2045]; + goto compare; + } + break; + case 9947: + if (len == 6) + { + resword = &wordlist[2046]; + goto compare; + } + break; + case 9948: + if (len == 10) + { + resword = &wordlist[2047]; + goto compare; + } + break; + case 9973: + if (len == 3) + { + resword = &wordlist[2048]; + goto compare; + } + break; + case 9997: + if (len == 6) + { + resword = &wordlist[2049]; + goto compare; + } + break; + case 9999: + if (len == 6) + { + resword = &wordlist[2050]; + goto compare; + } + break; + case 10005: + if (len == 5) + { + resword = &wordlist[2051]; + goto compare; + } + break; + case 10036: + if (len == 5) + { + resword = &wordlist[2052]; + goto compare; + } + break; + case 10128: + if (len == 6) + { + resword = &wordlist[2053]; + goto compare; + } + break; + case 10157: + if (len == 3) + { + resword = &wordlist[2054]; + goto compare; + } + break; + case 10193: + if (len == 7) + { + resword = &wordlist[2055]; + goto compare; + } + break; + case 10201: + if (len == 15) + { + resword = &wordlist[2056]; + goto compare; + } + break; + case 10214: + if (len == 13) + { + resword = &wordlist[2057]; + goto compare; + } + break; + case 10257: + if (len == 15) + { + resword = &wordlist[2058]; + goto compare; + } + break; + case 10295: + if (len == 15) + { + resword = &wordlist[2059]; + goto compare; + } + break; + case 10336: + if (len == 6) + { + resword = &wordlist[2060]; + goto compare; + } + break; + case 10357: + if (len == 5) + { + resword = &wordlist[2061]; + goto compare; + } + break; + case 10437: + if (len == 5) + { + resword = &wordlist[2062]; + goto compare; + } + break; + case 10524: + if (len == 7) + { + resword = &wordlist[2063]; + goto compare; + } + break; + case 10617: + if (len == 6) + { + resword = &wordlist[2064]; + goto compare; + } + break; + case 10622: + if (len == 7) + { + resword = &wordlist[2065]; + goto compare; + } + break; + case 10635: + if (len == 9) + { + resword = &wordlist[2066]; + goto compare; + } + break; + case 10675: + if (len == 6) + { + resword = &wordlist[2067]; + goto compare; + } + break; + case 10691: + if (len == 4) + { + resword = &wordlist[2068]; + goto compare; + } + break; + case 10840: + if (len == 5) + { + resword = &wordlist[2069]; + goto compare; + } + break; + case 10869: + if (len == 11) + { + resword = &wordlist[2070]; + goto compare; + } + break; + case 10907: + if (len == 8) + { + resword = &wordlist[2071]; + goto compare; + } + break; + case 10943: + if (len == 6) + { + resword = &wordlist[2072]; + goto compare; + } + break; + case 10945: + if (len == 3) + { + resword = &wordlist[2073]; + goto compare; + } + break; + case 10979: + if (len == 7) + { + resword = &wordlist[2074]; + goto compare; + } + break; + case 11048: + if (len == 7) + { + resword = &wordlist[2075]; + goto compare; + } + break; + case 11120: + if (len == 6) + { + resword = &wordlist[2076]; + goto compare; + } + break; + case 11133: + if (len == 3) + { + resword = &wordlist[2077]; + goto compare; + } + break; + case 11162: + if (len == 17) + { + resword = &wordlist[2078]; + goto compare; + } + break; + case 11179: + if (len == 5) + { + resword = &wordlist[2079]; + goto compare; + } + break; + case 11216: + if (len == 5) + { + resword = &wordlist[2080]; + goto compare; + } + break; + case 11346: + if (len == 8) + { + resword = &wordlist[2081]; + goto compare; + } + break; + case 11454: + if (len == 13) + { + resword = &wordlist[2082]; + goto compare; + } + break; + case 11457: + if (len == 16) + { + resword = &wordlist[2083]; + goto compare; + } + break; + case 11462: + if (len == 8) + { + resword = &wordlist[2084]; + goto compare; + } + break; + case 11507: + if (len == 6) + { + resword = &wordlist[2085]; + goto compare; + } + break; + case 11518: + if (len == 13) + { + resword = &wordlist[2086]; + goto compare; + } + break; + case 11534: + if (len == 6) + { + resword = &wordlist[2087]; + goto compare; + } + break; + case 11573: + if (len == 6) + { + resword = &wordlist[2088]; + goto compare; + } + break; + case 11587: + if (len == 15) + { + resword = &wordlist[2089]; + goto compare; + } + break; + case 11590: + if (len == 18) + { + resword = &wordlist[2090]; + goto compare; + } + break; + case 11626: + if (len == 8) + { + resword = &wordlist[2091]; + goto compare; + } + break; + case 11648: + if (len == 8) + { + resword = &wordlist[2092]; + goto compare; + } + break; + case 11669: + if (len == 7) + { + resword = &wordlist[2093]; + goto compare; + } + break; + case 11696: + if (len == 6) + { + resword = &wordlist[2094]; + goto compare; + } + break; + case 11705: + if (len == 6) + { + resword = &wordlist[2095]; + goto compare; + } + break; + case 11726: + if (len == 10) + { + resword = &wordlist[2096]; + goto compare; + } + break; + case 11733: + if (len == 6) + { + resword = &wordlist[2097]; + goto compare; + } + break; + case 11762: + if (len == 11) + { + resword = &wordlist[2098]; + goto compare; + } + break; + case 11843: + if (len == 6) + { + resword = &wordlist[2099]; + goto compare; + } + break; + case 11870: + if (len == 11) + { + resword = &wordlist[2100]; + goto compare; + } + break; + case 11898: + if (len == 17) + { + resword = &wordlist[2101]; + goto compare; + } + break; + case 11996: + if (len == 8) + { + resword = &wordlist[2102]; + goto compare; + } + break; + case 12105: + if (len == 8) + { + resword = &wordlist[2103]; + goto compare; + } + break; + case 12159: + if (len == 10) + { + resword = &wordlist[2104]; + goto compare; + } + break; + case 12308: + if (len == 10) + { + resword = &wordlist[2105]; + goto compare; + } + break; + case 12482: + if (len == 16) + { + resword = &wordlist[2106]; + goto compare; + } + break; + case 12488: + if (len == 6) + { + resword = &wordlist[2107]; + goto compare; + } + break; + case 12489: + if (len == 12) + { + resword = &wordlist[2108]; + goto compare; + } + break; + case 12592: + if (len == 7) + { + resword = &wordlist[2109]; + goto compare; + } + break; + case 12611: + if (len == 11) + { + resword = &wordlist[2110]; + goto compare; + } + break; + case 12713: + if (len == 6) + { + resword = &wordlist[2111]; + goto compare; + } + break; + case 12801: + if (len == 8) + { + resword = &wordlist[2112]; + goto compare; + } + break; + case 13031: + if (len == 5) + { + resword = &wordlist[2113]; + goto compare; + } + break; + case 13147: + if (len == 6) + { + resword = &wordlist[2114]; + goto compare; + } + break; + case 13182: + if (len == 4) + { + resword = &wordlist[2115]; + goto compare; + } + break; + case 13278: + if (len == 6) + { + resword = &wordlist[2116]; + goto compare; + } + break; + case 13750: + if (len == 11) + { + resword = &wordlist[2117]; + goto compare; + } + break; + case 13907: + if (len == 16) + { + resword = &wordlist[2118]; + goto compare; + } + break; + case 13958: + if (len == 14) + { + resword = &wordlist[2119]; + goto compare; + } + break; + case 14276: + if (len == 14) + { + resword = &wordlist[2120]; + goto compare; + } + break; + case 14361: + if (len == 11) + { + resword = &wordlist[2121]; + goto compare; + } + break; + case 14447: + if (len == 8) + { + resword = &wordlist[2122]; + goto compare; + } + break; + case 15305: + if (len == 14) + { + resword = &wordlist[2123]; + goto compare; + } + break; + case 15620: + if (len == 15) + { + resword = &wordlist[2124]; + goto compare; + } + break; + } + return 0; + compare: + { + register const char *s = resword->name; + + if (*str == *s && !memcmp (str + 1, s + 1, len - 1)) + return resword; + } + } + } + return 0; +} diff --git a/src/autolink.c b/src/autolink.c index e7019fd..2d7ac55 100644 --- a/src/autolink.c +++ b/src/autolink.c @@ -8,274 +8,264 @@ #ifndef _MSC_VER #include #else -#define strncasecmp _strnicmp +#define strncasecmp _strnicmp #endif -int -hoedown_autolink_is_safe(const uint8_t *data, size_t size) -{ - static const size_t valid_uris_count = 6; - static const char *valid_uris[] = { - "http://", "https://", "/", "#", "ftp://", "mailto:" - }; - static const size_t valid_uris_size[] = { 7, 8, 1, 1, 6, 7 }; - size_t i; +int hoedown_autolink_is_safe(const uint8_t *data, size_t size) { + static const size_t valid_uris_count = 6; + static const char *valid_uris[] = { + "http://", "https://", "/", "#", "ftp://", "mailto:" + }; + static const size_t valid_uris_size[] = { 7, 8, 1, 1, 6, 7 }; - for (i = 0; i < valid_uris_count; ++i) { - size_t len = valid_uris_size[i]; + for (size_t i = 0; i < valid_uris_count; ++i) { + size_t len = valid_uris_size[i]; - if (size > len && - strncasecmp((char *)data, valid_uris[i], len) == 0 && - isalnum(data[len])) - return 1; - } + if (size > len && + strncasecmp((char *)data, valid_uris[i], len) == 0 && + isalnum(data[len])) + return 1; + } - return 0; + return 0; } -static size_t -autolink_delim(uint8_t *data, size_t link_end, size_t max_rewind, size_t size) -{ - uint8_t cclose, copen = 0; - size_t i; +static size_t autolink_delim(uint8_t *data, size_t link_end, size_t max_rewind, size_t size) { + uint8_t cclose, copen = 0; + size_t i; - for (i = 0; i < link_end; ++i) - if (data[i] == '<') { - link_end = i; - break; - } + for (i = 0; i < link_end; ++i) + if (data[i] == '<') { + link_end = i; + break; + } - while (link_end > 0) { - if (strchr("?!.,:", data[link_end - 1]) != NULL) - link_end--; + while (link_end > 0) { + if (strchr("?!.,:", data[link_end - 1]) != NULL) + link_end--; - else if (data[link_end - 1] == ';') { - size_t new_end = link_end - 2; + else if (data[link_end - 1] == ';') { + size_t new_end = link_end - 2; - while (new_end > 0 && isalpha(data[new_end])) - new_end--; + while (new_end > 0 && isalpha(data[new_end])) + new_end--; - if (new_end < link_end - 2 && data[new_end] == '&') - link_end = new_end; - else - link_end--; - } - else break; - } + if (new_end < link_end - 2 && data[new_end] == '&') + link_end = new_end; + else + link_end--; + } + else break; + } - if (link_end == 0) - return 0; + if (link_end == 0) + return 0; - cclose = data[link_end - 1]; + cclose = data[link_end - 1]; - switch (cclose) { - case '"': copen = '"'; break; - case '\'': copen = '\''; break; - case ')': copen = '('; break; - case ']': copen = '['; break; - case '}': copen = '{'; break; - } + switch (cclose) { + case '"': copen = '"'; break; + case '\'': copen = '\''; break; + case ')': copen = '('; break; + case ']': copen = '['; break; + case '}': copen = '{'; break; + } - if (copen != 0) { - size_t closing = 0; - size_t opening = 0; - size_t i = 0; + if (copen != 0) { + size_t closing = 0; + size_t opening = 0; + size_t i = 0; - /* Try to close the final punctuation sign in this same line; - * if we managed to close it outside of the URL, that means that it's - * not part of the URL. If it closes inside the URL, that means it - * is part of the URL. - * - * Examples: - * - * foo http://www.pokemon.com/Pikachu_(Electric) bar - * => http://www.pokemon.com/Pikachu_(Electric) - * - * foo (http://www.pokemon.com/Pikachu_(Electric)) bar - * => http://www.pokemon.com/Pikachu_(Electric) - * - * foo http://www.pokemon.com/Pikachu_(Electric)) bar - * => http://www.pokemon.com/Pikachu_(Electric)) - * - * (foo http://www.pokemon.com/Pikachu_(Electric)) bar - * => foo http://www.pokemon.com/Pikachu_(Electric) - */ + /* Try to close the final punctuation sign in this same line; + * if we managed to close it outside of the URL, that means that it's + * not part of the URL. If it closes inside the URL, that means it + * is part of the URL. + * + * Examples: + * + * foo http://www.pokemon.com/Pikachu_(Electric) bar + * => http://www.pokemon.com/Pikachu_(Electric) + * + * foo (http://www.pokemon.com/Pikachu_(Electric)) bar + * => http://www.pokemon.com/Pikachu_(Electric) + * + * foo http://www.pokemon.com/Pikachu_(Electric)) bar + * => http://www.pokemon.com/Pikachu_(Electric)) + * + * (foo http://www.pokemon.com/Pikachu_(Electric)) bar + * => foo http://www.pokemon.com/Pikachu_(Electric) + */ - while (i < link_end) { - if (data[i] == copen) - opening++; - else if (data[i] == cclose) - closing++; + while (i < link_end) { + if (data[i] == copen) + opening++; + else if (data[i] == cclose) + closing++; - i++; - } + i++; + } - if (closing != opening) - link_end--; - } + if (closing != opening) + link_end--; + } - return link_end; + return link_end; } -static size_t -check_domain(uint8_t *data, size_t size, int allow_short) -{ - size_t i, np = 0; +static size_t check_domain(uint8_t *data, size_t size, int allow_short) { + size_t i, np = 0; - if (!isalnum(data[0])) - return 0; + if (!isalnum(data[0])) + return 0; - for (i = 1; i < size - 1; ++i) { - if (strchr(".:", data[i]) != NULL) np++; - else if (!isalnum(data[i]) && data[i] != '-') break; - } + for (i = 1; i < size - 1; ++i) { + if (strchr(".:", data[i]) != NULL) np++; + else if (!isalnum(data[i]) && data[i] != '-') break; + } - 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; - } + 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; + } } -size_t -hoedown_autolink__www( - size_t *rewind_p, - hoedown_buffer *link, - uint8_t *data, - size_t max_rewind, - size_t size, - unsigned int flags) -{ - size_t link_end; +size_t hoedown_autolink__www( + size_t *rewind_p, + hoedown_buffer *link, + uint8_t *data, + size_t max_rewind, + size_t size, + unsigned int flags +) { + size_t link_end; - if (max_rewind > 0 && !ispunct(data[-1]) && !isspace(data[-1])) - return 0; + if (max_rewind > 0 && !ispunct(data[-1]) && !isspace(data[-1])) + return 0; - if (size < 4 || memcmp(data, "www.", strlen("www.")) != 0) - return 0; + if (size < 4 || memcmp(data, "www.", strlen("www.")) != 0) + return 0; - link_end = check_domain(data, size, 0); + link_end = check_domain(data, size, 0); - if (link_end == 0) - return 0; + if (link_end == 0) + return 0; - while (link_end < size && !isspace(data[link_end])) - link_end++; + while (link_end < size && !isspace(data[link_end])) + link_end++; - link_end = autolink_delim(data, link_end, max_rewind, size); + link_end = autolink_delim(data, link_end, max_rewind, size); - if (link_end == 0) - return 0; + if (link_end == 0) + return 0; - hoedown_buffer_put(link, data, link_end); - *rewind_p = 0; + hoedown_buffer_put(link, data, link_end); + *rewind_p = 0; - return (int)link_end; + return (int)link_end; } -size_t -hoedown_autolink__email( - size_t *rewind_p, - hoedown_buffer *link, - uint8_t *data, - size_t max_rewind, - size_t size, - unsigned int flags) -{ - size_t link_end, rewind; - int nb = 0, np = 0; +size_t hoedown_autolink__email( + size_t *rewind_p, + hoedown_buffer *link, + uint8_t *data, + size_t max_rewind, + size_t size, + unsigned int flags +) { + size_t link_end, rewind; + int nb = 0, np = 0; - for (rewind = 0; rewind < max_rewind; ++rewind) { - uint8_t c = data[-1 - rewind]; + for (rewind = 0; rewind < max_rewind; ++rewind) { + uint8_t c = data[-1 - rewind]; - if (isalnum(c)) - continue; + if (isalnum(c)) + continue; - if (strchr(".+-_", c) != NULL) - continue; + if (strchr(".+-_", c) != NULL) + continue; - break; - } + break; + } - if (rewind == 0) - return 0; + if (rewind == 0) + return 0; - for (link_end = 0; link_end < size; ++link_end) { - uint8_t c = data[link_end]; + for (link_end = 0; link_end < size; ++link_end) { + uint8_t c = data[link_end]; - if (isalnum(c)) - continue; + if (isalnum(c)) + continue; - if (c == '@') - nb++; - else if (c == '.' && link_end < size - 1) - np++; - else if (c != '-' && c != '_') - break; - } + if (c == '@') + nb++; + else if (c == '.' && link_end < size - 1) + np++; + else if (c != '-' && c != '_') + break; + } - if (link_end < 2 || nb != 1 || np == 0 || - !isalpha(data[link_end - 1])) - return 0; + if (link_end < 2 || nb != 1 || np == 0 || + !isalpha(data[link_end - 1])) + return 0; - link_end = autolink_delim(data, link_end, max_rewind, size); + link_end = autolink_delim(data, link_end, max_rewind, size); - if (link_end == 0) - return 0; + if (link_end == 0) + return 0; - hoedown_buffer_put(link, data - rewind, link_end + rewind); - *rewind_p = rewind; + hoedown_buffer_put(link, data - rewind, link_end + rewind); + *rewind_p = rewind; - return link_end; + return link_end; } -size_t -hoedown_autolink__url( - size_t *rewind_p, - hoedown_buffer *link, - uint8_t *data, - size_t max_rewind, - size_t size, - unsigned int flags) -{ - size_t link_end, rewind = 0, domain_len; +size_t hoedown_autolink__url( + size_t *rewind_p, + hoedown_buffer *link, + uint8_t *data, + size_t max_rewind, + size_t size, + unsigned int flags +) { + size_t link_end, rewind = 0, domain_len; - if (size < 4 || data[1] != '/' || data[2] != '/') - return 0; + if (size < 4 || data[1] != '/' || data[2] != '/') + return 0; - while (rewind < max_rewind && isalpha(data[-1 - rewind])) - rewind++; + while (rewind < max_rewind && isalpha(data[-1 - rewind])) + rewind++; - if (!hoedown_autolink_is_safe(data - rewind, size + rewind)) - return 0; + if (!hoedown_autolink_is_safe(data - rewind, size + rewind)) + return 0; - link_end = strlen("://"); + link_end = strlen("://"); - domain_len = check_domain( - data + link_end, - size - link_end, - flags & HOEDOWN_AUTOLINK_SHORT_DOMAINS); + domain_len = check_domain( + data + link_end, + size - link_end, + flags & HOEDOWN_AUTOLINK_SHORT_DOMAINS); - if (domain_len == 0) - return 0; + if (domain_len == 0) + return 0; - link_end += domain_len; - while (link_end < size && !isspace(data[link_end])) - link_end++; + link_end += domain_len; + while (link_end < size && !isspace(data[link_end])) + link_end++; - link_end = autolink_delim(data, link_end, max_rewind, size); + link_end = autolink_delim(data, link_end, max_rewind, size); - if (link_end == 0) - return 0; + if (link_end == 0) + return 0; - hoedown_buffer_put(link, data - rewind, link_end + rewind); - *rewind_p = rewind; + hoedown_buffer_put(link, data - rewind, link_end + rewind); + *rewind_p = rewind; - return link_end; + return link_end; } diff --git a/src/autolink.h b/src/autolink.h index 528885c..becc16b 100644 --- a/src/autolink.h +++ b/src/autolink.h @@ -15,7 +15,7 @@ extern "C" { *************/ typedef enum hoedown_autolink_flags { - HOEDOWN_AUTOLINK_SHORT_DOMAINS = (1 << 0) + HOEDOWN_AUTOLINK_SHORT_DOMAINS = (1 << 0) } hoedown_autolink_flags; @@ -27,16 +27,34 @@ typedef enum hoedown_autolink_flags { int hoedown_autolink_is_safe(const uint8_t *data, size_t size); /* hoedown_autolink__www: search for the next www link in data */ -size_t hoedown_autolink__www(size_t *rewind_p, hoedown_buffer *link, - uint8_t *data, size_t offset, size_t size, hoedown_autolink_flags flags); +size_t hoedown_autolink__www( + size_t *rewind_p, + hoedown_buffer *link, + uint8_t *data, + size_t offset, + size_t size, + hoedown_autolink_flags flags +); /* hoedown_autolink__email: search for the next email in data */ -size_t hoedown_autolink__email(size_t *rewind_p, hoedown_buffer *link, - uint8_t *data, size_t offset, size_t size, hoedown_autolink_flags flags); +size_t hoedown_autolink__email( + size_t *rewind_p, + hoedown_buffer *link, + uint8_t *data, + size_t offset, + size_t size, + hoedown_autolink_flags flags +); /* hoedown_autolink__url: search for the next URL in data */ -size_t hoedown_autolink__url(size_t *rewind_p, hoedown_buffer *link, - uint8_t *data, size_t offset, size_t size, hoedown_autolink_flags flags); +size_t hoedown_autolink__url( + size_t *rewind_p, + hoedown_buffer *link, + uint8_t *data, + size_t offset, + size_t size, + hoedown_autolink_flags flags +); #ifdef __cplusplus diff --git a/src/buffer.c b/src/buffer.c index 2ca0fd1..2726b7e 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -5,251 +5,211 @@ #include #include -void * -hoedown_malloc(size_t size) -{ - void *ret = malloc(size); +void hoedown_buffer_init( + hoedown_buffer *buf, + size_t unit, + hoedown_realloc_callback data_realloc, + hoedown_free_callback data_free +) { + assert(buf); - if (!ret) { - fprintf(stderr, "Allocation failed.\n"); - abort(); - } - - return ret; + buf->data = NULL; + buf->size = buf->asize = 0; + buf->unit = unit; + buf->data_realloc = data_realloc; + buf->data_free = data_free; } -void * -hoedown_calloc(size_t nmemb, size_t size) -{ - void *ret = calloc(nmemb, size); - - if (!ret) { - fprintf(stderr, "Allocation failed.\n"); - abort(); - } - - return ret; +void hoedown_buffer_uninit(hoedown_buffer *buf) { + buf->data_free(buf->data); } -void * -hoedown_realloc(void *ptr, size_t size) -{ - void *ret = realloc(ptr, size); - - if (!ret) { - fprintf(stderr, "Allocation failed.\n"); - abort(); - } - - return ret; +hoedown_buffer *hoedown_buffer_new(size_t unit) { + hoedown_buffer *ret = hoedown_malloc(sizeof (hoedown_buffer)); + hoedown_buffer_init(ret, unit, hoedown_realloc, free); + return ret; } -void -hoedown_buffer_init( - hoedown_buffer *buf, - size_t unit, - hoedown_realloc_callback data_realloc, - hoedown_free_callback data_free, - hoedown_free_callback buffer_free) -{ - assert(buf); - - buf->data = NULL; - buf->size = buf->asize = 0; - buf->unit = unit; - buf->data_realloc = data_realloc; - buf->data_free = data_free; - buf->buffer_free = buffer_free; +void hoedown_buffer_free(hoedown_buffer *buf) { + if (!buf) return; + hoedown_buffer_uninit(buf); + free(buf); } -hoedown_buffer * -hoedown_buffer_new(size_t unit) -{ - hoedown_buffer *ret = hoedown_malloc(sizeof (hoedown_buffer)); - hoedown_buffer_init(ret, unit, hoedown_realloc, free, free); - return ret; +void hoedown_buffer_reset(hoedown_buffer *buf) { + assert(buf && buf->unit); + + buf->data_free(buf->data); + buf->data = NULL; + buf->size = buf->asize = 0; } -void -hoedown_buffer_free(hoedown_buffer *buf) -{ - if (!buf) return; +void hoedown_buffer_grow(hoedown_buffer *buf, size_t neosz) { + size_t neoasz; + assert(buf && buf->unit); - buf->data_free(buf->data); + if (buf->asize >= neosz) + return; - if (buf->buffer_free) - buf->buffer_free(buf); + neoasz = buf->asize + buf->unit; + while (neoasz < neosz) + neoasz += buf->unit; + + buf->data = buf->data_realloc(buf->data, neoasz); + buf->asize = neoasz; } -void -hoedown_buffer_reset(hoedown_buffer *buf) -{ - assert(buf && buf->unit); +void hoedown_buffer_put(hoedown_buffer *buf, const uint8_t *data, size_t size) { + assert(buf && buf->unit); - buf->data_free(buf->data); - buf->data = NULL; - buf->size = buf->asize = 0; + if (buf->size + size > buf->asize) + hoedown_buffer_grow(buf, buf->size + size); + + memcpy(buf->data + buf->size, data, size); + buf->size += size; } -void -hoedown_buffer_grow(hoedown_buffer *buf, size_t neosz) -{ - size_t neoasz; - assert(buf && buf->unit); - - if (buf->asize >= neosz) - return; - - neoasz = buf->asize + buf->unit; - while (neoasz < neosz) - neoasz += buf->unit; - - buf->data = buf->data_realloc(buf->data, neoasz); - buf->asize = neoasz; +void hoedown_buffer_puts(hoedown_buffer *buf, const char *str) { + hoedown_buffer_put(buf, (const uint8_t *)str, strlen(str)); } -void -hoedown_buffer_put(hoedown_buffer *buf, const uint8_t *data, size_t size) -{ - assert(buf && buf->unit); +void hoedown_buffer_putc(hoedown_buffer *buf, uint8_t c) { + assert(buf && buf->unit); - if (buf->size + size > buf->asize) - hoedown_buffer_grow(buf, buf->size + size); + if (buf->size >= buf->asize) + hoedown_buffer_grow(buf, buf->size + 1); - memcpy(buf->data + buf->size, data, size); - buf->size += size; + buf->data[buf->size] = c; + buf->size += 1; } -void -hoedown_buffer_puts(hoedown_buffer *buf, const char *str) -{ - hoedown_buffer_put(buf, (const uint8_t *)str, strlen(str)); +void hoedown_buffer_set(hoedown_buffer *buf, const uint8_t *data, size_t size) { + assert(buf && buf->unit); + + if (size > buf->asize) + hoedown_buffer_grow(buf, size); + + memcpy(buf->data, data, size); + buf->size = size; } -void -hoedown_buffer_putc(hoedown_buffer *buf, uint8_t c) -{ - assert(buf && buf->unit); - - if (buf->size >= buf->asize) - hoedown_buffer_grow(buf, buf->size + 1); - - buf->data[buf->size] = c; - buf->size += 1; +void hoedown_buffer_sets(hoedown_buffer *buf, const char *str) { + hoedown_buffer_set(buf, (const uint8_t *)str, strlen(str)); } -void -hoedown_buffer_set(hoedown_buffer *buf, const uint8_t *data, size_t size) -{ - assert(buf && buf->unit); - - if (size > buf->asize) - hoedown_buffer_grow(buf, size); - - memcpy(buf->data, data, size); - buf->size = size; +int hoedown_buffer_eq(const hoedown_buffer *buf, const uint8_t *data, size_t size) { + if (buf->size != size) return 0; + return memcmp(buf->data, data, size) == 0; } -void -hoedown_buffer_sets(hoedown_buffer *buf, const char *str) -{ - hoedown_buffer_set(buf, (const uint8_t *)str, strlen(str)); +int hoedown_buffer_eqs(const hoedown_buffer *buf, const char *str) { + return hoedown_buffer_eq(buf, (const uint8_t *)str, strlen(str)); } -int -hoedown_buffer_eq(const hoedown_buffer *buf, const uint8_t *data, size_t size) -{ - if (buf->size != size) return 0; - return memcmp(buf->data, data, size) == 0; +int hoedown_buffer_prefix(const hoedown_buffer *buf, const char *prefix) { + assert(buf && buf->unit); + + for (size_t i = 0; i < buf->size; ++i) { + if (prefix[i] == 0) + return 0; + + if (buf->data[i] != prefix[i]) + return buf->data[i] - prefix[i]; + } + + return 0; } -int -hoedown_buffer_eqs(const hoedown_buffer *buf, const char *str) -{ - return hoedown_buffer_eq(buf, (const uint8_t *)str, strlen(str)); +void hoedown_buffer_slurp(hoedown_buffer *buf, size_t size) { + assert(buf && buf->unit); + + if (size >= buf->size) { + buf->size = 0; + return; + } + + buf->size -= size; + memmove(buf->data, buf->data + size, buf->size); } -int -hoedown_buffer_prefix(const hoedown_buffer *buf, const char *prefix) -{ - size_t i; +const char *hoedown_buffer_cstr(hoedown_buffer *buf) { + assert(buf && buf->unit); - assert(buf && buf->unit); + if (buf->size < buf->asize && buf->data[buf->size] == 0) + return (char *)buf->data; - for (i = 0; i < buf->size; ++i) { - if (prefix[i] == 0) - return 0; + hoedown_buffer_grow(buf, buf->size + 1); + buf->data[buf->size] = 0; - if (buf->data[i] != prefix[i]) - return buf->data[i] - prefix[i]; - } - - return 0; + return (char *)buf->data; } -void -hoedown_buffer_slurp(hoedown_buffer *buf, size_t size) -{ - assert(buf && buf->unit); +void hoedown_buffer_printf(hoedown_buffer *buf, const char *fmt, ...) { + va_list ap; + int n; - if (size >= buf->size) { - buf->size = 0; - return; - } + assert(buf && buf->unit); - buf->size -= size; - memmove(buf->data, buf->data + size, buf->size); -} + if (buf->size >= buf->asize) + hoedown_buffer_grow(buf, buf->size + 1); -const char * -hoedown_buffer_cstr(hoedown_buffer *buf) -{ - assert(buf && buf->unit); + va_start(ap, fmt); + n = vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap); + va_end(ap); - if (buf->size < buf->asize && buf->data[buf->size] == 0) - return (char *)buf->data; - - hoedown_buffer_grow(buf, buf->size + 1); - buf->data[buf->size] = 0; - - return (char *)buf->data; -} - -void -hoedown_buffer_printf(hoedown_buffer *buf, const char *fmt, ...) -{ - va_list ap; - int n; - - assert(buf && buf->unit); - - if (buf->size >= buf->asize) - hoedown_buffer_grow(buf, buf->size + 1); - - va_start(ap, fmt); - n = vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap); - va_end(ap); - - if (n < 0) { + if (n < 0) { #ifndef _MSC_VER - return; + return; #else - va_start(ap, fmt); - n = _vscprintf(fmt, ap); - va_end(ap); + va_start(ap, fmt); + n = _vscprintf(fmt, ap); + va_end(ap); #endif - } + } - if ((size_t)n >= buf->asize - buf->size) { - hoedown_buffer_grow(buf, buf->size + n + 1); + if ((size_t)n >= buf->asize - buf->size) { + hoedown_buffer_grow(buf, buf->size + n + 1); - va_start(ap, fmt); - n = vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap); - va_end(ap); - } + va_start(ap, fmt); + n = vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap); + va_end(ap); + } - if (n < 0) - return; + if (n < 0) + return; - buf->size += n; + buf->size += n; } + +void hoedown_buffer_put_utf8(hoedown_buffer *ob, unsigned int c) { + unsigned char unichar[4]; + + if (c < 0x80) { + hoedown_buffer_putc(ob, c); + } + else if (c < 0x800) { + unichar[0] = 192 + (c / 64); + unichar[1] = 128 + (c % 64); + hoedown_buffer_put(ob, unichar, 2); + } + else if (c - 0xd800u < 0x800) { + HOEDOWN_BUFPUTSL(ob, "\xef\xbf\xbd"); + } + else if (c < 0x10000) { + unichar[0] = 224 + (c / 4096); + unichar[1] = 128 + (c / 64) % 64; + unichar[2] = 128 + (c % 64); + hoedown_buffer_put(ob, unichar, 3); + } + else if (c < 0x110000) { + unichar[0] = 240 + (c / 262144); + unichar[1] = 128 + (c / 4096) % 64; + unichar[2] = 128 + (c / 64) % 64; + unichar[3] = 128 + (c % 64); + hoedown_buffer_put(ob, unichar, 4); + } + else { + HOEDOWN_BUFPUTSL(ob, "\xef\xbf\xbd"); + } +} + diff --git a/src/buffer.h b/src/buffer.h index fcda83c..1e38c06 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -27,18 +27,27 @@ extern "C" { typedef void *(*hoedown_realloc_callback)(void *, size_t); typedef void (*hoedown_free_callback)(void *); -struct hoedown_buffer { - uint8_t *data; /* actual character data */ - size_t size; /* size of the string */ - size_t asize; /* allocated size (0 = volatile buffer) */ - size_t unit; /* reallocation unit size (0 = read-only buffer) */ +typedef struct hoedown_buffer { + uint8_t *data; /* actual character data */ + size_t size; /* size of the string */ + size_t asize; /* allocated size (0 = volatile buffer) */ + size_t unit; /* reallocation unit size (0 = read-only buffer) */ - hoedown_realloc_callback data_realloc; - hoedown_free_callback data_free; - hoedown_free_callback buffer_free; -}; + hoedown_realloc_callback data_realloc; + hoedown_free_callback data_free; +} hoedown_buffer; -typedef struct hoedown_buffer hoedown_buffer; +/* malloc / realloc / calloc wrappers */ +#define HOEDOWN_ALLOC_WRAPPER(sig, call) \ + static inline void *hoedown_##sig __attribute__ ((malloc)); \ + static inline void *hoedown_##sig { \ + void *ret = call; \ + if (!ret) { \ + fprintf(stderr, "Allocation failed.\n"); \ + abort(); \ + } \ + return ret; \ + } /************* @@ -46,19 +55,21 @@ typedef struct hoedown_buffer hoedown_buffer; *************/ /* allocation wrappers */ -void *hoedown_malloc(size_t size) __attribute__ ((malloc)); -void *hoedown_calloc(size_t nmemb, size_t size) __attribute__ ((malloc)); -void *hoedown_realloc(void *ptr, size_t size) __attribute__ ((malloc)); +HOEDOWN_ALLOC_WRAPPER(malloc(size_t size), malloc(size)); +HOEDOWN_ALLOC_WRAPPER(calloc(size_t nmemb, size_t size), calloc(nmemb, size)); +HOEDOWN_ALLOC_WRAPPER(realloc(void *ptr, size_t size), realloc(ptr, size)); /* hoedown_buffer_init: initialize a buffer with custom allocators */ void hoedown_buffer_init( - hoedown_buffer *buffer, - size_t unit, - hoedown_realloc_callback data_realloc, - hoedown_free_callback data_free, - hoedown_free_callback buffer_free + hoedown_buffer *buffer, + size_t unit, + hoedown_realloc_callback data_realloc, + hoedown_free_callback data_free ); +/* hoedown_buffer_uninit: uninitialize an existing buffer */ +void hoedown_buffer_uninit(hoedown_buffer *buf); + /* hoedown_buffer_new: allocate a new buffer */ hoedown_buffer *hoedown_buffer_new(size_t unit) __attribute__ ((malloc)); @@ -101,21 +112,24 @@ const char *hoedown_buffer_cstr(hoedown_buffer *buf); /* hoedown_buffer_printf: formatted printing to a buffer */ void hoedown_buffer_printf(hoedown_buffer *buf, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); +/* hoedown_buffer_put_utf8: put a Unicode character encoded as UTF-8 */ +void hoedown_buffer_put_utf8(hoedown_buffer *buf, unsigned int codepoint); + /* hoedown_buffer_free: free the buffer */ void hoedown_buffer_free(hoedown_buffer *buf); /* HOEDOWN_BUFPUTSL: optimized hoedown_buffer_puts of a string literal */ #define HOEDOWN_BUFPUTSL(output, literal) \ - hoedown_buffer_put(output, (const uint8_t *)literal, sizeof(literal) - 1) + hoedown_buffer_put(output, (const uint8_t *)literal, sizeof(literal) - 1) /* HOEDOWN_BUFSETSL: optimized hoedown_buffer_sets of a string literal */ #define HOEDOWN_BUFSETSL(output, literal) \ - hoedown_buffer_set(output, (const uint8_t *)literal, sizeof(literal) - 1) + hoedown_buffer_set(output, (const uint8_t *)literal, sizeof(literal) - 1) /* HOEDOWN_BUFEQSL: optimized hoedown_buffer_eqs of a string literal */ #define HOEDOWN_BUFEQSL(output, literal) \ - hoedown_buffer_eq(output, (const uint8_t *)literal, sizeof(literal) - 1) + hoedown_buffer_eq(output, (const uint8_t *)literal, sizeof(literal) - 1) #ifdef __cplusplus diff --git a/src/document.c b/src/document.c index 3ce4416..2541636 100644 --- a/src/document.c +++ b/src/document.c @@ -1,2953 +1,2419 @@ #include "document.h" -#include +#include "pool.h" +#include "escape.h" + #include -#include -#include +#include -#include "stack.h" -#ifndef _MSC_VER -#include -#else -#define strncasecmp _strnicmp -#endif +#define likely(x) __builtin_expect((x),1) +#define unlikely(x) __builtin_expect((x),0) -#define REF_TABLE_SIZE 8 -#define BUFFER_BLOCK 0 -#define BUFFER_SPAN 1 -#define HOEDOWN_LI_END 8 /* internal list flag */ +// GENERAL INITIALIZATION +// ---------------------- +// +// Define hoedown_document, and export the constructor, destructor +// and general utilities and types used across the code. -const char *hoedown_find_block_tag(const char *str, unsigned int len); -/*************** - * LOCAL TYPES * - ***************/ +#define LINK_REFS_TABLE_SIZE 16 -/* link_ref: reference to a link */ struct link_ref { - unsigned int id; + unsigned int id; + hoedown_buffer *dest; + hoedown_buffer *title; + int has_title; - hoedown_buffer *link; - hoedown_buffer *title; - - struct link_ref *next; + struct link_ref *next; }; -/* footnote_ref: reference to a footnote */ -struct footnote_ref { - unsigned int id; +static void *new_link_ref(void *opaque) { + struct link_ref *ref = malloc(sizeof(struct link_ref)); + ref->dest = hoedown_buffer_new(16); + ref->title = hoedown_buffer_new(16); + return ref; +} - int is_used; - unsigned int num; +static void free_link_ref(void *item, void *opaque) { + struct link_ref *ref = item; + hoedown_buffer_free(ref->title); + hoedown_buffer_free(ref->dest); +} - hoedown_buffer *contents; -}; -/* footnote_item: an item in a footnote_list */ -struct footnote_item { - struct footnote_ref *ref; - struct footnote_item *next; -}; +typedef size_t (*char_trigger)(hoedown_document *doc, void *target, const uint8_t *data, size_t parsed, size_t start, size_t size); +typedef int (*delimiter_check)(hoedown_document *doc, const uint8_t *data, size_t parsed, size_t start, size_t size, void *opaque); -/* footnote_list: linked list of footnote_item */ -struct footnote_list { - unsigned int count; - struct footnote_item *head; - struct footnote_item *tail; -}; +static inline void restrict_features(const hoedown_renderer *rndr, hoedown_features *ft); +static inline void set_active_chars(char_trigger *active_chars, hoedown_features ft); -/* char_trigger: function pointer to render active chars */ -/* returns the number of chars taken care of */ -/* data is the pointer of the beginning of the span */ -/* offset is the number of valid chars before data */ -typedef size_t -(*char_trigger)(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size); +enum parsing_mode { + // Skip all blocks without parsing their inline content, + // but still parse block content. + DUMB_PARSING, -static size_t char_emphasis(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size); -static size_t char_quote(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size); -static size_t char_linebreak(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size); -static size_t char_codespan(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size); -static size_t char_escape(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size); -static size_t char_entity(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size); -static size_t char_langle_tag(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size); -static size_t char_autolink_url(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size); -static size_t char_autolink_email(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size); -static size_t char_autolink_www(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size); -static size_t char_link(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size); -static size_t char_superscript(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size); -static size_t char_math(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size); + // In this mode, blocks are parsed, but not rendered. + // The content of a block is not parsed unless it's also block content, + // or it's the content of a marker. + // + // This mode is used once when rendering, to parse the markers of a document. + // Markers themselves aren't rendered, but their content is parsed, rendered + // and hashed for later. + MARKER_PARSING, -enum markdown_char_t { - MD_CHAR_NONE = 0, - MD_CHAR_EMPHASIS, - MD_CHAR_CODESPAN, - MD_CHAR_LINEBREAK, - MD_CHAR_LINK, - MD_CHAR_LANGLE, - MD_CHAR_ESCAPE, - MD_CHAR_ENTITY, - MD_CHAR_AUTOLINK_URL, - MD_CHAR_AUTOLINK_EMAIL, - MD_CHAR_AUTOLINK_WWW, - MD_CHAR_SUPERSCRIPT, - MD_CHAR_QUOTE, - MD_CHAR_MATH -}; - -static char_trigger markdown_char_ptrs[] = { - NULL, - &char_emphasis, - &char_codespan, - &char_linebreak, - &char_link, - &char_langle_tag, - &char_escape, - &char_entity, - &char_autolink_url, - &char_autolink_email, - &char_autolink_www, - &char_superscript, - &char_quote, - &char_math + // This is the normal mode of operation. Everything is parsed and renderer, + // except markers, which are simply skipped. + // + // After parsing with MARKER_PARSING mode, this mode is used to parse + // and render the document. + NORMAL_PARSING, }; struct hoedown_document { - hoedown_renderer md; - hoedown_renderer_data data; + // user-specified + hoedown_renderer rndr; + hoedown_features ft; + size_t max_nesting; - struct link_ref *refs[REF_TABLE_SIZE]; - struct footnote_list footnotes_found; - struct footnote_list footnotes_used; - uint8_t active_char[256]; - hoedown_stack work_bufs[2]; - hoedown_extensions ext_flags; - size_t max_nesting; - int in_link_body; + // for renderer use + hoedown_renderer_data data; + + // for general operation + size_t current_nesting; + size_t is_tight; + enum parsing_mode mode; + int inside_link; + hoedown_buffer *text; + + // for marker parsing + hoedown_pool marker_link_refs; + struct link_ref *link_refs_table [LINK_REFS_TABLE_SIZE]; + + // for normal parsing + hoedown_pool buffers_block; + hoedown_pool buffers_inline; + char_trigger active_chars[256]; }; -/*************************** - * HELPER FUNCTIONS * - ***************************/ +hoedown_document *hoedown_document_new( + hoedown_renderer *renderer, + hoedown_features features, + size_t max_nesting +) { + restrict_features(renderer, &features); -static hoedown_buffer * -newbuf(hoedown_document *doc, int type) -{ - static const size_t buf_size[2] = {256, 64}; - hoedown_buffer *work = NULL; - hoedown_stack *pool = &doc->work_bufs[type]; + hoedown_document *doc = hoedown_malloc(sizeof(hoedown_document)); - if (pool->size < pool->asize && - pool->item[pool->size] != NULL) { - work = pool->item[pool->size++]; - work->size = 0; - } else { - work = hoedown_buffer_new(buf_size[type]); - hoedown_stack_push(pool, work); - } + memcpy(&doc->rndr, renderer, sizeof(hoedown_renderer)); + doc->ft = features; + doc->max_nesting = max_nesting; - return work; -} - -static void -popbuf(hoedown_document *doc, int type) -{ - doc->work_bufs[type].size--; -} + doc->data.doc = (hoedown_internal *)doc; + doc->data.opaque = renderer->opaque; -static void -unscape_text(hoedown_buffer *ob, hoedown_buffer *src) -{ - size_t i = 0, org; - while (i < src->size) { - org = i; - while (i < src->size && src->data[i] != '\\') - i++; + doc->current_nesting = 0; + doc->inside_link = 0; + doc->is_tight = 0; + doc->text = hoedown_buffer_new(64); - if (i > org) - hoedown_buffer_put(ob, src->data + org, i - org); + //FIXME: this needs limiting + hoedown_pool_init(&doc->marker_link_refs, 4, new_link_ref, free_link_ref, NULL); - if (i + 1 >= src->size) - break; + hoedown_buffer_pool_init(&doc->buffers_block, 4, 16); + hoedown_buffer_pool_init(&doc->buffers_inline, 8, 16); + set_active_chars(doc->active_chars, features); - hoedown_buffer_putc(ob, src->data[i + 1]); - i += 2; - } + return doc; } -static unsigned int -hash_link_ref(const uint8_t *link_ref, size_t length) -{ - size_t i; - unsigned int hash = 0; +void hoedown_document_free(hoedown_document *doc) { + if (!doc) return; - for (i = 0; i < length; ++i) - hash = tolower(link_ref[i]) + (hash << 6) + (hash << 16) - hash; + hoedown_buffer_free(doc->text); - return hash; -} + hoedown_pool_uninit(&doc->marker_link_refs); -static struct link_ref * -add_link_ref( - struct link_ref **references, - const uint8_t *name, size_t name_size) -{ - struct link_ref *ref = hoedown_calloc(1, sizeof(struct link_ref)); + hoedown_pool_uninit(&doc->buffers_block); + hoedown_pool_uninit(&doc->buffers_inline); - ref->id = hash_link_ref(name, name_size); - ref->next = references[ref->id % REF_TABLE_SIZE]; - - references[ref->id % REF_TABLE_SIZE] = ref; - return ref; + free(doc); } -static struct link_ref * -find_link_ref(struct link_ref **references, uint8_t *name, size_t length) -{ - unsigned int hash = hash_link_ref(name, length); - struct link_ref *ref = NULL; - ref = references[hash % REF_TABLE_SIZE]; - while (ref != NULL) { - if (ref->id == hash) - return ref; +// LOW LEVEL PARSING UTILITIES +// --------------------------- +// +// Very simple methods that help in parsing. We could use isalpha, isspace, +// isalnum and friends, but they're locale dependent. We don't like that. +// +// **Important:** the code in the section below for parsing HTML depends on +// these functions. If any of these functions is modified, the code at the +// section below should call a (preserved) copy instead. - ref = ref->next; - } - return NULL; +// Checks if the char is an ASCII digit. +static inline int is_digit_ascii(uint8_t ch) { + return ch >= '0' && ch <= '9'; } -static void -free_link_refs(struct link_ref **references) -{ - size_t i; - - for (i = 0; i < REF_TABLE_SIZE; ++i) { - struct link_ref *r = references[i]; - struct link_ref *next; - - while (r) { - next = r->next; - hoedown_buffer_free(r->link); - hoedown_buffer_free(r->title); - free(r); - r = next; - } - } +// Checks if the char is an uppercase ASCII letter. +static inline int is_upper_ascii(uint8_t ch) { + return ch >= 'A' && ch <= 'Z'; } -static struct footnote_ref * -create_footnote_ref(struct footnote_list *list, const uint8_t *name, size_t name_size) -{ - struct footnote_ref *ref = hoedown_calloc(1, sizeof(struct footnote_ref)); +// Checks if the char is an lowercase ASCII letter. +static inline int is_lower_ascii(uint8_t ch) { + return ch >= 'a' && ch <= 'z'; +} - ref->id = hash_link_ref(name, name_size); +// Checks if the char is an alphanumeric ASCII character. +static inline int is_alnum_ascii(uint8_t ch) { + return is_lower_ascii(ch) || is_upper_ascii(ch) || is_digit_ascii(ch); +} + +// Checks if the char is an ASCII punctuation character. +static inline int is_punct_ascii(uint8_t ch) { + static const char punctuation_chars [256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, + }; + return punctuation_chars[ch]; +} + +// Checks if the char is a valid space character. +// Tabs and carriage returns are stripped during preprocessing. +// Form feeds aren't treated as spacing (except for HTML). +static inline int is_space(uint8_t ch) { + return ch == 0x20 // space + // ch == 0x09 // tab + || ch == 0x0a // linefeed + // ch == 0x0c // form feed + // ch == 0x0d // carriage return + ; +} - return ref; +// HTML-specific version of is_space +static inline int html_is_space(uint8_t ch) { + return ch == 0x20 // space + // ch == 0x09 // tab + || ch == 0x0a // linefeed + || ch == 0x0c // form feed + // ch == 0x0d // carriage return + ; } -static int -add_footnote_ref(struct footnote_list *list, struct footnote_ref *ref) -{ - struct footnote_item *item = hoedown_calloc(1, sizeof(struct footnote_item)); - if (!item) - return 0; - item->ref = ref; - if (list->head == NULL) { - list->head = list->tail = item; - } else { - list->tail->next = item; - list->tail = item; - } - list->count++; +// Checks if the character at a certain position in the input +// is backslash escaped or not. +static inline int is_escaped(const uint8_t *data, size_t position) { + size_t start = position; + while (start > 0 && data[start-1] == '\\') start--; + return (position - start) % 2; +} - return 1; +// Replaces all uppercase ASCII letters in the string +// with their lowercase counterparts. +static inline void to_lower_ascii(uint8_t *data, size_t size) { + for (size_t i = 0; i < size; i++) { + if (is_upper_ascii(data[i])) + data[i] += 0x20; + } } -static struct footnote_ref * -find_footnote_ref(struct footnote_list *list, uint8_t *name, size_t length) -{ - unsigned int hash = hash_link_ref(name, length); - struct footnote_item *item = NULL; +// Checks if the data passed is all spacing. +static inline int is_empty(const uint8_t *data, size_t size) { + size_t i = 0; + while (i < size && is_space(data[i])) i++; + return i >= size; +} + +// Returns position of the next line (or end of input, wathever happens before) +// but only if the current line is all spacing. Otherwise, zero is returned. +static inline size_t next_line_empty(const uint8_t *data, size_t size) { + size_t i = 0; + + while (i < size && data[i] == ' ') i++; + + if (unlikely(i >= size)) return i; + if (data[i] == '\n') return i + 1; + return 0; +} - item = list->head; +// Replaces all occurences of consecutive spacing characters with a single +// space character. +static inline void collapse_spacing(hoedown_buffer *ob, const uint8_t *data, size_t size) { + size_t i = 0, mark = 0; + while (1) { + while (i < size && !is_space(data[i])) i++; + + // Optimization: it's a single space, we don't need to replace anything + if (likely(i+1 < size && data[i] == ' ' && !is_space(data[i+1]))) { + i += 2; + continue; + } - while (item != NULL) { - if (item->ref->id == hash) - return item->ref; - item = item->next; - } + // Optimization: there's nothing to replace + if (mark == 0 && i >= size) { + hoedown_buffer_put(ob, data, size); + return; + } + + hoedown_buffer_put(ob, data + mark, i - mark); + if (i >= size) break; - return NULL; -} + hoedown_buffer_putc(ob, ' '); + i++; -static void -free_footnote_ref(struct footnote_ref *ref) -{ - hoedown_buffer_free(ref->contents); - free(ref); + while (i < size && is_space(data[i])) i++; + mark = i; + } } -static void -free_footnote_list(struct footnote_list *list, int free_refs) -{ - struct footnote_item *item = list->head; - struct footnote_item *next; - - while (item) { - next = item->next; - if (free_refs) - free_footnote_ref(item->ref); - free(item); - item = next; - } -} +// Unescapes ASCII punctuation characters escaped with a backslash. +static inline void unescape_backslash(hoedown_buffer *ob, const uint8_t *data, size_t size) { + size_t i = 0, mark = 0; + while (1) { + while (i < size && data[i] != '\\') i++; + // Optimization: there's nothing to unescape + if (mark == 0 && i >= size) { + hoedown_buffer_put(ob, data, size); + return; + } -/* - * Check whether a char is a Markdown spacing char. + if (i+1 < size && !is_punct_ascii(data[i+1])) { + i += 2; + continue; + } - * Right now we only consider spaces the actual - * space and a newline: tabs and carriage returns - * are filtered out during the preprocessing phase. - * - * If we wanted to actually be UTF-8 compliant, we - * should instead extract an Unicode codepoint from - * this character and check for space properties. - */ -static int -_isspace(int c) -{ - return c == ' ' || c == '\n'; -} - -/* is_empty_all: verify that all the data is spacing */ -static int -is_empty_all(const uint8_t *data, size_t size) -{ - size_t i = 0; - while (i < size && _isspace(data[i])) i++; - return i == size; -} - -/* - * Replace all spacing characters in data with spaces. As a special - * case, this collapses a newline with the previous space, if possible. - */ -static void -replace_spacing(hoedown_buffer *ob, const uint8_t *data, size_t size) -{ - size_t i = 0, mark; - hoedown_buffer_grow(ob, size); - while (1) { - mark = i; - while (i < size && data[i] != '\n') i++; - hoedown_buffer_put(ob, data + mark, i - mark); - - if (i >= size) break; - - if (!(i > 0 && data[i-1] == ' ')) - hoedown_buffer_putc(ob, ' '); - i++; - } -} - -/**************************** - * INLINE PARSING FUNCTIONS * - ****************************/ - -/* is_mail_autolink • looks for the address part of a mail autolink and '>' */ -/* this is less strict than the original markdown e-mail address matching */ -static size_t -is_mail_autolink(uint8_t *data, size_t size) -{ - size_t i = 0, nb = 0; - - /* address is assumed to be: [-@._a-zA-Z0-9]+ with exactly one '@' */ - for (i = 0; i < size; ++i) { - if (isalnum(data[i])) - continue; - - switch (data[i]) { - case '@': - nb++; - - case '-': - case '.': - case '_': - break; - - case '>': - return (nb == 1) ? i + 1 : 0; - - default: - return 0; - } - } - - return 0; -} - -/* tag_length • returns the length of the given tag, or 0 is it's not valid */ -static size_t -tag_length(uint8_t *data, size_t size, hoedown_autolink_type *autolink) -{ - size_t i, j; - - /* a valid tag can't be shorter than 3 chars */ - if (size < 3) return 0; - - /* begins with a '<' optionally followed by '/', followed by letter or number */ - if (data[0] != '<') return 0; - i = (data[1] == '/') ? 2 : 1; - - if (!isalnum(data[i])) - return 0; - - /* scheme test */ - *autolink = HOEDOWN_AUTOLINK_NONE; - - /* try to find the beginning of an URI */ - while (i < size && (isalnum(data[i]) || data[i] == '.' || data[i] == '+' || data[i] == '-')) - i++; - - if (i > 1 && data[i] == '@') { - if ((j = is_mail_autolink(data + i, size - i)) != 0) { - *autolink = HOEDOWN_AUTOLINK_EMAIL; - return i + j; - } - } - - if (i > 2 && data[i] == ':') { - *autolink = HOEDOWN_AUTOLINK_NORMAL; - i++; - } - - /* completing autolink test: no spacing or ' or " */ - if (i >= size) - *autolink = HOEDOWN_AUTOLINK_NONE; - - else if (*autolink) { - j = i; - - while (i < size) { - if (data[i] == '\\') i += 2; - else if (data[i] == '>' || data[i] == '\'' || - data[i] == '"' || data[i] == ' ' || data[i] == '\n') - break; - else i++; - } - - if (i >= size) return 0; - if (i > j && data[i] == '>') return i + 1; - /* one of the forbidden chars has been found */ - *autolink = HOEDOWN_AUTOLINK_NONE; - } - - /* looking for something looking like a tag end */ - while (i < size && data[i] != '>') i++; - if (i >= size) return 0; - return i + 1; -} - -/* parse_inline • parses inline markdown elements */ -static void -parse_inline(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t size) -{ - size_t i = 0, end = 0; - hoedown_buffer work = { 0, 0, 0, 0, NULL, NULL, NULL }; - uint8_t *active_char = doc->active_char; - - if (doc->work_bufs[BUFFER_SPAN].size + - doc->work_bufs[BUFFER_BLOCK].size > doc->max_nesting) - return; - - while (i < size) { - /* copying inactive chars into the output */ - while (end < size && active_char[data[end]] == 0) - end++; - - if (doc->md.normal_text) { - work.data = data + i; - work.size = end - i; - doc->md.normal_text(ob, &work, &doc->data); - } - else - hoedown_buffer_put(ob, data + i, end - i); - - if (end >= size) break; - i = end; - - end = markdown_char_ptrs[ (int)active_char[data[end]] ](ob, doc, data + i, i, size - i); - if (!end) /* no action from the callback */ - end = i + 1; - else { - i += end; - end = i; - } - } -} - -/* is_escaped • returns whether special char at data[loc] is escaped by '\\' */ -static int -is_escaped(uint8_t *data, size_t loc) -{ - size_t i = loc; - while (i >= 1 && data[i - 1] == '\\') - i--; - - /* odd numbers of backslashes escapes data[loc] */ - return (loc - i) % 2; -} - -/* find_emph_char • looks for the next emph uint8_t, skipping other constructs */ -static size_t -find_emph_char(uint8_t *data, size_t size, uint8_t c) -{ - size_t i = 0; - - while (i < size) { - while (i < size && data[i] != c && data[i] != '[' && data[i] != '`') - i++; - - if (i == size) - return 0; - - /* not counting escaped chars */ - if (is_escaped(data, i)) { - i++; continue; - } - - if (data[i] == c) - return i; - - /* skipping a codespan */ - if (data[i] == '`') { - size_t span_nb = 0, bt; - size_t tmp_i = 0; - - /* counting the number of opening backticks */ - while (i < size && data[i] == '`') { - i++; span_nb++; - } - - if (i >= size) return 0; - - /* finding the matching closing sequence */ - bt = 0; - while (i < size && bt < span_nb) { - if (!tmp_i && data[i] == c) tmp_i = i; - if (data[i] == '`') bt++; - else bt = 0; - i++; - } - - /* not a well-formed codespan; use found matching emph char */ - if (i >= size) return tmp_i; - } - /* skipping a link */ - else if (data[i] == '[') { - size_t tmp_i = 0; - uint8_t cc; - - i++; - while (i < size && data[i] != ']') { - if (!tmp_i && data[i] == c) tmp_i = i; - i++; - } - - i++; - while (i < size && _isspace(data[i])) - i++; - - if (i >= size) - return tmp_i; - - switch (data[i]) { - case '[': - cc = ']'; break; - - case '(': - cc = ')'; break; - - default: - if (tmp_i) - return tmp_i; - else - continue; - } - - i++; - while (i < size && data[i] != cc) { - if (!tmp_i && data[i] == c) tmp_i = i; - i++; - } - - if (i >= size) - return tmp_i; - - i++; - } - } - - return 0; -} - -/* parse_emph1 • parsing single emphase */ -/* closed by a symbol not preceded by spacing and not followed by symbol */ -static size_t -parse_emph1(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t size, uint8_t c) -{ - size_t i = 0, len; - hoedown_buffer *work = 0; - int r; - - /* skipping one symbol if coming from emph3 */ - if (size > 1 && data[0] == c && data[1] == c) i = 1; - - while (i < size) { - len = find_emph_char(data + i, size - i, c); - if (!len) return 0; - i += len; - if (i >= size) return 0; - - if (data[i] == c && !_isspace(data[i - 1])) { - - if (doc->ext_flags & HOEDOWN_EXT_NO_INTRA_EMPHASIS) { - if (i + 1 < size && isalnum(data[i + 1])) - continue; - } - - work = newbuf(doc, BUFFER_SPAN); - parse_inline(work, doc, data, i); - - if (doc->ext_flags & HOEDOWN_EXT_UNDERLINE && c == '_') - r = doc->md.underline(ob, work, &doc->data); - else - r = doc->md.emphasis(ob, work, &doc->data); - - popbuf(doc, BUFFER_SPAN); - return r ? i + 1 : 0; - } - } - - return 0; -} - -/* parse_emph2 • parsing single emphase */ -static size_t -parse_emph2(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t size, uint8_t c) -{ - size_t i = 0, len; - hoedown_buffer *work = 0; - int r; - - while (i < size) { - len = find_emph_char(data + i, size - i, c); - if (!len) return 0; - i += len; - - if (i + 1 < size && data[i] == c && data[i + 1] == c && i && !_isspace(data[i - 1])) { - work = newbuf(doc, BUFFER_SPAN); - parse_inline(work, doc, data, i); - - if (c == '~') - r = doc->md.strikethrough(ob, work, &doc->data); - else if (c == '=') - r = doc->md.highlight(ob, work, &doc->data); - else - r = doc->md.double_emphasis(ob, work, &doc->data); - - popbuf(doc, BUFFER_SPAN); - return r ? i + 2 : 0; - } - i++; - } - return 0; -} - -/* parse_emph3 • parsing single emphase */ -/* finds the first closing tag, and delegates to the other emph */ -static size_t -parse_emph3(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t size, uint8_t c) -{ - size_t i = 0, len; - int r; - - while (i < size) { - len = find_emph_char(data + i, size - i, c); - if (!len) return 0; - i += len; - - /* skip spacing preceded symbols */ - if (data[i] != c || _isspace(data[i - 1])) - continue; - - if (i + 2 < size && data[i + 1] == c && data[i + 2] == c && doc->md.triple_emphasis) { - /* triple symbol found */ - hoedown_buffer *work = newbuf(doc, BUFFER_SPAN); - - parse_inline(work, doc, data, i); - r = doc->md.triple_emphasis(ob, work, &doc->data); - popbuf(doc, BUFFER_SPAN); - return r ? i + 3 : 0; - - } else if (i + 1 < size && data[i + 1] == c) { - /* double symbol found, handing over to emph1 */ - len = parse_emph1(ob, doc, data - 2, size + 2, c); - if (!len) return 0; - else return len - 2; - - } else { - /* single symbol found, handing over to emph2 */ - len = parse_emph2(ob, doc, data - 1, size + 1, c); - if (!len) return 0; - else return len - 1; - } - } - return 0; -} - -/* parse_math • parses a math span until the given ending delimiter */ -static size_t -parse_math(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size, const char *end, size_t delimsz, int displaymode) -{ - hoedown_buffer text = { NULL, 0, 0, 0, NULL, NULL, NULL }; - size_t i = delimsz; - - if (!doc->md.math) - return 0; - - /* find ending delimiter */ - while (1) { - while (i < size && data[i] != (uint8_t)end[0]) - i++; - - if (i >= size) - return 0; - - if (!is_escaped(data, i) && !(i + delimsz > size) - && memcmp(data + i, end, delimsz) == 0) - break; - - i++; - } - - /* prepare buffers */ - text.data = data + delimsz; - text.size = i - delimsz; - - /* if this is a $$ and MATH_EXPLICIT is not active, - * guess whether displaymode should be enabled from the context */ - i += delimsz; - if (delimsz == 2 && !(doc->ext_flags & HOEDOWN_EXT_MATH_EXPLICIT)) - displaymode = is_empty_all(data - offset, offset) && is_empty_all(data + i, size - i); - - /* call callback */ - if (doc->md.math(ob, &text, displaymode, &doc->data)) - return i; - - return 0; -} - -/* char_emphasis • single and double emphasis parsing */ -static size_t -char_emphasis(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size) -{ - uint8_t c = data[0]; - size_t ret; - - if (doc->ext_flags & HOEDOWN_EXT_NO_INTRA_EMPHASIS) { - if (offset > 0 && !_isspace(data[-1]) && data[-1] != '>' && data[-1] != '(') - return 0; - } - - if (size > 2 && data[1] != c) { - /* spacing cannot follow an opening emphasis; - * strikethrough and highlight only takes two characters '~~' */ - if (c == '~' || c == '=' || _isspace(data[1]) || (ret = parse_emph1(ob, doc, data + 1, size - 1, c)) == 0) - return 0; - - return ret + 1; - } - - if (size > 3 && data[1] == c && data[2] != c) { - if (_isspace(data[2]) || (ret = parse_emph2(ob, doc, data + 2, size - 2, c)) == 0) - return 0; - - return ret + 2; - } - - if (size > 4 && data[1] == c && data[2] == c && data[3] != c) { - if (c == '~' || c == '=' || _isspace(data[3]) || (ret = parse_emph3(ob, doc, data + 3, size - 3, c)) == 0) - return 0; - - return ret + 3; - } - - return 0; -} - - -/* char_linebreak • '\n' preceded by two spaces (assuming linebreak != 0) */ -static size_t -char_linebreak(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size) -{ - if (offset < 2 || data[-1] != ' ' || data[-2] != ' ') - return 0; - - /* removing the last space from ob and rendering */ - while (ob->size && ob->data[ob->size - 1] == ' ') - ob->size--; - - return doc->md.linebreak(ob, &doc->data) ? 1 : 0; -} + hoedown_buffer_put(ob, data + mark, i - mark); + if (i >= size) break; + i++; + mark = i; + i++; + } +} -/* char_codespan • '`' parsing a code span (assuming codespan != 0) */ -static size_t -char_codespan(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size) -{ - hoedown_buffer work = { NULL, 0, 0, 0, NULL, NULL, NULL }; - size_t end, nb = 0, i, f_begin, f_end; - - /* counting the number of backticks in the delimiter */ - while (nb < size && data[nb] == '`') - nb++; +// Utility method to unescape both backslashes and HTML entities. +static inline void unescape_both(hoedown_document *doc, hoedown_buffer *ob, const uint8_t *data, size_t size) { + hoedown_buffer *intermediate = hoedown_pool_get(&doc->buffers_inline); + intermediate->size = 0; - /* finding the next delimiter */ - i = 0; - for (end = nb; end < size && i < nb; end++) { - if (data[end] == '`') i++; - else i = 0; - } - - if (i < nb && end >= size) - return 0; /* no matching delimiter */ - - /* trimming outside spaces */ - f_begin = nb; - while (f_begin < end && data[f_begin] == ' ') - f_begin++; - - f_end = end - nb; - while (f_end > nb && data[f_end-1] == ' ') - f_end--; - - /* real code span */ - if (f_begin < f_end) { - work.data = data + f_begin; - work.size = f_end - f_begin; - - if (!doc->md.codespan(ob, &work, &doc->data)) - end = 0; - } else { - if (!doc->md.codespan(ob, 0, &doc->data)) - end = 0; - } - - return end; -} - -/* char_quote • '"' parsing a quote */ -static size_t -char_quote(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size) -{ - size_t end, nq = 0, i, f_begin, f_end; - - /* counting the number of quotes in the delimiter */ - while (nq < size && data[nq] == '"') - nq++; - - /* finding the next delimiter */ - end = nq; - while (1) { - i = end; - end += find_emph_char(data + end, size - end, '"'); - if (end == i) return 0; /* no matching delimiter */ - i = end; - while (end < size && data[end] == '"' && end - i < nq) end++; - if (end - i >= nq) break; - } - - /* trimming outside spaces */ - f_begin = nq; - while (f_begin < end && data[f_begin] == ' ') - f_begin++; - - f_end = end - nq; - while (f_end > nq && data[f_end-1] == ' ') - f_end--; - - /* real quote */ - if (f_begin < f_end) { - hoedown_buffer *work = newbuf(doc, BUFFER_SPAN); - parse_inline(work, doc, data + f_begin, f_end - f_begin); - - if (!doc->md.quote(ob, work, &doc->data)) - end = 0; - popbuf(doc, BUFFER_SPAN); - } else { - if (!doc->md.quote(ob, 0, &doc->data)) - end = 0; - } - - return end; -} - - -/* char_escape • '\\' backslash escape */ -static size_t -char_escape(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size) -{ - static const char *escape_chars = "\\`*_{}[]()#+-.!:|&<>^~=\"$"; - hoedown_buffer work = { 0, 0, 0, 0, NULL, NULL, NULL }; - size_t w; - - if (size > 1) { - if (data[1] == '\\' && (doc->ext_flags & HOEDOWN_EXT_MATH) && - size > 2 && (data[2] == '(' || data[2] == '[')) { - const char *end = (data[2] == '[') ? "\\\\]" : "\\\\)"; - w = parse_math(ob, doc, data, offset, size, end, 3, data[2] == '['); - if (w) return w; - } - - if (strchr(escape_chars, data[1]) == NULL) - return 0; - - if (doc->md.normal_text) { - work.data = data + 1; - work.size = 1; - doc->md.normal_text(ob, &work, &doc->data); - } - else hoedown_buffer_putc(ob, data[1]); - } else if (size == 1) { - hoedown_buffer_putc(ob, data[0]); - } - - return 2; -} - -/* char_entity • '&' escaped when it doesn't belong to an entity */ -/* valid entities are assumed to be anything matching &#?[A-Za-z0-9]+; */ -static size_t -char_entity(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size) -{ - size_t end = 1; - hoedown_buffer work = { 0, 0, 0, 0, NULL, NULL, NULL }; - - if (end < size && data[end] == '#') - end++; - - while (end < size && isalnum(data[end])) - end++; - - if (end < size && data[end] == ';') - end++; /* real entity */ - else - return 0; /* lone '&' */ - - if (doc->md.entity) { - work.data = data; - work.size = end; - doc->md.entity(ob, &work, &doc->data); - } - else hoedown_buffer_put(ob, data, end); - - return end; -} - -/* char_langle_tag • '<' when tags or autolinks are allowed */ -static size_t -char_langle_tag(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size) -{ - hoedown_buffer work = { NULL, 0, 0, 0, NULL, NULL, NULL }; - hoedown_autolink_type altype = HOEDOWN_AUTOLINK_NONE; - size_t end = tag_length(data, size, &altype); - int ret = 0; - - work.data = data; - work.size = end; - - if (end > 2) { - if (doc->md.autolink && altype != HOEDOWN_AUTOLINK_NONE) { - hoedown_buffer *u_link = newbuf(doc, BUFFER_SPAN); - work.data = data + 1; - work.size = end - 2; - unscape_text(u_link, &work); - ret = doc->md.autolink(ob, u_link, altype, &doc->data); - popbuf(doc, BUFFER_SPAN); - } - else if (doc->md.raw_html) - ret = doc->md.raw_html(ob, &work, &doc->data); - } - - if (!ret) return 0; - else return end; -} - -static size_t -char_autolink_www(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size) -{ - hoedown_buffer *link, *link_url, *link_text; - size_t link_len, rewind; - - if (!doc->md.link || doc->in_link_body) - return 0; - - link = newbuf(doc, BUFFER_SPAN); - - if ((link_len = hoedown_autolink__www(&rewind, link, data, offset, size, HOEDOWN_AUTOLINK_SHORT_DOMAINS)) > 0) { - link_url = newbuf(doc, BUFFER_SPAN); - HOEDOWN_BUFPUTSL(link_url, "http://"); - hoedown_buffer_put(link_url, link->data, link->size); - - ob->size -= rewind; - if (doc->md.normal_text) { - link_text = newbuf(doc, BUFFER_SPAN); - doc->md.normal_text(link_text, link, &doc->data); - doc->md.link(ob, link_text, link_url, NULL, &doc->data); - popbuf(doc, BUFFER_SPAN); - } else { - doc->md.link(ob, link, link_url, NULL, &doc->data); - } - popbuf(doc, BUFFER_SPAN); - } - - popbuf(doc, BUFFER_SPAN); - return link_len; -} - -static size_t -char_autolink_email(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size) -{ - hoedown_buffer *link; - size_t link_len, rewind; - - if (!doc->md.autolink || doc->in_link_body) - return 0; - - link = newbuf(doc, BUFFER_SPAN); - - if ((link_len = hoedown_autolink__email(&rewind, link, data, offset, size, 0)) > 0) { - ob->size -= rewind; - doc->md.autolink(ob, link, HOEDOWN_AUTOLINK_EMAIL, &doc->data); - } - - popbuf(doc, BUFFER_SPAN); - return link_len; -} - -static size_t -char_autolink_url(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size) -{ - hoedown_buffer *link; - size_t link_len, rewind; - - if (!doc->md.autolink || doc->in_link_body) - return 0; - - link = newbuf(doc, BUFFER_SPAN); - - if ((link_len = hoedown_autolink__url(&rewind, link, data, offset, size, 0)) > 0) { - ob->size -= rewind; - doc->md.autolink(ob, link, HOEDOWN_AUTOLINK_NORMAL, &doc->data); - } - - popbuf(doc, BUFFER_SPAN); - return link_len; -} - -/* char_link • '[': parsing a link, a footnote or an image */ -static size_t -char_link(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size) -{ - int is_img = (offset && data[-1] == '!' && !is_escaped(data - offset, offset - 1)); - int is_footnote = (doc->ext_flags & HOEDOWN_EXT_FOOTNOTES && data[1] == '^'); - size_t i = 1, txt_e, link_b = 0, link_e = 0, title_b = 0, title_e = 0; - hoedown_buffer *content = NULL; - hoedown_buffer *link = NULL; - hoedown_buffer *title = NULL; - hoedown_buffer *u_link = NULL; - size_t org_work_size = doc->work_bufs[BUFFER_SPAN].size; - int ret = 0, in_title = 0, qtype = 0; - - /* checking whether the correct renderer exists */ - if ((is_footnote && !doc->md.footnote_ref) || (is_img && !doc->md.image) - || (!is_img && !is_footnote && !doc->md.link)) - goto cleanup; - - /* looking for the matching closing bracket */ - i += find_emph_char(data + i, size - i, ']'); - txt_e = i; - - if (i < size && data[i] == ']') i++; - else goto cleanup; - - /* footnote link */ - if (is_footnote) { - hoedown_buffer id = { NULL, 0, 0, 0, NULL, NULL, NULL }; - struct footnote_ref *fr; - - if (txt_e < 3) - goto cleanup; - - id.data = data + 2; - id.size = txt_e - 2; - - fr = find_footnote_ref(&doc->footnotes_found, id.data, id.size); - - /* mark footnote used */ - if (fr && !fr->is_used) { - if(!add_footnote_ref(&doc->footnotes_used, fr)) - goto cleanup; - fr->is_used = 1; - fr->num = doc->footnotes_used.count; - - /* render */ - if (doc->md.footnote_ref) - ret = doc->md.footnote_ref(ob, fr->num, &doc->data); - } - - goto cleanup; - } - - /* skip any amount of spacing */ - /* (this is much more laxist than original markdown syntax) */ - while (i < size && _isspace(data[i])) - i++; - - /* inline style link */ - if (i < size && data[i] == '(') { - size_t nb_p; - - /* skipping initial spacing */ - i++; - - while (i < size && _isspace(data[i])) - i++; - - link_b = i; - - /* looking for link end: ' " ) */ - /* Count the number of open parenthesis */ - nb_p = 0; - - while (i < size) { - if (data[i] == '\\') i += 2; - else if (data[i] == '(' && i != 0) { - nb_p++; i++; - } - else if (data[i] == ')') { - if (nb_p == 0) break; - else nb_p--; i++; - } else if (i >= 1 && _isspace(data[i-1]) && (data[i] == '\'' || data[i] == '"')) break; - else i++; - } - - if (i >= size) goto cleanup; - link_e = i; - - /* looking for title end if present */ - if (data[i] == '\'' || data[i] == '"') { - qtype = data[i]; - in_title = 1; - i++; - title_b = i; - - while (i < size) { - if (data[i] == '\\') i += 2; - else if (data[i] == qtype) {in_title = 0; i++;} - else if ((data[i] == ')') && !in_title) break; - else i++; - } - - if (i >= size) goto cleanup; - - /* skipping spacing after title */ - title_e = i - 1; - while (title_e > title_b && _isspace(data[title_e])) - title_e--; - - /* checking for closing quote presence */ - if (data[title_e] != '\'' && data[title_e] != '"') { - title_b = title_e = 0; - link_e = i; - } - } - - /* remove spacing at the end of the link */ - while (link_e > link_b && _isspace(data[link_e - 1])) - link_e--; - - /* remove optional angle brackets around the link */ - if (data[link_b] == '<') link_b++; - if (data[link_e - 1] == '>') link_e--; - - /* building escaped link and title */ - if (link_e > link_b) { - link = newbuf(doc, BUFFER_SPAN); - hoedown_buffer_put(link, data + link_b, link_e - link_b); - } - - if (title_e > title_b) { - title = newbuf(doc, BUFFER_SPAN); - hoedown_buffer_put(title, data + title_b, title_e - title_b); - } - - i++; - } - - /* reference style link */ - else if (i < size && data[i] == '[') { - hoedown_buffer *id = newbuf(doc, BUFFER_SPAN); - struct link_ref *lr; - - /* looking for the id */ - i++; - link_b = i; - while (i < size && data[i] != ']') i++; - if (i >= size) goto cleanup; - link_e = i; - - /* finding the link_ref */ - if (link_b == link_e) - replace_spacing(id, data + 1, txt_e - 1); - else - hoedown_buffer_put(id, data + link_b, link_e - link_b); - - lr = find_link_ref(doc->refs, id->data, id->size); - if (!lr) - goto cleanup; - - /* keeping link and title from link_ref */ - link = lr->link; - title = lr->title; - i++; - } - - /* shortcut reference style link */ - else { - hoedown_buffer *id = newbuf(doc, BUFFER_SPAN); - struct link_ref *lr; - - /* crafting the id */ - replace_spacing(id, data + 1, txt_e - 1); - - /* finding the link_ref */ - lr = find_link_ref(doc->refs, id->data, id->size); - if (!lr) - goto cleanup; - - /* keeping link and title from link_ref */ - link = lr->link; - title = lr->title; - - /* rewinding the spacing */ - i = txt_e + 1; - } - - /* building content: img alt is kept, only link content is parsed */ - if (txt_e > 1) { - content = newbuf(doc, BUFFER_SPAN); - if (is_img) { - hoedown_buffer_put(content, data + 1, txt_e - 1); - } else { - /* disable autolinking when parsing inline the - * content of a link */ - doc->in_link_body = 1; - parse_inline(content, doc, data + 1, txt_e - 1); - doc->in_link_body = 0; - } - } - - if (link) { - u_link = newbuf(doc, BUFFER_SPAN); - unscape_text(u_link, link); - } - - /* calling the relevant rendering function */ - if (is_img) { - if (ob->size && ob->data[ob->size - 1] == '!') - ob->size -= 1; - - ret = doc->md.image(ob, u_link, title, content, &doc->data); - } else { - ret = doc->md.link(ob, content, u_link, title, &doc->data); - } - - /* cleanup */ -cleanup: - doc->work_bufs[BUFFER_SPAN].size = (int)org_work_size; - return ret ? i : 0; -} - -static size_t -char_superscript(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size) -{ - size_t sup_start, sup_len; - hoedown_buffer *sup; - - if (!doc->md.superscript) - return 0; - - if (size < 2) - return 0; - - if (data[1] == '(') { - sup_start = 2; - sup_len = find_emph_char(data + 2, size - 2, ')') + 2; - - if (sup_len == size) - return 0; - } else { - sup_start = sup_len = 1; - - while (sup_len < size && !_isspace(data[sup_len])) - sup_len++; - } - - if (sup_len - sup_start == 0) - return (sup_start == 2) ? 3 : 0; - - sup = newbuf(doc, BUFFER_SPAN); - parse_inline(sup, doc, data + sup_start, sup_len - sup_start); - doc->md.superscript(ob, sup, &doc->data); - popbuf(doc, BUFFER_SPAN); - - return (sup_start == 2) ? sup_len + 1 : sup_len; -} - -static size_t -char_math(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size) -{ - /* double dollar */ - if (size > 1 && data[1] == '$') - return parse_math(ob, doc, data, offset, size, "$$", 2, 1); - - /* single dollar allowed only with MATH_EXPLICIT flag */ - if (doc->ext_flags & HOEDOWN_EXT_MATH_EXPLICIT) - return parse_math(ob, doc, data, offset, size, "$", 1, 0); - - return 0; -} - -/********************************* - * BLOCK-LEVEL PARSING FUNCTIONS * - *********************************/ - -/* is_empty • returns the line length when it is empty, 0 otherwise */ -static size_t -is_empty(const uint8_t *data, size_t size) -{ - size_t i; + unescape_backslash(intermediate, data, size); + hoedown_unescape_html(ob, intermediate->data, intermediate->size); - for (i = 0; i < size && data[i] != '\n'; i++) - if (data[i] != ' ') - return 0; + hoedown_pool_pop(&doc->buffers_inline); +} - return i + 1; -} - -/* is_hrule • returns whether a line is a horizontal rule */ -static int -is_hrule(uint8_t *data, size_t size) -{ - size_t i = 0, n = 0; - uint8_t c; - /* skipping initial spaces */ - if (size < 3) return 0; - if (data[0] == ' ') { i++; - if (data[1] == ' ') { i++; - if (data[2] == ' ') { i++; } } } - /* looking at the hrule uint8_t */ - if (i + 2 >= size - || (data[i] != '*' && data[i] != '-' && data[i] != '_')) - return 0; - c = data[i]; +// OTHER UTILITIES +// --------------- +// +// Miscellaneous logic used when parsing. - /* the whole line must be the char or space */ - while (i < size && data[i] != '\n') { - if (data[i] == c) n++; - else if (data[i] != ' ') - return 0; +static inline unsigned int hash_string(const uint8_t *data, size_t size) { + unsigned int hash = 0; - i++; - } + for (size_t i = 0; i < size; i++) { + uint8_t c = data[i]; + if (c >= 'A' && c <= 'Z') c += 0x20; + hash = c + (hash << 6) + (hash << 16) - hash; + } - return n >= 3; + return hash; } -/* check if a line is a code fence; return the - * end of the code fence. if passed, width of - * the fence rule and character will be returned */ -static size_t -is_codefence(uint8_t *data, size_t size, size_t *width, uint8_t *chr) -{ - size_t i = 0, n = 1; - uint8_t c; +static inline void add_link_ref(hoedown_document *doc, struct link_ref *ref) { + struct link_ref **slot = &doc->link_refs_table[ref->id % LINK_REFS_TABLE_SIZE]; + ref->next = *slot; + *slot = ref; +} - /* skipping initial spaces */ - if (size < 3) - return 0; +static inline struct link_ref *find_link_ref(hoedown_document *doc, unsigned int id) { + struct link_ref *ref = doc->link_refs_table[id % LINK_REFS_TABLE_SIZE]; - if (data[0] == ' ') { i++; - if (data[1] == ' ') { i++; - if (data[2] == ' ') { i++; } } } + while (ref) { + if (ref->id == id) return ref; + ref = ref->next; + } - /* looking at the hrule uint8_t */ - c = data[i]; - if (i + 2 >= size || !(c=='~' || c=='`')) - return 0; + return NULL; +} - /* the fence must be that same character */ - while (++i < size && data[i] == c) - ++n; - if (n < 3) - return 0; - if (width) *width = n; - if (chr) *chr = c; - return i; -} +// HTML PARSING +// ------------ +// +// This code is an adapted version of Lanli's HTML parsing routines. +// This only returns the end of a tag, without saving any data, since we +// don't need to interpret a tag, only skip it. The name of the tag can +// optionally be saved, since we need it to check if a tag is a block. -/* expects single line, checks if it's a codefence and extracts language */ -static size_t -parse_codefence(uint8_t *data, size_t size, hoedown_buffer *lang, size_t *width, uint8_t *chr) -{ - size_t i, w, lang_start; - i = w = is_codefence(data, size, width, chr); - if (i == 0) - return 0; +// Checks if the char can be part of an attribute name. +// NOTE: CommonMark is stricter than HTML5. +static inline int html_is_attr_name_char(uint8_t ch) { + // If we wanted to be 100% HTML-compliant, we should allow + // more characters to be part of attribute names. + return is_alnum_ascii(ch) || ch == '-' || ch == '_' || ch == ':' || ch == '.'; +} - while (i < size && _isspace(data[i])) - i++; +// Checks if the char is sensitive and can't be found inside +// unquoted attribute values, according to the HTML5 spec. +static inline int html_is_attr_sensitive(uint8_t ch) { + return ch == '<' || ch == '>' || ch == '=' + || ch == '"' || ch == '`' || ch == '\''; +} - lang_start = i; +// Parse an attribute value if there's one, according to the HTML5 spec. +// Sets parsed value to the buffer passed. +// Returns 0 if there's no value, size of the value otherwise. +static size_t html_parse_attribute_value(const uint8_t *data, size_t size) { + size_t i = 0, mark; + while (i < size && html_is_space(data[i])) i++; - while (i < size && !_isspace(data[i])) - i++; + if (!(i < size)) return 0; + uint8_t delimiter = data[i]; - lang->data = data + lang_start; - lang->size = i - lang_start; + if (delimiter == '\'' || delimiter == '"') { + i++; + // Quoted attribute + while (i < size && data[i] != delimiter) i++; + if (likely(i < size)) return i + 1; + return 0; + } - /* Avoid parsing a codespan as a fence */ - i = lang_start + 2; - while (i < size && !(data[i] == *chr && data[i-1] == *chr && data[i-2] == *chr)) i++; - if (i < size) return 0; + // Unquoted attribute + mark = i; + while (i < size && !html_is_space(data[i]) && !html_is_attr_sensitive(data[i])) i++; + if (unlikely(mark == i)) return 0; - return w; + return i; } -/* is_atxheader • returns whether the line is a hash-prefixed header */ -static int -is_atxheader(hoedown_document *doc, uint8_t *data, size_t size) -{ - if (data[0] != '#') - return 0; +// Parse an attribute if there's one, according to the HTML5 spec. +// Returns 0 if there's no valid attribute, size of the attribute otherwise. +static size_t html_parse_attribute(const uint8_t *data, size_t size) { + size_t i = 0, mark; - if (doc->ext_flags & HOEDOWN_EXT_SPACE_HEADERS) { - size_t level = 0; + // There must be at least one space character as separation + mark = i; + while (i < size && html_is_space(data[i])) i++; + if (mark == i) return 0; - while (level < size && level < 6 && data[level] == '#') - level++; + // Collect attribute name + mark = i; + while (i < size && html_is_attr_name_char(data[i])) i++; + if (mark == i || data[mark] == '.' || data[mark] == '-') return 0; - if (level < size && data[level] != ' ') - return 0; - } + // Collect attribute value, if there is + mark = i; + while (i < size && html_is_space(data[i])) i++; + if (i < size && data[i] == '=') { + i++; + // Attribute with value + mark = i; + i += html_parse_attribute_value(data + i, size - i); + if (mark == i) return 0; + return i; + } else { + // Attribute without value + return mark; + } - return 1; -} - -/* is_headerline • returns whether the line is a setext-style hdr underline */ -static int -is_headerline(uint8_t *data, size_t size) -{ - size_t i = 0; + // If we wanted to be 100% HTML-compliant, we should enforce + // an unquoted attribute to have at least one space character + // next, if it's followed by a slash. +} - /* test of level 1 header */ - if (data[i] == '=') { - for (i = 1; i < size && data[i] == '='; i++); - while (i < size && data[i] == ' ') i++; - return (i >= size || data[i] == '\n') ? 1 : 0; } +// Parse a start tag if there's one, according to CommonMark. +// This method assumes that data[0] == '<', so check that before calling it. +// Returns 0 if there's no start tag, size of the tag otherwise. +// NOTE: CommonMark requires a tag name to start with a letter +static size_t html_parse_start_tag(hoedown_buffer *name, const uint8_t *data, size_t size) { + size_t i = 1, mark; - /* test of level 2 header */ - if (data[i] == '-') { - for (i = 1; i < size && data[i] == '-'; i++); - while (i < size && data[i] == ' ') i++; - return (i >= size || data[i] == '\n') ? 2 : 0; } + // Collect the tag name + mark = i; - return 0; -} + if (i < size && (is_lower_ascii(data[i]) || is_upper_ascii(data[i]))) i++; + else return 0; + + while (i < size && is_alnum_ascii(data[i])) i++; + + if (mark == i) return 0; + if (name) hoedown_buffer_set(name, data + mark, i - mark); + + // Collect the attributes + while (1) { + mark = i; + i += html_parse_attribute(data + i, size - i); + if (mark == i) break; + } + + // Collect optional spacing + while (i < size && html_is_space(data[i])) i++; + + // Optional slash + if (i < size && data[i] == '/') i++; + + // Ending angle bracket + if (i < size && data[i] == '>') + return i + 1; + return 0; +} + +// Parse an end tag if there's one, according to the HTML5 spec. +// This method assumes that data[0] == '<', so check that before calling it. +// Returns 0 if there's no end tag, size of the tag otherwise. +static size_t html_parse_end_tag(hoedown_buffer *name, const uint8_t *data, size_t size) { + size_t i = 1, mark; + + // Slash + if (i < size && data[i] == '/') i++; + else return 0; + + // Collect tag name + mark = i; + while (i < size && is_alnum_ascii(data[i])) i++; + if (mark == i) return 0; + if (name) hoedown_buffer_set(name, data + mark, i - mark); + + // Collect optional spacing + while (i < size && html_is_space(data[i])) i++; + + // Ending angle bracket + if (i < size && data[i] == '>') + return i + 1; + return 0; +} + +// Validate that a comment's content is allowed, according to the HTML5 spec. +static inline int html_is_valid_comment_content(const uint8_t *data, size_t size) { + if (size == 0) return 1; + if (data[0] == '>') return 0; + if (data[size - 1] == '-') return 0; + + if (size == 1) return 1; + if (data[0] == '-' && data[1] == '>') return 0; + + for (size_t i = 0; i+1 < size; i++) + if (data[i] == '-' && data[i+1] == '-') return 0; + return 1; +} + +// Parse a comment if there's one, according to the HTML5 spec. +// This method assumes that data[0] == '<', so check that before calling it. +// Returns 0 if there's no comment, size of the comment otherwise. +static size_t html_parse_comment(const uint8_t *data, size_t size) { + size_t i = 1, mark; + if (size < 7) return 0; + + // Ensure starting sequence + if (data[1] == '!' && data[2] == '-' && data[3] == '-') i = 4; + else return 0; + + // Collect content + mark = i; + while (1) { + if (i+2 >= size) return 0; + if (data[i] == '-' && data[i+1] == '-' && data[i+2] == '>') break; + i++; + } + + // Validate content + if (html_is_valid_comment_content(data + mark, i - mark)) + return i + 3; + return 0; +} + + + +// ACTUAL PARSING +// -------------- +// +// Logic to parse various Markdown constructs. By convention, inline +// constructs are declared first, then block constructs. +// +// There are two types of methods. Tests are prefixed with `text_`, and they +// doesn't parse the construct, just look quickly for a *possibility* +// of the construct being present. +// +// Then there are the actual parsing routines, prefixed with `parse_`. They +// follow very specific guidelines, which are there to prevent bugs or +// unsafe operations, and guarantee readability. +// +// Block parsing functions should never return a position that falls in the +// middle of a line. Block parsing functions should always be called at the +// start of a non-empty line. +// +// Parsing functions must ALWAYS be called ONLY if +// the associated callbacks are defined in the renderer, that is, if the +// feature flag is set. + +// These are defined later +static size_t parse_inline(hoedown_document *doc, void *target, const uint8_t *data, size_t size, uint8_t delimiter, delimiter_check check, void *opaque); +static size_t parse_any_block(hoedown_document *doc, void *target, const uint8_t *data, size_t parsed, size_t i, size_t size, size_t lazy_size, hoedown_features lazy_ft); +static size_t parse_block(hoedown_document *doc, void *target, const uint8_t *data, size_t size, size_t lazy_size, hoedown_features lazy_ft); + + +// COMMON PARSING +// Syntax shared between block and inline constructs + +static inline size_t parse_link_destination(hoedown_document *doc, hoedown_buffer *dest, const uint8_t *data, size_t size) { + size_t i = 0, mark; + if (i >= size) return 0; + + if (data[i] == '<') { + i++; + mark = i; + + // Find ending delimiter + while (1) { + while (i < size && data[i] != '>' && data[i] != '<' && data[i] != '\n') i++; + if (i >= size) return 0; + + if ((data[i] == '>' || data[i] == '<') && is_escaped(data, i)) { + i++; + continue; + } + + if (data[i] == '>') break; + return 0; + } + + if (dest) { + dest->size = 0; + unescape_both(doc, dest, data + mark, i - mark); + } + return i + 1; + } else { + mark = i; + + // Find ending delimiter + int in_parenthesis = 0; + while (1) { + while (i < size && data[i] > ' ' && data[i] != '(' && data[i] != ')') i++; + if (i >= size) break; + + if (data[i] == '(' || data[i] == ')') { + if (is_escaped(data, i)) { + i++; + continue; + } + if ((data[i] == ')') == in_parenthesis) { + i++; + in_parenthesis = !in_parenthesis; + continue; + } + } + + break; + } + + if (i == mark || in_parenthesis) return 0; + if (dest) { + dest->size = 0; + unescape_both(doc, dest, data + mark, i - mark); + } + return i; + } +} + +static inline size_t parse_link_title(hoedown_document *doc, hoedown_buffer *title, const uint8_t *data, size_t size) { + size_t i = 0, mark; + + // Spacing, up to one newline + mark = i; + while (i < size && data[i] == ' ') i++; + if (i < size && data[i] == '\n') { + i++; + while (i < size && data[i] == ' ') i++; + } + if (mark == i) return 0; + + // Starting delimiter + uint8_t delimiter = data[i]; + if (delimiter == '\'' || delimiter == '"' || delimiter == '(') i++; + else return 0; + + if (delimiter == '(') delimiter = ')'; + + // Find ending delimiter + mark = i; + while (1) { + while (i < size && data[i] != delimiter) i++; + if (i >= size) return 0; + + if (is_escaped(data, i)) { + i++; + continue; + } + + break; + } -static int -is_next_headerline(uint8_t *data, size_t size) -{ - size_t i = 0; + if (title) { + title->size = 0; + unescape_both(doc, title, data + mark, i - mark); + } + return i + 1; +} + +static inline size_t parse_link_spec(hoedown_document *doc, struct link_ref *spec, const uint8_t *data, size_t size) { + size_t i = 0, mark; - while (i < size && data[i] != '\n') - i++; + // Link destination + mark = i; + i += parse_link_destination(doc, spec ? spec->dest : NULL, data + i, size - i); + if (mark == i) return 0; - if (++i >= size) - return 0; + // Optional link title + mark = i; + i += parse_link_title(doc, spec ? spec->title : NULL, data + i, size - i); + if (spec) spec->has_title = (mark < i); - return is_headerline(data + i, size - i); + return i; } -/* prefix_quote • returns blockquote prefix length */ -static size_t -prefix_quote(uint8_t *data, size_t size) -{ - size_t i = 0; - if (i < size && data[i] == ' ') i++; - if (i < size && data[i] == ' ') i++; - if (i < size && data[i] == ' ') i++; - - if (i < size && data[i] == '>') { - if (i + 1 < size && data[i + 1] == ' ') - return i + 2; - return i + 1; - } +// INLINE PARSING - return 0; +// This is the fallback parsing function for inline parsing. +static inline void parse_string(hoedown_document *doc, void *target, const uint8_t *data, size_t size) { + if (size == 0) return; + hoedown_buffer text = {(uint8_t *)data, size, 0, 0, NULL, NULL}; + doc->rndr.string(target, &text, &doc->data); } -/* prefix_code • returns prefix length for block code*/ -static size_t -prefix_code(uint8_t *data, size_t size) -{ - if (size > 3 && data[0] == ' ' && data[1] == ' ' - && data[2] == ' ' && data[3] == ' ') return 4; +// Assumes data[0] == '`' +static inline size_t parse_code_span(hoedown_document *doc, void *target, const uint8_t *data, size_t parsed, size_t start, size_t size) { + if (start > parsed && data[start-1] == '`') return 0; - return 0; -} + size_t i = start + 1, content_start, mark; + size_t width; + + // Opening backticks + mark = i; + while (i < size && data[i] == '`') i++; + width = i - mark; + + // Skip leading spacing + while (i < size && is_space(data[i])) i++; -/* prefix_oli • returns ordered list item prefix */ -static size_t -prefix_oli(uint8_t *data, size_t size) -{ - size_t i = 0; + // Consume content + content_start = i; + while (1) { + while (i < size && data[i] != '`') i++; - if (i < size && data[i] == ' ') i++; - if (i < size && data[i] == ' ') i++; - if (i < size && data[i] == ' ') i++; + if (i < size) i++; + else return 0; - if (i >= size || data[i] < '0' || data[i] > '9') - return 0; + mark = i; + while (i < size && data[i] == '`') i++; + if (i - mark == width) break; + } + i = mark + width; + mark--; - while (i < size && data[i] >= '0' && data[i] <= '9') - i++; + // Rewind trailing spaces on content + while (mark > content_start && is_space(data[mark-1])) mark--; - if (i + 1 >= size || data[i] != '.' || data[i + 1] != ' ') - return 0; + // Render! + parse_string(doc, target, data + parsed, start - parsed); - if (is_next_headerline(data + i, size - i)) - return 0; + hoedown_buffer *code = hoedown_pool_get(&doc->buffers_block); + code->size = 0; + collapse_spacing(code, data + content_start, mark - content_start); - return i + 2; + doc->rndr.code_span(target, code, &doc->data); + hoedown_pool_pop(&doc->buffers_block); + return i; } -/* prefix_uli • returns ordered list item prefix */ -static size_t -prefix_uli(uint8_t *data, size_t size) -{ - size_t i = 0; +// data[0] is assumed to be '<' +static inline size_t parse_uri_autolink(hoedown_document *doc, void *target, const uint8_t *data, size_t parsed, size_t start, size_t size) { + size_t i = start + 1, mark; - if (i < size && data[i] == ' ') i++; - if (i < size && data[i] == ' ') i++; - if (i < size && data[i] == ' ') i++; + // Collect scheme + mark = i; + while (i < size && data[i] != ':') i++; + if (i < size && hoedown_find_autolink_scheme((const char *)data + mark, i - mark)) i++; + else return 0; - if (i + 1 >= size || - (data[i] != '*' && data[i] != '+' && data[i] != '-') || - data[i + 1] != ' ') - return 0; + // Rest of URL + while (i < size && data[i] > ' ' && data[i] != '>' && data[i] != '<') i++; + if (i >= size || data[i] != '>') return 0; - if (is_next_headerline(data + i, size - i)) - return 0; + // Render! + parse_string(doc, target, data + parsed, start - parsed); - return i + 2; + hoedown_buffer url = {(uint8_t *)data + mark, i - mark, 0, 0, NULL, NULL}; + doc->rndr.uri_autolink(target, &url, &doc->data); + return i + 1; } +// data[0] is assumed to be '<' +static inline size_t parse_email_autolink(hoedown_document *doc, void *target, const uint8_t *data, size_t parsed, size_t start, size_t size) { + size_t i = start + 1, mark;//TODO -/* parse_block • parsing of one block, returning next uint8_t to parse */ -static void parse_block(hoedown_buffer *ob, hoedown_document *doc, - uint8_t *data, size_t size); + // Collect username + + return i + 1; +} +// Parse the syntax for an inline link. +// If the syntax is invalid, zero will be returned. +// If it's valid, `target` will be populated with the parsed data. +static inline size_t parse_link_target_inline(hoedown_document *doc, struct link_ref *spec, const uint8_t *data, size_t size) { + size_t i = 0, mark; -/* parse_blockquote • handles parsing of a blockquote fragment */ -static size_t -parse_blockquote(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t size) -{ - size_t beg, end = 0, pre, work_size = 0; - uint8_t *work_data = 0; - hoedown_buffer *out = 0; + // Parenthesis + if (i < size && data[i] == '(') i++; + else return 0; - out = newbuf(doc, BUFFER_BLOCK); - beg = 0; - while (beg < size) { - for (end = beg + 1; end < size && data[end - 1] != '\n'; end++); + // Optional spacing + while (i < size && is_space(data[i])) i++; - pre = prefix_quote(data + beg, end - beg); + // Optional spec + mark = i; + i += parse_link_spec(doc, spec, data + i, size - i); - if (pre) - beg += pre; /* skipping prefix */ + if (mark == i) { + // If there's no specification, empty destination and no title + spec->dest->size = 0; + spec->has_title = 0; + } - /* empty line followed by non-quote line */ - else if (is_empty(data + beg, end - beg) && - (end >= size || (prefix_quote(data + end, size - end) == 0 && - !is_empty(data + end, size - end)))) - break; + // Optional spacing + while (i < size && is_space(data[i])) i++; - if (beg < end) { /* copy into the in-place working buffer */ - /* hoedown_buffer_put(work, data + beg, end - beg); */ - if (!work_data) - work_data = data + beg; - else if (data + beg != work_data + work_size) - memmove(work_data + work_size, data + beg, end - beg); - work_size += end - beg; - } - beg = end; - } + // Parenthesis + if (i < size && data[i] == ')') i++; + else return 0; - parse_block(out, doc, work_data, work_size); - if (doc->md.blockquote) - doc->md.blockquote(ob, out, &doc->data); - popbuf(doc, BUFFER_BLOCK); - return end; + return i; } -static size_t -parse_htmlblock(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t size, int do_render); - -/* parse_blockquote • handles parsing of a regular paragraph */ -static size_t -parse_paragraph(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t size) -{ - hoedown_buffer work = { NULL, 0, 0, 0, NULL, NULL, NULL }; - size_t i = 0, end = 0; - int level = 0; +// Parses the syntax for a full / collapsed reference link. +// If the syntax is invalid, zero will be returned. +// If the syntax is valid, `target` will be set to the match +// (or NULL if there's no match). +static inline size_t parse_link_target_reference(hoedown_document *doc, struct link_ref **spec, const uint8_t *data, size_t size, const hoedown_buffer *content) { + size_t i = 0, mark; - work.data = data; - - while (i < size) { - for (end = i + 1; end < size && data[end - 1] != '\n'; end++) /* empty */; + // Optional spacing + while (i < size && is_space(data[i])) i++; - if (is_empty(data + i, size - i)) - break; + // Bracket + if (i < size && data[i] == '[') i++; + else return 0; - if ((level = is_headerline(data + i, size - i)) != 0) - break; + // Content + mark = i; + while (i < size && data[i] != ']') i++; + if (i >= size) return 0; - if (is_atxheader(doc, data + i, size - i) || - is_hrule(data + i, size - i) || - prefix_quote(data + i, size - i)) { - end = i; - break; - } + // Lookup the reference + hoedown_buffer *label = hoedown_pool_get(&doc->buffers_inline); + label->size = 0; - i = end; - } - - work.size = i; - while (work.size && data[work.size - 1] == '\n') - work.size--; + if (mark < i) + collapse_spacing(label, data + mark, i - mark); + else + collapse_spacing(label, content->data, content->size); - if (!level) { - hoedown_buffer *tmp = newbuf(doc, BUFFER_BLOCK); - parse_inline(tmp, doc, work.data, work.size); - if (doc->md.paragraph) - doc->md.paragraph(ob, tmp, &doc->data); - popbuf(doc, BUFFER_BLOCK); - } else { - hoedown_buffer *header_work; + *spec = find_link_ref(doc, hash_string(label->data, label->size)); + hoedown_pool_pop(&doc->buffers_inline); + return i + 1; +} - if (work.size) { - size_t beg; - i = work.size; - work.size -= 1; - - while (work.size && data[work.size] != '\n') - work.size -= 1; - - beg = work.size + 1; - while (work.size && data[work.size - 1] == '\n') - work.size -= 1; - - if (work.size > 0) { - hoedown_buffer *tmp = newbuf(doc, BUFFER_BLOCK); - parse_inline(tmp, doc, work.data, work.size); - - if (doc->md.paragraph) - doc->md.paragraph(ob, tmp, &doc->data); - - popbuf(doc, BUFFER_BLOCK); - work.data += beg; - work.size = i - beg; - } - else work.size = i; - } - - header_work = newbuf(doc, BUFFER_SPAN); - parse_inline(header_work, doc, work.data, work.size); - - if (doc->md.header) - doc->md.header(ob, header_work, (int)level, &doc->data); - - popbuf(doc, BUFFER_SPAN); - } - - return end; -} - -/* parse_fencedcode • handles parsing of a block-level code fragment */ -static size_t -parse_fencedcode(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t size) -{ - hoedown_buffer text = { 0, 0, 0, 0, NULL, NULL, NULL }; - hoedown_buffer lang = { 0, 0, 0, 0, NULL, NULL, NULL }; - size_t i = 0, text_start, line_start; - size_t w, w2; - size_t width, width2; - uint8_t chr, chr2; - - /* parse codefence line */ - while (i < size && data[i] != '\n') - i++; - - w = parse_codefence(data, i, &lang, &width, &chr); - if (!w) - return 0; - - /* search for end */ - i++; - text_start = i; - while ((line_start = i) < size) { - while (i < size && data[i] != '\n') - i++; +static inline size_t parse_link_target(hoedown_document *doc, struct link_ref **spec, const uint8_t *data, size_t size, const hoedown_buffer *content) { + size_t result; - w2 = is_codefence(data + line_start, i - line_start, &width2, &chr2); - if (w == w2 && width == width2 && chr == chr2 && - is_empty(data + (line_start+w), i - (line_start+w))) - break; - - i++; - } - - text.data = data + text_start; - text.size = line_start - text_start; - - if (doc->md.blockcode) - doc->md.blockcode(ob, text.size ? &text : NULL, lang.size ? &lang : NULL, &doc->data); - - return i; -} - -static size_t -parse_blockcode(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t size) -{ - size_t beg, end, pre; - hoedown_buffer *work = 0; - - work = newbuf(doc, BUFFER_BLOCK); - - beg = 0; - while (beg < size) { - for (end = beg + 1; end < size && data[end - 1] != '\n'; end++) {}; - pre = prefix_code(data + beg, end - beg); - - if (pre) - beg += pre; /* skipping prefix */ - else if (!is_empty(data + beg, end - beg)) - /* non-empty non-prefixed line breaks the pre */ - break; - - if (beg < end) { - /* verbatim copy to the working buffer, - escaping entities */ - if (is_empty(data + beg, end - beg)) - hoedown_buffer_putc(work, '\n'); - else hoedown_buffer_put(work, data + beg, end - beg); - } - beg = end; - } - - while (work->size && work->data[work->size - 1] == '\n') - work->size -= 1; - - hoedown_buffer_putc(work, '\n'); - - if (doc->md.blockcode) - doc->md.blockcode(ob, work, NULL, &doc->data); - - popbuf(doc, BUFFER_BLOCK); - return beg; -} - -/* parse_listitem • parsing of a single list item */ -/* assuming initial prefix is already removed */ -static size_t -parse_listitem(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t size, hoedown_list_flags *flags) -{ - hoedown_buffer *work = 0, *inter = 0; - size_t beg = 0, end, pre, sublist = 0, orgpre = 0, i; - int in_empty = 0, has_inside_empty = 0, in_fence = 0; - - /* keeping track of the first indentation prefix */ - while (orgpre < 3 && orgpre < size && data[orgpre] == ' ') - orgpre++; - - beg = prefix_uli(data, size); - if (!beg) - beg = prefix_oli(data, size); - - if (!beg) - return 0; - - /* skipping to the beginning of the following line */ - end = beg; - while (end < size && data[end - 1] != '\n') - end++; - - /* getting working buffers */ - work = newbuf(doc, BUFFER_SPAN); - inter = newbuf(doc, BUFFER_SPAN); - - /* putting the first line into the working buffer */ - hoedown_buffer_put(work, data + beg, end - beg); - beg = end; - - /* process the following lines */ - while (beg < size) { - size_t has_next_uli = 0, has_next_oli = 0; - - end++; - - while (end < size && data[end - 1] != '\n') - end++; - - /* process an empty line */ - if (is_empty(data + beg, end - beg)) { - in_empty = 1; - beg = end; - continue; - } - - /* calculating the indentation */ - i = 0; - while (i < 4 && beg + i < end && data[beg + i] == ' ') - i++; - - pre = i; - - if (doc->ext_flags & HOEDOWN_EXT_FENCED_CODE) { - if (is_codefence(data + beg + i, end - beg - i, NULL, NULL)) - in_fence = !in_fence; - } - - /* Only check for new list items if we are **not** inside - * a fenced code block */ - if (!in_fence) { - has_next_uli = prefix_uli(data + beg + i, end - beg - i); - has_next_oli = prefix_oli(data + beg + i, end - beg - i); - } - - /* checking for a new item */ - if ((has_next_uli && !is_hrule(data + beg + i, end - beg - i)) || has_next_oli) { - if (in_empty) - has_inside_empty = 1; - - /* the following item must have the same (or less) indentation */ - if (pre <= orgpre) { - /* if the following item has different list type, we end this list */ - if (in_empty && ( - ((*flags & HOEDOWN_LIST_ORDERED) && has_next_uli) || - (!(*flags & HOEDOWN_LIST_ORDERED) && has_next_oli))) - *flags |= HOEDOWN_LI_END; - - break; - } - - if (!sublist) - sublist = work->size; - } - /* joining only indented stuff after empty lines; - * note that now we only require 1 space of indentation - * to continue a list */ - else if (in_empty && pre == 0) { - *flags |= HOEDOWN_LI_END; - break; - } - - if (in_empty) { - hoedown_buffer_putc(work, '\n'); - has_inside_empty = 1; - in_empty = 0; - } - - /* adding the line without prefix into the working buffer */ - hoedown_buffer_put(work, data + beg + i, end - beg - i); - beg = end; - } - - /* render of li contents */ - if (has_inside_empty) - *flags |= HOEDOWN_LI_BLOCK; - - if (*flags & HOEDOWN_LI_BLOCK) { - /* intermediate render of block li */ - if (sublist && sublist < work->size) { - parse_block(inter, doc, work->data, sublist); - parse_block(inter, doc, work->data + sublist, work->size - sublist); - } - else - parse_block(inter, doc, work->data, work->size); - } else { - /* intermediate render of inline li */ - if (sublist && sublist < work->size) { - parse_inline(inter, doc, work->data, sublist); - parse_block(inter, doc, work->data + sublist, work->size - sublist); - } - else - parse_inline(inter, doc, work->data, work->size); - } - - /* render of li itself */ - if (doc->md.listitem) - doc->md.listitem(ob, inter, *flags, &doc->data); - - popbuf(doc, BUFFER_SPAN); - popbuf(doc, BUFFER_SPAN); - return beg; -} - - -/* parse_list • parsing ordered or unordered list block */ -static size_t -parse_list(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t size, hoedown_list_flags flags) -{ - hoedown_buffer *work = 0; - size_t i = 0, j; - - work = newbuf(doc, BUFFER_BLOCK); - - while (i < size) { - j = parse_listitem(work, doc, data + i, size - i, &flags); - i += j; - - if (!j || (flags & HOEDOWN_LI_END)) - break; - } - - if (doc->md.list) - doc->md.list(ob, work, flags, &doc->data); - popbuf(doc, BUFFER_BLOCK); - return i; -} - -/* parse_atxheader • parsing of atx-style headers */ -static size_t -parse_atxheader(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t size) -{ - size_t level = 0; - size_t i, end, skip; - - while (level < size && level < 6 && data[level] == '#') - level++; - - for (i = level; i < size && data[i] == ' '; i++); - - for (end = i; end < size && data[end] != '\n'; end++); - skip = end; - - while (end && data[end - 1] == '#') - end--; - - while (end && data[end - 1] == ' ') - end--; - - if (end > i) { - hoedown_buffer *work = newbuf(doc, BUFFER_SPAN); - - parse_inline(work, doc, data + i, end - i); - - if (doc->md.header) - doc->md.header(ob, work, (int)level, &doc->data); - - popbuf(doc, BUFFER_SPAN); - } - - return skip; -} - -/* parse_footnote_def • parse a single footnote definition */ -static void -parse_footnote_def(hoedown_buffer *ob, hoedown_document *doc, unsigned int num, uint8_t *data, size_t size) -{ - hoedown_buffer *work = 0; - work = newbuf(doc, BUFFER_SPAN); - - parse_block(work, doc, data, size); - - if (doc->md.footnote_def) - doc->md.footnote_def(ob, work, num, &doc->data); - popbuf(doc, BUFFER_SPAN); -} - -/* parse_footnote_list • render the contents of the footnotes */ -static void -parse_footnote_list(hoedown_buffer *ob, hoedown_document *doc, struct footnote_list *footnotes) -{ - hoedown_buffer *work = 0; - struct footnote_item *item; - struct footnote_ref *ref; - - if (footnotes->count == 0) - return; - - work = newbuf(doc, BUFFER_BLOCK); - - item = footnotes->head; - while (item) { - ref = item->ref; - parse_footnote_def(work, doc, ref->num, ref->contents->data, ref->contents->size); - item = item->next; - } + // Try to parse inline link - if (doc->md.footnotes) - doc->md.footnotes(ob, work, &doc->data); - popbuf(doc, BUFFER_BLOCK); -} + // DANGER: we're doing something unsafe, taking a link ref and + // revoking it, but still using it and passing it upwards. As long as it's + // only called by `parse_link`... + *spec = hoedown_pool_get(&doc->marker_link_refs); + result = parse_link_target_inline(doc, *spec, data, size); + hoedown_pool_pop(&doc->marker_link_refs); -/* htmlblock_is_end • check for end of HTML block : ( *)\n */ -/* returns tag length on match, 0 otherwise */ -/* assumes data starts with "<" */ -static size_t -htmlblock_is_end( - const char *tag, - size_t tag_len, - hoedown_document *doc, - uint8_t *data, - size_t size) -{ - size_t i = tag_len + 3, w; + if (result) return result; - /* try to match the end tag */ - /* note: we're not considering tags like "" which are still valid */ - if (i > size || - data[1] != '/' || - strncasecmp((char *)data + 2, tag, tag_len) != 0 || - data[tag_len + 2] != '>') - return 0; - - /* rest of the line must be empty */ - if ((w = is_empty(data + i, size - i)) == 0 && i < size) - return 0; - - return i + w; -} - -/* htmlblock_find_end • try to find HTML block ending tag */ -/* returns the length on match, 0 otherwise */ -static size_t -htmlblock_find_end( - const char *tag, - size_t tag_len, - hoedown_document *doc, - uint8_t *data, - size_t size) -{ - size_t i = 0, w; - - while (1) { - while (i < size && data[i] != '<') i++; - if (i >= size) return 0; - - w = htmlblock_is_end(tag, tag_len, doc, data + i, size - i); - if (w) return i + w; - i++; - } -} - -/* htmlblock_find_end_strict • try to find end of HTML block in strict mode */ -/* (it must be an unindented line, and have a blank line afterwads) */ -/* returns the length on match, 0 otherwise */ -static size_t -htmlblock_find_end_strict( - const char *tag, - size_t tag_len, - hoedown_document *doc, - uint8_t *data, - size_t size) -{ - size_t i = 0, mark; - - while (1) { - mark = i; - while (i < size && data[i] != '\n') i++; - if (i < size) i++; - if (i == mark) return 0; - - if (data[mark] == ' ' && mark > 0) continue; - mark += htmlblock_find_end(tag, tag_len, doc, data + mark, i - mark); - if (mark == i && (is_empty(data + i, size - i) || i >= size)) break; - } - - return i; -} - -/* parse_htmlblock • parsing of inline HTML block */ -static size_t -parse_htmlblock(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t size, int do_render) -{ - hoedown_buffer work = { NULL, 0, 0, 0, NULL, NULL, NULL }; - size_t i, j = 0, tag_len, tag_end; - const char *curtag = NULL; - - work.data = data; - - /* identification of the opening tag */ - if (size < 2 || data[0] != '<') - return 0; - - i = 1; - while (i < size && data[i] != '>' && data[i] != ' ') - i++; - - if (i < size) - curtag = hoedown_find_block_tag((char *)data + 1, (int)i - 1); - - /* handling of special cases */ - if (!curtag) { - - /* HTML comment, laxist form */ - if (size > 5 && data[1] == '!' && data[2] == '-' && data[3] == '-') { - i = 5; - - while (i < size && !(data[i - 2] == '-' && data[i - 1] == '-' && data[i] == '>')) - i++; - - i++; - - if (i < size) - j = is_empty(data + i, size - i); - - if (j) { - work.size = i + j; - if (do_render && doc->md.blockhtml) - doc->md.blockhtml(ob, &work, &doc->data); - return work.size; - } - } + // Try to parse full / collapsed reference link - /* HR, which is the only self-closing block tag considered */ - if (size > 4 && (data[1] == 'h' || data[1] == 'H') && (data[2] == 'r' || data[2] == 'R')) { - i = 3; - while (i < size && data[i] != '>') - i++; - - if (i + 1 < size) { - i++; - j = is_empty(data + i, size - i); - if (j) { - work.size = i + j; - if (do_render && doc->md.blockhtml) - doc->md.blockhtml(ob, &work, &doc->data); - return work.size; - } - } - } - - /* no special case recognised */ - return 0; - } - - /* looking for a matching closing tag in strict mode */ - tag_len = strlen(curtag); - tag_end = htmlblock_find_end_strict(curtag, tag_len, doc, data, size); - - /* if not found, trying a second pass looking for indented match */ - /* but not if tag is "ins" or "del" (following original Markdown.pl) */ - if (!tag_end && strcmp(curtag, "ins") != 0 && strcmp(curtag, "del") != 0) - tag_end = htmlblock_find_end(curtag, tag_len, doc, data, size); - - if (!tag_end) - return 0; + if ((result = parse_link_target_reference(doc, spec, data, size, content))) + return result; - /* the end of the block has been found */ - work.size = tag_end; - if (do_render && doc->md.blockhtml) - doc->md.blockhtml(ob, &work, &doc->data); + // Nothing? Then try to match this as a shortcut link - return tag_end; + hoedown_buffer *label = hoedown_pool_get(&doc->buffers_inline); + label->size = 0; + collapse_spacing(label, content->data, content->size); + *spec = find_link_ref(doc, hash_string(label->data, label->size)); + hoedown_pool_pop(&doc->buffers_inline); + return 0; } -static void -parse_table_row( - hoedown_buffer *ob, - hoedown_document *doc, - uint8_t *data, - size_t size, - size_t columns, - hoedown_table_flags *col_data, - hoedown_table_flags header_flag) -{ - size_t i = 0, col, len; - hoedown_buffer *row_work = 0; +// data[0] is assumed to be '[' +static inline size_t parse_link(hoedown_document *doc, void *target, const uint8_t *data, size_t parsed, size_t start, size_t size) { + size_t i = start + 1, mark, label_start, label_end; + int current_inside_link = doc->inside_link; + int is_image = 0; - if (!doc->md.table_cell || !doc->md.table_row) - return; + // Is it an image? + if (start > parsed && data[start-1] == '!' && doc->ft & HOEDOWN_FT_LINK_IMAGE) { + is_image = 1; + start--; + } - row_work = newbuf(doc, BUFFER_SPAN); + // Link label + void *content = doc->rndr.object_get(1, &doc->data); + label_start = i; - if (i < size && data[i] == '|') - i++; + doc->inside_link = 1; + i += parse_inline(doc, content, data + i, size - i, ']', NULL, NULL); + doc->inside_link = current_inside_link; - for (col = 0; col < columns && i < size; ++col) { - size_t cell_start, cell_end; - hoedown_buffer *cell_work; + if (i >= size) { + // delimiter not found + doc->rndr.object_pop(content, 1, &doc->data); + return 0; + } - cell_work = newbuf(doc, BUFFER_SPAN); + label_end = i; + i++; - while (i < size && _isspace(data[i])) - i++; + // Try to parse some type of link target + struct link_ref *spec = NULL; + hoedown_buffer content_text = {(uint8_t *)data + label_start, label_end - label_start, 0, 0, NULL, NULL}; - cell_start = i; + mark = i; + if (!doc->inside_link || is_image) + i += parse_link_target(doc, &spec, data + i, size - i, &content_text); - len = find_emph_char(data + i, size - i, '|'); - i += len ? len : size - i; + // Render! + if (spec) { + // We have a valid link + parse_string(doc, target, data + parsed, start - parsed); + doc->rndr.link(target, content, spec->dest, spec->has_title ? spec->title : NULL, is_image, &doc->data); + return i; + } else { + doc->rndr.object_pop(content, 1, &doc->data); + // Following hack is to bind [] even if it's not a valid link + parse_string(doc, target, data + parsed, label_start - parsed); + parse_inline(doc, target, data + label_start, label_end - label_start, 0, NULL, NULL); + parse_string(doc, target, data + label_end, mark - label_end); + return mark; + } +} - cell_end = i - 1; +// data[0] is assumed to be '<' +static inline size_t parse_cdata(const uint8_t *data, size_t size) { + size_t i = 0; - while (cell_end > cell_start && _isspace(data[cell_end])) - cell_end--; + // Starting prefix + if (size >= 9 && memcmp(data, "md.table_cell(row_work, cell_work, col_data[col] | header_flag, &doc->data); + // Content + size -= 2; + while (i < size && !(data[i] == ']' && data[i+1] == ']' && data[i+2] == '>')) i++; - popbuf(doc, BUFFER_SPAN); - i++; - } + if (i < size) return i + 3; + return 0; +} - for (; col < columns; ++col) { - hoedown_buffer empty_cell = { 0, 0, 0, 0, NULL, NULL, NULL }; - doc->md.table_cell(row_work, &empty_cell, col_data[col] | header_flag, &doc->data); - } +// data[0] is assumed to be '<' +static inline size_t parse_processing_instruction(const uint8_t *data, size_t size) { + size_t i = 1; - doc->md.table_row(ob, row_work, &doc->data); + // Starting prefix + if (i < size && data[i] == '?') i++; + else return 0; + + // Content + size -= 1; + while (i < size && !(data[i] == '?' && data[i+1] == '>')) i++; - popbuf(doc, BUFFER_SPAN); -} + if (i < size) return i + 2; + return 0; +} -static size_t -parse_table_header( - hoedown_buffer *ob, - hoedown_document *doc, - uint8_t *data, - size_t size, - size_t *columns, - hoedown_table_flags **column_data) -{ - int pipes; - size_t i = 0, col, header_end, under_end; +// data[0] is assumed to be '<' +static inline size_t parse_declaration(const uint8_t *data, size_t size) { + size_t i = 1, mark; + + // Starting prefix + if (i < size && data[i] == '!') i++; + else return 0; + + // Name + mark = i; + while (i < size && is_upper_ascii(data[i])) i++; + if (mark == i) return 0; + + // Spacing + mark = i; + while (i < size && is_space(data[i])) i++; + if (mark == i) return 0; + + // Rest of tag + while (i < size && data[i] != '>') i++; + + if (i < size) return i + 1; + return 0; +} + +// data[start] is assumed to be a valid emphasis delimiter +static int check_emphasis_end(hoedown_document *doc, const uint8_t *data, size_t parsed, size_t start, size_t size, void *opaque) { + uint8_t delimiter = data[start]; + size_t i = start; + size_t *count = opaque; - pipes = 0; - while (i < size && data[i] != '\n') - if (data[i++] == '|') - pipes++; + // Validate end delimiter + if (parsed < start && (data[start-1] == delimiter || is_space(data[start-1]))) return 0; + + // Count number of characters in the delimiter + i++; + while (i < size && data[i] == delimiter) i++; + *count = i - start; - if (i == size || pipes == 0) - return 0; + // Further validate delimiter + if (delimiter == '_' && !(doc->ft & HOEDOWN_FT_INTRA_EMPHASIS) && i < size && is_alnum_ascii(data[i])) return 0; + if (*count > 3) return 0; - header_end = i; + return 1; +} + +// data[start] is assumed to be '*' or '_' +static inline size_t parse_emphasis(hoedown_document *doc, void *target, const uint8_t *data, size_t parsed, size_t start, size_t size) { + uint8_t delimiter = data[start]; + size_t i = start, mark; + size_t open, close, total_open; + void *content; - while (header_end > 0 && _isspace(data[header_end - 1])) - header_end--; + void *reserved_objects [3]; + size_t reserved_count = 3; - if (data[0] == '|') - pipes--; + //FIXME: refactor the object allocation part - if (header_end && data[header_end - 1] == '|') - pipes--; + // Validate start delimiter + if (parsed < start && data[start-1] == delimiter) return 0; + if (delimiter == '_' && !(doc->ft & HOEDOWN_FT_INTRA_EMPHASIS) && parsed < start && is_alnum_ascii(data[start-1])) return 0; - if (pipes < 0) - return 0; + // Count number of characters in the delimiter + i++; + while (i < size && data[i] == delimiter) i++; + open = i - start; - *columns = pipes + 1; - *column_data = hoedown_calloc(*columns, sizeof(hoedown_table_flags)); + // Furter validate delimiter + if (i < size && is_space(data[i])) return 0; + if (open > 3) return 0; + total_open = open; - /* Parse the header underline */ - i++; - if (i < size && data[i] == '|') - i++; + // We can't allocate on the way, since that wouldn't be + // stack-based. So we reserve all three objects now. + reserved_objects[0] = doc->rndr.object_get(1, &doc->data); + reserved_objects[1] = doc->rndr.object_get(1, &doc->data); + reserved_objects[2] = doc->rndr.object_get(1, &doc->data); - under_end = i; - while (under_end < size && data[under_end] != '\n') - under_end++; + // Parse the content of our [nested] emphasis + content = doc->rndr.object_get(1, &doc->data); + while (1) { + void *subcontent = doc->rndr.object_get(1, &doc->data); + mark = i; + i += parse_inline(doc, subcontent, data + i, size - i, delimiter, check_emphasis_end, &close); - for (col = 0; col < *columns && i < under_end; ++col) { - size_t dashes = 0; + if (i >= size) { + // No delimiter found + doc->rndr.object_pop(subcontent, 1, &doc->data); + i = mark; + break; + } - while (i < under_end && data[i] == ' ') - i++; + // [Nested] emphasis of level `close` was found! Render it + if (close >= open) close = open; - if (data[i] == ':') { - i++; (*column_data)[col] |= HOEDOWN_TABLE_ALIGN_LEFT; - dashes++; - } + doc->rndr.object_merge(content, subcontent, 1, &doc->data); + subcontent = content; + content = reserved_objects[--reserved_count]; + doc->rndr.emphasis(content, subcontent, close, &doc->data); - while (i < under_end && data[i] == '-') { - i++; dashes++; - } + i += close; + open -= close; + if (!open) break; + } - if (i < under_end && data[i] == ':') { - i++; (*column_data)[col] |= HOEDOWN_TABLE_ALIGN_RIGHT; - dashes++; - } + if (total_open > open) { + // Content now has the top-level parsed emphasis, merge! + start += open; + parse_string(doc, target, data + parsed, start - parsed); + doc->rndr.object_merge(target, content, 1, &doc->data); + } else { + doc->rndr.object_pop(content, 1, &doc->data); + i = 0; + } + + // Deallocate (merge) unused objects + while (reserved_count) doc->rndr.object_pop(reserved_objects[--reserved_count], 1, &doc->data); + return i; +} - while (i < under_end && data[i] == ' ') - i++; - if (i < under_end && data[i] != '|' && data[i] != '+') - break; +// BLOCK PARSING + +// This is the fallback parsing function for block parsing. +static inline void parse_paragraph(hoedown_document *doc, void *target, const uint8_t *data, size_t size) { + if (size == 0 || doc->mode != NORMAL_PARSING) return; + + size_t content_start = 0, content_end = size; + while (content_start < size && is_space(data[content_start])) content_start++; + while (content_end > content_start && is_space(data[content_end-1])) content_end--; + + void *content = doc->rndr.object_get(1, &doc->data); + parse_inline(doc, content, data + content_start, content_end - content_start, 0, NULL, NULL); + doc->rndr.paragraph(target, content, doc->is_tight == doc->current_nesting, &doc->data); +} + +static inline int test_atx_header(const uint8_t *data, size_t size) { + return size >= 1 && (data[0] == '#' || (data[0] == ' ' && + size >= 2 && (data[1] == '#' || (data[1] == ' ' && + size >= 3 && (data[2] == '#' || (data[2] == ' ' && + size >= 4 && (data[3] == '#'))))))); +} + +static inline size_t parse_atx_header_end(const uint8_t *data, size_t size) { + size_t i = size, mark; + + // Retract to skip trailing spaces + while (i > 0 && data[i-1] == ' ') i--; + + // Retract to skip trailing hashes + mark = i; + while (i > 0 && data[i-1] == '#') i--; + if (i == mark) return i; + + // Check that they're present, and not escaped + if (is_escaped(data, i)) return i + 1; + + // Retract again to skip spaces between content and hashes + while (i > 0 && data[i-1] == ' ') i--; + return i; +} + +static inline size_t parse_atx_header(hoedown_document *doc, void *target, const uint8_t *data, size_t parsed, size_t start, size_t size) { + size_t i = start, mark, content_start; + size_t level; + + // Initial spaces + mark = i; + while (i < size && data[i] == ' ') i++; + if ((i - mark) > 3) return 0; + + // Hashes + mark = i; + while (i < size && data[i] == '#') i++; + level = i - mark; + if (level == 0 || level > 6) return 0; - if (dashes < 3) - break; + // Mandatory spaces + mark = i; + while (i < size && data[i] == ' ') i++; + if (mark == i && data[i] != '\n') return 0; - i++; - } + content_start = i; - if (col < *columns) - return 0; + // Skip until end of line, determine end of content + while (i < size && data[i] != '\n') i++; + mark = content_start + parse_atx_header_end(data + content_start, i - content_start); + + // Skip past newline + if (i < size) i++; - parse_table_row( - ob, doc, data, - header_end, - *columns, - *column_data, - HOEDOWN_TABLE_HEADER - ); + // Render! + if (doc->mode == NORMAL_PARSING) { + parse_paragraph(doc, target, data + parsed, start - parsed); + + void *content = doc->rndr.object_get(1, &doc->data); + parse_inline(doc, content, data + content_start, mark - content_start, 0, NULL, NULL); + doc->rndr.atx_header(target, content, level, &doc->data); + } - return under_end + 1; + return i; } -static size_t -parse_table( - hoedown_buffer *ob, - hoedown_document *doc, - uint8_t *data, - size_t size) -{ - size_t i; +static inline size_t parse_setext_header(hoedown_document *doc, void *target, const uint8_t *data, size_t parsed, size_t start, size_t size) { + size_t i = start, mark, content_start, content_end; + uint8_t character; - hoedown_buffer *work = 0; - hoedown_buffer *header_work = 0; - hoedown_buffer *body_work = 0; + // Skip indentation + mark = i; + while (i < size && data[i] == ' ') i++; + if (i - mark > 3) return 0; - size_t columns; - hoedown_table_flags *col_data = NULL; + // Skip until next line + content_start = i; + while (i < size && data[i] != '\n') i++; + if (i >= size || content_start == i) return 0; + content_end = i; + i++; // skip past newline - work = newbuf(doc, BUFFER_BLOCK); - header_work = newbuf(doc, BUFFER_SPAN); - body_work = newbuf(doc, BUFFER_BLOCK); + // Skip indentation + mark = i; + while (i < size && data[i] == ' ') i++; + if (i >= size || i - mark > 3) return 0; - i = parse_table_header(header_work, doc, data, size, &columns, &col_data); - if (i > 0) { + // Collect first character + character = data[i]; + if (character == '-' || character == '=') i++; + else return 0; - while (i < size) { - size_t row_start; - int pipes = 0; + // Collect rest of the characters, then trailing spaces + while (i < size && data[i] == character) i++; + while (i < size && data[i] == ' ') i++; - row_start = i; + // Line should end here + if (i < size && data[i] != '\n') return 0; + i++; + + // Trim spaces on content + while (content_start < content_end && data[content_start] == ' ') content_start++; + while (content_end > content_start && data[content_end-1] == ' ') content_end--; - while (i < size && data[i] != '\n') - if (data[i++] == '|') - pipes++; + // Render! + if (doc->mode == NORMAL_PARSING) { + parse_paragraph(doc, target, data + parsed, start - parsed); + + void *content = doc->rndr.object_get(1, &doc->data); + parse_inline(doc, content, data + content_start, content_end - content_start, 0, NULL, NULL); + doc->rndr.setext_header(target, content, character == '=', &doc->data); + } + + return i; +} - if (pipes == 0 || i == size) { - i = row_start; - break; - } +//FIXME: test_horizontal_rule + +static inline size_t parse_horizontal_rule(hoedown_document *doc, void *target, const uint8_t *data, size_t parsed, size_t start, size_t size) { + size_t i = start; + uint8_t character; + size_t count; + + // Skip three optional spaces + if (unlikely(i + 3 > size)) return 0; + + if (data[i] == ' ') { i++; + if (data[i] == ' ') { i++; + if (data[i] == ' ') { i++; + }}} + + // Collect valid character + if (unlikely(i >= size)) return 0; + + character = data[i]; + if (character == '*' || character == '-' || character == '_') i++; + else return 0; + + count = 1; + + // Collect rest of characters until end of line + while (1) { + while (i < size && data[i] == ' ') i++; - parse_table_row( - body_work, - doc, - data + row_start, - i - row_start, - columns, - col_data, 0 - ); + if (i < size && data[i] == character) { + i++; + count++; + } else break; + } + + // Verify there's at least three characters, and end of line + if (count < 3) return 0; + + if (likely(i < size)) { + if (data[i] == '\n') i++; + else return 0; + } + + // Render! + if (doc->mode == NORMAL_PARSING) { + parse_paragraph(doc, target, data + parsed, start - parsed); + + doc->rndr.horizontal_rule(target, &doc->data); + } + + return i; +} + +static inline int test_indented_code_block(const uint8_t *data, size_t size) { + return size > 4 && data[0] == ' ' && data[1] == ' ' && data[2] == ' ' && data[3] == ' '; +} + +static inline size_t parse_indented_code_block(hoedown_document *doc, void *target, const uint8_t *data, size_t parsed, size_t start, size_t size) { + size_t i = start, mark; + size_t last_non_empty_line = 0; + hoedown_buffer *code = hoedown_pool_get(&doc->buffers_block); + code->size = 0; + + while (1) { + // Parse initial spaces + mark = i; + while (i < size && data[i] == ' ') i++; + + if (i >= size) break; + if (i < mark + 4 && data[i] != '\n') break; + + // If line is non-empty, set the length later + if (data[i] != '\n') last_non_empty_line = 0; + + // Add rest of line to working buffer + mark += 4; + if (i < mark) mark = i; + + while (i < size && data[i] != '\n') i++; + if (i < size) i++; + hoedown_buffer_put(code, data + mark, i - mark); + if (!last_non_empty_line) last_non_empty_line = code->size; + } + + // Rewind i to the line start + i = mark; + + // Rewind the work buffer to cut empty lines at the end + code->size = last_non_empty_line; + + // Render! + if (doc->mode == NORMAL_PARSING) { + parse_paragraph(doc, target, data + parsed, start - parsed); + + doc->rndr.indented_code_block(target, code, &doc->data); + } + + hoedown_pool_pop(&doc->buffers_block); + return i; +} + +static inline size_t parse_code_fence(const uint8_t *data, size_t size, uint8_t *character, size_t *width) { + size_t i = 0, mark; + + // Skip three optional spaces + if (unlikely(i + 3 > size)) return 0; + + if (data[i] == ' ') { i++; + if (data[i] == ' ') { i++; + if (data[i] == ' ') { i++; + }}} + + // Process first character + if (i >= size) return 0; + *character = data[i]; + mark = i; + if (*character == '~' || *character == '`') i++; + else return 0; + + // Process rest of fence + while (i < size && data[i] == *character) i++; + if ((*width = i - mark) < 3) return 0; + + return i; +} + +//FIXME: test_fenced_code_block + +static inline size_t parse_fenced_code_block(hoedown_document *doc, void *target, const uint8_t *data, size_t parsed, size_t start, size_t size) { + size_t i = start, mark; + size_t indentation, start_width, end_width; + uint8_t start_character, end_character; + + // Parse initial fence + mark = i; + i += parse_code_fence(data + i, size - i, &start_character, &start_width); + if (mark == i) return 0; + indentation = (i - mark) - start_width; + + // Parse optional info string + while (i < size && data[i] == ' ') i++; + + mark = i; + while (i < size && data[i] != '`' && data[i] != '\n') i++; + if (unlikely(i < size && data[i] == '`')) return 0; + + hoedown_buffer *info = NULL; + + if (doc->mode == NORMAL_PARSING) { + info = hoedown_pool_get(&doc->buffers_inline); + info->size = 0; + unescape_both(doc, info, data + mark, i - mark); + while (info->size > 0 && info->data[info->size-1] == ' ') info->size--; + } + + if (i < size) i++; + + // Parse the content + if (unlikely(indentation) && doc->mode == NORMAL_PARSING) { + hoedown_buffer *code = hoedown_pool_get(&doc->buffers_block); + code->size = 0; + + size_t line_start; + while (i < size) { + // Advance until end of line + line_start = i; + while (i < size && data[i] != '\n') i++; + if (i < size) i++; + + // Check if there's an ending fence here + mark = parse_code_fence(data + line_start, i - line_start, &end_character, &end_width); + + if (mark && start_character == end_character && start_width <= end_width && + is_empty(data + line_start + mark, i - line_start - mark)) + break; + + // Skip optional indentation + mark = line_start; + while (mark < size && data[mark] == ' ' && mark - line_start < indentation) mark++; + + // Copy line into work buffer + hoedown_buffer_put(code, data + mark, i - mark); + } + + // Render! + parse_paragraph(doc, target, data + parsed, start - parsed); + + doc->rndr.fenced_code_block(target, code, info->size ? info : NULL, &doc->data); + hoedown_pool_pop(&doc->buffers_block); + } else { + // Optimization: When indentation is 0 we don't need intermediate buffers. + size_t text_start = i, line_start; + while (1) { + line_start = i; + if (i >= size) break; + + // Advance until end of line + while (i < size && data[i] != '\n') i++; + if (i < size) i++; + + // Check if there's an ending fence here + mark = parse_code_fence(data + line_start, i - line_start, &end_character, &end_width); + + if (mark && start_character == end_character && start_width <= end_width && + is_empty(data + line_start + mark, i - line_start - mark)) + break; + } + + // Render! + if (doc->mode == NORMAL_PARSING) { + parse_paragraph(doc, target, data + parsed, start - parsed); + + hoedown_buffer code = {(uint8_t *)data + text_start, line_start - text_start, 0, 0, NULL, NULL}; + doc->rndr.fenced_code_block(target, &code, info->size ? info : NULL, &doc->data); + } + } + + if (doc->mode == NORMAL_PARSING) + hoedown_pool_pop(&doc->buffers_inline); + + return i; +} + +static inline int test_html_block(const uint8_t *data, size_t size) { + return size >= 1 && (data[0] == '<' || (data[0] == ' ' && + size >= 2 && (data[1] == '<' || (data[1] == ' ' && + size >= 3 && (data[2] == '<' || (data[2] == ' ' && + size >= 4 && (data[3] == '<'))))))); +} + +static inline size_t parse_html_block(hoedown_document *doc, void *target, const uint8_t *data, size_t parsed, size_t start, size_t size) { + size_t i = start, content_start, mark; + + // Skip three optional spaces + if (unlikely(i + 3 > size)) return 0; + + if (data[i] == ' ') { i++; + if (data[i] == ' ') { i++; + if (data[i] == ' ') { i++; + }}} + + // Check for initial '<' + if (data[i] != '<') return 0; + content_start = i; + + // Advance until empty line + while (1) { + mark = i; + while (i < size && data[i] == ' ') i++; + + if (i < size && data[i] != '\n') i++; + else break; + + while (i < size && data[i] != '\n') i++; + if (i < size) i++; + } + + // Try to parse various constructs with a mega-if + const uint8_t *html_data = data + content_start; + size_t html_size = mark - content_start; + hoedown_buffer *name = hoedown_pool_get(&doc->buffers_block); + + if ( + // HTML start / end tag + ( + (html_parse_start_tag(name, html_data, html_size) || + html_parse_end_tag(name, html_data, html_size)) + && hoedown_find_block_tag((const char *)name->data, name->size) + ) + + // HTML comment + || html_parse_comment(html_data, html_size) + + // CDATA section + || parse_cdata(html_data, html_size) + + // Processing instruction + || parse_processing_instruction(html_data, html_size) + + // Declaration + || parse_declaration(html_data, html_size) + ) { + hoedown_pool_pop(&doc->buffers_block); + + // Render! + if (doc->mode == NORMAL_PARSING) { + parse_paragraph(doc, target, data + parsed, start - parsed); + + hoedown_buffer html = {(uint8_t *)html_data, html_size, 0, 0, NULL, NULL}; + doc->rndr.html_block(target, &html, &doc->data); + } + + return i; + } + + hoedown_pool_pop(&doc->buffers_block); + return 0; +} + +static inline int test_link_reference(const uint8_t *data, size_t size) { + return size >= 1 && (data[0] == '[' || (data[0] == ' ' && + size >= 2 && (data[1] == '[' || (data[1] == ' ' && + size >= 3 && (data[2] == '[' || (data[2] == ' ' && + size >= 4 && (data[3] == '['))))))); +} + +// Marker parsing method. +static inline size_t parse_link_reference(hoedown_document *doc, void *target, const uint8_t *data, size_t parsed, size_t start, size_t size) { + size_t i = start, mark, label_start, label_end; + struct link_ref *ref = NULL; + + // Skip three optional spaces + if (unlikely(i + 3 > size)) return 0; + + if (data[i] == ' ') { i++; + if (data[i] == ' ') { i++; + if (data[i] == ' ') { i++; + }}} + + // Label starting delimiter + if (i < size && data[i] == '[') i++; + else return 0; + + // Find label ending delimiter + // FIXME: spec doesn't clarify wether newlines are allowed here + mark = i; + size_t level = 0; + while (1) { + while (i < size && data[i] != ']' && data[i] != '[') i++; + if (i >= size) return 0; + + if (is_escaped(data, i)) { + i++; + continue; + } + + if (likely(data[i] == ']')) { + if (level == 0) break; + level--; + } else level++; + + i++; + } + + label_start = mark; + label_end = i; + i++; + + // Colon and spacing, up to one newline + if (i < size && data[i] == ':') i++; + else return 0; + + while (i < size && data[i] == ' ') i++; + if (i < size && data[i] == '\n') { + i++; + while (i < size && data[i] == ' ') i++; + } + + // Link spec + if (doc->mode == MARKER_PARSING) + ref = hoedown_pool_get(&doc->marker_link_refs); + + mark = i; + i += parse_link_spec(doc, ref, data + i, size - i); + if (mark == i) { + if (ref) hoedown_pool_pop(&doc->marker_link_refs); + return 0; + } + + // Rest of line must be empty + mark = i; + i += next_line_empty(data + i, size - i); + if (mark == i && i < size) { + if (ref) hoedown_pool_pop(&doc->marker_link_refs); + return 0; + } + + // Store! + if (doc->mode == MARKER_PARSING) { + // Hash the label to get ID + hoedown_buffer *label = hoedown_pool_get(&doc->buffers_inline); + label->size = 0; + collapse_spacing(label, data + label_start, label_end - label_start); + ref->id = hash_string(label->data, label->size); + hoedown_pool_pop(&doc->buffers_inline); + + // If another reference with same ID exists, return + if (find_link_ref(doc, ref->id)) { + hoedown_pool_pop(&doc->marker_link_refs); + return 0; + } + + // Store entry + add_link_ref(doc, ref); + } else if (doc->mode == NORMAL_PARSING) { + parse_paragraph(doc, target, data + parsed, start - parsed); + } + return i; +} + +static inline size_t parse_quote_block_prefix(const uint8_t *data, size_t size) { + size_t i = 0; + + // Skip three optional spaces + while (i < size && data[i] == ' ') i++; + if (i >= 4) return 0; + + // Angle bracket + if (i < size && data[i] == '>') i++; + else return 0; + + // Optional space + if (i < size && data[i] == ' ') i++; + + return i; +} + +// The strategy here is: enter dumb parsing mode and collect the quote block +// content to `work`. When an empty line is reached, we break the loop. +// When we have finished collecting content, restore parsing mode and parse it. +// +// If we find a lazy line, we [dumb-]parse the content (starting from +// `parsed`) with these lazy lines to see if they are valid lazy lines; +// we break if they aren't. +static inline size_t parse_quote_block_content(hoedown_document *doc, void *content, hoedown_buffer *work, const uint8_t *data, size_t size) { + size_t i = 0, mark; + size_t parsed = 0, current_size; + enum parsing_mode original_mode = doc->mode; + doc->mode = DUMB_PARSING; + //FIXME: refactor + + while (1) { + mark = i; + while (i < size && data[i] == ' ') i++; + + // Empty line always ends the quote block + if (i >= size || data[i] == '\n') break; + + // A prefixed line continues the block + if (i - mark < 4 && data[i] == '>') { + i++; + if (i < size && data[i] == ' ') i++; + + // Put line into working buffer + mark = i; + while (i < size && data[i] != '\n') i++; + if (i < size) i++; + + hoedown_buffer_put(work, data + mark, i - mark); + continue; + } + + // Possible lazy line, collect this and following possible lazy lines + i = mark; + current_size = work->size; + while (1) { + if (parse_any_block(doc, NULL, data, i, i, size, size, 0)) break; + + while (i < size && data[i] != '\n') i++; + if (i < size) i++; + + if (i >= size || next_line_empty(data + i, size - i) || parse_quote_block_prefix(data + i, size - i)) + break; + } + hoedown_buffer_put(work, data + mark, i - mark); + + // If the next line is prefixed, the block could continue. + // Otherwise, we can be sure it ends here and return immediately. + if (parse_quote_block_prefix(data + i, size - i)) { + // Can these lines continue the block? + parsed += parse_block(doc, NULL, work->data + parsed, current_size - parsed, work->size - parsed, HOEDOWN_FT_QUOTE_BLOCK | HOEDOWN_FT_LIST); + if (parsed == current_size) { + work->size = current_size; + break; + } + parsed = work->size; + } else { + // Definitively parse and return + doc->mode = original_mode; + parsed = parse_block(doc, content, work->data, current_size, work->size, HOEDOWN_FT_QUOTE_BLOCK | HOEDOWN_FT_LIST); + if (parsed == current_size) { + work->size = current_size; + return mark; + } + + // These are valid lazy lines, parse reminder if present and return + if (parsed < current_size) parse_block(doc, content, work->data + parsed, work->size - parsed, work->size - parsed, 0); + return i; + } + } + + // Actually parse collected content + doc->mode = original_mode; + parse_block(doc, content, work->data, work->size, work->size, 0); + return mark; +} + +// This block construct is a container. +static inline size_t parse_quote_block(hoedown_document *doc, void *target, const uint8_t *data, size_t parsed, size_t start, size_t size) { + size_t i = start, mark; + hoedown_buffer *work = NULL; + void *content = NULL; + + // We should have a quote block prefix here + mark = i; + i += parse_quote_block_prefix(data + i, size - i); + if (mark == i) return 0; + + // Get working buffer & content + work = hoedown_pool_get(&doc->buffers_block); + work->size = 0; + + if (doc->mode == NORMAL_PARSING) + content = doc->rndr.object_get(0, &doc->data); + + // Collect first line + mark = i; + while (i < size && data[i] != '\n') i++; + if (i < size) i++; + + hoedown_buffer_put(work, data + mark, i - mark); + + // Parse rest of content + i += parse_quote_block_content(doc, content, work, data + i, size - i); + + // Render! + if (doc->mode == NORMAL_PARSING) { + parse_paragraph(doc, target, data + parsed, start - parsed); + doc->rndr.quote_block(target, content, &doc->data); + } + + hoedown_pool_pop(&doc->buffers_block); + return i; +} + +static inline size_t parse_list_marker(const uint8_t *data, size_t size, int *is_ordered, int *number, uint8_t *character) { + if (size < 1) return 0; + + if (data[0] == '-' || data[0] == '*' || data[0] == '+') { + *is_ordered = 0; + *character = data[0]; + return 1; + } + + if (is_digit_ascii(data[0])) { + size_t i = 1; + while (i < size && is_digit_ascii(data[i])) i++; + + if (i < size && (data[i] == '.' || data[i] == ')')) { + // Parse the integer + if (number) { + *number = 0; + for (size_t a = 0; a < i; a++) + *number = (*number * 10) + (data[a] - '0'); + } + + *is_ordered = 1; + *character = data[i]; + return i + 1; + } + } + + return 0; +} + +static inline size_t parse_list_prefix(const uint8_t *data, size_t size, int *is_ordered, int *number, uint8_t *character) { + size_t i = 0, mark; + + // Optional indentation + while (i < size && data[i] == ' ') i++; + if (i >= 4) return 0; + + // Marker + mark = i; + i += parse_list_marker(data + i, size - i, is_ordered, number, character); + if (mark == i) return 0; + + // Followed by spacing or EOF + if (i < size && !is_space(data[i])) return 0; + if (i < size && data[i] == ' ') i++; + + return i; +} + +//FIXME: test_list + +// Should only be called from parse_list_item_content. Tries to resolve if the +// list item ends on that empty line, or continues afterwards. If it continues, +// the point where the list item continues is returned. +static inline size_t parse_list_item_empty(hoedown_document *doc, hoedown_buffer *work, size_t *parsed, int *is_loose, const uint8_t *data, size_t start, size_t size, size_t indentation, size_t empty_start) { + size_t i = start, mark; + int multiple_lines = 0; + + // Start by skipping empty lines and finding a non-empty non-lazy line + // If such a line cannot be found, the list item cannot continue. + while (1) { + mark = i + indentation; + while (i < size && data[i] == ' ') i++; + if (i >= size) return 0; + + // Empty line is accepted (for now) + if (data[i] == '\n') { + if (mark > i) mark = i; + i++; + hoedown_buffer_put(work, data + mark, i - mark); + multiple_lines = 1; + continue; + } + + // Lazy line not allowed here + if (mark > i) return 0; + + // Found a non-empty non-lazy line! + while (i < size && data[i] != '\n') i++; + if (i < size) i++; + hoedown_buffer_put(work, data + mark, i - mark); + break; + } + + // If there were no extra lines skipped, just one empty line, + // then we can be sure it belongs to the block. + if (!multiple_lines) { + // But before returning, look if that line makes the list loose + if (!*is_loose) { + *parsed += parse_block(doc, NULL, work->data + *parsed, empty_start - *parsed, work->size - *parsed, HOEDOWN_FT_FENCED_CODE_BLOCK | HOEDOWN_FT_LIST); + *is_loose = *parsed < work->size; + } + + return i; + } + + // If we get here there is more than one empty line, and we need + // to check if these empty lines belong to a fenced code block. + // Only in that case can the list item continue. + if (doc->ft & HOEDOWN_FT_FENCED_CODE_BLOCK) { + *parsed += parse_block(doc, NULL, work->data + *parsed, empty_start - *parsed, work->size - *parsed, HOEDOWN_FT_FENCED_CODE_BLOCK | HOEDOWN_FT_LIST); + if (*parsed > empty_start) return i; + } + + return 0; +} + +// Gets a new buffer from the block_buffers pool and collects the +// contents of a list item there. Assumes mode is DUMB_PARSING. +static inline size_t parse_list_item_content(hoedown_document *doc, int *is_loose, const uint8_t *data, size_t size, size_t indentation) { + size_t i = 0, mark, line_start; + size_t parsed = 0, work_mark; + + hoedown_buffer *work = hoedown_pool_get(&doc->buffers_block); + work->size = 0; + + // Collect first line, which decides the indentation + while (i < size && data[i] == ' ') i++; + if (i < 4 || !(doc->ft & HOEDOWN_FT_INDENTED_CODE_BLOCK)) indentation += i; + + while (i < size && data[i] != '\n') i++; + if (i < size) i++; + hoedown_buffer_put(work, data, i); + + // Rest of the lines + while (i < size) { + line_start = i; + mark = i + indentation; + while (i < size && data[i] == ' ') i++; + + // Empty line is checked + if (i >= size || data[i] == '\n') { + if (mark > i) mark = i; + if (i < size) i++; + work_mark = work->size; + hoedown_buffer_put(work, data + mark, i - mark); + + i = parse_list_item_empty(doc, work, &parsed, is_loose, data, i, size, indentation, work_mark); + if (i) continue; + work->size = work_mark; + i = line_start; + break; + } + + // Non-empty, lazy line is checked + if (mark > i) { + mark = i; + while (i < size && data[i] != '\n') i++; + if (i < size) i++; + + //FIXME: refactor this + if (parse_any_block(doc, NULL, data + mark, 0, 0, i - mark, i - mark, 0)) { + i = line_start; + break; + } + work_mark = work->size; + hoedown_buffer_put(work, data + mark, i - mark); + + parsed += parse_block(doc, NULL, data + parsed, work_mark - parsed, work->size - parsed, HOEDOWN_FT_LIST | HOEDOWN_FT_QUOTE_BLOCK); + if (parsed != work_mark) continue; + work->size = work_mark; + i = line_start; + break; + } + + // Non-empty, non-lazy line is accepted + while (i < size && data[i] != '\n') i++; + if (i < size) i++; + hoedown_buffer_put(work, data + mark, i - mark); + } + + return i; +} + +// Parse the rest of the list, starting from the end of the first list item. +static inline size_t parse_list_items(hoedown_document *doc, int *is_loose, const uint8_t *data, size_t size, uint8_t character) { + size_t i = 0, mark; + size_t last_item = 0; + int is_ordered; + uint8_t ncharacter; + int possible_loose; + + while (i < size) { + // Optional empty line (which makes list loose) + mark = i; + i += next_line_empty(data + i, size - i); + possible_loose = mark < i; + + // If the item we're about to parse is a rule, break + if (parse_horizontal_rule(doc, NULL, data, i, i, size)) break; + + // List item prefix of the same type + mark = i; + i += parse_list_prefix(data + i, size - i, &is_ordered, NULL, &ncharacter); + if (mark == i || character != ncharacter) break; + + // List item content + i += parse_list_item_content(doc, is_loose, data + i, size - i, i - mark); + last_item = i; + if (possible_loose) *is_loose = 1; + } + + return last_item; +} + +static inline size_t parse_list(hoedown_document *doc, void *target, const uint8_t *data, size_t parsed, size_t start, size_t size) { + int current_is_tight = doc->is_tight; + int current_mode = doc->mode; + size_t current_pool_position = doc->buffers_block.size; + + size_t i = start, mark; + int is_ordered, is_loose, number = 0; + uint8_t character; + void *content = NULL; + + // Collect first list item + mark = i; + i += parse_list_prefix(data + i, size - i, &is_ordered, &number, &character); + if (mark == i) return 0; + + is_loose = 0; + doc->mode = DUMB_PARSING; + i += parse_list_item_content(doc, &is_loose, data + i, size - i, i - mark); + + // Collect rest of the items + i += parse_list_items(doc, &is_loose, data + i, size - i, character); + + // Actually parse and render each list item + if (!is_loose) doc->is_tight = doc->current_nesting + 1; + doc->mode = current_mode; + if (current_mode == NORMAL_PARSING) + content = doc->rndr.object_get(0, &doc->data); + + for (size_t a = current_pool_position; a < doc->buffers_block.size; a++) { + hoedown_buffer *work = doc->buffers_block.item[a]; + void *item_content = NULL; + if (current_mode == NORMAL_PARSING) + item_content = doc->rndr.object_get(0, &doc->data); + + if (current_mode != DUMB_PARSING) + parse_block(doc, item_content, work->data, work->size, work->size, 0); + + if (current_mode == NORMAL_PARSING) + doc->rndr.list_item(content, item_content, is_ordered, !is_loose, &doc->data); + } + + // Render the list itself + doc->is_tight = current_is_tight; + doc->buffers_block.size = current_pool_position; + + if (current_mode == NORMAL_PARSING) { + parse_paragraph(doc, target, data + parsed, start - parsed); + doc->rndr.list(target, content, is_ordered, !is_loose, number, &doc->data); + } + return i; +} + + + +// BLOCK PARSING +// ------------- +// +// Here's the implementation of `parse_block`, the entry point for block +// parsing, and `parse_any_block`, which defines the priorities and +// requirements for all block constructs. +// +// For regular block parsing, `parse_block` should be called with the +// same value in `size` and `lazy_size`. +// +// But if there are lazy lines at the end of the regular content: `lazy_size` +// should be set to the size of the regular content plus the lazy lines. +// +// Lazy lines are only parsed if they belong to a block of type `lazy_ft`. +// Please note that not *all* of the additional content may be parsed, only +// the valid lazy lines. If the returned value equals `size`, there were no +// valid lazy lines parsed. +// +// If the lazy lines were parsed as part of the specified block, returned value +// will be greater than `size`. But if the lazy lines continued a paragraph at +// the end of the regular content, the paragraph (and lazy lines) will not be +// parsed, and the returned value will be less than `size`. Both cases are +// valid lazy lines, but must be handled differently; see i.e. quote blocks. + + +// Try to parse a block construct at a specific position, which is assumed +// to be the start of a non-empty line. +static inline size_t parse_any_block(hoedown_document *doc, void *target, const uint8_t *data, size_t parsed, size_t i, size_t size, size_t lazy_size, hoedown_features lazy_ft) { + size_t result; + + // Some constructs can't interrupt paragraphs, so we check that parsed == i + + if (doc->ft & HOEDOWN_FT_INDENTED_CODE_BLOCK && parsed == i && + test_indented_code_block(data + i, size - i) && + (result = parse_indented_code_block(doc, target, data, parsed, i, size))) + return result; + + if (doc->ft & HOEDOWN_FT_FENCED_CODE_BLOCK && + (result = parse_fenced_code_block(doc, target, data, parsed, i, + lazy_ft & HOEDOWN_FT_FENCED_CODE_BLOCK ? lazy_size : size))) + return result; + + if (doc->ft & HOEDOWN_FT_HORIZONTAL_RULE && + (result = parse_horizontal_rule(doc, target, data, parsed, i, size))) + return result; + + if (doc->ft & HOEDOWN_FT_QUOTE_BLOCK && + (result = parse_quote_block(doc, target, data, parsed, i, + lazy_ft & HOEDOWN_FT_QUOTE_BLOCK ? lazy_size : size))) + return result; + + if (doc->ft & HOEDOWN_FT_LIST && + (result = parse_list(doc, target, data, parsed, i, + lazy_ft & HOEDOWN_FT_LIST ? lazy_size : size))) + return result; + + if (doc->ft & HOEDOWN_FT_ATX_HEADER && + test_atx_header(data + i, size - i) && + (result = parse_atx_header(doc, target, data, parsed, i, size))) + return result; + + if (doc->ft & HOEDOWN_FT_SETEXT_HEADER && parsed == i && + (result = parse_setext_header(doc, target, data, parsed, i, size))) + return result; + + if (doc->ft & HOEDOWN_FT_HTML_BLOCK && + test_html_block(data + i, size - i) && + (result = parse_html_block(doc, target, data, parsed, i, size))) + return result; + + if (doc->ft & HOEDOWN_FT_LINK && parsed == i && + test_link_reference(data + i, size - i) && + (result = parse_link_reference(doc, target, data, parsed, i, size))) + return result; + + return 0; +} + + +static size_t parse_block(hoedown_document *doc, void *target, const uint8_t *data, size_t size, size_t lazy_size, hoedown_features lazy_ft) { + if (doc->current_nesting > doc->max_nesting) return size; //FIXME: stop all parsing here + doc->current_nesting++; + + size_t i = 0, result, parsed = 0; + + while (i < size) { + // First, check to see if this is an empty line + // If it is, parse any accumulated content as paragraph, and skip + if ((result = next_line_empty(data + i, size - i))) { + parse_paragraph(doc, target, data + parsed, i - parsed); + i += result; + parsed = i; + continue; + } + + // Try to parse a construct here + if ((result = parse_any_block(doc, target, data, parsed, i, size, lazy_size, lazy_ft))) { + i = parsed = result; + continue; + } + + // Nothing could be parsed on this line, skip to the next + while (i < size && data[i] != '\n') i++; + if (i < size) i++; + } + + // Parse rest of the content as paragraph + if (lazy_size == size && parsed < i) { + parse_paragraph(doc, target, data + parsed, i - parsed); + parsed = i; + } + + doc->current_nesting--; + return parsed; +} - i++; - } - if (doc->md.table_header) - doc->md.table_header(work, header_work, &doc->data); - if (doc->md.table_body) - doc->md.table_body(work, body_work, &doc->data); +// CHAR TRIGGERS, INLINE PARSING +// ----------------------------- +// +// Here's the implementation of `inline_parse`. When it finds an interesting +// character in the input, it looks up the appropiate function (called *char +// trigger*) to process the input at that point. +// +// The char trigger (for example, `char_dollar`) then calls routines to +// parse possible constructs at that point. +// +// If passed a delimiter, `parse_inline` will look for that character in +// unparsed input. If it's found, and the passed check callback accepts it, +// parsing ends at that point. - if (doc->md.table) - doc->md.table(ob, work, &doc->data); - } - free(col_data); - popbuf(doc, BUFFER_SPAN); - popbuf(doc, BUFFER_BLOCK); - popbuf(doc, BUFFER_BLOCK); - return i; -} +static size_t char_escape(hoedown_document *doc, void *target, const uint8_t *data, size_t parsed, size_t start, size_t size) { + size_t i = start + 1; -/* parse_block • parsing of one block, returning next uint8_t to parse */ -static void -parse_block(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t size) -{ - size_t beg, end, i; - uint8_t *txt_data; - beg = 0; + if (i >= size) return 0; - if (doc->work_bufs[BUFFER_SPAN].size + - doc->work_bufs[BUFFER_BLOCK].size > doc->max_nesting) - return; + if (doc->ft & HOEDOWN_FT_ESCAPE && is_punct_ascii(data[i])) { + parse_string(doc, target, data + parsed, start - parsed); + doc->rndr.escape(target, data[i], &doc->data); + return i + 1; + } - while (beg < size) { - txt_data = data + beg; - end = size - beg; + if (doc->ft & HOEDOWN_FT_HARD_LINEBREAK && data[i] == '\n') { + parse_string(doc, target, data + parsed, start - parsed); + doc->rndr.hard_linebreak(target, &doc->data); + return i + 1; + } - if (is_atxheader(doc, txt_data, end)) - beg += parse_atxheader(ob, doc, txt_data, end); - - else if (data[beg] == '<' && doc->md.blockhtml && - (i = parse_htmlblock(ob, doc, txt_data, end, 1)) != 0) - beg += i; - - else if ((i = is_empty(txt_data, end)) != 0) - beg += i; - - else if (is_hrule(txt_data, end)) { - if (doc->md.hrule) - doc->md.hrule(ob, &doc->data); - - while (beg < size && data[beg] != '\n') - beg++; - - beg++; - } - - else if ((doc->ext_flags & HOEDOWN_EXT_FENCED_CODE) != 0 && - (i = parse_fencedcode(ob, doc, txt_data, end)) != 0) - beg += i; - - else if ((doc->ext_flags & HOEDOWN_EXT_TABLES) != 0 && - (i = parse_table(ob, doc, txt_data, end)) != 0) - beg += i; - - else if (prefix_quote(txt_data, end)) - beg += parse_blockquote(ob, doc, txt_data, end); - - else if (!(doc->ext_flags & HOEDOWN_EXT_DISABLE_INDENTED_CODE) && prefix_code(txt_data, end)) - beg += parse_blockcode(ob, doc, txt_data, end); - - else if (prefix_uli(txt_data, end)) - beg += parse_list(ob, doc, txt_data, end, 0); - - else if (prefix_oli(txt_data, end)) - beg += parse_list(ob, doc, txt_data, end, HOEDOWN_LIST_ORDERED); - - else - beg += parse_paragraph(ob, doc, txt_data, end); - } -} - - - -/********************* - * REFERENCE PARSING * - *********************/ - -/* is_footnote • returns whether a line is a footnote definition or not */ -static int -is_footnote(const uint8_t *data, size_t beg, size_t end, size_t *last, struct footnote_list *list) -{ - size_t i = 0; - hoedown_buffer *contents = 0; - size_t ind = 0; - int in_empty = 0; - size_t start = 0; - - size_t id_offset, id_end; - - /* up to 3 optional leading spaces */ - if (beg + 3 >= end) return 0; - if (data[beg] == ' ') { i = 1; - if (data[beg + 1] == ' ') { i = 2; - if (data[beg + 2] == ' ') { i = 3; - if (data[beg + 3] == ' ') return 0; } } } - i += beg; - - /* id part: caret followed by anything between brackets */ - if (data[i] != '[') return 0; - i++; - if (i >= end || data[i] != '^') return 0; - i++; - id_offset = i; - while (i < end && data[i] != '\n' && data[i] != '\r' && data[i] != ']') - i++; - if (i >= end || data[i] != ']') return 0; - id_end = i; - - /* spacer: colon (space | tab)* newline? (space | tab)* */ - i++; - if (i >= end || data[i] != ':') return 0; - i++; - - /* getting content buffer */ - contents = hoedown_buffer_new(64); - - start = i; - - /* process lines similar to a list item */ - while (i < end) { - while (i < end && data[i] != '\n' && data[i] != '\r') i++; - - /* process an empty line */ - if (is_empty(data + start, i - start)) { - in_empty = 1; - if (i < end && (data[i] == '\n' || data[i] == '\r')) { - i++; - if (i < end && data[i] == '\n' && data[i - 1] == '\r') i++; - } - start = i; - continue; - } - - /* calculating the indentation */ - ind = 0; - while (ind < 4 && start + ind < end && data[start + ind] == ' ') - ind++; - - /* joining only indented stuff after empty lines; - * note that now we only require 1 space of indentation - * to continue, just like lists */ - if (ind == 0) { - if (start == id_end + 2 && data[start] == '\t') {} - else break; - } - else if (in_empty) { - hoedown_buffer_putc(contents, '\n'); - } - - in_empty = 0; - - /* adding the line into the content buffer */ - hoedown_buffer_put(contents, data + start + ind, i - start - ind); - /* add carriage return */ - if (i < end) { - hoedown_buffer_putc(contents, '\n'); - if (i < end && (data[i] == '\n' || data[i] == '\r')) { - i++; - if (i < end && data[i] == '\n' && data[i - 1] == '\r') i++; - } - } - start = i; - } - - if (last) - *last = start; - - if (list) { - struct footnote_ref *ref; - ref = create_footnote_ref(list, data + id_offset, id_end - id_offset); - if (!ref) - return 0; - if (!add_footnote_ref(list, ref)) { - free_footnote_ref(ref); - return 0; - } - ref->contents = contents; - } - - return 1; -} - -/* is_ref • returns whether a line is a reference or not */ -static int -is_ref(const uint8_t *data, size_t beg, size_t end, size_t *last, struct link_ref **refs) -{ -/* int n; */ - size_t i = 0; - size_t id_offset, id_end; - size_t link_offset, link_end; - size_t title_offset, title_end; - size_t line_end; - - /* up to 3 optional leading spaces */ - if (beg + 3 >= end) return 0; - if (data[beg] == ' ') { i = 1; - if (data[beg + 1] == ' ') { i = 2; - if (data[beg + 2] == ' ') { i = 3; - if (data[beg + 3] == ' ') return 0; } } } - i += beg; - - /* id part: anything but a newline between brackets */ - if (data[i] != '[') return 0; - i++; - id_offset = i; - while (i < end && data[i] != '\n' && data[i] != '\r' && data[i] != ']') - i++; - if (i >= end || data[i] != ']') return 0; - id_end = i; - - /* spacer: colon (space | tab)* newline? (space | tab)* */ - i++; - if (i >= end || data[i] != ':') return 0; - i++; - while (i < end && data[i] == ' ') i++; - if (i < end && (data[i] == '\n' || data[i] == '\r')) { - i++; - if (i < end && data[i] == '\r' && data[i - 1] == '\n') i++; } - while (i < end && data[i] == ' ') i++; - if (i >= end) return 0; - - /* link: spacing-free sequence, optionally between angle brackets */ - if (data[i] == '<') - i++; - - link_offset = i; - - while (i < end && data[i] != ' ' && data[i] != '\n' && data[i] != '\r') - i++; - - if (data[i - 1] == '>') link_end = i - 1; - else link_end = i; - - /* optional spacer: (space | tab)* (newline | '\'' | '"' | '(' ) */ - while (i < end && data[i] == ' ') i++; - if (i < end && data[i] != '\n' && data[i] != '\r' - && data[i] != '\'' && data[i] != '"' && data[i] != '(') - return 0; - line_end = 0; - /* computing end-of-line */ - if (i >= end || data[i] == '\r' || data[i] == '\n') line_end = i; - if (i + 1 < end && data[i] == '\n' && data[i + 1] == '\r') - line_end = i + 1; - - /* optional (space|tab)* spacer after a newline */ - if (line_end) { - i = line_end + 1; - while (i < end && data[i] == ' ') i++; } - - /* optional title: any non-newline sequence enclosed in '"() - alone on its line */ - title_offset = title_end = 0; - if (i + 1 < end - && (data[i] == '\'' || data[i] == '"' || data[i] == '(')) { - i++; - title_offset = i; - /* looking for EOL */ - while (i < end && data[i] != '\n' && data[i] != '\r') i++; - if (i + 1 < end && data[i] == '\n' && data[i + 1] == '\r') - title_end = i + 1; - else title_end = i; - /* stepping back */ - i -= 1; - while (i > title_offset && data[i] == ' ') - i -= 1; - if (i > title_offset - && (data[i] == '\'' || data[i] == '"' || data[i] == ')')) { - line_end = title_end; - title_end = i; } } - - if (!line_end || link_end == link_offset) - return 0; /* garbage after the link empty link */ - - /* a valid ref has been found, filling-in return structures */ - if (last) - *last = line_end; - - if (refs) { - struct link_ref *ref; - - ref = add_link_ref(refs, data + id_offset, id_end - id_offset); - if (!ref) - return 0; - - ref->link = hoedown_buffer_new(link_end - link_offset); - hoedown_buffer_put(ref->link, data + link_offset, link_end - link_offset); - - if (title_end > title_offset) { - ref->title = hoedown_buffer_new(title_end - title_offset); - hoedown_buffer_put(ref->title, data + title_offset, title_end - title_offset); - } - } - - return 1; -} - -static void expand_tabs(hoedown_buffer *ob, const uint8_t *line, size_t size) -{ - /* This code makes two assumptions: - * - Input is valid UTF-8. (Any byte with top two bits 10 is skipped, - * whether or not it is a valid UTF-8 continuation byte.) - * - Input contains no combining characters. (Combining characters - * should be skipped but are not.) - */ - size_t i = 0, tab = 0; - - while (i < size) { - size_t org = i; - - while (i < size && line[i] != '\t') { - i++; - /* ignore UTF-8 continuation bytes */ - if ((line[i] & 0xc0) != 0x80) - tab++; - } - - if (i > org) - hoedown_buffer_put(ob, line + org, i - org); + return 0; +} - if (i >= size) - break; - - do { - hoedown_buffer_putc(ob, ' '); tab++; - } while (tab % 4); - - i++; - } -} - -/********************** - * EXPORTED FUNCTIONS * - **********************/ - -hoedown_document * -hoedown_document_new( - const hoedown_renderer *renderer, - hoedown_extensions extensions, - size_t max_nesting) -{ - hoedown_document *doc = NULL; - - assert(max_nesting > 0 && renderer); - - doc = hoedown_malloc(sizeof(hoedown_document)); - memcpy(&doc->md, renderer, sizeof(hoedown_renderer)); - - doc->data.opaque = renderer->opaque; - - hoedown_stack_init(&doc->work_bufs[BUFFER_BLOCK], 4); - hoedown_stack_init(&doc->work_bufs[BUFFER_SPAN], 8); - - memset(doc->active_char, 0x0, 256); - - if (doc->md.emphasis || doc->md.double_emphasis || doc->md.triple_emphasis) { - doc->active_char['*'] = MD_CHAR_EMPHASIS; - doc->active_char['_'] = MD_CHAR_EMPHASIS; - if (extensions & HOEDOWN_EXT_STRIKETHROUGH) - doc->active_char['~'] = MD_CHAR_EMPHASIS; - if (extensions & HOEDOWN_EXT_HIGHLIGHT) - doc->active_char['='] = MD_CHAR_EMPHASIS; - } +static size_t char_newline(hoedown_document *doc, void *target, const uint8_t *data, size_t parsed, size_t start, size_t size) { + size_t i = start; + // Rewind on all trailing spaces + while (i > parsed && data[i-1] == ' ') i--; - if (doc->md.codespan) - doc->active_char['`'] = MD_CHAR_CODESPAN; + if (doc->ft & HOEDOWN_FT_LINEBREAK && start - i >= 2) { + parse_string(doc, target, data + parsed, i - parsed); + doc->rndr.hard_linebreak(target, &doc->data); + return start + 1; + } - if (doc->md.linebreak) - doc->active_char['\n'] = MD_CHAR_LINEBREAK; + //FIXME: SOFT_LINEBREAK - if (doc->md.image || doc->md.link) - doc->active_char['['] = MD_CHAR_LINK; + if (i == start) return 0; + parse_string(doc, target, data + parsed, i - parsed); + parse_string(doc, target, data + start, 1); + return start + 1; +} - doc->active_char['<'] = MD_CHAR_LANGLE; - doc->active_char['\\'] = MD_CHAR_ESCAPE; - doc->active_char['&'] = MD_CHAR_ENTITY; +static size_t char_angle_bracket(hoedown_document *doc, void *target, const uint8_t *data, size_t parsed, size_t start, size_t size) { + size_t result; - if (extensions & HOEDOWN_EXT_AUTOLINK) { - doc->active_char[':'] = MD_CHAR_AUTOLINK_URL; - doc->active_char['@'] = MD_CHAR_AUTOLINK_EMAIL; - doc->active_char['w'] = MD_CHAR_AUTOLINK_WWW; - } + if (doc->ft & HOEDOWN_FT_URI_AUTOLINK && + (result = parse_uri_autolink(doc, target, data, parsed, start, size))) + return result; - if (extensions & HOEDOWN_EXT_SUPERSCRIPT) - doc->active_char['^'] = MD_CHAR_SUPERSCRIPT; - if (extensions & HOEDOWN_EXT_QUOTE) - doc->active_char['"'] = MD_CHAR_QUOTE; + if (!(doc->ft & HOEDOWN_FT_HTML)) return 0; - if (extensions & HOEDOWN_EXT_MATH) - doc->active_char['$'] = MD_CHAR_MATH; + const uint8_t *cur_data = data + start; + size_t cur_size = size - start; - /* Extension data */ - doc->ext_flags = extensions; - doc->max_nesting = max_nesting; - doc->in_link_body = 0; + if ( + (result = html_parse_start_tag(NULL, cur_data, cur_size)) || + (result = html_parse_end_tag(NULL, cur_data, cur_size)) || + (result = html_parse_comment(cur_data, cur_size)) || + (result = parse_cdata(cur_data, cur_size)) || + (result = parse_processing_instruction(cur_data, cur_size)) || + (result = parse_declaration(cur_data, cur_size)) + ) { + parse_string(doc, target, data + parsed, start - parsed); + hoedown_buffer html = {(uint8_t *)cur_data, result, 0, 0, NULL, NULL}; + doc->rndr.html(target, &html, &doc->data); + return start + result; + } - return doc; + return 0; } -void -hoedown_document_render(hoedown_document *doc, hoedown_buffer *ob, const uint8_t *data, size_t size) -{ - static const uint8_t UTF8_BOM[] = {0xEF, 0xBB, 0xBF}; +static size_t char_backtick(hoedown_document *doc, void *target, const uint8_t *data, size_t parsed, size_t start, size_t size) { + return parse_code_span(doc, target, data, parsed, start, size); +} - hoedown_buffer *text; - size_t beg, end; +static size_t char_ampersand(hoedown_document *doc, void *target, const uint8_t *data, size_t parsed, size_t start, size_t size) { + size_t i = start + 1; - int footnotes_enabled; + hoedown_buffer *character = hoedown_pool_get(&doc->buffers_inline); + character->size = 0; + i += hoedown_unescape_entity(character, data + i, size - i); - text = hoedown_buffer_new(64); + if (i > start + 1) { + parse_string(doc, target, data + parsed, start - parsed); - /* Preallocate enough space for our buffer to avoid expanding while copying */ - hoedown_buffer_grow(text, size); + doc->rndr.entity(target, character, &doc->data); + hoedown_pool_pop(&doc->buffers_inline); + return i; + } - /* reset the references table */ - memset(&doc->refs, 0x0, REF_TABLE_SIZE * sizeof(void *)); + hoedown_pool_pop(&doc->buffers_inline); + return 0; +} - footnotes_enabled = doc->ext_flags & HOEDOWN_EXT_FOOTNOTES; +static size_t char_star(hoedown_document *doc, void *target, const uint8_t *data, size_t parsed, size_t start, size_t size) { + return parse_emphasis(doc, target, data, parsed, start, size); +} - /* reset the footnotes lists */ - if (footnotes_enabled) { - memset(&doc->footnotes_found, 0x0, sizeof(doc->footnotes_found)); - memset(&doc->footnotes_used, 0x0, sizeof(doc->footnotes_used)); - } +static size_t char_underscore(hoedown_document *doc, void *target, const uint8_t *data, size_t parsed, size_t start, size_t size) { + return parse_emphasis(doc, target, data, parsed, start, size); +} - /* first pass: looking for references, copying everything else */ - beg = 0; +static size_t char_square_bracket(hoedown_document *doc, void *target, const uint8_t *data, size_t parsed, size_t start, size_t size) { + return parse_link(doc, target, data, parsed, start, size); +} - /* Skip a possible UTF-8 BOM, even though the Unicode standard - * discourages having these in UTF-8 documents */ - if (size >= 3 && memcmp(data, UTF8_BOM, 3) == 0) - beg += 3; - while (beg < size) /* iterating over lines */ - if (footnotes_enabled && is_footnote(data, beg, size, &end, &doc->footnotes_found)) - beg = end; - else if (is_ref(data, beg, size, &end, doc->refs)) - beg = end; - else { /* skipping to the next line */ - end = beg; - while (end < size && data[end] != '\n' && data[end] != '\r') - end++; +static size_t parse_inline(hoedown_document *doc, void *target, const uint8_t *data, size_t size, uint8_t delimiter, delimiter_check check, void *opaque) { + if (doc->current_nesting > doc->max_nesting) return size; + doc->current_nesting++; + + size_t i = 0, result, parsed = 0; + char_trigger *active_chars = doc->active_chars; + + while (i < size) { + // Skip any chars we're not interested in + if (delimiter) { + while (i < size && active_chars[data[i]] == NULL && data[i] != delimiter) i++; + if (i < size && data[i] == delimiter) { + // We found the delimiter we were looking for! + if (!check || check(doc, data, parsed, i, size, opaque)) break; + } + } else { + while (i < size && active_chars[data[i]] == NULL) i++; + } - /* adding the line body if present */ - if (end > beg) - expand_tabs(text, data + beg, end - beg); + if (i >= size) break; - while (end < size && (data[end] == '\n' || data[end] == '\r')) { - /* add one \n per newline */ - if (data[end] == '\n' || (end + 1 < size && data[end + 1] != '\n')) - hoedown_buffer_putc(text, '\n'); - end++; - } + // Call the char trigger, see if we can parse something here + if (active_chars[data[i]] && (result = active_chars[data[i]](doc, target, data, parsed, i, size))) { + parsed = i = result; + continue; + } - beg = end; - } + // Okay, skip this character and move on + i++; + } - /* pre-grow the output buffer to minimize allocations */ - hoedown_buffer_grow(ob, text->size + (text->size >> 1)); + // Parse rest of content as string + parse_string(doc, target, data + parsed, i - parsed); - /* second pass: actual rendering */ - if (doc->md.doc_header) - doc->md.doc_header(ob, 0, &doc->data); + doc->current_nesting--; + return i; +} - if (text->size) { - /* adding a final newline if not already present */ - if (text->data[text->size - 1] != '\n' && text->data[text->size - 1] != '\r') - hoedown_buffer_putc(text, '\n'); +static inline void set_active_chars(char_trigger *active_chars, hoedown_features ft) { + memset(active_chars, 0, 256 * sizeof(char_trigger *)); - parse_block(ob, doc, text->data, text->size); - } + if (ft & (HOEDOWN_FT_ESCAPE | HOEDOWN_FT_MATH)) + active_chars['\\'] = char_escape; - /* footnotes */ - if (footnotes_enabled) - parse_footnote_list(ob, doc, &doc->footnotes_used); + if (ft & (HOEDOWN_FT_HARD_LINEBREAK | HOEDOWN_FT_LINEBREAK | HOEDOWN_FT_SOFT_LINEBREAK)) + active_chars['\n'] = char_newline; - if (doc->md.doc_footer) - doc->md.doc_footer(ob, 0, &doc->data); + if (ft & (HOEDOWN_FT_HTML | HOEDOWN_FT_URI_AUTOLINK | HOEDOWN_FT_EMAIL_AUTOLINK)) + active_chars['<'] = char_angle_bracket; - /* clean-up */ - hoedown_buffer_free(text); - free_link_refs(doc->refs); - if (footnotes_enabled) { - free_footnote_list(&doc->footnotes_found, 1); - free_footnote_list(&doc->footnotes_used, 0); - } + if (ft & (HOEDOWN_FT_CODE_SPAN)) + active_chars['`'] = char_backtick; - assert(doc->work_bufs[BUFFER_SPAN].size == 0); - assert(doc->work_bufs[BUFFER_BLOCK].size == 0); + if (ft & (HOEDOWN_FT_ENTITY)) + active_chars['&'] = char_ampersand; + + if (ft & (HOEDOWN_FT_EMPHASIS)) + active_chars['*'] = char_star; + + if (ft & (HOEDOWN_FT_EMPHASIS)) + active_chars['_'] = char_underscore; + + if (ft & (HOEDOWN_FT_LINK)) + active_chars['['] = char_square_bracket; } -void -hoedown_document_render_inline(hoedown_document *doc, hoedown_buffer *ob, const uint8_t *data, size_t size) -{ - size_t i = 0, mark; - hoedown_buffer *text = hoedown_buffer_new(64); - /* reset the references table */ - memset(&doc->refs, 0x0, REF_TABLE_SIZE * sizeof(void *)); - /* first pass: expand tabs and process newlines */ - hoedown_buffer_grow(text, size); - while (1) { - mark = i; - while (i < size && data[i] != '\n' && data[i] != '\r') - i++; +// PUBLIC METHODS & MISC +// --------------------- +// +// There it is. The public entry point for rendering. The method prepares the +// `hoedown_document` struct for a render, calls `parse_block` or +// `parse_inline` as appropiate, then cleans everything up. +// +// Other things can be implemented here, such as exposed internal methods. - expand_tabs(text, data + mark, i - mark); - if (i >= size) - break; +static inline void restrict_features(const hoedown_renderer *rndr, hoedown_features *ft) { + hoedown_features not_present = 0; + + //TODO + + // Remove not present features from *ft + *ft &= ~not_present; +} - while (i < size && (data[i] == '\n' || data[i] == '\r')) { - /* add one \n per newline */ - if (data[i] == '\n' || (i + 1 < size && data[i + 1] != '\n')) - hoedown_buffer_putc(text, '\n'); - i++; - } - } - /* second pass: actual rendering */ - hoedown_buffer_grow(ob, text->size + (text->size >> 1)); +static inline void expand_tabs(hoedown_buffer *ob, const uint8_t *data, size_t i, size_t size) { + size_t mark; + size_t isize = ob->size; + static const uint8_t *tab = (const uint8_t *)" "; - if (doc->md.doc_header) - doc->md.doc_header(ob, 1, &doc->data); + while (i < size) { + mark = i; + while (1) { + // Advance until we find a tab, but keep multi-byte characters in mind + while (i < size && (data[i] & 0xc0) != 0x80 && data[i] != '\t') i++; + if (i >= size || data[i] == '\t') break; + // this byte should not be counted + i++; isize++; + } + + hoedown_buffer_put(ob, data + mark, i - mark); + if (i >= size) break; + + hoedown_buffer_put(ob, tab, 4 - (ob->size - isize) % 4); + i++; + } +} - parse_inline(ob, doc, text->data, text->size); +void hoedown_preprocess(hoedown_buffer *ob, const uint8_t *data, size_t size) { + size_t i = 0, mark; + hoedown_buffer_grow(ob, size); - if (doc->md.doc_footer) - doc->md.doc_footer(ob, 1, &doc->data); + while (1) { + mark = i; + while (i < size && data[i] != '\n' && data[i] != '\r') i++; + expand_tabs(ob, data, mark, i); - /* clean-up */ - hoedown_buffer_free(text); + if (i >= size) break; - assert(doc->work_bufs[BUFFER_SPAN].size == 0); - assert(doc->work_bufs[BUFFER_BLOCK].size == 0); + if (data[i] == '\r') i++; + if (i < size && data[i] == '\n') i++; + hoedown_buffer_putc(ob, '\n'); + } } -void -hoedown_document_free(hoedown_document *doc) -{ - size_t i; - - for (i = 0; i < (size_t)doc->work_bufs[BUFFER_SPAN].asize; ++i) - hoedown_buffer_free(doc->work_bufs[BUFFER_SPAN].item[i]); +void hoedown_document_render( + hoedown_document *doc, + void *output, + const uint8_t *data, size_t size, + int is_inline +) { + // Initialize everything + memset(&doc->link_refs_table, 0, sizeof(doc->link_refs_table)); - for (i = 0; i < (size_t)doc->work_bufs[BUFFER_BLOCK].asize; ++i) - hoedown_buffer_free(doc->work_bufs[BUFFER_BLOCK].item[i]); + // Preprocess the input + if (doc->ft & HOEDOWN_FT_PREPROCESS) { + hoedown_preprocess(doc->text, data, size); + data = doc->text->data; + size = doc->text->size; + doc->text->size = 0; + } - hoedown_stack_uninit(&doc->work_bufs[BUFFER_SPAN]); - hoedown_stack_uninit(&doc->work_bufs[BUFFER_BLOCK]); + // Prepare + doc->data.output = output; + if (doc->rndr.render_start) doc->rndr.render_start(output, is_inline, &doc->data); - free(doc); + // First, parse the markers + doc->mode = MARKER_PARSING; + if (!is_inline) + parse_block(doc, NULL, data, size, size, 0); + + // Render! + doc->mode = NORMAL_PARSING; + void *target = doc->rndr.object_get(is_inline, &doc->data); + if (is_inline) + parse_inline(doc, target, data, size, 0, NULL, NULL); + else + parse_block(doc, target, data, size, size, 0); + + // Finish & cleanup + if (doc->rndr.render_end) doc->rndr.render_end(output, target, is_inline, &doc->data); + + doc->marker_link_refs.size = 0; + assert(doc->current_nesting == 0); + assert(doc->buffers_block.size == 0); + assert(doc->buffers_inline.size == 0); } diff --git a/src/document.h b/src/document.h index a8178fe..6ce8e8c 100644 --- a/src/document.h +++ b/src/document.h @@ -15,153 +15,232 @@ extern "C" { * CONSTANTS * *************/ -typedef enum hoedown_extensions { - /* block-level extensions */ - HOEDOWN_EXT_TABLES = (1 << 0), - HOEDOWN_EXT_FENCED_CODE = (1 << 1), - HOEDOWN_EXT_FOOTNOTES = (1 << 2), +typedef enum hoedown_features { + /* Block constructs */ + HOEDOWN_FT_DIRECTIVE = (1 << 0), + HOEDOWN_FT_INDENTED_CODE_BLOCK = (1 << 1), + HOEDOWN_FT_FENCED_CODE_BLOCK = (1 << 2), + HOEDOWN_FT_HORIZONTAL_RULE = (1 << 3), + HOEDOWN_FT_ATX_HEADER = (1 << 4), + HOEDOWN_FT_SETEXT_HEADER = (1 << 5), + HOEDOWN_FT_LIST = (1 << 8), + HOEDOWN_FT_QUOTE_BLOCK = (1 << 31), + HOEDOWN_FT_HTML_BLOCK = (1 << 6), + HOEDOWN_FT_TABLE = (1 << 7), - /* span-level extensions */ - HOEDOWN_EXT_AUTOLINK = (1 << 3), - HOEDOWN_EXT_STRIKETHROUGH = (1 << 4), - HOEDOWN_EXT_UNDERLINE = (1 << 5), - HOEDOWN_EXT_HIGHLIGHT = (1 << 6), - HOEDOWN_EXT_QUOTE = (1 << 7), - HOEDOWN_EXT_SUPERSCRIPT = (1 << 8), - HOEDOWN_EXT_MATH = (1 << 9), + /* Inline constructs */ + HOEDOWN_FT_ROLE = (1 << 9), + HOEDOWN_FT_ESCAPE = (1 << 10), + HOEDOWN_FT_HARD_LINEBREAK = (1 << 11), + HOEDOWN_FT_LINEBREAK = (1 << 12), + HOEDOWN_FT_SOFT_LINEBREAK = (1 << 13), + HOEDOWN_FT_URI_AUTOLINK = (1 << 14), + HOEDOWN_FT_EMAIL_AUTOLINK = (1 << 15), + HOEDOWN_FT_HTML = (1 << 16), + HOEDOWN_FT_ENTITY = (1 << 17), + HOEDOWN_FT_CODE_SPAN = (1 << 18), + HOEDOWN_FT_EMPHASIS = (1 << 19), + HOEDOWN_FT_LINK = (1 << 20), + HOEDOWN_FT_MATH = (1 << 22), + HOEDOWN_FT_SUPERSCRIPT = (1 << 23), + HOEDOWN_FT_QUOTE = (1 << 24), + HOEDOWN_FT_STRIKETHROUGH = (1 << 25), + HOEDOWN_FT_HIGHLIGHT = (1 << 26), + HOEDOWN_FT_FOOTNOTE = (1 << 27), - /* other flags */ - HOEDOWN_EXT_NO_INTRA_EMPHASIS = (1 << 11), - HOEDOWN_EXT_SPACE_HEADERS = (1 << 12), - HOEDOWN_EXT_MATH_EXPLICIT = (1 << 13), + /* Other features */ + HOEDOWN_FT_PREPROCESS = (1 << 28), - /* negative flags */ - HOEDOWN_EXT_DISABLE_INDENTED_CODE = (1 << 14) -} hoedown_extensions; + /* Flags */ + HOEDOWN_FT_LINK_IMAGE = (1 << 21), + HOEDOWN_FT_INTRA_EMPHASIS = (1 << 29), + HOEDOWN_FT_MATH_EXPLICIT = (1 << 30), +} hoedown_features; -#define HOEDOWN_EXT_BLOCK (\ - HOEDOWN_EXT_TABLES |\ - HOEDOWN_EXT_FENCED_CODE |\ - HOEDOWN_EXT_FOOTNOTES ) -#define HOEDOWN_EXT_SPAN (\ - HOEDOWN_EXT_AUTOLINK |\ - HOEDOWN_EXT_STRIKETHROUGH |\ - HOEDOWN_EXT_UNDERLINE |\ - HOEDOWN_EXT_HIGHLIGHT |\ - HOEDOWN_EXT_QUOTE |\ - HOEDOWN_EXT_SUPERSCRIPT |\ - HOEDOWN_EXT_MATH ) +#define HOEDOWN_FT_BLOCK (\ + HOEDOWN_FT_DIRECTIVE |\ + HOEDOWN_FT_INDENTED_CODE_BLOCK |\ + HOEDOWN_FT_FENCED_CODE_BLOCK |\ + HOEDOWN_FT_HORIZONTAL_RULE |\ + HOEDOWN_FT_ATX_HEADER |\ + HOEDOWN_FT_SETEXT_HEADER |\ + HOEDOWN_FT_LIST |\ + HOEDOWN_FT_QUOTE_BLOCK |\ + HOEDOWN_FT_HTML_BLOCK |\ + HOEDOWN_FT_TABLE |\ +0) -#define HOEDOWN_EXT_FLAGS (\ - HOEDOWN_EXT_NO_INTRA_EMPHASIS |\ - HOEDOWN_EXT_SPACE_HEADERS |\ - HOEDOWN_EXT_MATH_EXPLICIT ) +#define HOEDOWN_FT_INLINE (\ + HOEDOWN_FT_ROLE |\ + HOEDOWN_FT_ESCAPE |\ + HOEDOWN_FT_HARD_LINEBREAK |\ + HOEDOWN_FT_LINEBREAK |\ + HOEDOWN_FT_SOFT_LINEBREAK |\ + HOEDOWN_FT_URI_AUTOLINK |\ + HOEDOWN_FT_EMAIL_AUTOLINK |\ + HOEDOWN_FT_HTML |\ + HOEDOWN_FT_ENTITY |\ + HOEDOWN_FT_CODE_SPAN |\ + HOEDOWN_FT_EMPHASIS |\ + HOEDOWN_FT_LINK |\ + HOEDOWN_FT_MATH |\ + HOEDOWN_FT_SUPERSCRIPT |\ + HOEDOWN_FT_QUOTE |\ + HOEDOWN_FT_STRIKETHROUGH |\ + HOEDOWN_FT_HIGHLIGHT |\ + HOEDOWN_FT_FOOTNOTE |\ +0) -#define HOEDOWN_EXT_NEGATIVE (\ - HOEDOWN_EXT_DISABLE_INDENTED_CODE ) +#define HOEDOWN_FT_OTHER (\ + HOEDOWN_FT_PREPROCESS |\ +0) -typedef enum hoedown_list_flags { - HOEDOWN_LIST_ORDERED = (1 << 0), - HOEDOWN_LI_BLOCK = (1 << 1) /*
  • containing block data */ -} hoedown_list_flags; +#define HOEDOWN_FT_FLAGS (\ + HOEDOWN_FT_LINK_IMAGE |\ + HOEDOWN_FT_INTRA_EMPHASIS |\ + HOEDOWN_FT_MATH_EXPLICIT |\ +0) -typedef enum hoedown_table_flags { - HOEDOWN_TABLE_ALIGN_LEFT = 1, - HOEDOWN_TABLE_ALIGN_RIGHT = 2, - HOEDOWN_TABLE_ALIGN_CENTER = 3, - HOEDOWN_TABLE_ALIGNMASK = 3, - HOEDOWN_TABLE_HEADER = 4 -} hoedown_table_flags; -typedef enum hoedown_autolink_type { - HOEDOWN_AUTOLINK_NONE, /* used internally when it is not an autolink*/ - HOEDOWN_AUTOLINK_NORMAL, /* normal http/http/ftp/mailto/etc link */ - HOEDOWN_AUTOLINK_EMAIL /* e-mail link without explit mailto: */ -} hoedown_autolink_type; +/*********** + * PRESETS * + ***********/ + +#define HOEDOWN_FT_COMMONMARK (\ + HOEDOWN_FT_INDENTED_CODE_BLOCK |\ + HOEDOWN_FT_FENCED_CODE_BLOCK |\ + HOEDOWN_FT_HORIZONTAL_RULE |\ + HOEDOWN_FT_ATX_HEADER |\ + HOEDOWN_FT_SETEXT_HEADER |\ + HOEDOWN_FT_LIST |\ + HOEDOWN_FT_QUOTE_BLOCK |\ + HOEDOWN_FT_HTML_BLOCK |\ +\ + HOEDOWN_FT_ESCAPE |\ + HOEDOWN_FT_HARD_LINEBREAK |\ + HOEDOWN_FT_LINEBREAK |\ + HOEDOWN_FT_URI_AUTOLINK |\ + HOEDOWN_FT_EMAIL_AUTOLINK |\ + HOEDOWN_FT_HTML |\ + HOEDOWN_FT_ENTITY |\ + HOEDOWN_FT_CODE_SPAN |\ + HOEDOWN_FT_EMPHASIS |\ + HOEDOWN_FT_LINK |\ +\ + HOEDOWN_FT_PREPROCESS |\ +\ + HOEDOWN_FT_LINK_IMAGE |\ +0) + +#define HOEDOWN_FT_MARKDOWN (\ + HOEDOWN_FT_INDENTED_CODE_BLOCK |\ + HOEDOWN_FT_HORIZONTAL_RULE |\ + HOEDOWN_FT_ATX_HEADER |\ + HOEDOWN_FT_SETEXT_HEADER |\ + HOEDOWN_FT_LIST |\ + HOEDOWN_FT_QUOTE_BLOCK |\ + HOEDOWN_FT_HTML_BLOCK |\ +\ + HOEDOWN_FT_ESCAPE |\ + HOEDOWN_FT_LINEBREAK |\ + HOEDOWN_FT_URI_AUTOLINK |\ + HOEDOWN_FT_EMAIL_AUTOLINK |\ + HOEDOWN_FT_HTML |\ + HOEDOWN_FT_ENTITY |\ + HOEDOWN_FT_CODE_SPAN |\ + HOEDOWN_FT_EMPHASIS |\ + HOEDOWN_FT_LINK |\ +\ + HOEDOWN_FT_PREPROCESS |\ +\ + HOEDOWN_FT_LINK_IMAGE |\ + HOEDOWN_FT_INTRA_EMPHASIS |\ +0) /********* * TYPES * *********/ -struct hoedown_document; typedef struct hoedown_document hoedown_document; -struct hoedown_renderer_data { - void *opaque; -}; -typedef struct hoedown_renderer_data hoedown_renderer_data; +typedef struct hoedown_internal hoedown_internal; -/* hoedown_renderer - functions for rendering parsed data */ -struct hoedown_renderer { - /* state object */ - void *opaque; +typedef struct hoedown_renderer_data { + void *opaque; + void *output; + hoedown_internal *doc; +} hoedown_renderer_data; - /* block level callbacks - NULL skips the block */ - void (*blockcode)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_buffer *lang, const hoedown_renderer_data *data); - void (*blockquote)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data); - void (*header)(hoedown_buffer *ob, const hoedown_buffer *content, int level, const hoedown_renderer_data *data); - void (*hrule)(hoedown_buffer *ob, const hoedown_renderer_data *data); - void (*list)(hoedown_buffer *ob, const hoedown_buffer *content, hoedown_list_flags flags, const hoedown_renderer_data *data); - void (*listitem)(hoedown_buffer *ob, const hoedown_buffer *content, hoedown_list_flags flags, const hoedown_renderer_data *data); - void (*paragraph)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data); - void (*table)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data); - void (*table_header)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data); - void (*table_body)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data); - void (*table_row)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data); - void (*table_cell)(hoedown_buffer *ob, const hoedown_buffer *content, hoedown_table_flags flags, const hoedown_renderer_data *data); - void (*footnotes)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data); - void (*footnote_def)(hoedown_buffer *ob, const hoedown_buffer *content, unsigned int num, const hoedown_renderer_data *data); - void (*blockhtml)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data); +typedef struct hoedown_renderer { + void *opaque; - /* span level callbacks - NULL or return 0 prints the span verbatim */ - int (*autolink)(hoedown_buffer *ob, const hoedown_buffer *link, hoedown_autolink_type type, const hoedown_renderer_data *data); - int (*codespan)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data); - int (*double_emphasis)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data); - int (*emphasis)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data); - int (*underline)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data); - int (*highlight)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data); - int (*quote)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data); - int (*image)(hoedown_buffer *ob, const hoedown_buffer *link, const hoedown_buffer *title, const hoedown_buffer *alt, const hoedown_renderer_data *data); - int (*linebreak)(hoedown_buffer *ob, const hoedown_renderer_data *data); - int (*link)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_buffer *link, const hoedown_buffer *title, const hoedown_renderer_data *data); - int (*triple_emphasis)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data); - int (*strikethrough)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data); - int (*superscript)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data); - int (*footnote_ref)(hoedown_buffer *ob, unsigned int num, const hoedown_renderer_data *data); - int (*math)(hoedown_buffer *ob, const hoedown_buffer *text, int displaymode, const hoedown_renderer_data *data); - int (*raw_html)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data); + /* Block constructs */ + void (*paragraph)(void *target, void *content, int is_tight, const hoedown_renderer_data *data); + void (*indented_code_block)(void *target, const hoedown_buffer *code, const hoedown_renderer_data *data); + void (*fenced_code_block)(void *target, const hoedown_buffer *code, const hoedown_buffer *info, const hoedown_renderer_data *data); + void (*horizontal_rule)(void *target, const hoedown_renderer_data *data); + void (*atx_header)(void *target, void *content, size_t level, const hoedown_renderer_data *data); + void (*setext_header)(void *target, void *content, int is_double, const hoedown_renderer_data *data); + void (*list)(void *target, void *content, int is_ordered, int is_tight, int start, const hoedown_renderer_data *data); + void (*list_item)(void *target, void *content, int is_ordered, int is_tight, const hoedown_renderer_data *data); + void (*quote_block)(void *target, void *content, const hoedown_renderer_data *data); + void (*html_block)(void *target, const hoedown_buffer *html, const hoedown_renderer_data *data); - /* low level callbacks - NULL copies input directly into the output */ - void (*entity)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data); - void (*normal_text)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data); + /* Inline constructs */ + void (*string)(void *target, const hoedown_buffer *text, const hoedown_renderer_data *data); + void (*escape)(void *target, uint8_t character, const hoedown_renderer_data *data); + void (*hard_linebreak)(void *target, const hoedown_renderer_data *data); + void (*linebreak)(void *target, const hoedown_renderer_data *data); + void (*uri_autolink)(void *target, const hoedown_buffer *uri, const hoedown_renderer_data *data); + void (*email_autolink)(void *target, const hoedown_buffer *email, const hoedown_renderer_data *data); + void (*html)(void *target, const hoedown_buffer *html, const hoedown_renderer_data *data); + void (*entity)(void *target, const hoedown_buffer *character, const hoedown_renderer_data *data); + void (*code_span)(void *target, const hoedown_buffer *code, const hoedown_renderer_data *data); + void (*emphasis)(void *target, void *content, size_t level, const hoedown_renderer_data *data); + void (*link)(void *target, void *content, const hoedown_buffer *dest, const hoedown_buffer *title, int is_image, const hoedown_renderer_data *data); - /* miscellaneous callbacks */ - void (*doc_header)(hoedown_buffer *ob, int inline_render, const hoedown_renderer_data *data); - void (*doc_footer)(hoedown_buffer *ob, int inline_render, const hoedown_renderer_data *data); -}; -typedef struct hoedown_renderer hoedown_renderer; + /* Global callbacks */ + void *(*object_get)(int is_inline, const hoedown_renderer_data *data); + void (*object_merge)(void *target, void *content, int is_inline, const hoedown_renderer_data *data); + void (*object_pop)(void *target, int is_inline, const hoedown_renderer_data *data); + + void (*render_start)(void *output, int is_inline, const hoedown_renderer_data *data); + void (*render_end)(void *output, void *target, int is_inline, const hoedown_renderer_data *data); +} hoedown_renderer; /************* * FUNCTIONS * *************/ -/* hoedown_document_new: allocate a new document processor instance */ +/* hoedown_find_block_tag: lookup if an HTML tag name is a block */ +const char *hoedown_find_block_tag(const char *str, unsigned int len); + +/* hoedown_find_autolink_scheme: lookup if a scheme is well-known */ +const char *hoedown_find_autolink_scheme(const char *str, unsigned int len); + +/* hoedown_preprocess: preprocess input for markdown rendering */ +void hoedown_preprocess(hoedown_buffer *ob, const uint8_t *data, size_t size); + + +/* hoedown_document_new: allocate a new document processor */ hoedown_document *hoedown_document_new( - const hoedown_renderer *renderer, - hoedown_extensions extensions, - size_t max_nesting -) __attribute__ ((malloc)); + hoedown_renderer *renderer, + hoedown_features features, + size_t max_nesting +) __attribute__((malloc)); -/* hoedown_document_render: render regular Markdown using the document processor */ -void hoedown_document_render(hoedown_document *doc, hoedown_buffer *ob, const uint8_t *data, size_t size); +/* hoedown_document_render: render markdown with a document processor */ +void hoedown_document_render( + hoedown_document *doc, + void *output, + const uint8_t *data, size_t size, + int is_inline +); -/* hoedown_document_render_inline: render inline Markdown using the document processor */ -void hoedown_document_render_inline(hoedown_document *doc, hoedown_buffer *ob, const uint8_t *data, size_t size); - -/* hoedown_document_free: deallocate a document processor instance */ +/* hoedown_document_free: deallocate a document processor */ void hoedown_document_free(hoedown_document *doc); diff --git a/src/escape.c b/src/escape.c index 122c6ec..d675cd5 100644 --- a/src/escape.c +++ b/src/escape.c @@ -8,19 +8,24 @@ #define likely(x) __builtin_expect((x),1) #define unlikely(x) __builtin_expect((x),0) +#define _isxdigit(c) (strchr("0123456789ABCDEFabcdef", (c)) != NULL) +#define _isdigit(c) ((c) >= '0' && (c) <= '9') + +#include "_html_entities.h" + /* * The following characters will not be escaped: * - * -_.+!*'(),%#@?=;:/,+&$ alphanum + * -_.+!*'(),%#@?=;:/,+&$ 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. + * - 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 assume (lazily) that any RESERVED char that + * 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. @@ -35,84 +40,82 @@ * */ static const uint8_t HREF_SAFE[UINT8_MAX+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, 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, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, }; -void -hoedown_escape_href(hoedown_buffer *ob, const uint8_t *data, size_t size) -{ - static const char hex_chars[] = "0123456789ABCDEF"; - size_t i = 0, mark; - char hex_str[3]; +void hoedown_escape_href(hoedown_buffer *ob, const uint8_t *data, size_t size) { + static const char hex_chars[] = "0123456789ABCDEF"; + size_t i = 0, mark; + char hex_str[3]; - hex_str[0] = '%'; + hex_str[0] = '%'; - while (i < size) { - mark = i; - while (i < size && HREF_SAFE[data[i]]) i++; + while (i < size) { + mark = i; + while (i < size && HREF_SAFE[data[i]]) i++; - /* Optimization for cases where there's nothing to escape */ - if (mark == 0 && i >= size) { - hoedown_buffer_put(ob, data, size); - return; - } + /* Optimization for cases where there's nothing to escape */ + if (mark == 0 && i >= size) { + hoedown_buffer_put(ob, data, size); + return; + } - if (likely(i > mark)) { - hoedown_buffer_put(ob, data + mark, i - mark); - } + if (likely(i > mark)) { + hoedown_buffer_put(ob, data + mark, i - mark); + } - /* escaping */ - if (i >= size) - break; + /* escaping */ + if (i >= size) + break; - switch (data[i]) { - /* amp appears all the time in URLs, but needs - * HTML-entity escaping to be inside an href */ - case '&': - HOEDOWN_BUFPUTSL(ob, "&"); - break; + switch (data[i]) { + /* amp appears all the time in URLs, but needs + * HTML-entity escaping to be inside an href */ + case '&': + HOEDOWN_BUFPUTSL(ob, "&"); + break; - /* the single quote is a valid URL character - * according to the standard; it needs HTML - * entity escaping too */ - case '\'': - HOEDOWN_BUFPUTSL(ob, "'"); - break; + /* the single quote is a valid URL character + * according to the standard; it needs HTML + * entity escaping too */ + case '\'': + HOEDOWN_BUFPUTSL(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 */ + /* 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 ' ': - hoedown_buffer_putc(ob, '+'); - break; + case ' ': + hoedown_buffer_putc(ob, '+'); + break; #endif - /* every other character goes with a %XX escaping */ - default: - hex_str[1] = hex_chars[(data[i] >> 4) & 0xF]; - hex_str[2] = hex_chars[data[i] & 0xF]; - hoedown_buffer_put(ob, (uint8_t *)hex_str, 3); - } + /* every other character goes with a %XX escaping */ + default: + hex_str[1] = hex_chars[(data[i] >> 4) & 0xF]; + hex_str[2] = hex_chars[data[i] & 0xF]; + hoedown_buffer_put(ob, (uint8_t *)hex_str, 3); + } - i++; - } + i++; + } } @@ -128,22 +131,22 @@ hoedown_escape_href(hoedown_buffer *ob, const uint8_t *data, size_t size) * */ static const uint8_t HTML_ESCAPE_TABLE[UINT8_MAX+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, 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, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 5, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 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[] = { @@ -151,38 +154,110 @@ static const char *HTML_ESCAPES[] = { """, "&", "'", - "/", "<", ">" }; -void -hoedown_escape_html(hoedown_buffer *ob, const uint8_t *data, size_t size, int secure) -{ - size_t i = 0, mark; +void hoedown_escape_html(hoedown_buffer *ob, const uint8_t *data, size_t size) { + size_t i = 0, mark; - while (1) { - mark = i; - while (i < size && HTML_ESCAPE_TABLE[data[i]] == 0) i++; + while (1) { + mark = i; + while (i < size && HTML_ESCAPE_TABLE[data[i]] == 0) i++; - /* Optimization for cases where there's nothing to escape */ - if (mark == 0 && i >= size) { - hoedown_buffer_put(ob, data, size); - return; - } + /* Optimization for cases where there's nothing to escape */ + if (mark == 0 && i >= size) { + hoedown_buffer_put(ob, data, size); + return; + } - if (likely(i > mark)) - hoedown_buffer_put(ob, data + mark, i - mark); + if (likely(i > mark)) + hoedown_buffer_put(ob, data + mark, i - mark); - if (i >= size) break; + if (i >= size) break; - /* The forward slash is only escaped in secure mode */ - if (!secure && data[i] == '/') { - hoedown_buffer_putc(ob, '/'); - } else { - hoedown_buffer_puts(ob, HTML_ESCAPES[HTML_ESCAPE_TABLE[data[i]]]); - } - - i++; - } + hoedown_buffer_puts(ob, HTML_ESCAPES[HTML_ESCAPE_TABLE[data[i]]]); + i++; + } +} + +void hoedown_escape_character(hoedown_buffer *ob, const uint8_t *data, size_t size) { + if (size == 1 && HTML_ESCAPE_TABLE[data[0]]) { + hoedown_buffer_puts(ob, HTML_ESCAPES[HTML_ESCAPE_TABLE[data[0]]]); + return; + } + /* Character doesn't need escaping */ + hoedown_buffer_put(ob, data, size); +} + + + +size_t hoedown_unescape_entity(hoedown_buffer *ob, const uint8_t *data, size_t size) { + size_t i = 0; + + if (size > 3 && data[0] == '#') { + int codepoint = 0; + + if (_isdigit(data[1])) { + for (i = 1; i < size && _isdigit(data[i]); ++i) + codepoint = (codepoint * 10) + (data[i] - '0'); + } + + else if (data[1] == 'x' || data[1] == 'X') { + for (i = 2; i < size && _isxdigit(data[i]); ++i) + codepoint = (codepoint * 16) + ((data[i] | 32) % 39 - 9); + if (i == 2) return 0; + } + + if (i < size && data[i] == ';') { + hoedown_buffer_put_utf8(ob, codepoint); + return i + 1; + } + } + + else { + if (size > MAX_WORD_LENGTH) + size = MAX_WORD_LENGTH; + + for (i = MIN_WORD_LENGTH; i < size; ++i) { + if (data[i] == ' ') + break; + + if (data[i] == ';') { + const struct html_entity *entity = find_entity((const char *)data, i); + + if (entity != NULL) { + hoedown_buffer_put(ob, entity->utf8, entity->size); + return i + 1; + } + + break; + } + } + } + + return 0; +} + +void hoedown_unescape_html(hoedown_buffer *ob, const uint8_t *data, size_t size) { + size_t i = 0, mark = 0; + while (1) { + while (i < size && data[i] != '&') i++; + + /* Optimization for cases where there's nothing to escape */ + if (mark == 0 && i >= size) { + hoedown_buffer_put(ob, data, size); + return; + } + + if (likely(i > mark)) + hoedown_buffer_put(ob, data + mark, i - mark); + + if (i >= size) break; + + mark = i; + i++; + i += hoedown_unescape_entity(ob, data + i, size - i); + if (i > mark + 1) mark = i; + } } diff --git a/src/escape.h b/src/escape.h index d7659c2..01fece5 100644 --- a/src/escape.h +++ b/src/escape.h @@ -18,7 +18,17 @@ extern "C" { void hoedown_escape_href(hoedown_buffer *ob, const uint8_t *data, size_t size); /* hoedown_escape_html: escape HTML */ -void hoedown_escape_html(hoedown_buffer *ob, const uint8_t *data, size_t size, int secure); +void hoedown_escape_html(hoedown_buffer *ob, const uint8_t *data, size_t size); + +/* hoedown_unescape_html: unescape HTML */ +void hoedown_unescape_html(hoedown_buffer *ob, const uint8_t *data, size_t size); + +/* hoedown_unescape_entity: unescape a single HTML entity */ +size_t hoedown_unescape_entity(hoedown_buffer *ob, const uint8_t *data, size_t size); + +/* hoedown_escape_character: escape a single UTF-8 character in HTML (if needed) */ +/* DO NOT USE unless you know it's a single character */ +void hoedown_escape_character(hoedown_buffer *ob, const uint8_t *data, size_t size); #ifdef __cplusplus diff --git a/src/html.c b/src/html.c index ddebff7..c7da70d 100644 --- a/src/html.c +++ b/src/html.c @@ -1,752 +1,340 @@ #include "html.h" -#include -#include -#include -#include - #include "escape.h" -#define USE_XHTML(opt) (opt->flags & HOEDOWN_HTML_USE_XHTML) +#include +#include -hoedown_html_tag -hoedown_html_is_tag(const uint8_t *data, size_t size, const char *tagname) -{ - size_t i; - int closed = 0; +typedef struct renderer_state { + hoedown_pool buffers; +} renderer_state; - if (size < 3 || data[0] != '<') - return HOEDOWN_HTML_TAG_NONE; - - i = 1; - - if (data[i] == '/') { - closed = 1; - i++; - } - - for (; i < size; ++i, ++tagname) { - if (*tagname == 0) - break; - - if (data[i] != *tagname) - return HOEDOWN_HTML_TAG_NONE; - } - - if (i == size) - return HOEDOWN_HTML_TAG_NONE; - - if (isspace(data[i]) || data[i] == '>') - return closed ? HOEDOWN_HTML_TAG_CLOSE : HOEDOWN_HTML_TAG_OPEN; - - return HOEDOWN_HTML_TAG_NONE; +static void *object_get(int is_inline, const hoedown_renderer_data *data) { + renderer_state *state = data->opaque; + hoedown_buffer *ob = hoedown_pool_get(&state->buffers); + ob->size = 0; + return ob; } -static void escape_html(hoedown_buffer *ob, const uint8_t *source, size_t length) -{ - hoedown_escape_html(ob, source, length, 0); +static void object_merge(void *target, void *content_, int is_inline, const hoedown_renderer_data *data) { + renderer_state *state = data->opaque; + hoedown_buffer *ob = target, *content = content_; + hoedown_buffer_put(ob, content->data, content->size); + hoedown_pool_pop(&state->buffers); } -static void escape_href(hoedown_buffer *ob, const uint8_t *source, size_t length) -{ - hoedown_escape_href(ob, source, length); +static void object_pop(void *target, int is_inline, const hoedown_renderer_data *data) { + renderer_state *state = data->opaque; + hoedown_pool_pop(&state->buffers); } -/******************** - * GENERIC RENDERER * - ********************/ -static int -rndr_autolink(hoedown_buffer *ob, const hoedown_buffer *link, hoedown_autolink_type type, const hoedown_renderer_data *data) -{ - hoedown_html_renderer_state *state = data->opaque; +static void render_end(void *output, void *target, int is_inline, const hoedown_renderer_data *data) { + renderer_state *state = data->opaque; + hoedown_buffer *ob = output, *content = target; - if (!link || !link->size) - return 0; + hoedown_buffer_set(ob, content->data, content->size); - HOEDOWN_BUFPUTSL(ob, "data, link->size); - - if (state->link_attributes) { - hoedown_buffer_putc(ob, '\"'); - state->link_attributes(ob, link, data); - hoedown_buffer_putc(ob, '>'); - } else { - HOEDOWN_BUFPUTSL(ob, "\">"); - } - - /* - * Pretty printing: if we get an email address as - * an actual URI, e.g. `mailto:foo@bar.com`, we don't - * want to print the `mailto:` prefix - */ - if (hoedown_buffer_prefix(link, "mailto:") == 0) { - escape_html(ob, link->data + 7, link->size - 7); - } else { - escape_html(ob, link->data, link->size); - } - - HOEDOWN_BUFPUTSL(ob, ""); - - return 1; + hoedown_pool_pop(&state->buffers); + assert(state->buffers.size == 0); } -static void -rndr_blockcode(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_buffer *lang, const hoedown_renderer_data *data) -{ - if (ob->size) hoedown_buffer_putc(ob, '\n'); - if (lang) { - HOEDOWN_BUFPUTSL(ob, "
    data, lang->size);
    -		HOEDOWN_BUFPUTSL(ob, "\">");
    -	} else {
    -		HOEDOWN_BUFPUTSL(ob, "
    ");
    -	}
    +// BLOCK CONSTRUCTS
     
    -	if (text)
    -		escape_html(ob, text->data, text->size);
    +static void rndr_paragraph(void *target, void *content_, int is_tight, const hoedown_renderer_data *data) {
    +  renderer_state *state = data->opaque;
    +  hoedown_buffer *ob = target, *content = content_;
     
    -	HOEDOWN_BUFPUTSL(ob, "
    \n"); -} - -static void -rndr_blockquote(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data) -{ - if (ob->size) hoedown_buffer_putc(ob, '\n'); - HOEDOWN_BUFPUTSL(ob, "
    \n"); - if (content) hoedown_buffer_put(ob, content->data, content->size); - HOEDOWN_BUFPUTSL(ob, "
    \n"); -} - -static int -rndr_codespan(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data) -{ - HOEDOWN_BUFPUTSL(ob, ""); - if (text) escape_html(ob, text->data, text->size); - HOEDOWN_BUFPUTSL(ob, ""); - return 1; -} - -static int -rndr_strikethrough(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data) -{ - if (!content || !content->size) - return 0; - - HOEDOWN_BUFPUTSL(ob, ""); - hoedown_buffer_put(ob, content->data, content->size); - HOEDOWN_BUFPUTSL(ob, ""); - return 1; -} - -static int -rndr_double_emphasis(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data) -{ - if (!content || !content->size) - return 0; - - HOEDOWN_BUFPUTSL(ob, ""); - hoedown_buffer_put(ob, content->data, content->size); - HOEDOWN_BUFPUTSL(ob, ""); - - return 1; -} - -static int -rndr_emphasis(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data) -{ - if (!content || !content->size) return 0; - HOEDOWN_BUFPUTSL(ob, ""); - if (content) hoedown_buffer_put(ob, content->data, content->size); - HOEDOWN_BUFPUTSL(ob, ""); - return 1; -} - -static int -rndr_underline(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data) -{ - if (!content || !content->size) - return 0; - - HOEDOWN_BUFPUTSL(ob, ""); - hoedown_buffer_put(ob, content->data, content->size); - HOEDOWN_BUFPUTSL(ob, ""); - - return 1; -} - -static int -rndr_highlight(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data) -{ - if (!content || !content->size) - return 0; - - HOEDOWN_BUFPUTSL(ob, ""); - hoedown_buffer_put(ob, content->data, content->size); - HOEDOWN_BUFPUTSL(ob, ""); - - return 1; -} - -static int -rndr_quote(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data) -{ - if (!content || !content->size) - return 0; - - HOEDOWN_BUFPUTSL(ob, ""); - hoedown_buffer_put(ob, content->data, content->size); - HOEDOWN_BUFPUTSL(ob, ""); - - return 1; -} - -static int -rndr_linebreak(hoedown_buffer *ob, const hoedown_renderer_data *data) -{ - hoedown_html_renderer_state *state = data->opaque; - hoedown_buffer_puts(ob, USE_XHTML(state) ? "
    \n" : "
    \n"); - return 1; -} - -static void -rndr_header(hoedown_buffer *ob, const hoedown_buffer *content, int level, const hoedown_renderer_data *data) -{ - hoedown_html_renderer_state *state = data->opaque; - - if (ob->size) - hoedown_buffer_putc(ob, '\n'); - - if (level <= state->toc_data.nesting_level) - hoedown_buffer_printf(ob, "", level, state->toc_data.header_count++); - else - hoedown_buffer_printf(ob, "", level); - - if (content) hoedown_buffer_put(ob, content->data, content->size); - hoedown_buffer_printf(ob, "\n", level); -} - -static int -rndr_link(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_buffer *link, const hoedown_buffer *title, const hoedown_renderer_data *data) -{ - hoedown_html_renderer_state *state = data->opaque; - - HOEDOWN_BUFPUTSL(ob, "size) - escape_href(ob, link->data, link->size); - - if (title && title->size) { - HOEDOWN_BUFPUTSL(ob, "\" title=\""); - escape_html(ob, title->data, title->size); - } - - if (state->link_attributes) { - hoedown_buffer_putc(ob, '\"'); - state->link_attributes(ob, link, data); - hoedown_buffer_putc(ob, '>'); - } else { - HOEDOWN_BUFPUTSL(ob, "\">"); - } - - if (content && content->size) hoedown_buffer_put(ob, content->data, content->size); - HOEDOWN_BUFPUTSL(ob, ""); - return 1; -} - -static void -rndr_list(hoedown_buffer *ob, const hoedown_buffer *content, hoedown_list_flags flags, const hoedown_renderer_data *data) -{ - if (ob->size) hoedown_buffer_putc(ob, '\n'); - hoedown_buffer_put(ob, (const uint8_t *)(flags & HOEDOWN_LIST_ORDERED ? "
      \n" : "
        \n"), 5); - if (content) hoedown_buffer_put(ob, content->data, content->size); - hoedown_buffer_put(ob, (const uint8_t *)(flags & HOEDOWN_LIST_ORDERED ? "
    \n" : "\n"), 6); -} - -static void -rndr_listitem(hoedown_buffer *ob, const hoedown_buffer *content, hoedown_list_flags flags, const hoedown_renderer_data *data) -{ - HOEDOWN_BUFPUTSL(ob, "
  • "); - if (content) { - size_t size = content->size; - while (size && content->data[size - 1] == '\n') - size--; - - hoedown_buffer_put(ob, content->data, size); - } - HOEDOWN_BUFPUTSL(ob, "
  • \n"); -} - -static void -rndr_paragraph(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data) -{ - hoedown_html_renderer_state *state = data->opaque; - size_t i = 0; - - if (ob->size) hoedown_buffer_putc(ob, '\n'); - - if (!content || !content->size) - return; - - while (i < content->size && isspace(content->data[i])) i++; - - if (i == content->size) - return; - - HOEDOWN_BUFPUTSL(ob, "

    "); - if (state->flags & HOEDOWN_HTML_HARD_WRAP) { - size_t org; - while (i < content->size) { - org = i; - while (i < content->size && content->data[i] != '\n') - i++; - - if (i > org) - hoedown_buffer_put(ob, content->data + org, i - org); - - /* - * do not insert a line break if this newline - * is the last character on the paragraph - */ - if (i >= content->size - 1) - break; - - rndr_linebreak(ob, data); - i++; - } - } else { - hoedown_buffer_put(ob, content->data + i, content->size - i); - } - HOEDOWN_BUFPUTSL(ob, "

    \n"); -} - -static void -rndr_raw_block(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data) -{ - size_t org, sz; - - if (!text) - return; - - /* FIXME: Do we *really* need to trim the HTML? How does that make a difference? */ - sz = text->size; - while (sz > 0 && text->data[sz - 1] == '\n') - sz--; - - org = 0; - while (org < sz && text->data[org] == '\n') - org++; - - if (org >= sz) - return; - - if (ob->size) - hoedown_buffer_putc(ob, '\n'); - - hoedown_buffer_put(ob, text->data + org, sz - org); - hoedown_buffer_putc(ob, '\n'); -} - -static int -rndr_triple_emphasis(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data) -{ - if (!content || !content->size) return 0; - HOEDOWN_BUFPUTSL(ob, ""); - hoedown_buffer_put(ob, content->data, content->size); - HOEDOWN_BUFPUTSL(ob, ""); - return 1; -} - -static void -rndr_hrule(hoedown_buffer *ob, const hoedown_renderer_data *data) -{ - hoedown_html_renderer_state *state = data->opaque; - if (ob->size) hoedown_buffer_putc(ob, '\n'); - hoedown_buffer_puts(ob, USE_XHTML(state) ? "
    \n" : "
    \n"); -} - -static int -rndr_image(hoedown_buffer *ob, const hoedown_buffer *link, const hoedown_buffer *title, const hoedown_buffer *alt, const hoedown_renderer_data *data) -{ - hoedown_html_renderer_state *state = data->opaque; - if (!link || !link->size) return 0; - - HOEDOWN_BUFPUTSL(ob, "data, link->size); - HOEDOWN_BUFPUTSL(ob, "\" alt=\""); - - if (alt && alt->size) - escape_html(ob, alt->data, alt->size); - - if (title && title->size) { - HOEDOWN_BUFPUTSL(ob, "\" title=\""); - escape_html(ob, title->data, title->size); } - - hoedown_buffer_puts(ob, USE_XHTML(state) ? "\"/>" : "\">"); - return 1; -} - -static int -rndr_raw_html(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data) -{ - hoedown_html_renderer_state *state = data->opaque; - - /* ESCAPE overrides SKIP_HTML. It doesn't look to see if - * there are any valid tags, just escapes all of them. */ - if((state->flags & HOEDOWN_HTML_ESCAPE) != 0) { - escape_html(ob, text->data, text->size); - return 1; - } - - if ((state->flags & HOEDOWN_HTML_SKIP_HTML) != 0) - return 1; - - hoedown_buffer_put(ob, text->data, text->size); - return 1; -} - -static void -rndr_table(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data) -{ - if (ob->size) hoedown_buffer_putc(ob, '\n'); - HOEDOWN_BUFPUTSL(ob, "\n"); + if (is_tight) { hoedown_buffer_put(ob, content->data, content->size); - HOEDOWN_BUFPUTSL(ob, "
    \n"); -} - -static void -rndr_table_header(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data) -{ - if (ob->size) hoedown_buffer_putc(ob, '\n'); - HOEDOWN_BUFPUTSL(ob, "\n"); + hoedown_buffer_putc(ob, '\n'); + } else { + HOEDOWN_BUFPUTSL(ob, "

    "); hoedown_buffer_put(ob, content->data, content->size); - HOEDOWN_BUFPUTSL(ob, "\n"); + HOEDOWN_BUFPUTSL(ob, "

    \n"); + } + + hoedown_pool_pop(&state->buffers); } -static void -rndr_table_body(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data) -{ - if (ob->size) hoedown_buffer_putc(ob, '\n'); - HOEDOWN_BUFPUTSL(ob, "\n"); +static void rndr_indented_code_block(void *target, const hoedown_buffer *code, const hoedown_renderer_data *data) { + hoedown_buffer *ob = target; + + HOEDOWN_BUFPUTSL(ob, "
    ");
    +  hoedown_escape_html(ob, code->data, code->size);
    +  HOEDOWN_BUFPUTSL(ob, "
    \n"); +} + +static void rndr_fenced_code_block(void *target, const hoedown_buffer *code, const hoedown_buffer *info, const hoedown_renderer_data *data) { + hoedown_buffer *ob = target; + HOEDOWN_BUFPUTSL(ob, "
    size && info->data[first_word] != ' ') first_word++;
    +
    +    HOEDOWN_BUFPUTSL(ob, " class=\"language-");
    +    hoedown_escape_html(ob, info->data, first_word);
    +    hoedown_buffer_putc(ob, '"');
    +  }
    +
    +  hoedown_buffer_putc(ob, '>');
    +  hoedown_escape_html(ob, code->data, code->size);
    +  HOEDOWN_BUFPUTSL(ob, "
    \n"); +} + +static void rndr_horizontal_rule(void *target, const hoedown_renderer_data *data) { + hoedown_buffer *ob = target; + + HOEDOWN_BUFPUTSL(ob, "
    \n"); +} + +static void rndr_atx_header(void *target, void *content_, size_t level, const hoedown_renderer_data *data) { + renderer_state *state = data->opaque; + hoedown_buffer *ob = target, *content = content_; + + hoedown_buffer_printf(ob, "", level); + hoedown_buffer_put(ob, content->data, content->size); + hoedown_buffer_printf(ob, "\n", level); + + hoedown_pool_pop(&state->buffers); +} + +static void rndr_setext_header(void *target, void *content_, int is_double, const hoedown_renderer_data *data) { + renderer_state *state = data->opaque; + hoedown_buffer *ob = target, *content = content_; + + hoedown_buffer_put(ob, (uint8_t *)(is_double ? "

    " : "

    "), 4); + hoedown_buffer_put(ob, content->data, content->size); + hoedown_buffer_put(ob, (uint8_t *)(is_double ? "

    \n" : "\n"), 6); + + hoedown_pool_pop(&state->buffers); +} + +static void rndr_list(void *target, void *content_, int is_ordered, int is_tight, int start, const hoedown_renderer_data *data) { + renderer_state *state = data->opaque; + hoedown_buffer *ob = target, *content = content_; + + hoedown_buffer_put(ob, (uint8_t *)(is_ordered ? "\n"); + + hoedown_buffer_put(ob, content->data, content->size); + hoedown_buffer_put(ob, (uint8_t *)(is_ordered ? "\n" : "\n"), 6); + + hoedown_pool_pop(&state->buffers); +} + +static void rndr_list_item(void *target, void *content_, int is_ordered, int is_tight, const hoedown_renderer_data *data) { + renderer_state *state = data->opaque; + hoedown_buffer *ob = target, *content = content_; + + HOEDOWN_BUFPUTSL(ob, "
  • "); + if (!is_tight) hoedown_buffer_putc(ob, '\n'); + + hoedown_buffer_put(ob, content->data, content->size); + if (is_tight && ob->data[ob->size-1] == '\n') ob->size--; + + HOEDOWN_BUFPUTSL(ob, "
  • \n"); + + hoedown_pool_pop(&state->buffers); +} + +static void rndr_quote_block(void *target, void *content_, const hoedown_renderer_data *data) { + renderer_state *state = data->opaque; + hoedown_buffer *ob = target, *content = content_; + + HOEDOWN_BUFPUTSL(ob, "
    \n"); + hoedown_buffer_put(ob, content->data, content->size); + HOEDOWN_BUFPUTSL(ob, "
    \n"); + + hoedown_pool_pop(&state->buffers); +} + +static void rndr_html_block(void *target, const hoedown_buffer *html, const hoedown_renderer_data *data) { + hoedown_buffer *ob = target; + + hoedown_buffer_put(ob, html->data, html->size); +} + + + +// INLINE CONSTRUCTS + +static void rndr_string(void *target, const hoedown_buffer *text, const hoedown_renderer_data *data) { + hoedown_buffer *ob = target; + + hoedown_escape_html(ob, text->data, text->size); +} + +static void rndr_escape(void *target, uint8_t character, const hoedown_renderer_data *data) { + hoedown_buffer *ob = target; + + hoedown_escape_html(ob, &character, 1); +} + +// hard_linebreak is set to rndr_linebreak + +static void rndr_linebreak(void *target, const hoedown_renderer_data *data) { + hoedown_buffer *ob = target; + + HOEDOWN_BUFPUTSL(ob, "
    \n"); +} + +static void rndr_uri_autolink(void *target, const hoedown_buffer *uri, const hoedown_renderer_data *data) { + hoedown_buffer *ob = target; + + HOEDOWN_BUFPUTSL(ob, "data, uri->size); + HOEDOWN_BUFPUTSL(ob, "\">"); + hoedown_escape_html(ob, uri->data, uri->size); + HOEDOWN_BUFPUTSL(ob, ""); +} + +static void rndr_email_autolink(void *target, const hoedown_buffer *email, const hoedown_renderer_data *data) { + hoedown_buffer *ob = target; + + HOEDOWN_BUFPUTSL(ob, "data, email->size); + HOEDOWN_BUFPUTSL(ob, "\">"); + hoedown_escape_html(ob, email->data, email->size); + HOEDOWN_BUFPUTSL(ob, ""); +} + +static void rndr_html(void *target, const hoedown_buffer *html, const hoedown_renderer_data *data) { + hoedown_buffer *ob = target; + + hoedown_buffer_put(ob, html->data, html->size); +} + +static void rndr_entity(void *target, const hoedown_buffer *character, const hoedown_renderer_data *data) { + hoedown_buffer *ob = target; + + hoedown_escape_character(ob, character->data, character->size); +} + +static void rndr_code_span(void *target, const hoedown_buffer *code, const hoedown_renderer_data *data) { + hoedown_buffer *ob = target; + + HOEDOWN_BUFPUTSL(ob, ""); + hoedown_escape_html(ob, code->data, code->size); + HOEDOWN_BUFPUTSL(ob, ""); +} + +static void rndr_emphasis(void *target, void *content_, size_t level, const hoedown_renderer_data *data) { + renderer_state *state = data->opaque; + hoedown_buffer *ob = target, *content = content_; + + if (level == 3) { + HOEDOWN_BUFPUTSL(ob, ""); hoedown_buffer_put(ob, content->data, content->size); - HOEDOWN_BUFPUTSL(ob, "\n"); + HOEDOWN_BUFPUTSL(ob, ""); + } else if (level == 2) { + HOEDOWN_BUFPUTSL(ob, ""); + hoedown_buffer_put(ob, content->data, content->size); + HOEDOWN_BUFPUTSL(ob, ""); + } else { + HOEDOWN_BUFPUTSL(ob, ""); + hoedown_buffer_put(ob, content->data, content->size); + HOEDOWN_BUFPUTSL(ob, ""); + } + + hoedown_pool_pop(&state->buffers); } -static void -rndr_tablerow(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data) -{ - HOEDOWN_BUFPUTSL(ob, "\n"); - if (content) hoedown_buffer_put(ob, content->data, content->size); - HOEDOWN_BUFPUTSL(ob, "\n"); +static void rndr_link(void *target, void *content_, const hoedown_buffer *dest, const hoedown_buffer *title, int is_image, const hoedown_renderer_data *data) { + renderer_state *state = data->opaque; + hoedown_buffer *ob = target, *content = content_; + + if (is_image) { + HOEDOWN_BUFPUTSL(ob, "data, dest->size); + HOEDOWN_BUFPUTSL(ob, "\" alt=\""); + hoedown_escape_html(ob, content->data, content->size); + hoedown_buffer_putc(ob, '"'); + + if (title) { + HOEDOWN_BUFPUTSL(ob, " title=\""); + hoedown_escape_html(ob, title->data, title->size); + hoedown_buffer_putc(ob, '"'); + } + + HOEDOWN_BUFPUTSL(ob, " />"); + } else { + HOEDOWN_BUFPUTSL(ob, "data, dest->size); + hoedown_buffer_putc(ob, '"'); + + if (title) { + HOEDOWN_BUFPUTSL(ob, " title=\""); + hoedown_escape_html(ob, title->data, title->size); + hoedown_buffer_putc(ob, '"'); + } + + hoedown_buffer_putc(ob, '>'); + hoedown_buffer_put(ob, content->data, content->size); + HOEDOWN_BUFPUTSL(ob, ""); + } + + hoedown_pool_pop(&state->buffers); } -static void -rndr_tablecell(hoedown_buffer *ob, const hoedown_buffer *content, hoedown_table_flags flags, const hoedown_renderer_data *data) -{ - if (flags & HOEDOWN_TABLE_HEADER) { - HOEDOWN_BUFPUTSL(ob, ""); - break; - case HOEDOWN_TABLE_ALIGN_LEFT: - HOEDOWN_BUFPUTSL(ob, " style=\"text-align: left\">"); - break; +// RENDERER INITIALIZATION - case HOEDOWN_TABLE_ALIGN_RIGHT: - HOEDOWN_BUFPUTSL(ob, " style=\"text-align: right\">"); - break; +hoedown_renderer *hoedown_html_renderer_new() { + static const hoedown_renderer temp = { + NULL, - default: - HOEDOWN_BUFPUTSL(ob, ">"); - } + rndr_paragraph, + rndr_indented_code_block, + rndr_fenced_code_block, + rndr_horizontal_rule, + rndr_atx_header, + rndr_setext_header, + rndr_list, + rndr_list_item, + rndr_quote_block, + rndr_html_block, - if (content) - hoedown_buffer_put(ob, content->data, content->size); + rndr_string, + rndr_escape, + rndr_linebreak, + rndr_linebreak, + rndr_uri_autolink, + rndr_email_autolink, + rndr_html, + rndr_entity, + rndr_code_span, + rndr_emphasis, + rndr_link, - if (flags & HOEDOWN_TABLE_HEADER) { - HOEDOWN_BUFPUTSL(ob, "\n"); - } else { - HOEDOWN_BUFPUTSL(ob, "\n"); - } + object_get, + object_merge, + object_pop, + + NULL, + render_end, + }; + + hoedown_renderer *rndr = hoedown_malloc(sizeof(hoedown_renderer)); + renderer_state *state = hoedown_malloc(sizeof(renderer_state)); + + memcpy(rndr, &temp, sizeof(hoedown_renderer)); + rndr->opaque = state; + + hoedown_buffer_pool_init(&state->buffers, 16, 16); + + return rndr; } -static int -rndr_superscript(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data) -{ - if (!content || !content->size) return 0; - HOEDOWN_BUFPUTSL(ob, ""); - hoedown_buffer_put(ob, content->data, content->size); - HOEDOWN_BUFPUTSL(ob, ""); - return 1; -} - -static void -rndr_normal_text(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data) -{ - if (content) - escape_html(ob, content->data, content->size); -} - -static void -rndr_footnotes(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data) -{ - hoedown_html_renderer_state *state = data->opaque; - - if (ob->size) hoedown_buffer_putc(ob, '\n'); - HOEDOWN_BUFPUTSL(ob, "
    \n"); - hoedown_buffer_puts(ob, USE_XHTML(state) ? "
    \n" : "
    \n"); - HOEDOWN_BUFPUTSL(ob, "
      \n"); - - if (content) hoedown_buffer_put(ob, content->data, content->size); - - HOEDOWN_BUFPUTSL(ob, "\n
    \n
    \n"); -} - -static void -rndr_footnote_def(hoedown_buffer *ob, const hoedown_buffer *content, unsigned int num, const hoedown_renderer_data *data) -{ - size_t i = 0; - int pfound = 0; - - /* insert anchor at the end of first paragraph block */ - if (content) { - while ((i+3) < content->size) { - if (content->data[i++] != '<') continue; - if (content->data[i++] != '/') continue; - if (content->data[i++] != 'p' && content->data[i] != 'P') continue; - if (content->data[i] != '>') continue; - i -= 3; - pfound = 1; - break; - } - } - - hoedown_buffer_printf(ob, "\n
  • \n", num); - if (pfound) { - hoedown_buffer_put(ob, content->data, i); - hoedown_buffer_printf(ob, " ", num); - hoedown_buffer_put(ob, content->data + i, content->size - i); - } else if (content) { - hoedown_buffer_put(ob, content->data, content->size); - } - HOEDOWN_BUFPUTSL(ob, "
  • \n"); -} - -static int -rndr_footnote_ref(hoedown_buffer *ob, unsigned int num, const hoedown_renderer_data *data) -{ - hoedown_buffer_printf(ob, "%d", num, num, num); - return 1; -} - -static int -rndr_math(hoedown_buffer *ob, const hoedown_buffer *text, int displaymode, const hoedown_renderer_data *data) -{ - hoedown_buffer_put(ob, (const uint8_t *)(displaymode ? "\\[" : "\\("), 2); - escape_html(ob, text->data, text->size); - hoedown_buffer_put(ob, (const uint8_t *)(displaymode ? "\\]" : "\\)"), 2); - return 1; -} - -static void -toc_header(hoedown_buffer *ob, const hoedown_buffer *content, int level, const hoedown_renderer_data *data) -{ - hoedown_html_renderer_state *state = data->opaque; - - if (level <= state->toc_data.nesting_level) { - /* set the level offset if this is the first header - * we're parsing for the document */ - if (state->toc_data.current_level == 0) - state->toc_data.level_offset = level - 1; - - level -= state->toc_data.level_offset; - - if (level > state->toc_data.current_level) { - while (level > state->toc_data.current_level) { - HOEDOWN_BUFPUTSL(ob, "
      \n
    • \n"); - state->toc_data.current_level++; - } - } else if (level < state->toc_data.current_level) { - HOEDOWN_BUFPUTSL(ob, "
    • \n"); - while (level < state->toc_data.current_level) { - HOEDOWN_BUFPUTSL(ob, "
    \n
  • \n"); - state->toc_data.current_level--; - } - HOEDOWN_BUFPUTSL(ob,"
  • \n"); - } else { - HOEDOWN_BUFPUTSL(ob,"
  • \n
  • \n"); - } - - hoedown_buffer_printf(ob, "", state->toc_data.header_count++); - if (content) escape_html(ob, content->data, content->size); - HOEDOWN_BUFPUTSL(ob, "\n"); - } -} - -static int -toc_link(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_buffer *link, const hoedown_buffer *title, const hoedown_renderer_data *data) -{ - if (content && content->size) hoedown_buffer_put(ob, content->data, content->size); - return 1; -} - -static void -toc_finalize(hoedown_buffer *ob, int inline_render, const hoedown_renderer_data *data) -{ - hoedown_html_renderer_state *state; - - if (inline_render) - return; - - state = data->opaque; - - while (state->toc_data.current_level > 0) { - HOEDOWN_BUFPUTSL(ob, "
  • \n\n"); - state->toc_data.current_level--; - } -} - -hoedown_renderer * -hoedown_html_toc_renderer_new(int nesting_level) -{ - static const hoedown_renderer cb_default = { - NULL, - - NULL, - NULL, - toc_header, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - - NULL, - rndr_codespan, - rndr_double_emphasis, - rndr_emphasis, - rndr_underline, - rndr_highlight, - rndr_quote, - NULL, - NULL, - toc_link, - rndr_triple_emphasis, - rndr_strikethrough, - rndr_superscript, - NULL, - NULL, - NULL, - - NULL, - NULL, - - NULL, - toc_finalize - }; - - hoedown_html_renderer_state *state; - hoedown_renderer *renderer; - - /* Prepare the state pointer */ - state = hoedown_malloc(sizeof(hoedown_html_renderer_state)); - memset(state, 0x0, sizeof(hoedown_html_renderer_state)); - - state->toc_data.nesting_level = nesting_level; - - /* Prepare the renderer */ - renderer = hoedown_malloc(sizeof(hoedown_renderer)); - memcpy(renderer, &cb_default, sizeof(hoedown_renderer)); - - renderer->opaque = state; - return renderer; -} - -hoedown_renderer * -hoedown_html_renderer_new(hoedown_html_flags render_flags, int nesting_level) -{ - static const hoedown_renderer cb_default = { - NULL, - - rndr_blockcode, - rndr_blockquote, - rndr_header, - rndr_hrule, - rndr_list, - rndr_listitem, - rndr_paragraph, - rndr_table, - rndr_table_header, - rndr_table_body, - rndr_tablerow, - rndr_tablecell, - rndr_footnotes, - rndr_footnote_def, - rndr_raw_block, - - rndr_autolink, - rndr_codespan, - rndr_double_emphasis, - rndr_emphasis, - rndr_underline, - rndr_highlight, - rndr_quote, - rndr_image, - rndr_linebreak, - rndr_link, - rndr_triple_emphasis, - rndr_strikethrough, - rndr_superscript, - rndr_footnote_ref, - rndr_math, - rndr_raw_html, - - NULL, - rndr_normal_text, - - NULL, - NULL - }; - - hoedown_html_renderer_state *state; - hoedown_renderer *renderer; - - /* Prepare the state pointer */ - state = hoedown_malloc(sizeof(hoedown_html_renderer_state)); - memset(state, 0x0, sizeof(hoedown_html_renderer_state)); - - state->flags = render_flags; - state->toc_data.nesting_level = nesting_level; - - /* Prepare the renderer */ - renderer = hoedown_malloc(sizeof(hoedown_renderer)); - memcpy(renderer, &cb_default, sizeof(hoedown_renderer)); - - if (render_flags & HOEDOWN_HTML_SKIP_HTML || render_flags & HOEDOWN_HTML_ESCAPE) - renderer->blockhtml = NULL; - - renderer->opaque = state; - return renderer; -} - -void -hoedown_html_renderer_free(hoedown_renderer *renderer) -{ - free(renderer->opaque); - free(renderer); +void hoedown_html_renderer_free(hoedown_renderer *rndr) { + if (!rndr) return; + + renderer_state *state = rndr->opaque; + hoedown_pool_uninit(&state->buffers); + free(state); + + free(rndr); } diff --git a/src/html.h b/src/html.h index e46e7fd..2a575c9 100644 --- a/src/html.h +++ b/src/html.h @@ -5,6 +5,7 @@ #include "document.h" #include "buffer.h" +#include "pool.h" #ifdef __cplusplus extern "C" { @@ -15,66 +16,25 @@ extern "C" { * CONSTANTS * *************/ -typedef enum hoedown_html_flags { - HOEDOWN_HTML_SKIP_HTML = (1 << 0), - HOEDOWN_HTML_ESCAPE = (1 << 1), - HOEDOWN_HTML_HARD_WRAP = (1 << 2), - HOEDOWN_HTML_USE_XHTML = (1 << 3) -} hoedown_html_flags; - -typedef enum hoedown_html_tag { - HOEDOWN_HTML_TAG_NONE = 0, - HOEDOWN_HTML_TAG_OPEN, - HOEDOWN_HTML_TAG_CLOSE -} hoedown_html_tag; +//TODO /********* * TYPES * *********/ -struct hoedown_html_renderer_state { - void *opaque; - - struct { - int header_count; - int current_level; - int level_offset; - int nesting_level; - } toc_data; - - hoedown_html_flags flags; - - /* extra callbacks */ - void (*link_attributes)(hoedown_buffer *ob, const hoedown_buffer *url, const hoedown_renderer_data *data); -}; -typedef struct hoedown_html_renderer_state hoedown_html_renderer_state; +//TODO /************* * FUNCTIONS * *************/ -/* hoedown_html_smartypants: process an HTML snippet using SmartyPants for smart punctuation */ -void hoedown_html_smartypants(hoedown_buffer *ob, const uint8_t *data, size_t size); - -/* hoedown_html_is_tag: checks if data starts with a specific tag, returns the tag type or NONE */ -hoedown_html_tag hoedown_html_is_tag(const uint8_t *data, size_t size, const char *tagname); - - -/* hoedown_html_renderer_new: allocates a regular HTML renderer */ -hoedown_renderer *hoedown_html_renderer_new( - hoedown_html_flags render_flags, - int nesting_level -) __attribute__ ((malloc)); - -/* hoedown_html_toc_renderer_new: like hoedown_html_renderer_new, but the returned renderer produces the Table of Contents */ -hoedown_renderer *hoedown_html_toc_renderer_new( - int nesting_level -) __attribute__ ((malloc)); +/* hoedown_html_renderer_new: allocate a new HTML renderer */ +hoedown_renderer *hoedown_html_renderer_new() __attribute__((malloc)); /* hoedown_html_renderer_free: deallocate an HTML renderer */ -void hoedown_html_renderer_free(hoedown_renderer *renderer); +void hoedown_html_renderer_free(hoedown_renderer *rndr); #ifdef __cplusplus diff --git a/src/html_smartypants.c b/src/html_smartypants.c deleted file mode 100644 index bbe4fc5..0000000 --- a/src/html_smartypants.c +++ /dev/null @@ -1,425 +0,0 @@ -#include "html.h" - -#include -#include -#include -#include - -#ifdef _MSC_VER -#define snprintf _snprintf -#endif - -struct smartypants_data { - int in_squote; - int in_dquote; -}; - -static size_t smartypants_cb__ltag(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size); -static size_t smartypants_cb__dquote(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size); -static size_t smartypants_cb__amp(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size); -static size_t smartypants_cb__period(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size); -static size_t smartypants_cb__number(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size); -static size_t smartypants_cb__dash(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size); -static size_t smartypants_cb__parens(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size); -static size_t smartypants_cb__squote(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size); -static size_t smartypants_cb__backtick(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size); -static size_t smartypants_cb__escape(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size); - -static size_t (*smartypants_cb_ptrs[]) - (hoedown_buffer *, struct smartypants_data *, uint8_t, const uint8_t *, size_t) = -{ - NULL, /* 0 */ - smartypants_cb__dash, /* 1 */ - smartypants_cb__parens, /* 2 */ - smartypants_cb__squote, /* 3 */ - smartypants_cb__dquote, /* 4 */ - smartypants_cb__amp, /* 5 */ - smartypants_cb__period, /* 6 */ - smartypants_cb__number, /* 7 */ - smartypants_cb__ltag, /* 8 */ - smartypants_cb__backtick, /* 9 */ - smartypants_cb__escape, /* 10 */ -}; - -static const uint8_t smartypants_cb_chars[UINT8_MAX+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, 4, 0, 0, 0, 5, 3, 2, 0, 0, 0, 0, 1, 6, 0, - 0, 7, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 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 int -word_boundary(uint8_t c) -{ - return c == 0 || isspace(c) || ispunct(c); -} - -/* - If 'text' begins with any kind of single quote (e.g. "'" or "'" etc.), - returns the length of the sequence of characters that makes up the single- - quote. Otherwise, returns zero. -*/ -static size_t -squote_len(const uint8_t *text, size_t size) -{ - static char* single_quote_list[] = { "'", "'", "'", "'", NULL }; - char** p; - - for (p = single_quote_list; *p; ++p) { - size_t len = strlen(*p); - if (size >= len && memcmp(text, *p, len) == 0) { - return len; - } - } - - return 0; -} - -/* Converts " or ' at very beginning or end of a word to left or right quote */ -static int -smartypants_quotes(hoedown_buffer *ob, uint8_t previous_char, uint8_t next_char, uint8_t quote, int *is_open) -{ - char ent[8]; - - if (*is_open && !word_boundary(next_char)) - return 0; - - if (!(*is_open) && !word_boundary(previous_char)) - return 0; - - snprintf(ent, sizeof(ent), "&%c%cquo;", (*is_open) ? 'r' : 'l', quote); - *is_open = !(*is_open); - hoedown_buffer_puts(ob, ent); - return 1; -} - -/* - Converts ' to left or right single quote; but the initial ' might be in - different forms, e.g. ' or ' or '. - 'squote_text' points to the original single quote, and 'squote_size' is its length. - 'text' points at the last character of the single-quote, e.g. ' or ; -*/ -static size_t -smartypants_squote(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size, - const uint8_t *squote_text, size_t squote_size) -{ - if (size >= 2) { - uint8_t t1 = tolower(text[1]); - size_t next_squote_len = squote_len(text+1, size-1); - - /* convert '' to “ or ” */ - if (next_squote_len > 0) { - uint8_t next_char = (size > 1+next_squote_len) ? text[1+next_squote_len] : 0; - if (smartypants_quotes(ob, previous_char, next_char, 'd', &smrt->in_dquote)) - return next_squote_len; - } - - /* Tom's, isn't, I'm, I'd */ - if ((t1 == 's' || t1 == 't' || t1 == 'm' || t1 == 'd') && - (size == 3 || word_boundary(text[2]))) { - HOEDOWN_BUFPUTSL(ob, "’"); - return 0; - } - - /* you're, you'll, you've */ - if (size >= 3) { - uint8_t t2 = tolower(text[2]); - - if (((t1 == 'r' && t2 == 'e') || - (t1 == 'l' && t2 == 'l') || - (t1 == 'v' && t2 == 'e')) && - (size == 4 || word_boundary(text[3]))) { - HOEDOWN_BUFPUTSL(ob, "’"); - return 0; - } - } - } - - if (smartypants_quotes(ob, previous_char, size > 0 ? text[1] : 0, 's', &smrt->in_squote)) - return 0; - - hoedown_buffer_put(ob, squote_text, squote_size); - return 0; -} - -/* Converts ' to left or right single quote. */ -static size_t -smartypants_cb__squote(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size) -{ - return smartypants_squote(ob, smrt, previous_char, text, size, text, 1); -} - -/* Converts (c), (r), (tm) */ -static size_t -smartypants_cb__parens(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size) -{ - if (size >= 3) { - uint8_t t1 = tolower(text[1]); - uint8_t t2 = tolower(text[2]); - - if (t1 == 'c' && t2 == ')') { - HOEDOWN_BUFPUTSL(ob, "©"); - return 2; - } - - if (t1 == 'r' && t2 == ')') { - HOEDOWN_BUFPUTSL(ob, "®"); - return 2; - } - - if (size >= 4 && t1 == 't' && t2 == 'm' && text[3] == ')') { - HOEDOWN_BUFPUTSL(ob, "™"); - return 3; - } - } - - hoedown_buffer_putc(ob, text[0]); - return 0; -} - -/* Converts "--" to em-dash, etc. */ -static size_t -smartypants_cb__dash(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size) -{ - if (size >= 3 && text[1] == '-' && text[2] == '-') { - HOEDOWN_BUFPUTSL(ob, "—"); - return 2; - } - - if (size >= 2 && text[1] == '-') { - HOEDOWN_BUFPUTSL(ob, "–"); - return 1; - } - - hoedown_buffer_putc(ob, text[0]); - return 0; -} - -/* Converts " etc. */ -static size_t -smartypants_cb__amp(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size) -{ - size_t len; - if (size >= 6 && memcmp(text, """, 6) == 0) { - if (smartypants_quotes(ob, previous_char, size >= 7 ? text[6] : 0, 'd', &smrt->in_dquote)) - return 5; - } - - len = squote_len(text, size); - if (len > 0) { - return (len-1) + smartypants_squote(ob, smrt, previous_char, text+(len-1), size-(len-1), text, len); - } - - if (size >= 4 && memcmp(text, "�", 4) == 0) - return 3; - - hoedown_buffer_putc(ob, '&'); - return 0; -} - -/* Converts "..." to ellipsis */ -static size_t -smartypants_cb__period(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size) -{ - if (size >= 3 && text[1] == '.' && text[2] == '.') { - HOEDOWN_BUFPUTSL(ob, "…"); - return 2; - } - - if (size >= 5 && text[1] == ' ' && text[2] == '.' && text[3] == ' ' && text[4] == '.') { - HOEDOWN_BUFPUTSL(ob, "…"); - return 4; - } - - hoedown_buffer_putc(ob, text[0]); - return 0; -} - -/* Converts `` to opening double quote */ -static size_t -smartypants_cb__backtick(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size) -{ - if (size >= 2 && text[1] == '`') { - if (smartypants_quotes(ob, previous_char, size >= 3 ? text[2] : 0, 'd', &smrt->in_dquote)) - return 1; - } - - hoedown_buffer_putc(ob, text[0]); - return 0; -} - -/* Converts 1/2, 1/4, 3/4 */ -static size_t -smartypants_cb__number(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size) -{ - if (word_boundary(previous_char) && size >= 3) { - if (text[0] == '1' && text[1] == '/' && text[2] == '2') { - if (size == 3 || word_boundary(text[3])) { - HOEDOWN_BUFPUTSL(ob, "½"); - return 2; - } - } - - if (text[0] == '1' && text[1] == '/' && text[2] == '4') { - if (size == 3 || word_boundary(text[3]) || - (size >= 5 && tolower(text[3]) == 't' && tolower(text[4]) == 'h')) { - HOEDOWN_BUFPUTSL(ob, "¼"); - return 2; - } - } - - if (text[0] == '3' && text[1] == '/' && text[2] == '4') { - if (size == 3 || word_boundary(text[3]) || - (size >= 6 && tolower(text[3]) == 't' && tolower(text[4]) == 'h' && tolower(text[5]) == 's')) { - HOEDOWN_BUFPUTSL(ob, "¾"); - return 2; - } - } - } - - hoedown_buffer_putc(ob, text[0]); - return 0; -} - -/* Converts " to left or right double quote */ -static size_t -smartypants_cb__dquote(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size) -{ - if (!smartypants_quotes(ob, previous_char, size > 0 ? text[1] : 0, 'd', &smrt->in_dquote)) - HOEDOWN_BUFPUTSL(ob, """); - - return 0; -} - -static size_t -smartypants_cb__ltag(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size) -{ - static const char *skip_tags[] = { - "pre", "code", "var", "samp", "kbd", "math", "script", "style" - }; - static const size_t skip_tags_count = 8; - - size_t tag, i = 0; - - while (i < size && text[i] != '>') - i++; - - for (tag = 0; tag < skip_tags_count; ++tag) { - if (hoedown_html_is_tag(text, size, skip_tags[tag]) == HOEDOWN_HTML_TAG_OPEN) - break; - } - - if (tag < skip_tags_count) { - for (;;) { - while (i < size && text[i] != '<') - i++; - - if (i == size) - break; - - if (hoedown_html_is_tag(text + i, size - i, skip_tags[tag]) == HOEDOWN_HTML_TAG_CLOSE) - break; - - i++; - } - - while (i < size && text[i] != '>') - i++; - } - - hoedown_buffer_put(ob, text, i + 1); - return i; -} - -static size_t -smartypants_cb__escape(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size) -{ - if (size < 2) - return 0; - - switch (text[1]) { - case '\\': - case '"': - case '\'': - case '.': - case '-': - case '`': - hoedown_buffer_putc(ob, text[1]); - return 1; - - default: - hoedown_buffer_putc(ob, '\\'); - return 0; - } -} - -#if 0 -static struct { - uint8_t c0; - const uint8_t *pattern; - const uint8_t *entity; - int skip; -} smartypants_subs[] = { - { '\'', "'s>", "’", 0 }, - { '\'', "'t>", "’", 0 }, - { '\'', "'re>", "’", 0 }, - { '\'', "'ll>", "’", 0 }, - { '\'', "'ve>", "’", 0 }, - { '\'', "'m>", "’", 0 }, - { '\'', "'d>", "’", 0 }, - { '-', "--", "—", 1 }, - { '-', "<->", "–", 0 }, - { '.', "...", "…", 2 }, - { '.', ". . .", "…", 4 }, - { '(', "(c)", "©", 2 }, - { '(', "(r)", "®", 2 }, - { '(', "(tm)", "™", 3 }, - { '3', "<3/4>", "¾", 2 }, - { '3', "<3/4ths>", "¾", 2 }, - { '1', "<1/2>", "½", 2 }, - { '1', "<1/4>", "¼", 2 }, - { '1', "<1/4th>", "¼", 2 }, - { '&', "�", 0, 3 }, -}; -#endif - -void -hoedown_html_smartypants(hoedown_buffer *ob, const uint8_t *text, size_t size) -{ - size_t i; - struct smartypants_data smrt = {0, 0}; - - if (!text) - return; - - hoedown_buffer_grow(ob, size); - - for (i = 0; i < size; ++i) { - size_t org; - uint8_t action = 0; - - org = i; - while (i < size && (action = smartypants_cb_chars[text[i]]) == 0) - i++; - - if (i > org) - hoedown_buffer_put(ob, text + org, i - org); - - if (i < size) { - i += smartypants_cb_ptrs[(int)action] - (ob, &smrt, i ? text[i - 1] : 0, text + i, size - i); - } - } -} diff --git a/src/pool.c b/src/pool.c new file mode 100644 index 0000000..13c0f0e --- /dev/null +++ b/src/pool.c @@ -0,0 +1,63 @@ +#include "pool.h" + +#define likely(x) __builtin_expect((x),1) +#define unlikely(x) __builtin_expect((x),0) + + +void hoedown_pool_init( + hoedown_pool *pool, + size_t initial_size, + void *(*new_function)(void *opaque), + void (*free_function)(void *item, void *opaque), + void *opaque +) { + if (!initial_size) initial_size = 8; + + pool->item = hoedown_malloc(sizeof(void *) * initial_size); + pool->size = pool->isize = 0; + pool->asize = initial_size; + + pool->new_function = new_function; + pool->free_function = free_function; + pool->opaque = opaque; +} + + +void *hoedown_pool_get(hoedown_pool *pool) { + if (unlikely(pool->size >= pool->isize)) { + /* Make sure there's space allocated */ + if (unlikely(pool->isize >= pool->asize)) { + pool->asize *= 2; + pool->item = hoedown_realloc(pool->item, sizeof(void *) * pool->asize); + } + + /* Initialize a new object */ + pool->item[pool->isize++] = pool->new_function(pool->opaque); + } + return pool->item[pool->size++]; +} + +void hoedown_pool_pop(hoedown_pool *pool) { + pool->size--; +} + +void hoedown_pool_uninit(hoedown_pool *pool) { + for (size_t i = 0; i < pool->isize; i++) + pool->free_function(pool->item[i], pool->opaque); + + free(pool->item); +} + + +/* Pool of hoedown_buffer objects */ + +static void *buffer_new(void *opaque) { + return hoedown_buffer_new((size_t)opaque); +} +static void buffer_free(void *item, void *opaque) { + hoedown_buffer_free(item); +} + +void hoedown_buffer_pool_init(hoedown_pool *pool, size_t initial_size, size_t unit) { + hoedown_pool_init(pool, initial_size, buffer_new, buffer_free, (void *)unit); +} diff --git a/src/pool.h b/src/pool.h new file mode 100644 index 0000000..5fa0255 --- /dev/null +++ b/src/pool.h @@ -0,0 +1,60 @@ +/* pool.h - stack-based pool of reusable objects */ + +#ifndef HOEDOWN_POOL_H +#define HOEDOWN_POOL_H + +#include "buffer.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/********* + * TYPES * + *********/ + +typedef struct hoedown_pool { + void **item; + size_t size; + size_t isize; + size_t asize; + + void *(*new_function)(void *opaque); + void (*free_function)(void *item, void *opaque); + void *opaque; +} hoedown_pool; + + +/************* + * FUNCTIONS * + *************/ + +/* hoedown_pool_init: initialize a new pool of objects */ +void hoedown_pool_init( + hoedown_pool *pool, + size_t initial_size, + void *(*new_function)(void *opaque), + void (*free_function)(void *item, void *opaque), + void *opaque +); + +/* hoedown_pool_get: reserve and return the next object from the pool */ +void *hoedown_pool_get(hoedown_pool *pool); + +/* hoedown_pool_pop: unreserve the last reserved object from the pool */ +void hoedown_pool_pop(hoedown_pool *pool); + +/* hoedown_pool_uninit: uninitialize a pool of objects */ +void hoedown_pool_uninit(hoedown_pool *pool); + + +/* hoedown_buffer_pool_init: convenience method to create a pool of buffers */ +void hoedown_buffer_pool_init(hoedown_pool *pool, size_t initial_size, size_t unit); + + +#ifdef __cplusplus +} +#endif + +#endif /** HOEDOWN_POOL_H **/ diff --git a/src/stack.c b/src/stack.c deleted file mode 100644 index 5c6102c..0000000 --- a/src/stack.c +++ /dev/null @@ -1,79 +0,0 @@ -#include "stack.h" - -#include "buffer.h" - -#include -#include -#include - -void -hoedown_stack_init(hoedown_stack *st, size_t initial_size) -{ - assert(st); - - st->item = NULL; - st->size = st->asize = 0; - - if (!initial_size) - initial_size = 8; - - hoedown_stack_grow(st, initial_size); -} - -void -hoedown_stack_uninit(hoedown_stack *st) -{ - assert(st); - - free(st->item); -} - -void -hoedown_stack_grow(hoedown_stack *st, size_t neosz) -{ - assert(st); - - if (st->asize >= neosz) - return; - - st->item = hoedown_realloc(st->item, neosz * sizeof(void *)); - memset(st->item + st->asize, 0x0, (neosz - st->asize) * sizeof(void *)); - - st->asize = neosz; - - if (st->size > neosz) - st->size = neosz; -} - -void -hoedown_stack_push(hoedown_stack *st, void *item) -{ - assert(st); - - if (st->size >= st->asize) - hoedown_stack_grow(st, st->size * 2); - - st->item[st->size++] = item; -} - -void * -hoedown_stack_pop(hoedown_stack *st) -{ - assert(st); - - if (!st->size) - return NULL; - - return st->item[--st->size]; -} - -void * -hoedown_stack_top(const hoedown_stack *st) -{ - assert(st); - - if (!st->size) - return NULL; - - return st->item[st->size - 1]; -} diff --git a/src/stack.h b/src/stack.h deleted file mode 100644 index bf9b439..0000000 --- a/src/stack.h +++ /dev/null @@ -1,52 +0,0 @@ -/* stack.h - simple stacking */ - -#ifndef HOEDOWN_STACK_H -#define HOEDOWN_STACK_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -/********* - * TYPES * - *********/ - -struct hoedown_stack { - void **item; - size_t size; - size_t asize; -}; -typedef struct hoedown_stack hoedown_stack; - - -/************* - * FUNCTIONS * - *************/ - -/* hoedown_stack_init: initialize a stack */ -void hoedown_stack_init(hoedown_stack *st, size_t initial_size); - -/* hoedown_stack_uninit: free internal data of the stack */ -void hoedown_stack_uninit(hoedown_stack *st); - -/* hoedown_stack_grow: increase the allocated size to the given value */ -void hoedown_stack_grow(hoedown_stack *st, size_t neosz); - -/* hoedown_stack_push: push an item to the top of the stack */ -void hoedown_stack_push(hoedown_stack *st, void *item); - -/* hoedown_stack_pop: retrieve and remove the item at the top of the stack */ -void *hoedown_stack_pop(hoedown_stack *st); - -/* hoedown_stack_top: retrieve the item at the top of the stack */ -void *hoedown_stack_top(const hoedown_stack *st); - - -#ifdef __cplusplus -} -#endif - -#endif /** HOEDOWN_STACK_H **/ diff --git a/src/version.c b/src/version.c index 744209b..cb84a08 100644 --- a/src/version.c +++ b/src/version.c @@ -1,9 +1,7 @@ #include "version.h" -void -hoedown_version(int *major, int *minor, int *revision) -{ - *major = HOEDOWN_VERSION_MAJOR; - *minor = HOEDOWN_VERSION_MINOR; - *revision = HOEDOWN_VERSION_REVISION; +void hoedown_version(int *major, int *minor, int *revision) { + *major = HOEDOWN_VERSION_MAJOR; + *minor = HOEDOWN_VERSION_MINOR; + *revision = HOEDOWN_VERSION_REVISION; } diff --git a/src/version.h b/src/version.h index 9b30f1d..c2d026a 100644 --- a/src/version.h +++ b/src/version.h @@ -12,8 +12,8 @@ extern "C" { * CONSTANTS * *************/ -#define HOEDOWN_VERSION "2.0.0" -#define HOEDOWN_VERSION_MAJOR 2 +#define HOEDOWN_VERSION "4.0.0-pre" +#define HOEDOWN_VERSION_MAJOR 4 #define HOEDOWN_VERSION_MINOR 0 #define HOEDOWN_VERSION_REVISION 0 diff --git a/stmd b/stmd new file mode 160000 index 0000000..a5fa2d5 --- /dev/null +++ b/stmd @@ -0,0 +1 @@ +Subproject commit a5fa2d573185bcc565da89effcfbfdc2967ef939 diff --git a/test/MarkdownTest_1.0.3/MarkdownTest.pl b/test/MarkdownTest_1.0.3/MarkdownTest.pl deleted file mode 100755 index c84685c..0000000 --- a/test/MarkdownTest_1.0.3/MarkdownTest.pl +++ /dev/null @@ -1,177 +0,0 @@ -#!/usr/bin/perl - -# -# MarkdownTester -- Run tests for Markdown implementations -# -# Copyright (c) 2004-2005 John Gruber -# -# - -use strict; -use warnings; -use Getopt::Long; -use Benchmark; - -our $VERSION = '1.0.2'; -# Sat 24 Dec 2005 - -my $time_start = new Benchmark; -my $test_dir = "Tests"; -my $script = "./Markdown.pl"; -my $use_tidy = 0; -my ($flag_version); - -GetOptions ( - "script=s" => \$script, - "testdir=s" => \$test_dir, - "tidy" => \$use_tidy, - "version" => \$flag_version, - ); - -if($flag_version) { - my $progname = $0; - $progname =~ s{.*/}{}; - die "$progname version $VERSION\n"; -} - -unless (-d $test_dir) { die "'$test_dir' is not a directory.\n"; } -unless (-f $script) { die "$script does not exist.\n"; } -unless (-x $script) { die "$script is not executable.\n"; } - -my $tests_passed = 0; -my $tests_failed = 0; - -TEST: -foreach my $testfile (glob "$test_dir/*.text") { - my $testname = $testfile; - $testname =~ s{.*/(.+)\.text$}{$1}i; - print "$testname ... "; - - # Look for a corresponding .html file for each .text file: - my $resultfile = $testfile; - $resultfile =~ s{\.text$}{\.html}i; - unless (-f $resultfile) { - print "'$resultfile' does not exist.\n\n"; - next TEST; - } - - # open(TEST, $testfile) || die("Can't open testfile: $!"); - open(RESULT, $resultfile) || die("Can't open resultfile: $!"); - undef $/; - # my $t_input = ; - my $t_result = ; - - my $t_output = `'$script' '$testfile'`; - - # Normalize the output and expected result strings: - $t_result =~ s/\s+\z//; # trim trailing whitespace - $t_output =~ s/\s+\z//; # trim trailing whitespace - if ($use_tidy) { - # Escape the strings, pass them through to CLI tidy tool for tag-level equivalency - $t_result =~ s{'}{'\\''}g; # escape ' chars for shell - $t_output =~ s{'}{'\\''}g; - $t_result = `echo '$t_result' | tidy --show-body-only 1 --quiet 1 --show-warnings 0`; - $t_output = `echo '$t_output' | tidy --show-body-only 1 --quiet 1 --show-warnings 0`; - } - - if ($t_output eq $t_result) { - print "OK\n"; - $tests_passed++; - } - else { - print "FAILED\n\n"; -# This part added by JM to print diffs - open(OUT, '>tmp1') or die $!; - print OUT $t_output or die $!; - open(RES, '>tmp2') or die $!; - print RES $t_result or die $!; - print `diff tmp1 tmp2`; - close RES; - close OUT; - print "\n"; - `rm tmp?`; -# End of added part - $tests_failed++; - } -} - -print "\n\n"; -print "$tests_passed passed; $tests_failed failed.\n"; - -my $time_end = new Benchmark; -my $time_diff = timediff($time_end, $time_start); -print "Benchmark: ", timestr($time_diff), "\n"; - -exit 1 if $tests_failed; - -__END__ - -=pod - -=head1 NAME - -B - - -=head1 SYNOPSIS - -B [ B<--options> ] [ I ... ] - - -=head1 DESCRIPTION - - -=head1 OPTIONS - -Use "--" to end switch parsing. For example, to open a file named "-z", use: - - MarkdownTest.pl -- -z - -=over 4 - -=item B<--script> - -Specify the path to the Markdown script to test. Defaults to -"./Markdown.pl". Example: - - ./MarkdownTest.pl --script ./PHP-Markdown/php-markdown - -=item B<--testdir> - -Specify the path to a directory containing test data. Defaults to "Tests". - -=item B<--tidy> - -Flag to turn on using the command line 'tidy' tool to normalize HTML -output before comparing script output to the expected test result. -Assumes that the 'tidy' command is available in your PATH. Defaults to -off. - -=back - - - -=head1 BUGS - - - -=head1 VERSION HISTORY - -1.0 Mon 13 Dec 2004-2005 - -1.0.1 Mon 19 Sep 2005 - - + Better handling of case when foo.text exists, but foo.html doesn't. - It now prints a message and moves on, rather than dying. - - -=head1 COPYRIGHT AND LICENSE - -Copyright (c) 2004-2005 John Gruber - -All rights reserved. - -This is free software; you may redistribute it and/or modify it under -the same terms as Perl itself. - -=cut diff --git a/test/MarkdownTest_1.0.3/Tests/Amps and angle encoding.html b/test/MarkdownTest_1.0.3/Tests/Amps and angle encoding.html deleted file mode 100644 index 9606860..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Amps and angle encoding.html +++ /dev/null @@ -1,17 +0,0 @@ -

    AT&T has an ampersand in their name.

    - -

    AT&T is another way to write it.

    - -

    This & that.

    - -

    4 < 5.

    - -

    6 > 5.

    - -

    Here's a link with an ampersand in the URL.

    - -

    Here's a link with an amersand in the link text: AT&T.

    - -

    Here's an inline link.

    - -

    Here's an inline link.

    diff --git a/test/MarkdownTest_1.0.3/Tests/Amps and angle encoding.text b/test/MarkdownTest_1.0.3/Tests/Amps and angle encoding.text deleted file mode 100644 index 0e9527f..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Amps and angle encoding.text +++ /dev/null @@ -1,21 +0,0 @@ -AT&T has an ampersand in their name. - -AT&T is another way to write it. - -This & that. - -4 < 5. - -6 > 5. - -Here's a [link] [1] with an ampersand in the URL. - -Here's a link with an amersand in the link text: [AT&T] [2]. - -Here's an inline [link](/script?foo=1&bar=2). - -Here's an inline [link](). - - -[1]: http://example.com/?foo=1&bar=2 -[2]: http://att.com/ "AT&T" \ No newline at end of file diff --git a/test/MarkdownTest_1.0.3/Tests/Auto links.html b/test/MarkdownTest_1.0.3/Tests/Auto links.html deleted file mode 100644 index f8df985..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Auto links.html +++ /dev/null @@ -1,18 +0,0 @@ -

    Link: http://example.com/.

    - -

    With an ampersand: http://example.com/?foo=1&bar=2

    - - - -
    -

    Blockquoted: http://example.com/

    -
    - -

    Auto-links should not occur here: <http://example.com/>

    - -
    or here: <http://example.com/>
    -
    diff --git a/test/MarkdownTest_1.0.3/Tests/Auto links.text b/test/MarkdownTest_1.0.3/Tests/Auto links.text deleted file mode 100644 index abbc488..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Auto links.text +++ /dev/null @@ -1,13 +0,0 @@ -Link: . - -With an ampersand: - -* In a list? -* -* It should. - -> Blockquoted: - -Auto-links should not occur here: `` - - or here: \ No newline at end of file diff --git a/test/MarkdownTest_1.0.3/Tests/Backslash escapes.html b/test/MarkdownTest_1.0.3/Tests/Backslash escapes.html deleted file mode 100644 index 29870da..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Backslash escapes.html +++ /dev/null @@ -1,118 +0,0 @@ -

    These should all get escaped:

    - -

    Backslash: \

    - -

    Backtick: `

    - -

    Asterisk: *

    - -

    Underscore: _

    - -

    Left brace: {

    - -

    Right brace: }

    - -

    Left bracket: [

    - -

    Right bracket: ]

    - -

    Left paren: (

    - -

    Right paren: )

    - -

    Greater-than: >

    - -

    Hash: #

    - -

    Period: .

    - -

    Bang: !

    - -

    Plus: +

    - -

    Minus: -

    - -

    These should not, because they occur within a code block:

    - -
    Backslash: \\
    -
    -Backtick: \`
    -
    -Asterisk: \*
    -
    -Underscore: \_
    -
    -Left brace: \{
    -
    -Right brace: \}
    -
    -Left bracket: \[
    -
    -Right bracket: \]
    -
    -Left paren: \(
    -
    -Right paren: \)
    -
    -Greater-than: \>
    -
    -Hash: \#
    -
    -Period: \.
    -
    -Bang: \!
    -
    -Plus: \+
    -
    -Minus: \-
    -
    - -

    Nor should these, which occur in code spans:

    - -

    Backslash: \\

    - -

    Backtick: \`

    - -

    Asterisk: \*

    - -

    Underscore: \_

    - -

    Left brace: \{

    - -

    Right brace: \}

    - -

    Left bracket: \[

    - -

    Right bracket: \]

    - -

    Left paren: \(

    - -

    Right paren: \)

    - -

    Greater-than: \>

    - -

    Hash: \#

    - -

    Period: \.

    - -

    Bang: \!

    - -

    Plus: \+

    - -

    Minus: \-

    - - -

    These should get escaped, even though they're matching pairs for -other Markdown constructs:

    - -

    *asterisks*

    - -

    _underscores_

    - -

    `backticks`

    - -

    This is a code span with a literal backslash-backtick sequence: \`

    - -

    This is a tag with unescaped backticks bar.

    - -

    This is a tag with backslashes bar.

    diff --git a/test/MarkdownTest_1.0.3/Tests/Backslash escapes.text b/test/MarkdownTest_1.0.3/Tests/Backslash escapes.text deleted file mode 100644 index 5b014cb..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Backslash escapes.text +++ /dev/null @@ -1,120 +0,0 @@ -These should all get escaped: - -Backslash: \\ - -Backtick: \` - -Asterisk: \* - -Underscore: \_ - -Left brace: \{ - -Right brace: \} - -Left bracket: \[ - -Right bracket: \] - -Left paren: \( - -Right paren: \) - -Greater-than: \> - -Hash: \# - -Period: \. - -Bang: \! - -Plus: \+ - -Minus: \- - - - -These should not, because they occur within a code block: - - Backslash: \\ - - Backtick: \` - - Asterisk: \* - - Underscore: \_ - - Left brace: \{ - - Right brace: \} - - Left bracket: \[ - - Right bracket: \] - - Left paren: \( - - Right paren: \) - - Greater-than: \> - - Hash: \# - - Period: \. - - Bang: \! - - Plus: \+ - - Minus: \- - - -Nor should these, which occur in code spans: - -Backslash: `\\` - -Backtick: `` \` `` - -Asterisk: `\*` - -Underscore: `\_` - -Left brace: `\{` - -Right brace: `\}` - -Left bracket: `\[` - -Right bracket: `\]` - -Left paren: `\(` - -Right paren: `\)` - -Greater-than: `\>` - -Hash: `\#` - -Period: `\.` - -Bang: `\!` - -Plus: `\+` - -Minus: `\-` - - -These should get escaped, even though they're matching pairs for -other Markdown constructs: - -\*asterisks\* - -\_underscores\_ - -\`backticks\` - -This is a code span with a literal backslash-backtick sequence: `` \` `` - -This is a tag with unescaped backticks bar. - -This is a tag with backslashes bar. diff --git a/test/MarkdownTest_1.0.3/Tests/Blockquotes with code blocks.html b/test/MarkdownTest_1.0.3/Tests/Blockquotes with code blocks.html deleted file mode 100644 index 990202a..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Blockquotes with code blocks.html +++ /dev/null @@ -1,15 +0,0 @@ -
    -

    Example:

    - -
    sub status {
    -    print "working";
    -}
    -
    - -

    Or:

    - -
    sub status {
    -    return "working";
    -}
    -
    -
    diff --git a/test/MarkdownTest_1.0.3/Tests/Blockquotes with code blocks.text b/test/MarkdownTest_1.0.3/Tests/Blockquotes with code blocks.text deleted file mode 100644 index c31d171..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Blockquotes with code blocks.text +++ /dev/null @@ -1,11 +0,0 @@ -> Example: -> -> sub status { -> print "working"; -> } -> -> Or: -> -> sub status { -> return "working"; -> } diff --git a/test/MarkdownTest_1.0.3/Tests/Code Blocks.html b/test/MarkdownTest_1.0.3/Tests/Code Blocks.html deleted file mode 100644 index 32703f5..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Code Blocks.html +++ /dev/null @@ -1,18 +0,0 @@ -
    code block on the first line
    -
    - -

    Regular text.

    - -
    code block indented by spaces
    -
    - -

    Regular text.

    - -
    the lines in this block  
    -all contain trailing spaces  
    -
    - -

    Regular Text.

    - -
    code block on the last line
    -
    diff --git a/test/MarkdownTest_1.0.3/Tests/Code Blocks.text b/test/MarkdownTest_1.0.3/Tests/Code Blocks.text deleted file mode 100644 index b54b092..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Code Blocks.text +++ /dev/null @@ -1,14 +0,0 @@ - code block on the first line - -Regular text. - - code block indented by spaces - -Regular text. - - the lines in this block - all contain trailing spaces - -Regular Text. - - code block on the last line \ No newline at end of file diff --git a/test/MarkdownTest_1.0.3/Tests/Code Spans.html b/test/MarkdownTest_1.0.3/Tests/Code Spans.html deleted file mode 100644 index 4b8afbb..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Code Spans.html +++ /dev/null @@ -1,6 +0,0 @@ -

    <test a=" content of attribute ">

    - -

    Fix for backticks within HTML tag: like this

    - -

    Here's how you put `backticks` in a code span.

    - diff --git a/test/MarkdownTest_1.0.3/Tests/Code Spans.text b/test/MarkdownTest_1.0.3/Tests/Code Spans.text deleted file mode 100644 index 750a197..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Code Spans.text +++ /dev/null @@ -1,6 +0,0 @@ -`` - -Fix for backticks within HTML tag: like this - -Here's how you put `` `backticks` `` in a code span. - diff --git a/test/MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.html b/test/MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.html deleted file mode 100644 index e21ac79..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.html +++ /dev/null @@ -1,8 +0,0 @@ -

    In Markdown 1.0.0 and earlier. Version -8. This line turns into a list item. -Because a hard-wrapped line in the -middle of a paragraph looked like a -list item.

    - -

    Here's one with a bullet. -* criminey.

    diff --git a/test/MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.text b/test/MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.text deleted file mode 100644 index f8a5b27..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.text +++ /dev/null @@ -1,8 +0,0 @@ -In Markdown 1.0.0 and earlier. Version -8. This line turns into a list item. -Because a hard-wrapped line in the -middle of a paragraph looked like a -list item. - -Here's one with a bullet. -* criminey. diff --git a/test/MarkdownTest_1.0.3/Tests/Horizontal rules.html b/test/MarkdownTest_1.0.3/Tests/Horizontal rules.html deleted file mode 100644 index 2dc2ab6..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Horizontal rules.html +++ /dev/null @@ -1,71 +0,0 @@ -

    Dashes:

    - -
    - -
    - -
    - -
    - -
    ---
    -
    - -
    - -
    - -
    - -
    - -
    - - -
    -
    - -

    Asterisks:

    - -
    - -
    - -
    - -
    - -
    ***
    -
    - -
    - -
    - -
    - -
    - -
    * * *
    -
    - -

    Underscores:

    - -
    - -
    - -
    - -
    - -
    ___
    -
    - -
    - -
    - -
    - -
    - -
    _ _ _
    -
    diff --git a/test/MarkdownTest_1.0.3/Tests/Horizontal rules.text b/test/MarkdownTest_1.0.3/Tests/Horizontal rules.text deleted file mode 100644 index 1594bda..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Horizontal rules.text +++ /dev/null @@ -1,67 +0,0 @@ -Dashes: - ---- - - --- - - --- - - --- - - --- - -- - - - - - - - - - - - - - - - - - - - - - - - - -Asterisks: - -*** - - *** - - *** - - *** - - *** - -* * * - - * * * - - * * * - - * * * - - * * * - - -Underscores: - -___ - - ___ - - ___ - - ___ - - ___ - -_ _ _ - - _ _ _ - - _ _ _ - - _ _ _ - - _ _ _ diff --git a/test/MarkdownTest_1.0.3/Tests/Inline HTML (Advanced).html b/test/MarkdownTest_1.0.3/Tests/Inline HTML (Advanced).html deleted file mode 100644 index 3af9caf..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Inline HTML (Advanced).html +++ /dev/null @@ -1,15 +0,0 @@ -

    Simple block on one line:

    - -
    foo
    - -

    And nested without indentation:

    - -
    -
    -
    -foo -
    -
    -
    -
    bar
    -
    diff --git a/test/MarkdownTest_1.0.3/Tests/Inline HTML (Advanced).text b/test/MarkdownTest_1.0.3/Tests/Inline HTML (Advanced).text deleted file mode 100644 index 86b7206..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Inline HTML (Advanced).text +++ /dev/null @@ -1,15 +0,0 @@ -Simple block on one line: - -
    foo
    - -And nested without indentation: - -
    -
    -
    -foo -
    -
    -
    -
    bar
    -
    diff --git a/test/MarkdownTest_1.0.3/Tests/Inline HTML (Simple).html b/test/MarkdownTest_1.0.3/Tests/Inline HTML (Simple).html deleted file mode 100644 index 6bf78f8..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Inline HTML (Simple).html +++ /dev/null @@ -1,72 +0,0 @@ -

    Here's a simple block:

    - -
    - foo -
    - -

    This should be a code block, though:

    - -
    <div>
    -    foo
    -</div>
    -
    - -

    As should this:

    - -
    <div>foo</div>
    -
    - -

    Now, nested:

    - -
    -
    -
    - foo -
    -
    -
    - -

    This should just be an HTML comment:

    - - - -

    Multiline:

    - - - -

    Code block:

    - -
    <!-- Comment -->
    -
    - -

    Just plain comment, with trailing spaces on the line:

    - - - -

    Code:

    - -
    <hr />
    -
    - -

    Hr's:

    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    diff --git a/test/MarkdownTest_1.0.3/Tests/Inline HTML (Simple).text b/test/MarkdownTest_1.0.3/Tests/Inline HTML (Simple).text deleted file mode 100644 index 14aa2dc..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Inline HTML (Simple).text +++ /dev/null @@ -1,69 +0,0 @@ -Here's a simple block: - -
    - foo -
    - -This should be a code block, though: - -
    - foo -
    - -As should this: - -
    foo
    - -Now, nested: - -
    -
    -
    - foo -
    -
    -
    - -This should just be an HTML comment: - - - -Multiline: - - - -Code block: - - - -Just plain comment, with trailing spaces on the line: - - - -Code: - -
    - -Hr's: - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - diff --git a/test/MarkdownTest_1.0.3/Tests/Inline HTML comments.html b/test/MarkdownTest_1.0.3/Tests/Inline HTML comments.html deleted file mode 100644 index 3f167a1..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Inline HTML comments.html +++ /dev/null @@ -1,13 +0,0 @@ -

    Paragraph one.

    - - - - - -

    Paragraph two.

    - - - -

    The end.

    diff --git a/test/MarkdownTest_1.0.3/Tests/Inline HTML comments.text b/test/MarkdownTest_1.0.3/Tests/Inline HTML comments.text deleted file mode 100644 index 41d830d..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Inline HTML comments.text +++ /dev/null @@ -1,13 +0,0 @@ -Paragraph one. - - - - - -Paragraph two. - - - -The end. diff --git a/test/MarkdownTest_1.0.3/Tests/Links, inline style.html b/test/MarkdownTest_1.0.3/Tests/Links, inline style.html deleted file mode 100644 index f36607d..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Links, inline style.html +++ /dev/null @@ -1,11 +0,0 @@ -

    Just a URL.

    - -

    URL and title.

    - -

    URL and title.

    - -

    URL and title.

    - -

    URL and title.

    - -

    Empty.

    diff --git a/test/MarkdownTest_1.0.3/Tests/Links, inline style.text b/test/MarkdownTest_1.0.3/Tests/Links, inline style.text deleted file mode 100644 index 09017a9..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Links, inline style.text +++ /dev/null @@ -1,12 +0,0 @@ -Just a [URL](/url/). - -[URL and title](/url/ "title"). - -[URL and title](/url/ "title preceded by two spaces"). - -[URL and title](/url/ "title preceded by a tab"). - -[URL and title](/url/ "title has spaces afterward" ). - - -[Empty](). diff --git a/test/MarkdownTest_1.0.3/Tests/Links, reference style.html b/test/MarkdownTest_1.0.3/Tests/Links, reference style.html deleted file mode 100644 index 8e70c32..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Links, reference style.html +++ /dev/null @@ -1,52 +0,0 @@ -

    Foo bar.

    - -

    Foo bar.

    - -

    Foo bar.

    - -

    With embedded [brackets].

    - -

    Indented once.

    - -

    Indented twice.

    - -

    Indented thrice.

    - -

    Indented [four][] times.

    - -
    [four]: /url
    -
    - -
    - -

    this should work

    - -

    So should this.

    - -

    And this.

    - -

    And this.

    - -

    And this.

    - -

    But not [that] [].

    - -

    Nor [that][].

    - -

    Nor [that].

    - -

    [Something in brackets like this should work]

    - -

    [Same with this.]

    - -

    In this case, this points to something else.

    - -

    Backslashing should suppress [this] and [this].

    - -
    - -

    Here's one where the link -breaks across lines.

    - -

    Here's another where the link -breaks across lines, but with a line-ending space.

    diff --git a/test/MarkdownTest_1.0.3/Tests/Links, reference style.text b/test/MarkdownTest_1.0.3/Tests/Links, reference style.text deleted file mode 100644 index 341ec88..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Links, reference style.text +++ /dev/null @@ -1,71 +0,0 @@ -Foo [bar] [1]. - -Foo [bar][1]. - -Foo [bar] -[1]. - -[1]: /url/ "Title" - - -With [embedded [brackets]] [b]. - - -Indented [once][]. - -Indented [twice][]. - -Indented [thrice][]. - -Indented [four][] times. - - [once]: /url - - [twice]: /url - - [thrice]: /url - - [four]: /url - - -[b]: /url/ - -* * * - -[this] [this] should work - -So should [this][this]. - -And [this] []. - -And [this][]. - -And [this]. - -But not [that] []. - -Nor [that][]. - -Nor [that]. - -[Something in brackets like [this][] should work] - -[Same with [this].] - -In this case, [this](/somethingelse/) points to something else. - -Backslashing should suppress \[this] and [this\]. - -[this]: foo - - -* * * - -Here's one where the [link -breaks] across lines. - -Here's another where the [link -breaks] across lines, but with a line-ending space. - - -[link breaks]: /url/ diff --git a/test/MarkdownTest_1.0.3/Tests/Links, shortcut references.html b/test/MarkdownTest_1.0.3/Tests/Links, shortcut references.html deleted file mode 100644 index bf81e93..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Links, shortcut references.html +++ /dev/null @@ -1,9 +0,0 @@ -

    This is the simple case.

    - -

    This one has a line -break.

    - -

    This one has a line -break with a line-ending space.

    - -

    this and the other

    diff --git a/test/MarkdownTest_1.0.3/Tests/Links, shortcut references.text b/test/MarkdownTest_1.0.3/Tests/Links, shortcut references.text deleted file mode 100644 index 8c44c98..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Links, shortcut references.text +++ /dev/null @@ -1,20 +0,0 @@ -This is the [simple case]. - -[simple case]: /simple - - - -This one has a [line -break]. - -This one has a [line -break] with a line-ending space. - -[line break]: /foo - - -[this] [that] and the [other] - -[this]: /this -[that]: /that -[other]: /other diff --git a/test/MarkdownTest_1.0.3/Tests/Literal quotes in titles.html b/test/MarkdownTest_1.0.3/Tests/Literal quotes in titles.html deleted file mode 100644 index 611c1ac..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Literal quotes in titles.html +++ /dev/null @@ -1,3 +0,0 @@ -

    Foo bar.

    - -

    Foo bar.

    diff --git a/test/MarkdownTest_1.0.3/Tests/Literal quotes in titles.text b/test/MarkdownTest_1.0.3/Tests/Literal quotes in titles.text deleted file mode 100644 index 29d0e42..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Literal quotes in titles.text +++ /dev/null @@ -1,7 +0,0 @@ -Foo [bar][]. - -Foo [bar](/url/ "Title with "quotes" inside"). - - - [bar]: /url/ "Title with "quotes" inside" - diff --git a/test/MarkdownTest_1.0.3/Tests/Markdown Documentation - Basics.html b/test/MarkdownTest_1.0.3/Tests/Markdown Documentation - Basics.html deleted file mode 100644 index d5bdbb2..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Markdown Documentation - Basics.html +++ /dev/null @@ -1,314 +0,0 @@ -

    Markdown: Basics

    - - - -

    Getting the Gist of Markdown's Formatting Syntax

    - -

    This page offers a brief overview of what it's like to use Markdown. -The syntax page provides complete, detailed documentation for -every feature, but Markdown should be very easy to pick up simply by -looking at a few examples of it in action. The examples on this page -are written in a before/after style, showing example syntax and the -HTML output produced by Markdown.

    - -

    It's also helpful to simply try Markdown out; the Dingus is a -web application that allows you type your own Markdown-formatted text -and translate it to XHTML.

    - -

    Note: This document is itself written using Markdown; you -can see the source for it by adding '.text' to the URL.

    - -

    Paragraphs, Headers, Blockquotes

    - -

    A paragraph is simply one or more consecutive lines of text, separated -by one or more blank lines. (A blank line is any line that looks like a -blank line -- a line containing nothing spaces or tabs is considered -blank.) Normal paragraphs should not be intended with spaces or tabs.

    - -

    Markdown offers two styles of headers: Setext and atx. -Setext-style headers for <h1> and <h2> are created by -"underlining" with equal signs (=) and hyphens (-), respectively. -To create an atx-style header, you put 1-6 hash marks (#) at the -beginning of the line -- the number of hashes equals the resulting -HTML header level.

    - -

    Blockquotes are indicated using email-style '>' angle brackets.

    - -

    Markdown:

    - -
    A First Level Header
    -====================
    -
    -A Second Level Header
    ----------------------
    -
    -Now is the time for all good men to come to
    -the aid of their country. This is just a
    -regular paragraph.
    -
    -The quick brown fox jumped over the lazy
    -dog's back.
    -
    -### Header 3
    -
    -> This is a blockquote.
    -> 
    -> This is the second paragraph in the blockquote.
    ->
    -> ## This is an H2 in a blockquote
    -
    - -

    Output:

    - -
    <h1>A First Level Header</h1>
    -
    -<h2>A Second Level Header</h2>
    -
    -<p>Now is the time for all good men to come to
    -the aid of their country. This is just a
    -regular paragraph.</p>
    -
    -<p>The quick brown fox jumped over the lazy
    -dog's back.</p>
    -
    -<h3>Header 3</h3>
    -
    -<blockquote>
    -    <p>This is a blockquote.</p>
    -
    -    <p>This is the second paragraph in the blockquote.</p>
    -
    -    <h2>This is an H2 in a blockquote</h2>
    -</blockquote>
    -
    - -

    Phrase Emphasis

    - -

    Markdown uses asterisks and underscores to indicate spans of emphasis.

    - -

    Markdown:

    - -
    Some of these words *are emphasized*.
    -Some of these words _are emphasized also_.
    -
    -Use two asterisks for **strong emphasis**.
    -Or, if you prefer, __use two underscores instead__.
    -
    - -

    Output:

    - -
    <p>Some of these words <em>are emphasized</em>.
    -Some of these words <em>are emphasized also</em>.</p>
    -
    -<p>Use two asterisks for <strong>strong emphasis</strong>.
    -Or, if you prefer, <strong>use two underscores instead</strong>.</p>
    -
    - -

    Lists

    - -

    Unordered (bulleted) lists use asterisks, pluses, and hyphens (*, -+, and -) as list markers. These three markers are -interchangable; this:

    - -
    *   Candy.
    -*   Gum.
    -*   Booze.
    -
    - -

    this:

    - -
    +   Candy.
    -+   Gum.
    -+   Booze.
    -
    - -

    and this:

    - -
    -   Candy.
    --   Gum.
    --   Booze.
    -
    - -

    all produce the same output:

    - -
    <ul>
    -<li>Candy.</li>
    -<li>Gum.</li>
    -<li>Booze.</li>
    -</ul>
    -
    - -

    Ordered (numbered) lists use regular numbers, followed by periods, as -list markers:

    - -
    1.  Red
    -2.  Green
    -3.  Blue
    -
    - -

    Output:

    - -
    <ol>
    -<li>Red</li>
    -<li>Green</li>
    -<li>Blue</li>
    -</ol>
    -
    - -

    If you put blank lines between items, you'll get <p> tags for the -list item text. You can create multi-paragraph list items by indenting -the paragraphs by 4 spaces or 1 tab:

    - -
    *   A list item.
    -
    -    With multiple paragraphs.
    -
    -*   Another item in the list.
    -
    - -

    Output:

    - -
    <ul>
    -<li><p>A list item.</p>
    -<p>With multiple paragraphs.</p></li>
    -<li><p>Another item in the list.</p></li>
    -</ul>
    -
    - -

    Links

    - -

    Markdown supports two styles for creating links: inline and -reference. With both styles, you use square brackets to delimit the -text you want to turn into a link.

    - -

    Inline-style links use parentheses immediately after the link text. -For example:

    - -
    This is an [example link](http://example.com/).
    -
    - -

    Output:

    - -
    <p>This is an <a href="http://example.com/">
    -example link</a>.</p>
    -
    - -

    Optionally, you may include a title attribute in the parentheses:

    - -
    This is an [example link](http://example.com/ "With a Title").
    -
    - -

    Output:

    - -
    <p>This is an <a href="http://example.com/" title="With a Title">
    -example link</a>.</p>
    -
    - -

    Reference-style links allow you to refer to your links by names, which -you define elsewhere in your document:

    - -
    I get 10 times more traffic from [Google][1] than from
    -[Yahoo][2] or [MSN][3].
    -
    -[1]: http://google.com/        "Google"
    -[2]: http://search.yahoo.com/  "Yahoo Search"
    -[3]: http://search.msn.com/    "MSN Search"
    -
    - -

    Output:

    - -
    <p>I get 10 times more traffic from <a href="http://google.com/"
    -title="Google">Google</a> than from <a href="http://search.yahoo.com/"
    -title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/"
    -title="MSN Search">MSN</a>.</p>
    -
    - -

    The title attribute is optional. Link names may contain letters, -numbers and spaces, but are not case sensitive:

    - -
    I start my morning with a cup of coffee and
    -[The New York Times][NY Times].
    -
    -[ny times]: http://www.nytimes.com/
    -
    - -

    Output:

    - -
    <p>I start my morning with a cup of coffee and
    -<a href="http://www.nytimes.com/">The New York Times</a>.</p>
    -
    - -

    Images

    - -

    Image syntax is very much like link syntax.

    - -

    Inline (titles are optional):

    - -
    ![alt text](/path/to/img.jpg "Title")
    -
    - -

    Reference-style:

    - -
    ![alt text][id]
    -
    -[id]: /path/to/img.jpg "Title"
    -
    - -

    Both of the above examples produce the same output:

    - -
    <img src="/path/to/img.jpg" alt="alt text" title="Title" />
    -
    - -

    Code

    - -

    In a regular paragraph, you can create code span by wrapping text in -backtick quotes. Any ampersands (&) and angle brackets (< or ->) will automatically be translated into HTML entities. This makes -it easy to use Markdown to write about HTML example code:

    - -
    I strongly recommend against using any `<blink>` tags.
    -
    -I wish SmartyPants used named entities like `&mdash;`
    -instead of decimal-encoded entites like `&#8212;`.
    -
    - -

    Output:

    - -
    <p>I strongly recommend against using any
    -<code>&lt;blink&gt;</code> tags.</p>
    -
    -<p>I wish SmartyPants used named entities like
    -<code>&amp;mdash;</code> instead of decimal-encoded
    -entites like <code>&amp;#8212;</code>.</p>
    -
    - -

    To specify an entire block of pre-formatted code, indent every line of -the block by 4 spaces or 1 tab. Just like with code spans, &, <, -and > characters will be escaped automatically.

    - -

    Markdown:

    - -
    If you want your page to validate under XHTML 1.0 Strict,
    -you've got to put paragraph tags in your blockquotes:
    -
    -    <blockquote>
    -        <p>For example.</p>
    -    </blockquote>
    -
    - -

    Output:

    - -
    <p>If you want your page to validate under XHTML 1.0 Strict,
    -you've got to put paragraph tags in your blockquotes:</p>
    -
    -<pre><code>&lt;blockquote&gt;
    -    &lt;p&gt;For example.&lt;/p&gt;
    -&lt;/blockquote&gt;
    -</code></pre>
    -
    diff --git a/test/MarkdownTest_1.0.3/Tests/Markdown Documentation - Basics.text b/test/MarkdownTest_1.0.3/Tests/Markdown Documentation - Basics.text deleted file mode 100644 index 486055c..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Markdown Documentation - Basics.text +++ /dev/null @@ -1,306 +0,0 @@ -Markdown: Basics -================ - - - - -Getting the Gist of Markdown's Formatting Syntax ------------------------------------------------- - -This page offers a brief overview of what it's like to use Markdown. -The [syntax page] [s] provides complete, detailed documentation for -every feature, but Markdown should be very easy to pick up simply by -looking at a few examples of it in action. The examples on this page -are written in a before/after style, showing example syntax and the -HTML output produced by Markdown. - -It's also helpful to simply try Markdown out; the [Dingus] [d] is a -web application that allows you type your own Markdown-formatted text -and translate it to XHTML. - -**Note:** This document is itself written using Markdown; you -can [see the source for it by adding '.text' to the URL] [src]. - - [s]: /projects/markdown/syntax "Markdown Syntax" - [d]: /projects/markdown/dingus "Markdown Dingus" - [src]: /projects/markdown/basics.text - - -## Paragraphs, Headers, Blockquotes ## - -A paragraph is simply one or more consecutive lines of text, separated -by one or more blank lines. (A blank line is any line that looks like a -blank line -- a line containing nothing spaces or tabs is considered -blank.) Normal paragraphs should not be intended with spaces or tabs. - -Markdown offers two styles of headers: *Setext* and *atx*. -Setext-style headers for `

    ` and `

    ` are created by -"underlining" with equal signs (`=`) and hyphens (`-`), respectively. -To create an atx-style header, you put 1-6 hash marks (`#`) at the -beginning of the line -- the number of hashes equals the resulting -HTML header level. - -Blockquotes are indicated using email-style '`>`' angle brackets. - -Markdown: - - A First Level Header - ==================== - - A Second Level Header - --------------------- - - Now is the time for all good men to come to - the aid of their country. This is just a - regular paragraph. - - The quick brown fox jumped over the lazy - dog's back. - - ### Header 3 - - > This is a blockquote. - > - > This is the second paragraph in the blockquote. - > - > ## This is an H2 in a blockquote - - -Output: - -

    A First Level Header

    - -

    A Second Level Header

    - -

    Now is the time for all good men to come to - the aid of their country. This is just a - regular paragraph.

    - -

    The quick brown fox jumped over the lazy - dog's back.

    - -

    Header 3

    - -
    -

    This is a blockquote.

    - -

    This is the second paragraph in the blockquote.

    - -

    This is an H2 in a blockquote

    -
    - - - -### Phrase Emphasis ### - -Markdown uses asterisks and underscores to indicate spans of emphasis. - -Markdown: - - Some of these words *are emphasized*. - Some of these words _are emphasized also_. - - Use two asterisks for **strong emphasis**. - Or, if you prefer, __use two underscores instead__. - -Output: - -

    Some of these words are emphasized. - Some of these words are emphasized also.

    - -

    Use two asterisks for strong emphasis. - Or, if you prefer, use two underscores instead.

    - - - -## Lists ## - -Unordered (bulleted) lists use asterisks, pluses, and hyphens (`*`, -`+`, and `-`) as list markers. These three markers are -interchangable; this: - - * Candy. - * Gum. - * Booze. - -this: - - + Candy. - + Gum. - + Booze. - -and this: - - - Candy. - - Gum. - - Booze. - -all produce the same output: - -
      -
    • Candy.
    • -
    • Gum.
    • -
    • Booze.
    • -
    - -Ordered (numbered) lists use regular numbers, followed by periods, as -list markers: - - 1. Red - 2. Green - 3. Blue - -Output: - -
      -
    1. Red
    2. -
    3. Green
    4. -
    5. Blue
    6. -
    - -If you put blank lines between items, you'll get `

    ` tags for the -list item text. You can create multi-paragraph list items by indenting -the paragraphs by 4 spaces or 1 tab: - - * A list item. - - With multiple paragraphs. - - * Another item in the list. - -Output: - -

      -
    • A list item.

      -

      With multiple paragraphs.

    • -
    • Another item in the list.

    • -
    - - - -### Links ### - -Markdown supports two styles for creating links: *inline* and -*reference*. With both styles, you use square brackets to delimit the -text you want to turn into a link. - -Inline-style links use parentheses immediately after the link text. -For example: - - This is an [example link](http://example.com/). - -Output: - -

    This is an - example link.

    - -Optionally, you may include a title attribute in the parentheses: - - This is an [example link](http://example.com/ "With a Title"). - -Output: - -

    This is an - example link.

    - -Reference-style links allow you to refer to your links by names, which -you define elsewhere in your document: - - I get 10 times more traffic from [Google][1] than from - [Yahoo][2] or [MSN][3]. - - [1]: http://google.com/ "Google" - [2]: http://search.yahoo.com/ "Yahoo Search" - [3]: http://search.msn.com/ "MSN Search" - -Output: - -

    I get 10 times more traffic from Google than from Yahoo or MSN.

    - -The title attribute is optional. Link names may contain letters, -numbers and spaces, but are *not* case sensitive: - - I start my morning with a cup of coffee and - [The New York Times][NY Times]. - - [ny times]: http://www.nytimes.com/ - -Output: - -

    I start my morning with a cup of coffee and - The New York Times.

    - - -### Images ### - -Image syntax is very much like link syntax. - -Inline (titles are optional): - - ![alt text](/path/to/img.jpg "Title") - -Reference-style: - - ![alt text][id] - - [id]: /path/to/img.jpg "Title" - -Both of the above examples produce the same output: - - alt text - - - -### Code ### - -In a regular paragraph, you can create code span by wrapping text in -backtick quotes. Any ampersands (`&`) and angle brackets (`<` or -`>`) will automatically be translated into HTML entities. This makes -it easy to use Markdown to write about HTML example code: - - I strongly recommend against using any `` tags. - - I wish SmartyPants used named entities like `—` - instead of decimal-encoded entites like `—`. - -Output: - -

    I strongly recommend against using any - <blink> tags.

    - -

    I wish SmartyPants used named entities like - &mdash; instead of decimal-encoded - entites like &#8212;.

    - - -To specify an entire block of pre-formatted code, indent every line of -the block by 4 spaces or 1 tab. Just like with code spans, `&`, `<`, -and `>` characters will be escaped automatically. - -Markdown: - - If you want your page to validate under XHTML 1.0 Strict, - you've got to put paragraph tags in your blockquotes: - -
    -

    For example.

    -
    - -Output: - -

    If you want your page to validate under XHTML 1.0 Strict, - you've got to put paragraph tags in your blockquotes:

    - -
    <blockquote>
    -        <p>For example.</p>
    -    </blockquote>
    -    
    diff --git a/test/MarkdownTest_1.0.3/Tests/Markdown Documentation - Syntax.html b/test/MarkdownTest_1.0.3/Tests/Markdown Documentation - Syntax.html deleted file mode 100644 index 5c01306..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Markdown Documentation - Syntax.html +++ /dev/null @@ -1,942 +0,0 @@ -

    Markdown: Syntax

    - - - - - -

    Note: This document is itself written using Markdown; you -can see the source for it by adding '.text' to the URL.

    - -
    - -

    Overview

    - -

    Philosophy

    - -

    Markdown is intended to be as easy-to-read and easy-to-write as is feasible.

    - -

    Readability, however, is emphasized above all else. A Markdown-formatted -document should be publishable as-is, as plain text, without looking -like it's been marked up with tags or formatting instructions. While -Markdown's syntax has been influenced by several existing text-to-HTML -filters -- including Setext, atx, Textile, reStructuredText, -Grutatext, and EtText -- the single biggest source of -inspiration for Markdown's syntax is the format of plain text email.

    - -

    To this end, Markdown's syntax is comprised entirely of punctuation -characters, which punctuation characters have been carefully chosen so -as to look like what they mean. E.g., asterisks around a word actually -look like *emphasis*. Markdown lists look like, well, lists. Even -blockquotes look like quoted passages of text, assuming you've ever -used email.

    - -

    Inline HTML

    - -

    Markdown's syntax is intended for one purpose: to be used as a -format for writing for the web.

    - -

    Markdown is not a replacement for HTML, or even close to it. Its -syntax is very small, corresponding only to a very small subset of -HTML tags. The idea is not to create a syntax that makes it easier -to insert HTML tags. In my opinion, HTML tags are already easy to -insert. The idea for Markdown is to make it easy to read, write, and -edit prose. HTML is a publishing format; Markdown is a writing -format. Thus, Markdown's formatting syntax only addresses issues that -can be conveyed in plain text.

    - -

    For any markup that is not covered by Markdown's syntax, you simply -use HTML itself. There's no need to preface it or delimit it to -indicate that you're switching from Markdown to HTML; you just use -the tags.

    - -

    The only restrictions are that block-level HTML elements -- e.g. <div>, -<table>, <pre>, <p>, etc. -- must be separated from surrounding -content by blank lines, and the start and end tags of the block should -not be indented with tabs or spaces. Markdown is smart enough not -to add extra (unwanted) <p> tags around HTML block-level tags.

    - -

    For example, to add an HTML table to a Markdown article:

    - -
    This is a regular paragraph.
    -
    -<table>
    -    <tr>
    -        <td>Foo</td>
    -    </tr>
    -</table>
    -
    -This is another regular paragraph.
    -
    - -

    Note that Markdown formatting syntax is not processed within block-level -HTML tags. E.g., you can't use Markdown-style *emphasis* inside an -HTML block.

    - -

    Span-level HTML tags -- e.g. <span>, <cite>, or <del> -- can be -used anywhere in a Markdown paragraph, list item, or header. If you -want, you can even use HTML tags instead of Markdown formatting; e.g. if -you'd prefer to use HTML <a> or <img> tags instead of Markdown's -link or image syntax, go right ahead.

    - -

    Unlike block-level HTML tags, Markdown syntax is processed within -span-level tags.

    - -

    Automatic Escaping for Special Characters

    - -

    In HTML, there are two characters that demand special treatment: < -and &. Left angle brackets are used to start tags; ampersands are -used to denote HTML entities. If you want to use them as literal -characters, you must escape them as entities, e.g. &lt;, and -&amp;.

    - -

    Ampersands in particular are bedeviling for web writers. If you want to -write about 'AT&T', you need to write 'AT&amp;T'. You even need to -escape ampersands within URLs. Thus, if you want to link to:

    - -
    http://images.google.com/images?num=30&q=larry+bird
    -
    - -

    you need to encode the URL as:

    - -
    http://images.google.com/images?num=30&amp;q=larry+bird
    -
    - -

    in your anchor tag href attribute. Needless to say, this is easy to -forget, and is probably the single most common source of HTML validation -errors in otherwise well-marked-up web sites.

    - -

    Markdown allows you to use these characters naturally, taking care of -all the necessary escaping for you. If you use an ampersand as part of -an HTML entity, it remains unchanged; otherwise it will be translated -into &amp;.

    - -

    So, if you want to include a copyright symbol in your article, you can write:

    - -
    &copy;
    -
    - -

    and Markdown will leave it alone. But if you write:

    - -
    AT&T
    -
    - -

    Markdown will translate it to:

    - -
    AT&amp;T
    -
    - -

    Similarly, because Markdown supports inline HTML, if you use -angle brackets as delimiters for HTML tags, Markdown will treat them as -such. But if you write:

    - -
    4 < 5
    -
    - -

    Markdown will translate it to:

    - -
    4 &lt; 5
    -
    - -

    However, inside Markdown code spans and blocks, angle brackets and -ampersands are always encoded automatically. This makes it easy to use -Markdown to write about HTML code. (As opposed to raw HTML, which is a -terrible format for writing about HTML syntax, because every single < -and & in your example code needs to be escaped.)

    - -
    - -

    Block Elements

    - -

    Paragraphs and Line Breaks

    - -

    A paragraph is simply one or more consecutive lines of text, separated -by one or more blank lines. (A blank line is any line that looks like a -blank line -- a line containing nothing but spaces or tabs is considered -blank.) Normal paragraphs should not be intended with spaces or tabs.

    - -

    The implication of the "one or more consecutive lines of text" rule is -that Markdown supports "hard-wrapped" text paragraphs. This differs -significantly from most other text-to-HTML formatters (including Movable -Type's "Convert Line Breaks" option) which translate every line break -character in a paragraph into a <br /> tag.

    - -

    When you do want to insert a <br /> break tag using Markdown, you -end a line with two or more spaces, then type return.

    - -

    Yes, this takes a tad more effort to create a <br />, but a simplistic -"every line break is a <br />" rule wouldn't work for Markdown. -Markdown's email-style blockquoting and multi-paragraph list items -work best -- and look better -- when you format them with hard breaks.

    - - - -

    Markdown supports two styles of headers, Setext and atx.

    - -

    Setext-style headers are "underlined" using equal signs (for first-level -headers) and dashes (for second-level headers). For example:

    - -
    This is an H1
    -=============
    -
    -This is an H2
    --------------
    -
    - -

    Any number of underlining ='s or -'s will work.

    - -

    Atx-style headers use 1-6 hash characters at the start of the line, -corresponding to header levels 1-6. For example:

    - -
    # This is an H1
    -
    -## This is an H2
    -
    -###### This is an H6
    -
    - -

    Optionally, you may "close" atx-style headers. This is purely -cosmetic -- you can use this if you think it looks better. The -closing hashes don't even need to match the number of hashes -used to open the header. (The number of opening hashes -determines the header level.) :

    - -
    # This is an H1 #
    -
    -## This is an H2 ##
    -
    -### This is an H3 ######
    -
    - -

    Blockquotes

    - -

    Markdown uses email-style > characters for blockquoting. If you're -familiar with quoting passages of text in an email message, then you -know how to create a blockquote in Markdown. It looks best if you hard -wrap the text and put a > before every line:

    - -
    > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
    -> consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
    -> Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
    -> 
    -> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
    -> id sem consectetuer libero luctus adipiscing.
    -
    - -

    Markdown allows you to be lazy and only put the > before the first -line of a hard-wrapped paragraph:

    - -
    > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
    -consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
    -Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
    -
    -> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
    -id sem consectetuer libero luctus adipiscing.
    -
    - -

    Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by -adding additional levels of >:

    - -
    > This is the first level of quoting.
    ->
    -> > This is nested blockquote.
    ->
    -> Back to the first level.
    -
    - -

    Blockquotes can contain other Markdown elements, including headers, lists, -and code blocks:

    - -
    > ## This is a header.
    -> 
    -> 1.   This is the first list item.
    -> 2.   This is the second list item.
    -> 
    -> Here's some example code:
    -> 
    ->     return shell_exec("echo $input | $markdown_script");
    -
    - -

    Any decent text editor should make email-style quoting easy. For -example, with BBEdit, you can make a selection and choose Increase -Quote Level from the Text menu.

    - -

    Lists

    - -

    Markdown supports ordered (numbered) and unordered (bulleted) lists.

    - -

    Unordered lists use asterisks, pluses, and hyphens -- interchangably --- as list markers:

    - -
    *   Red
    -*   Green
    -*   Blue
    -
    - -

    is equivalent to:

    - -
    +   Red
    -+   Green
    -+   Blue
    -
    - -

    and:

    - -
    -   Red
    --   Green
    --   Blue
    -
    - -

    Ordered lists use numbers followed by periods:

    - -
    1.  Bird
    -2.  McHale
    -3.  Parish
    -
    - -

    It's important to note that the actual numbers you use to mark the -list have no effect on the HTML output Markdown produces. The HTML -Markdown produces from the above list is:

    - -
    <ol>
    -<li>Bird</li>
    -<li>McHale</li>
    -<li>Parish</li>
    -</ol>
    -
    - -

    If you instead wrote the list in Markdown like this:

    - -
    1.  Bird
    -1.  McHale
    -1.  Parish
    -
    - -

    or even:

    - -
    3. Bird
    -1. McHale
    -8. Parish
    -
    - -

    you'd get the exact same HTML output. The point is, if you want to, -you can use ordinal numbers in your ordered Markdown lists, so that -the numbers in your source match the numbers in your published HTML. -But if you want to be lazy, you don't have to.

    - -

    If you do use lazy list numbering, however, you should still start the -list with the number 1. At some point in the future, Markdown may support -starting ordered lists at an arbitrary number.

    - -

    List markers typically start at the left margin, but may be indented by -up to three spaces. List markers must be followed by one or more spaces -or a tab.

    - -

    To make lists look nice, you can wrap items with hanging indents:

    - -
    *   Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
    -    Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
    -    viverra nec, fringilla in, laoreet vitae, risus.
    -*   Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
    -    Suspendisse id sem consectetuer libero luctus adipiscing.
    -
    - -

    But if you want to be lazy, you don't have to:

    - -
    *   Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
    -Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
    -viverra nec, fringilla in, laoreet vitae, risus.
    -*   Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
    -Suspendisse id sem consectetuer libero luctus adipiscing.
    -
    - -

    If list items are separated by blank lines, Markdown will wrap the -items in <p> tags in the HTML output. For example, this input:

    - -
    *   Bird
    -*   Magic
    -
    - -

    will turn into:

    - -
    <ul>
    -<li>Bird</li>
    -<li>Magic</li>
    -</ul>
    -
    - -

    But this:

    - -
    *   Bird
    -
    -*   Magic
    -
    - -

    will turn into:

    - -
    <ul>
    -<li><p>Bird</p></li>
    -<li><p>Magic</p></li>
    -</ul>
    -
    - -

    List items may consist of multiple paragraphs. Each subsequent -paragraph in a list item must be intended by either 4 spaces -or one tab:

    - -
    1.  This is a list item with two paragraphs. Lorem ipsum dolor
    -    sit amet, consectetuer adipiscing elit. Aliquam hendrerit
    -    mi posuere lectus.
    -
    -    Vestibulum enim wisi, viverra nec, fringilla in, laoreet
    -    vitae, risus. Donec sit amet nisl. Aliquam semper ipsum
    -    sit amet velit.
    -
    -2.  Suspendisse id sem consectetuer libero luctus adipiscing.
    -
    - -

    It looks nice if you indent every line of the subsequent -paragraphs, but here again, Markdown will allow you to be -lazy:

    - -
    *   This is a list item with two paragraphs.
    -
    -    This is the second paragraph in the list item. You're
    -only required to indent the first line. Lorem ipsum dolor
    -sit amet, consectetuer adipiscing elit.
    -
    -*   Another item in the same list.
    -
    - -

    To put a blockquote within a list item, the blockquote's > -delimiters need to be indented:

    - -
    *   A list item with a blockquote:
    -
    -    > This is a blockquote
    -    > inside a list item.
    -
    - -

    To put a code block within a list item, the code block needs -to be indented twice -- 8 spaces or two tabs:

    - -
    *   A list item with a code block:
    -
    -        <code goes here>
    -
    - -

    It's worth noting that it's possible to trigger an ordered list by -accident, by writing something like this:

    - -
    1986. What a great season.
    -
    - -

    In other words, a number-period-space sequence at the beginning of a -line. To avoid this, you can backslash-escape the period:

    - -
    1986\. What a great season.
    -
    - -

    Code Blocks

    - -

    Pre-formatted code blocks are used for writing about programming or -markup source code. Rather than forming normal paragraphs, the lines -of a code block are interpreted literally. Markdown wraps a code block -in both <pre> and <code> tags.

    - -

    To produce a code block in Markdown, simply indent every line of the -block by at least 4 spaces or 1 tab. For example, given this input:

    - -
    This is a normal paragraph:
    -
    -    This is a code block.
    -
    - -

    Markdown will generate:

    - -
    <p>This is a normal paragraph:</p>
    -
    -<pre><code>This is a code block.
    -</code></pre>
    -
    - -

    One level of indentation -- 4 spaces or 1 tab -- is removed from each -line of the code block. For example, this:

    - -
    Here is an example of AppleScript:
    -
    -    tell application "Foo"
    -        beep
    -    end tell
    -
    - -

    will turn into:

    - -
    <p>Here is an example of AppleScript:</p>
    -
    -<pre><code>tell application "Foo"
    -    beep
    -end tell
    -</code></pre>
    -
    - -

    A code block continues until it reaches a line that is not indented -(or the end of the article).

    - -

    Within a code block, ampersands (&) and angle brackets (< and >) -are automatically converted into HTML entities. This makes it very -easy to include example HTML source code using Markdown -- just paste -it and indent it, and Markdown will handle the hassle of encoding the -ampersands and angle brackets. For example, this:

    - -
        <div class="footer">
    -        &copy; 2004 Foo Corporation
    -    </div>
    -
    - -

    will turn into:

    - -
    <pre><code>&lt;div class="footer"&gt;
    -    &amp;copy; 2004 Foo Corporation
    -&lt;/div&gt;
    -</code></pre>
    -
    - -

    Regular Markdown syntax is not processed within code blocks. E.g., -asterisks are just literal asterisks within a code block. This means -it's also easy to use Markdown to write about Markdown's own syntax.

    - -

    Horizontal Rules

    - -

    You can produce a horizontal rule tag (<hr />) by placing three or -more hyphens, asterisks, or underscores on a line by themselves. If you -wish, you may use spaces between the hyphens or asterisks. Each of the -following lines will produce a horizontal rule:

    - -
    * * *
    -
    -***
    -
    -*****
    -
    -- - -
    -
    ----------------------------------------
    -
    -_ _ _
    -
    - -
    - -

    Span Elements

    - - - -

    Markdown supports two style of links: inline and reference.

    - -

    In both styles, the link text is delimited by [square brackets].

    - -

    To create an inline link, use a set of regular parentheses immediately -after the link text's closing square bracket. Inside the parentheses, -put the URL where you want the link to point, along with an optional -title for the link, surrounded in quotes. For example:

    - -
    This is [an example](http://example.com/ "Title") inline link.
    -
    -[This link](http://example.net/) has no title attribute.
    -
    - -

    Will produce:

    - -
    <p>This is <a href="http://example.com/" title="Title">
    -an example</a> inline link.</p>
    -
    -<p><a href="http://example.net/">This link</a> has no
    -title attribute.</p>
    -
    - -

    If you're referring to a local resource on the same server, you can -use relative paths:

    - -
    See my [About](/about/) page for details.
    -
    - -

    Reference-style links use a second set of square brackets, inside -which you place a label of your choosing to identify the link:

    - -
    This is [an example][id] reference-style link.
    -
    - -

    You can optionally use a space to separate the sets of brackets:

    - -
    This is [an example] [id] reference-style link.
    -
    - -

    Then, anywhere in the document, you define your link label like this, -on a line by itself:

    - -
    [id]: http://example.com/  "Optional Title Here"
    -
    - -

    That is:

    - -
      -
    • Square brackets containing the link identifier (optionally -indented from the left margin using up to three spaces);
    • -
    • followed by a colon;
    • -
    • followed by one or more spaces (or tabs);
    • -
    • followed by the URL for the link;
    • -
    • optionally followed by a title attribute for the link, enclosed -in double or single quotes.
    • -
    - -

    The link URL may, optionally, be surrounded by angle brackets:

    - -
    [id]: <http://example.com/>  "Optional Title Here"
    -
    - -

    You can put the title attribute on the next line and use extra spaces -or tabs for padding, which tends to look better with longer URLs:

    - -
    [id]: http://example.com/longish/path/to/resource/here
    -    "Optional Title Here"
    -
    - -

    Link definitions are only used for creating links during Markdown -processing, and are stripped from your document in the HTML output.

    - -

    Link definition names may constist of letters, numbers, spaces, and punctuation -- but they are not case sensitive. E.g. these two links:

    - -
    [link text][a]
    -[link text][A]
    -
    - -

    are equivalent.

    - -

    The implicit link name shortcut allows you to omit the name of the -link, in which case the link text itself is used as the name. -Just use an empty set of square brackets -- e.g., to link the word -"Google" to the google.com web site, you could simply write:

    - -
    [Google][]
    -
    - -

    And then define the link:

    - -
    [Google]: http://google.com/
    -
    - -

    Because link names may contain spaces, this shortcut even works for -multiple words in the link text:

    - -
    Visit [Daring Fireball][] for more information.
    -
    - -

    And then define the link:

    - -
    [Daring Fireball]: http://daringfireball.net/
    -
    - -

    Link definitions can be placed anywhere in your Markdown document. I -tend to put them immediately after each paragraph in which they're -used, but if you want, you can put them all at the end of your -document, sort of like footnotes.

    - -

    Here's an example of reference links in action:

    - -
    I get 10 times more traffic from [Google] [1] than from
    -[Yahoo] [2] or [MSN] [3].
    -
    -  [1]: http://google.com/        "Google"
    -  [2]: http://search.yahoo.com/  "Yahoo Search"
    -  [3]: http://search.msn.com/    "MSN Search"
    -
    - -

    Using the implicit link name shortcut, you could instead write:

    - -
    I get 10 times more traffic from [Google][] than from
    -[Yahoo][] or [MSN][].
    -
    -  [google]: http://google.com/        "Google"
    -  [yahoo]:  http://search.yahoo.com/  "Yahoo Search"
    -  [msn]:    http://search.msn.com/    "MSN Search"
    -
    - -

    Both of the above examples will produce the following HTML output:

    - -
    <p>I get 10 times more traffic from <a href="http://google.com/"
    -title="Google">Google</a> than from
    -<a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a>
    -or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p>
    -
    - -

    For comparison, here is the same paragraph written using -Markdown's inline link style:

    - -
    I get 10 times more traffic from [Google](http://google.com/ "Google")
    -than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or
    -[MSN](http://search.msn.com/ "MSN Search").
    -
    - -

    The point of reference-style links is not that they're easier to -write. The point is that with reference-style links, your document -source is vastly more readable. Compare the above examples: using -reference-style links, the paragraph itself is only 81 characters -long; with inline-style links, it's 176 characters; and as raw HTML, -it's 234 characters. In the raw HTML, there's more markup than there -is text.

    - -

    With Markdown's reference-style links, a source document much more -closely resembles the final output, as rendered in a browser. By -allowing you to move the markup-related metadata out of the paragraph, -you can add links without interrupting the narrative flow of your -prose.

    - -

    Emphasis

    - -

    Markdown treats asterisks (*) and underscores (_) as indicators of -emphasis. Text wrapped with one * or _ will be wrapped with an -HTML <em> tag; double *'s or _'s will be wrapped with an HTML -<strong> tag. E.g., this input:

    - -
    *single asterisks*
    -
    -_single underscores_
    -
    -**double asterisks**
    -
    -__double underscores__
    -
    - -

    will produce:

    - -
    <em>single asterisks</em>
    -
    -<em>single underscores</em>
    -
    -<strong>double asterisks</strong>
    -
    -<strong>double underscores</strong>
    -
    - -

    You can use whichever style you prefer; the lone restriction is that -the same character must be used to open and close an emphasis span.

    - -

    Emphasis can be used in the middle of a word:

    - -
    un*fucking*believable
    -
    - -

    But if you surround an * or _ with spaces, it'll be treated as a -literal asterisk or underscore.

    - -

    To produce a literal asterisk or underscore at a position where it -would otherwise be used as an emphasis delimiter, you can backslash -escape it:

    - -
    \*this text is surrounded by literal asterisks\*
    -
    - -

    Code

    - -

    To indicate a span of code, wrap it with backtick quotes (`). -Unlike a pre-formatted code block, a code span indicates code within a -normal paragraph. For example:

    - -
    Use the `printf()` function.
    -
    - -

    will produce:

    - -
    <p>Use the <code>printf()</code> function.</p>
    -
    - -

    To include a literal backtick character within a code span, you can use -multiple backticks as the opening and closing delimiters:

    - -
    ``There is a literal backtick (`) here.``
    -
    - -

    which will produce this:

    - -
    <p><code>There is a literal backtick (`) here.</code></p>
    -
    - -

    The backtick delimiters surrounding a code span may include spaces -- -one after the opening, one before the closing. This allows you to place -literal backtick characters at the beginning or end of a code span:

    - -
    A single backtick in a code span: `` ` ``
    -
    -A backtick-delimited string in a code span: `` `foo` ``
    -
    - -

    will produce:

    - -
    <p>A single backtick in a code span: <code>`</code></p>
    -
    -<p>A backtick-delimited string in a code span: <code>`foo`</code></p>
    -
    - -

    With a code span, ampersands and angle brackets are encoded as HTML -entities automatically, which makes it easy to include example HTML -tags. Markdown will turn this:

    - -
    Please don't use any `<blink>` tags.
    -
    - -

    into:

    - -
    <p>Please don't use any <code>&lt;blink&gt;</code> tags.</p>
    -
    - -

    You can write this:

    - -
    `&#8212;` is the decimal-encoded equivalent of `&mdash;`.
    -
    - -

    to produce:

    - -
    <p><code>&amp;#8212;</code> is the decimal-encoded
    -equivalent of <code>&amp;mdash;</code>.</p>
    -
    - -

    Images

    - -

    Admittedly, it's fairly difficult to devise a "natural" syntax for -placing images into a plain text document format.

    - -

    Markdown uses an image syntax that is intended to resemble the syntax -for links, allowing for two styles: inline and reference.

    - -

    Inline image syntax looks like this:

    - -
    ![Alt text](/path/to/img.jpg)
    -
    -![Alt text](/path/to/img.jpg "Optional title")
    -
    - -

    That is:

    - -
      -
    • An exclamation mark: !;
    • -
    • followed by a set of square brackets, containing the alt -attribute text for the image;
    • -
    • followed by a set of parentheses, containing the URL or path to -the image, and an optional title attribute enclosed in double -or single quotes.
    • -
    - -

    Reference-style image syntax looks like this:

    - -
    ![Alt text][id]
    -
    - -

    Where "id" is the name of a defined image reference. Image references -are defined using syntax identical to link references:

    - -
    [id]: url/to/image  "Optional title attribute"
    -
    - -

    As of this writing, Markdown has no syntax for specifying the -dimensions of an image; if this is important to you, you can simply -use regular HTML <img> tags.

    - -
    - -

    Miscellaneous

    - - - -

    Markdown supports a shortcut style for creating "automatic" links for URLs and email addresses: simply surround the URL or email address with angle brackets. What this means is that if you want to show the actual text of a URL or email address, and also have it be a clickable link, you can do this:

    - -
    <http://example.com/>
    -
    - -

    Markdown will turn this into:

    - -
    <a href="http://example.com/">http://example.com/</a>
    -
    - -

    Automatic links for email addresses work similarly, except that -Markdown will also perform a bit of randomized decimal and hex -entity-encoding to help obscure your address from address-harvesting -spambots. For example, Markdown will turn this:

    - -
    <address@example.com>
    -
    - -

    into something like this:

    - -
    <a href="&#x6D;&#x61;i&#x6C;&#x74;&#x6F;:&#x61;&#x64;&#x64;&#x72;&#x65;
    -&#115;&#115;&#64;&#101;&#120;&#x61;&#109;&#x70;&#x6C;e&#x2E;&#99;&#111;
    -&#109;">&#x61;&#x64;&#x64;&#x72;&#x65;&#115;&#115;&#64;&#101;&#120;&#x61;
    -&#109;&#x70;&#x6C;e&#x2E;&#99;&#111;&#109;</a>
    -
    - -

    which will render in a browser as a clickable link to "address@example.com".

    - -

    (This sort of entity-encoding trick will indeed fool many, if not -most, address-harvesting bots, but it definitely won't fool all of -them. It's better than nothing, but an address published in this way -will probably eventually start receiving spam.)

    - -

    Backslash Escapes

    - -

    Markdown allows you to use backslash escapes to generate literal -characters which would otherwise have special meaning in Markdown's -formatting syntax. For example, if you wanted to surround a word with -literal asterisks (instead of an HTML <em> tag), you can backslashes -before the asterisks, like this:

    - -
    \*literal asterisks\*
    -
    - -

    Markdown provides backslash escapes for the following characters:

    - -
    \   backslash
    -`   backtick
    -*   asterisk
    -_   underscore
    -{}  curly braces
    -[]  square brackets
    -()  parentheses
    -#   hash mark
    -+   plus sign
    --   minus sign (hyphen)
    -.   dot
    -!   exclamation mark
    -
    diff --git a/test/MarkdownTest_1.0.3/Tests/Markdown Documentation - Syntax.text b/test/MarkdownTest_1.0.3/Tests/Markdown Documentation - Syntax.text deleted file mode 100644 index 57360a1..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Markdown Documentation - Syntax.text +++ /dev/null @@ -1,888 +0,0 @@ -Markdown: Syntax -================ - - - - -* [Overview](#overview) - * [Philosophy](#philosophy) - * [Inline HTML](#html) - * [Automatic Escaping for Special Characters](#autoescape) -* [Block Elements](#block) - * [Paragraphs and Line Breaks](#p) - * [Headers](#header) - * [Blockquotes](#blockquote) - * [Lists](#list) - * [Code Blocks](#precode) - * [Horizontal Rules](#hr) -* [Span Elements](#span) - * [Links](#link) - * [Emphasis](#em) - * [Code](#code) - * [Images](#img) -* [Miscellaneous](#misc) - * [Backslash Escapes](#backslash) - * [Automatic Links](#autolink) - - -**Note:** This document is itself written using Markdown; you -can [see the source for it by adding '.text' to the URL][src]. - - [src]: /projects/markdown/syntax.text - -* * * - -

    Overview

    - -

    Philosophy

    - -Markdown is intended to be as easy-to-read and easy-to-write as is feasible. - -Readability, however, is emphasized above all else. A Markdown-formatted -document should be publishable as-is, as plain text, without looking -like it's been marked up with tags or formatting instructions. While -Markdown's syntax has been influenced by several existing text-to-HTML -filters -- including [Setext] [1], [atx] [2], [Textile] [3], [reStructuredText] [4], -[Grutatext] [5], and [EtText] [6] -- the single biggest source of -inspiration for Markdown's syntax is the format of plain text email. - - [1]: http://docutils.sourceforge.net/mirror/setext.html - [2]: http://www.aaronsw.com/2002/atx/ - [3]: http://textism.com/tools/textile/ - [4]: http://docutils.sourceforge.net/rst.html - [5]: http://www.triptico.com/software/grutatxt.html - [6]: http://ettext.taint.org/doc/ - -To this end, Markdown's syntax is comprised entirely of punctuation -characters, which punctuation characters have been carefully chosen so -as to look like what they mean. E.g., asterisks around a word actually -look like \*emphasis\*. Markdown lists look like, well, lists. Even -blockquotes look like quoted passages of text, assuming you've ever -used email. - - - -

    Inline HTML

    - -Markdown's syntax is intended for one purpose: to be used as a -format for *writing* for the web. - -Markdown is not a replacement for HTML, or even close to it. Its -syntax is very small, corresponding only to a very small subset of -HTML tags. The idea is *not* to create a syntax that makes it easier -to insert HTML tags. In my opinion, HTML tags are already easy to -insert. The idea for Markdown is to make it easy to read, write, and -edit prose. HTML is a *publishing* format; Markdown is a *writing* -format. Thus, Markdown's formatting syntax only addresses issues that -can be conveyed in plain text. - -For any markup that is not covered by Markdown's syntax, you simply -use HTML itself. There's no need to preface it or delimit it to -indicate that you're switching from Markdown to HTML; you just use -the tags. - -The only restrictions are that block-level HTML elements -- e.g. `
    `, -``, `
    `, `

    `, etc. -- must be separated from surrounding -content by blank lines, and the start and end tags of the block should -not be indented with tabs or spaces. Markdown is smart enough not -to add extra (unwanted) `

    ` tags around HTML block-level tags. - -For example, to add an HTML table to a Markdown article: - - This is a regular paragraph. - -

    - - - -
    Foo
    - - This is another regular paragraph. - -Note that Markdown formatting syntax is not processed within block-level -HTML tags. E.g., you can't use Markdown-style `*emphasis*` inside an -HTML block. - -Span-level HTML tags -- e.g. ``, ``, or `` -- can be -used anywhere in a Markdown paragraph, list item, or header. If you -want, you can even use HTML tags instead of Markdown formatting; e.g. if -you'd prefer to use HTML `` or `` tags instead of Markdown's -link or image syntax, go right ahead. - -Unlike block-level HTML tags, Markdown syntax *is* processed within -span-level tags. - - -

    Automatic Escaping for Special Characters

    - -In HTML, there are two characters that demand special treatment: `<` -and `&`. Left angle brackets are used to start tags; ampersands are -used to denote HTML entities. If you want to use them as literal -characters, you must escape them as entities, e.g. `<`, and -`&`. - -Ampersands in particular are bedeviling for web writers. If you want to -write about 'AT&T', you need to write '`AT&T`'. You even need to -escape ampersands within URLs. Thus, if you want to link to: - - http://images.google.com/images?num=30&q=larry+bird - -you need to encode the URL as: - - http://images.google.com/images?num=30&q=larry+bird - -in your anchor tag `href` attribute. Needless to say, this is easy to -forget, and is probably the single most common source of HTML validation -errors in otherwise well-marked-up web sites. - -Markdown allows you to use these characters naturally, taking care of -all the necessary escaping for you. If you use an ampersand as part of -an HTML entity, it remains unchanged; otherwise it will be translated -into `&`. - -So, if you want to include a copyright symbol in your article, you can write: - - © - -and Markdown will leave it alone. But if you write: - - AT&T - -Markdown will translate it to: - - AT&T - -Similarly, because Markdown supports [inline HTML](#html), if you use -angle brackets as delimiters for HTML tags, Markdown will treat them as -such. But if you write: - - 4 < 5 - -Markdown will translate it to: - - 4 < 5 - -However, inside Markdown code spans and blocks, angle brackets and -ampersands are *always* encoded automatically. This makes it easy to use -Markdown to write about HTML code. (As opposed to raw HTML, which is a -terrible format for writing about HTML syntax, because every single `<` -and `&` in your example code needs to be escaped.) - - -* * * - - -

    Block Elements

    - - -

    Paragraphs and Line Breaks

    - -A paragraph is simply one or more consecutive lines of text, separated -by one or more blank lines. (A blank line is any line that looks like a -blank line -- a line containing nothing but spaces or tabs is considered -blank.) Normal paragraphs should not be intended with spaces or tabs. - -The implication of the "one or more consecutive lines of text" rule is -that Markdown supports "hard-wrapped" text paragraphs. This differs -significantly from most other text-to-HTML formatters (including Movable -Type's "Convert Line Breaks" option) which translate every line break -character in a paragraph into a `
    ` tag. - -When you *do* want to insert a `
    ` break tag using Markdown, you -end a line with two or more spaces, then type return. - -Yes, this takes a tad more effort to create a `
    `, but a simplistic -"every line break is a `
    `" rule wouldn't work for Markdown. -Markdown's email-style [blockquoting][bq] and multi-paragraph [list items][l] -work best -- and look better -- when you format them with hard breaks. - - [bq]: #blockquote - [l]: #list - - - - - -Markdown supports two styles of headers, [Setext] [1] and [atx] [2]. - -Setext-style headers are "underlined" using equal signs (for first-level -headers) and dashes (for second-level headers). For example: - - This is an H1 - ============= - - This is an H2 - ------------- - -Any number of underlining `=`'s or `-`'s will work. - -Atx-style headers use 1-6 hash characters at the start of the line, -corresponding to header levels 1-6. For example: - - # This is an H1 - - ## This is an H2 - - ###### This is an H6 - -Optionally, you may "close" atx-style headers. This is purely -cosmetic -- you can use this if you think it looks better. The -closing hashes don't even need to match the number of hashes -used to open the header. (The number of opening hashes -determines the header level.) : - - # This is an H1 # - - ## This is an H2 ## - - ### This is an H3 ###### - - -

    Blockquotes

    - -Markdown uses email-style `>` characters for blockquoting. If you're -familiar with quoting passages of text in an email message, then you -know how to create a blockquote in Markdown. It looks best if you hard -wrap the text and put a `>` before every line: - - > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, - > consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. - > Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. - > - > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse - > id sem consectetuer libero luctus adipiscing. - -Markdown allows you to be lazy and only put the `>` before the first -line of a hard-wrapped paragraph: - - > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, - consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. - Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. - - > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse - id sem consectetuer libero luctus adipiscing. - -Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by -adding additional levels of `>`: - - > This is the first level of quoting. - > - > > This is nested blockquote. - > - > Back to the first level. - -Blockquotes can contain other Markdown elements, including headers, lists, -and code blocks: - - > ## This is a header. - > - > 1. This is the first list item. - > 2. This is the second list item. - > - > Here's some example code: - > - > return shell_exec("echo $input | $markdown_script"); - -Any decent text editor should make email-style quoting easy. For -example, with BBEdit, you can make a selection and choose Increase -Quote Level from the Text menu. - - -

    Lists

    - -Markdown supports ordered (numbered) and unordered (bulleted) lists. - -Unordered lists use asterisks, pluses, and hyphens -- interchangably --- as list markers: - - * Red - * Green - * Blue - -is equivalent to: - - + Red - + Green - + Blue - -and: - - - Red - - Green - - Blue - -Ordered lists use numbers followed by periods: - - 1. Bird - 2. McHale - 3. Parish - -It's important to note that the actual numbers you use to mark the -list have no effect on the HTML output Markdown produces. The HTML -Markdown produces from the above list is: - -
      -
    1. Bird
    2. -
    3. McHale
    4. -
    5. Parish
    6. -
    - -If you instead wrote the list in Markdown like this: - - 1. Bird - 1. McHale - 1. Parish - -or even: - - 3. Bird - 1. McHale - 8. Parish - -you'd get the exact same HTML output. The point is, if you want to, -you can use ordinal numbers in your ordered Markdown lists, so that -the numbers in your source match the numbers in your published HTML. -But if you want to be lazy, you don't have to. - -If you do use lazy list numbering, however, you should still start the -list with the number 1. At some point in the future, Markdown may support -starting ordered lists at an arbitrary number. - -List markers typically start at the left margin, but may be indented by -up to three spaces. List markers must be followed by one or more spaces -or a tab. - -To make lists look nice, you can wrap items with hanging indents: - - * Lorem ipsum dolor sit amet, consectetuer adipiscing elit. - Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, - viverra nec, fringilla in, laoreet vitae, risus. - * Donec sit amet nisl. Aliquam semper ipsum sit amet velit. - Suspendisse id sem consectetuer libero luctus adipiscing. - -But if you want to be lazy, you don't have to: - - * Lorem ipsum dolor sit amet, consectetuer adipiscing elit. - Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, - viverra nec, fringilla in, laoreet vitae, risus. - * Donec sit amet nisl. Aliquam semper ipsum sit amet velit. - Suspendisse id sem consectetuer libero luctus adipiscing. - -If list items are separated by blank lines, Markdown will wrap the -items in `

    ` tags in the HTML output. For example, this input: - - * Bird - * Magic - -will turn into: - -

      -
    • Bird
    • -
    • Magic
    • -
    - -But this: - - * Bird - - * Magic - -will turn into: - -
      -
    • Bird

    • -
    • Magic

    • -
    - -List items may consist of multiple paragraphs. Each subsequent -paragraph in a list item must be intended by either 4 spaces -or one tab: - - 1. This is a list item with two paragraphs. Lorem ipsum dolor - sit amet, consectetuer adipiscing elit. Aliquam hendrerit - mi posuere lectus. - - Vestibulum enim wisi, viverra nec, fringilla in, laoreet - vitae, risus. Donec sit amet nisl. Aliquam semper ipsum - sit amet velit. - - 2. Suspendisse id sem consectetuer libero luctus adipiscing. - -It looks nice if you indent every line of the subsequent -paragraphs, but here again, Markdown will allow you to be -lazy: - - * This is a list item with two paragraphs. - - This is the second paragraph in the list item. You're - only required to indent the first line. Lorem ipsum dolor - sit amet, consectetuer adipiscing elit. - - * Another item in the same list. - -To put a blockquote within a list item, the blockquote's `>` -delimiters need to be indented: - - * A list item with a blockquote: - - > This is a blockquote - > inside a list item. - -To put a code block within a list item, the code block needs -to be indented *twice* -- 8 spaces or two tabs: - - * A list item with a code block: - - - - -It's worth noting that it's possible to trigger an ordered list by -accident, by writing something like this: - - 1986. What a great season. - -In other words, a *number-period-space* sequence at the beginning of a -line. To avoid this, you can backslash-escape the period: - - 1986\. What a great season. - - - -

    Code Blocks

    - -Pre-formatted code blocks are used for writing about programming or -markup source code. Rather than forming normal paragraphs, the lines -of a code block are interpreted literally. Markdown wraps a code block -in both `
    ` and `` tags.
    -
    -To produce a code block in Markdown, simply indent every line of the
    -block by at least 4 spaces or 1 tab. For example, given this input:
    -
    -    This is a normal paragraph:
    -
    -        This is a code block.
    -
    -Markdown will generate:
    -
    -    

    This is a normal paragraph:

    - -
    This is a code block.
    -    
    - -One level of indentation -- 4 spaces or 1 tab -- is removed from each -line of the code block. For example, this: - - Here is an example of AppleScript: - - tell application "Foo" - beep - end tell - -will turn into: - -

    Here is an example of AppleScript:

    - -
    tell application "Foo"
    -        beep
    -    end tell
    -    
    - -A code block continues until it reaches a line that is not indented -(or the end of the article). - -Within a code block, ampersands (`&`) and angle brackets (`<` and `>`) -are automatically converted into HTML entities. This makes it very -easy to include example HTML source code using Markdown -- just paste -it and indent it, and Markdown will handle the hassle of encoding the -ampersands and angle brackets. For example, this: - - - -will turn into: - -
    <div class="footer">
    -        &copy; 2004 Foo Corporation
    -    </div>
    -    
    - -Regular Markdown syntax is not processed within code blocks. E.g., -asterisks are just literal asterisks within a code block. This means -it's also easy to use Markdown to write about Markdown's own syntax. - - - -

    Horizontal Rules

    - -You can produce a horizontal rule tag (`
    `) by placing three or -more hyphens, asterisks, or underscores on a line by themselves. If you -wish, you may use spaces between the hyphens or asterisks. Each of the -following lines will produce a horizontal rule: - - * * * - - *** - - ***** - - - - - - - --------------------------------------- - - _ _ _ - - -* * * - -

    Span Elements

    - - - -Markdown supports two style of links: *inline* and *reference*. - -In both styles, the link text is delimited by [square brackets]. - -To create an inline link, use a set of regular parentheses immediately -after the link text's closing square bracket. Inside the parentheses, -put the URL where you want the link to point, along with an *optional* -title for the link, surrounded in quotes. For example: - - This is [an example](http://example.com/ "Title") inline link. - - [This link](http://example.net/) has no title attribute. - -Will produce: - -

    This is - an example inline link.

    - -

    This link has no - title attribute.

    - -If you're referring to a local resource on the same server, you can -use relative paths: - - See my [About](/about/) page for details. - -Reference-style links use a second set of square brackets, inside -which you place a label of your choosing to identify the link: - - This is [an example][id] reference-style link. - -You can optionally use a space to separate the sets of brackets: - - This is [an example] [id] reference-style link. - -Then, anywhere in the document, you define your link label like this, -on a line by itself: - - [id]: http://example.com/ "Optional Title Here" - -That is: - -* Square brackets containing the link identifier (optionally - indented from the left margin using up to three spaces); -* followed by a colon; -* followed by one or more spaces (or tabs); -* followed by the URL for the link; -* optionally followed by a title attribute for the link, enclosed - in double or single quotes. - -The link URL may, optionally, be surrounded by angle brackets: - - [id]: "Optional Title Here" - -You can put the title attribute on the next line and use extra spaces -or tabs for padding, which tends to look better with longer URLs: - - [id]: http://example.com/longish/path/to/resource/here - "Optional Title Here" - -Link definitions are only used for creating links during Markdown -processing, and are stripped from your document in the HTML output. - -Link definition names may constist of letters, numbers, spaces, and punctuation -- but they are *not* case sensitive. E.g. these two links: - - [link text][a] - [link text][A] - -are equivalent. - -The *implicit link name* shortcut allows you to omit the name of the -link, in which case the link text itself is used as the name. -Just use an empty set of square brackets -- e.g., to link the word -"Google" to the google.com web site, you could simply write: - - [Google][] - -And then define the link: - - [Google]: http://google.com/ - -Because link names may contain spaces, this shortcut even works for -multiple words in the link text: - - Visit [Daring Fireball][] for more information. - -And then define the link: - - [Daring Fireball]: http://daringfireball.net/ - -Link definitions can be placed anywhere in your Markdown document. I -tend to put them immediately after each paragraph in which they're -used, but if you want, you can put them all at the end of your -document, sort of like footnotes. - -Here's an example of reference links in action: - - I get 10 times more traffic from [Google] [1] than from - [Yahoo] [2] or [MSN] [3]. - - [1]: http://google.com/ "Google" - [2]: http://search.yahoo.com/ "Yahoo Search" - [3]: http://search.msn.com/ "MSN Search" - -Using the implicit link name shortcut, you could instead write: - - I get 10 times more traffic from [Google][] than from - [Yahoo][] or [MSN][]. - - [google]: http://google.com/ "Google" - [yahoo]: http://search.yahoo.com/ "Yahoo Search" - [msn]: http://search.msn.com/ "MSN Search" - -Both of the above examples will produce the following HTML output: - -

    I get 10 times more traffic from Google than from - Yahoo - or MSN.

    - -For comparison, here is the same paragraph written using -Markdown's inline link style: - - I get 10 times more traffic from [Google](http://google.com/ "Google") - than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or - [MSN](http://search.msn.com/ "MSN Search"). - -The point of reference-style links is not that they're easier to -write. The point is that with reference-style links, your document -source is vastly more readable. Compare the above examples: using -reference-style links, the paragraph itself is only 81 characters -long; with inline-style links, it's 176 characters; and as raw HTML, -it's 234 characters. In the raw HTML, there's more markup than there -is text. - -With Markdown's reference-style links, a source document much more -closely resembles the final output, as rendered in a browser. By -allowing you to move the markup-related metadata out of the paragraph, -you can add links without interrupting the narrative flow of your -prose. - - -

    Emphasis

    - -Markdown treats asterisks (`*`) and underscores (`_`) as indicators of -emphasis. Text wrapped with one `*` or `_` will be wrapped with an -HTML `` tag; double `*`'s or `_`'s will be wrapped with an HTML -`` tag. E.g., this input: - - *single asterisks* - - _single underscores_ - - **double asterisks** - - __double underscores__ - -will produce: - - single asterisks - - single underscores - - double asterisks - - double underscores - -You can use whichever style you prefer; the lone restriction is that -the same character must be used to open and close an emphasis span. - -Emphasis can be used in the middle of a word: - - un*fucking*believable - -But if you surround an `*` or `_` with spaces, it'll be treated as a -literal asterisk or underscore. - -To produce a literal asterisk or underscore at a position where it -would otherwise be used as an emphasis delimiter, you can backslash -escape it: - - \*this text is surrounded by literal asterisks\* - - - -

    Code

    - -To indicate a span of code, wrap it with backtick quotes (`` ` ``). -Unlike a pre-formatted code block, a code span indicates code within a -normal paragraph. For example: - - Use the `printf()` function. - -will produce: - -

    Use the printf() function.

    - -To include a literal backtick character within a code span, you can use -multiple backticks as the opening and closing delimiters: - - ``There is a literal backtick (`) here.`` - -which will produce this: - -

    There is a literal backtick (`) here.

    - -The backtick delimiters surrounding a code span may include spaces -- -one after the opening, one before the closing. This allows you to place -literal backtick characters at the beginning or end of a code span: - - A single backtick in a code span: `` ` `` - - A backtick-delimited string in a code span: `` `foo` `` - -will produce: - -

    A single backtick in a code span: `

    - -

    A backtick-delimited string in a code span: `foo`

    - -With a code span, ampersands and angle brackets are encoded as HTML -entities automatically, which makes it easy to include example HTML -tags. Markdown will turn this: - - Please don't use any `` tags. - -into: - -

    Please don't use any <blink> tags.

    - -You can write this: - - `—` is the decimal-encoded equivalent of `—`. - -to produce: - -

    &#8212; is the decimal-encoded - equivalent of &mdash;.

    - - - -

    Images

    - -Admittedly, it's fairly difficult to devise a "natural" syntax for -placing images into a plain text document format. - -Markdown uses an image syntax that is intended to resemble the syntax -for links, allowing for two styles: *inline* and *reference*. - -Inline image syntax looks like this: - - ![Alt text](/path/to/img.jpg) - - ![Alt text](/path/to/img.jpg "Optional title") - -That is: - -* An exclamation mark: `!`; -* followed by a set of square brackets, containing the `alt` - attribute text for the image; -* followed by a set of parentheses, containing the URL or path to - the image, and an optional `title` attribute enclosed in double - or single quotes. - -Reference-style image syntax looks like this: - - ![Alt text][id] - -Where "id" is the name of a defined image reference. Image references -are defined using syntax identical to link references: - - [id]: url/to/image "Optional title attribute" - -As of this writing, Markdown has no syntax for specifying the -dimensions of an image; if this is important to you, you can simply -use regular HTML `` tags. - - -* * * - - -

    Miscellaneous

    - - - -Markdown supports a shortcut style for creating "automatic" links for URLs and email addresses: simply surround the URL or email address with angle brackets. What this means is that if you want to show the actual text of a URL or email address, and also have it be a clickable link, you can do this: - - - -Markdown will turn this into: - - http://example.com/ - -Automatic links for email addresses work similarly, except that -Markdown will also perform a bit of randomized decimal and hex -entity-encoding to help obscure your address from address-harvesting -spambots. For example, Markdown will turn this: - - - -into something like this: - - address@exa - mple.com - -which will render in a browser as a clickable link to "address@example.com". - -(This sort of entity-encoding trick will indeed fool many, if not -most, address-harvesting bots, but it definitely won't fool all of -them. It's better than nothing, but an address published in this way -will probably eventually start receiving spam.) - - - -

    Backslash Escapes

    - -Markdown allows you to use backslash escapes to generate literal -characters which would otherwise have special meaning in Markdown's -formatting syntax. For example, if you wanted to surround a word with -literal asterisks (instead of an HTML `` tag), you can backslashes -before the asterisks, like this: - - \*literal asterisks\* - -Markdown provides backslash escapes for the following characters: - - \ backslash - ` backtick - * asterisk - _ underscore - {} curly braces - [] square brackets - () parentheses - # hash mark - + plus sign - - minus sign (hyphen) - . dot - ! exclamation mark - diff --git a/test/MarkdownTest_1.0.3/Tests/Nested blockquotes.html b/test/MarkdownTest_1.0.3/Tests/Nested blockquotes.html deleted file mode 100644 index d8ec7f8..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Nested blockquotes.html +++ /dev/null @@ -1,9 +0,0 @@ -
    -

    foo

    - -
    -

    bar

    -
    - -

    foo

    -
    diff --git a/test/MarkdownTest_1.0.3/Tests/Nested blockquotes.text b/test/MarkdownTest_1.0.3/Tests/Nested blockquotes.text deleted file mode 100644 index ed3c624..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Nested blockquotes.text +++ /dev/null @@ -1,5 +0,0 @@ -> foo -> -> > bar -> -> foo diff --git a/test/MarkdownTest_1.0.3/Tests/Ordered and unordered lists.html b/test/MarkdownTest_1.0.3/Tests/Ordered and unordered lists.html deleted file mode 100644 index ba71eab..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Ordered and unordered lists.html +++ /dev/null @@ -1,148 +0,0 @@ -

    Unordered

    - -

    Asterisks tight:

    - -
      -
    • asterisk 1
    • -
    • asterisk 2
    • -
    • asterisk 3
    • -
    - -

    Asterisks loose:

    - -
      -
    • asterisk 1

    • -
    • asterisk 2

    • -
    • asterisk 3

    • -
    - -
    - -

    Pluses tight:

    - -
      -
    • Plus 1
    • -
    • Plus 2
    • -
    • Plus 3
    • -
    - -

    Pluses loose:

    - -
      -
    • Plus 1

    • -
    • Plus 2

    • -
    • Plus 3

    • -
    - -
    - -

    Minuses tight:

    - -
      -
    • Minus 1
    • -
    • Minus 2
    • -
    • Minus 3
    • -
    - -

    Minuses loose:

    - -
      -
    • Minus 1

    • -
    • Minus 2

    • -
    • Minus 3

    • -
    - -

    Ordered

    - -

    Tight:

    - -
      -
    1. First
    2. -
    3. Second
    4. -
    5. Third
    6. -
    - -

    and:

    - -
      -
    1. One
    2. -
    3. Two
    4. -
    5. Three
    6. -
    - -

    Loose using tabs:

    - -
      -
    1. First

    2. -
    3. Second

    4. -
    5. Third

    6. -
    - -

    and using spaces:

    - -
      -
    1. One

    2. -
    3. Two

    4. -
    5. Three

    6. -
    - -

    Multiple paragraphs:

    - -
      -
    1. Item 1, graf one.

      - -

      Item 2. graf two. The quick brown fox jumped over the lazy dog's -back.

    2. -
    3. Item 2.

    4. -
    5. Item 3.

    6. -
    - -

    Nested

    - -
      -
    • Tab -
        -
      • Tab -
          -
        • Tab
        • -
      • -
    • -
    - -

    Here's another:

    - -
      -
    1. First
    2. -
    3. Second: -
        -
      • Fee
      • -
      • Fie
      • -
      • Foe
      • -
    4. -
    5. Third
    6. -
    - -

    Same thing but with paragraphs:

    - -
      -
    1. First

    2. -
    3. Second:

      - -
        -
      • Fee
      • -
      • Fie
      • -
      • Foe
      • -
    4. -
    5. Third

    6. -
    - - -

    This was an error in Markdown 1.0.1:

    - -
      -
    • this

      - -
      • sub
      - -

      that

    • -
    diff --git a/test/MarkdownTest_1.0.3/Tests/Ordered and unordered lists.text b/test/MarkdownTest_1.0.3/Tests/Ordered and unordered lists.text deleted file mode 100644 index 7f3b497..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Ordered and unordered lists.text +++ /dev/null @@ -1,131 +0,0 @@ -## Unordered - -Asterisks tight: - -* asterisk 1 -* asterisk 2 -* asterisk 3 - - -Asterisks loose: - -* asterisk 1 - -* asterisk 2 - -* asterisk 3 - -* * * - -Pluses tight: - -+ Plus 1 -+ Plus 2 -+ Plus 3 - - -Pluses loose: - -+ Plus 1 - -+ Plus 2 - -+ Plus 3 - -* * * - - -Minuses tight: - -- Minus 1 -- Minus 2 -- Minus 3 - - -Minuses loose: - -- Minus 1 - -- Minus 2 - -- Minus 3 - - -## Ordered - -Tight: - -1. First -2. Second -3. Third - -and: - -1. One -2. Two -3. Three - - -Loose using tabs: - -1. First - -2. Second - -3. Third - -and using spaces: - -1. One - -2. Two - -3. Three - -Multiple paragraphs: - -1. Item 1, graf one. - - Item 2. graf two. The quick brown fox jumped over the lazy dog's - back. - -2. Item 2. - -3. Item 3. - - - -## Nested - -* Tab - * Tab - * Tab - -Here's another: - -1. First -2. Second: - * Fee - * Fie - * Foe -3. Third - -Same thing but with paragraphs: - -1. First - -2. Second: - * Fee - * Fie - * Foe - -3. Third - - -This was an error in Markdown 1.0.1: - -* this - - * sub - - that diff --git a/test/MarkdownTest_1.0.3/Tests/Strong and em together.html b/test/MarkdownTest_1.0.3/Tests/Strong and em together.html deleted file mode 100644 index 71ec78c..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Strong and em together.html +++ /dev/null @@ -1,7 +0,0 @@ -

    This is strong and em.

    - -

    So is this word.

    - -

    This is strong and em.

    - -

    So is this word.

    diff --git a/test/MarkdownTest_1.0.3/Tests/Strong and em together.text b/test/MarkdownTest_1.0.3/Tests/Strong and em together.text deleted file mode 100644 index 95ee690..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Strong and em together.text +++ /dev/null @@ -1,7 +0,0 @@ -***This is strong and em.*** - -So is ***this*** word. - -___This is strong and em.___ - -So is ___this___ word. diff --git a/test/MarkdownTest_1.0.3/Tests/Tabs.html b/test/MarkdownTest_1.0.3/Tests/Tabs.html deleted file mode 100644 index 3301ba8..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Tabs.html +++ /dev/null @@ -1,25 +0,0 @@ -
      -
    • this is a list item -indented with tabs

    • -
    • this is a list item -indented with spaces

    • -
    - -

    Code:

    - -
    this code block is indented by one tab
    -
    - -

    And:

    - -
        this code block is indented by two tabs
    -
    - -

    And:

    - -
    +   this is an example list item
    -    indented with tabs
    -
    -+   this is an example list item
    -    indented with spaces
    -
    diff --git a/test/MarkdownTest_1.0.3/Tests/Tabs.text b/test/MarkdownTest_1.0.3/Tests/Tabs.text deleted file mode 100644 index 589d113..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Tabs.text +++ /dev/null @@ -1,21 +0,0 @@ -+ this is a list item - indented with tabs - -+ this is a list item - indented with spaces - -Code: - - this code block is indented by one tab - -And: - - this code block is indented by two tabs - -And: - - + this is an example list item - indented with tabs - - + this is an example list item - indented with spaces diff --git a/test/MarkdownTest_1.0.3/Tests/Tidyness.html b/test/MarkdownTest_1.0.3/Tests/Tidyness.html deleted file mode 100644 index f2a8ce7..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Tidyness.html +++ /dev/null @@ -1,8 +0,0 @@ -
    -

    A list within a blockquote:

    -
      -
    • asterisk 1
    • -
    • asterisk 2
    • -
    • asterisk 3
    • -
    -
    diff --git a/test/MarkdownTest_1.0.3/Tests/Tidyness.text b/test/MarkdownTest_1.0.3/Tests/Tidyness.text deleted file mode 100644 index 5f18b8d..0000000 --- a/test/MarkdownTest_1.0.3/Tests/Tidyness.text +++ /dev/null @@ -1,5 +0,0 @@ -> A list within a blockquote: -> -> * asterisk 1 -> * asterisk 2 -> * asterisk 3 diff --git a/test/Tests/Escape character.html b/test/Tests/Escape character.html deleted file mode 100644 index a6863ba..0000000 --- a/test/Tests/Escape character.html +++ /dev/null @@ -1,51 +0,0 @@ -

    ==Highlight==

    - -

    ~~Strikethrough~~

    - -

    _Underscore_

    - -

    _Underscore_

    - -

    _Underscore_

    - -

    _Underscore_

    - -

    _Underscore_

    - -

    *Asterisk*

    - -

    *Asterisk*

    - -

    *Asterisk*

    - -

    *Asterisk*

    - -

    *Asterisk*

    - -

    [Bracket]

    - -

    (Parenthesis)

    - -

    <Chevron>

    - -

    Super^script

    - -

    `Backtick`

    - -

    "Quote"

    - -

    Foo\

    - -

    Foo\*

    - -

    Foo\\Bar\

    - -

    *Foo\Bar\*

    - -

    Foo]

    - -

    Foo\

    - -

    Foo\]

    - -

    Foo\\

    diff --git a/test/Tests/Escape character.text b/test/Tests/Escape character.text deleted file mode 100644 index 3eab090..0000000 --- a/test/Tests/Escape character.text +++ /dev/null @@ -1,51 +0,0 @@ -\==Highlight\== - -\~~Strikethrough\~~ - -\_Underscore\_ - -\__Underscore\__ - -_\_Underscore_\_ - -\__Underscore_\_ - -_\_Underscore\__ - -\*Asterisk\* - -\**Asterisk\** - -\**Asterisk*\* - -*\*Asterisk\** - -*\*Asterisk*\* - -\[Bracket\] - -\(Parenthesis\) - -\ - -Super\^script - -\`Backtick\` - -\"Quote\" - -**Foo\\** - -*Foo\\\** - -**Foo\\\Bar\\** - -*Foo\\Bar\\\* - -[Foo\]](http://example.com) - -[Foo\\](http://example.com) - -[Foo\\\]](http://example.com) - -[Foo\\\\](http://example.com) diff --git a/test/Tests/Math.html b/test/Tests/Math.html deleted file mode 100644 index 72df249..0000000 --- a/test/Tests/Math.html +++ /dev/null @@ -1,31 +0,0 @@ -

    \[ -1*2*3 multi-line math -\]

    - -

    \( 1*2*3 inline-math \)

    - -

    \[ 1*2*3 math with dollar \]

    - -

    \[ 1*2*3 \$ \\ \text{dollar with escapes} \]

    - -

    \( \\ \text{backslash with escapes} \$ 1*2*3 \)

    - -

    ( not really math )

    - -

    $$ also not math $$

    - -

    this \(*should* be\) math

    - -

    this\( *should* also be\) math

    - -

    and \(this *should* \)too

    - -

    Something \{ like math but \} is not

    - -

    Also \(like math but \) is not

    - -

    \\( should be *math* as well \\\)

    - -

    This is \( math, and the \\\( inner one \\\) should be \) preserved

    - -

    \[ did you <em> know </em> this is math? \]

    diff --git a/test/Tests/Math.text b/test/Tests/Math.text deleted file mode 100644 index dbca401..0000000 --- a/test/Tests/Math.text +++ /dev/null @@ -1,31 +0,0 @@ -\\[ -1*2*3 multi-line math -\\] - -\\( 1*2*3 inline-math \\) - -$$ 1*2*3 math with dollar $$ - -$$ 1*2*3 \$ \\ \text{dollar with escapes} $$ - -\\( \\ \text{backslash with escapes} \$ 1*2*3 \\) - -\( not *really* math \) - -\$$ also *not* math \$$ - -this $$*should* be$$ math - -this$$ *should* also be$$ math - -and $$this *should* $$too - -Something \\{ like *math* but \\} is not - -Also \\\(like *math* but \\\) is not - -\\\\( should be *math* as well \\\\) - -This is \\( math, and the \\\( inner one \\\) should be \\) preserved - -$$ did you know this is math? $$ diff --git a/test/config.json b/test/config.json deleted file mode 100644 index 63cb1d7..0000000 --- a/test/config.json +++ /dev/null @@ -1,101 +0,0 @@ -{ - "tests": [ - { - "input": "MarkdownTest_1.0.3/Tests/Amps and angle encoding.text", - "output": "MarkdownTest_1.0.3/Tests/Amps and angle encoding.html" - }, - { - "input": "MarkdownTest_1.0.3/Tests/Auto links.text", - "output": "MarkdownTest_1.0.3/Tests/Auto links.html" - }, - { - "input": "MarkdownTest_1.0.3/Tests/Backslash escapes.text", - "output": "MarkdownTest_1.0.3/Tests/Backslash escapes.html" - }, - { - "input": "MarkdownTest_1.0.3/Tests/Blockquotes with code blocks.text", - "output": "MarkdownTest_1.0.3/Tests/Blockquotes with code blocks.html" - }, - { - "input": "MarkdownTest_1.0.3/Tests/Code Blocks.text", - "output": "MarkdownTest_1.0.3/Tests/Code Blocks.html" - }, - { - "input": "MarkdownTest_1.0.3/Tests/Code Spans.text", - "output": "MarkdownTest_1.0.3/Tests/Code Spans.html" - }, - { - "input": "MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.text", - "output": "MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.html" - }, - { - "input": "MarkdownTest_1.0.3/Tests/Horizontal rules.text", - "output": "MarkdownTest_1.0.3/Tests/Horizontal rules.html" - }, - { - "input": "MarkdownTest_1.0.3/Tests/Inline HTML (Advanced).text", - "output": "MarkdownTest_1.0.3/Tests/Inline HTML (Advanced).html" - }, - { - "input": "MarkdownTest_1.0.3/Tests/Inline HTML (Simple).text", - "output": "MarkdownTest_1.0.3/Tests/Inline HTML (Simple).html" - }, - { - "input": "MarkdownTest_1.0.3/Tests/Inline HTML comments.text", - "output": "MarkdownTest_1.0.3/Tests/Inline HTML comments.html" - }, - { - "input": "MarkdownTest_1.0.3/Tests/Links, inline style.text", - "output": "MarkdownTest_1.0.3/Tests/Links, inline style.html" - }, - { - "input": "MarkdownTest_1.0.3/Tests/Links, reference style.text", - "output": "MarkdownTest_1.0.3/Tests/Links, reference style.html" - }, - { - "input": "MarkdownTest_1.0.3/Tests/Links, shortcut references.text", - "output": "MarkdownTest_1.0.3/Tests/Links, shortcut references.html" - }, - { - "input": "MarkdownTest_1.0.3/Tests/Literal quotes in titles.text", - "output": "MarkdownTest_1.0.3/Tests/Literal quotes in titles.html" - }, - { - "input": "MarkdownTest_1.0.3/Tests/Markdown Documentation - Basics.text", - "output": "MarkdownTest_1.0.3/Tests/Markdown Documentation - Basics.html" - }, - { - "input": "MarkdownTest_1.0.3/Tests/Markdown Documentation - Syntax.text", - "output": "MarkdownTest_1.0.3/Tests/Markdown Documentation - Syntax.html" - }, - { - "input": "MarkdownTest_1.0.3/Tests/Nested blockquotes.text", - "output": "MarkdownTest_1.0.3/Tests/Nested blockquotes.html" - }, - { - "input": "MarkdownTest_1.0.3/Tests/Ordered and unordered lists.text", - "output": "MarkdownTest_1.0.3/Tests/Ordered and unordered lists.html" - }, - { - "input": "MarkdownTest_1.0.3/Tests/Strong and em together.text", - "output": "MarkdownTest_1.0.3/Tests/Strong and em together.html" - }, - { - "input": "MarkdownTest_1.0.3/Tests/Tabs.text", - "output": "MarkdownTest_1.0.3/Tests/Tabs.html" - }, - { - "input": "MarkdownTest_1.0.3/Tests/Tidyness.text", - "output": "MarkdownTest_1.0.3/Tests/Tidyness.html" - }, - { - "input": "Tests/Escape character.text", - "output": "Tests/Escape character.html" - }, - { - "input": "Tests/Math.text", - "output": "Tests/Math.html", - "flags": ["--math"] - } - ] -} diff --git a/test/runner.py b/test/runner.py deleted file mode 100755 index 4102fad..0000000 --- a/test/runner.py +++ /dev/null @@ -1,108 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -import difflib -import json -import os -import re -import subprocess -import unittest - -TEST_ROOT = os.path.dirname(__file__) -PROJECT_ROOT = os.path.dirname(TEST_ROOT) -HOEDOWN = [os.path.abspath(os.path.join(PROJECT_ROOT, 'hoedown'))] -TIDY = ['tidy', '--show-body-only', '1', '--show-warnings', '0', - '--quiet', '1'] -CONFIG_PATH = os.path.join(TEST_ROOT, 'config.json') -SLUGIFY_PATTERN = re.compile(r'\W') - - -def with_metaclass(meta, *bases): - """Metaclass injection utility from six. - - See: https://pythonhosted.org/six/ - """ - class metaclass(meta): - def __new__(cls, name, this_bases, d): - return meta(name, bases, d) - return type.__new__(metaclass, 'temporary_class', (), {}) - - -class TestFailed(AssertionError): - def __init__(self, name, expected, got): - super(TestFailed, self).__init__(self) - diff = difflib.unified_diff( - expected.splitlines(), got.splitlines(), - fromfile='Expected', tofile='Got', - ) - self.description = '{name}\n{diff}'.format( - name=name, diff='\n'.join(diff), - ) - - def __str__(self): - return self.description - - -def _test_func(test_case): - flags = test_case.get('flags') or [] - hoedown_proc = subprocess.Popen( - HOEDOWN + flags + [os.path.join(TEST_ROOT, test_case['input'])], - stdout=subprocess.PIPE, - ) - hoedown_proc.wait() - got_tidy_proc = subprocess.Popen( - TIDY, stdin=hoedown_proc.stdout, stdout=subprocess.PIPE, - ) - got_tidy_proc.wait() - got = got_tidy_proc.stdout.read().strip() - - expected_tidy_proc = subprocess.Popen( - TIDY + [os.path.join(TEST_ROOT, test_case['output'])], - stdout=subprocess.PIPE, - ) - expected_tidy_proc.wait() - expected = expected_tidy_proc.stdout.read().strip() - - # Cleanup. - hoedown_proc.stdout.close() - got_tidy_proc.stdout.close() - expected_tidy_proc.stdout.close() - - try: - assert expected == got - except AssertionError: - raise TestFailed(test_case['input'], expected, got) - - -def _make_test(test_case): - return lambda self: _test_func(test_case) - - -class MarkdownTestsMeta(type): - """Meta class for ``MarkdownTestCase`` to inject test cases on the fly. - """ - def __new__(meta, name, bases, attrs): - with open(CONFIG_PATH) as f: - config = json.load(f) - - for test in config['tests']: - input_name = test['input'] - attr_name = 'test_' + SLUGIFY_PATTERN.sub( - '_', os.path.splitext(input_name)[0].lower(), - ) - func = _make_test(test) - func.__doc__ = input_name - if test.get('skip', False): - func = unittest.skip(input_name)(func) - if test.get('fail', False): - func = unittest.expectsFailure(func) - attrs[attr_name] = func - return type.__new__(meta, name, bases, attrs) - - -class MarkdownTests(with_metaclass(MarkdownTestsMeta, unittest.TestCase)): - pass - - -if __name__ == '__main__': - unittest.main()