├── .github └── workflows │ └── codeql-analysis.yml ├── .gitignore ├── .travis.yml ├── LICENSE ├── Makefile ├── Makefile.win ├── README.md ├── bin ├── common.h ├── hoedown.c └── smartypants.c ├── hoedown.def ├── html5_block_names.gperf ├── html_block_names.gperf ├── src ├── autolink.c ├── autolink.h ├── buffer.c ├── buffer.h ├── context_test.c ├── context_test.h ├── document.c ├── document.h ├── escape.c ├── escape.h ├── hash.c ├── hash.h ├── html.c ├── html.h ├── html5_blocks.c ├── html_blocks.c ├── html_smartypants.c ├── stack.c ├── stack.h ├── version.c └── version.h └── test ├── MarkdownTest_1.0.3 ├── MarkdownTest.pl └── Tests │ ├── Amps and angle encoding.html │ ├── Amps and angle encoding.text │ ├── Auto links.html │ ├── Auto links.text │ ├── Backslash escapes.html │ ├── Backslash escapes.text │ ├── Blockquotes with code blocks.html │ ├── Blockquotes with code blocks.text │ ├── Code Blocks.html │ ├── Code Blocks.text │ ├── Code Spans.html │ ├── Code Spans.text │ ├── Hard-wrapped paragraphs with list-like lines.html │ ├── Hard-wrapped paragraphs with list-like lines.text │ ├── Horizontal rules.html │ ├── Horizontal rules.text │ ├── Inline HTML (Advanced).html │ ├── Inline HTML (Advanced).text │ ├── Inline HTML (Simple).html │ ├── Inline HTML (Simple).text │ ├── Inline HTML comments.html │ ├── Inline HTML comments.text │ ├── Links, inline style.html │ ├── Links, inline style.text │ ├── Links, reference style.html │ ├── Links, reference style.text │ ├── Links, shortcut references.html │ ├── Links, shortcut references.text │ ├── Literal quotes in titles.html │ ├── Literal quotes in titles.text │ ├── Markdown Documentation - Basics.html │ ├── Markdown Documentation - Basics.text │ ├── Markdown Documentation - Syntax.html │ ├── Markdown Documentation - Syntax.text │ ├── Nested blockquotes.html │ ├── Nested blockquotes.text │ ├── Ordered and unordered lists.html │ ├── Ordered and unordered lists.text │ ├── Strong and em together.html │ ├── Strong and em together.text │ ├── Tabs.html │ ├── Tabs.text │ ├── Tidyness.html │ └── Tidyness.text ├── Tests ├── CommentsInMiddleOfLine.html ├── CommentsInMiddleOfLine.text ├── EmptyHeaders.html ├── EmptyHeaders.text ├── Escape character.html ├── Escape character.text ├── Formatting in Table of Contents.html ├── Formatting in Table of Contents.text ├── Headers.html ├── Headers.text ├── Images.html ├── Images.text ├── Math.html ├── Math.text ├── Table.html ├── Table.text ├── Underline.html ├── Underline.text ├── context │ ├── Blockcode.input │ ├── Blockcode.output │ ├── Depth.input │ ├── Depth.output │ ├── Escaping.input │ ├── Escaping.output │ ├── Footnotes.input │ ├── Footnotes.output │ ├── HRules.input │ ├── HRules.output │ ├── Headers.input │ ├── Headers.output │ ├── Links.input │ ├── Links.output │ ├── Ordered_Lists.input │ ├── Ordered_Lists.output │ ├── Unordered_Lists.input │ └── Unordered_Lists.output └── extras │ ├── Attributes.html │ ├── Attributes.text │ ├── Blockquote_Empty_Line.html │ ├── Blockquote_Empty_Line.text │ ├── Codespans.html │ ├── Codespans.text │ ├── Definition_Lists.html │ ├── Definition_Lists.text │ ├── Emphases_Intra_Underline.html │ ├── Emphases_Intra_Underline.text │ ├── Escape_Backticks.html │ ├── Escape_Backticks.text │ ├── FencedCode_Script.html │ ├── FencedCode_Script.text │ ├── Footnotes.html │ ├── Footnotes.text │ ├── HTML5_Block.html │ ├── HTML5_Block.text │ ├── HTML_Block.html │ ├── HTML_Block.text │ ├── HTML_Nested.html │ ├── HTML_Nested.text │ ├── Header_Empty.html │ ├── Header_Empty.text │ ├── Header_Empty_Attribute.html │ ├── Header_Empty_Attribute.text │ ├── Header_ID.html │ ├── Header_ID.text │ ├── Line_Continue.html │ ├── Line_Continue.text │ ├── Link_Attributes.html │ ├── Link_Attributes.text │ ├── List_Item_FencedCode.html │ ├── List_Item_FencedCode.text │ ├── List_Item_Fenced_Code_First_Line.html │ ├── List_Item_Fenced_Code_First_Line.text │ ├── List_Item_First_Line.html │ ├── List_Item_First_Line.text │ ├── Meta_Block.html │ ├── Meta_Block.text │ ├── Meta_Block_Multi.html │ ├── Meta_Block_Multi.text │ ├── More_Tables.html │ ├── More_Tables.text │ ├── Multiline_Table.html │ ├── Multiline_Table.text │ ├── Multiline_Table_Malformed.html │ ├── Multiline_Table_Malformed.text │ ├── Radio.html │ ├── Radio.text │ ├── Script_Tags.html │ ├── Script_Tags.text │ ├── Special_Attribute_Activation.html │ ├── Special_Attribute_Activation.text │ ├── Special_Attribute_CodeBlock.html │ ├── Special_Attribute_CodeBlock.text │ ├── Special_Attribute_Codespan.html │ ├── Special_Attribute_Codespan.text │ ├── Special_Attribute_Escaped.html │ ├── Special_Attribute_Escaped.text │ ├── Special_Attribute_FencedCode.html │ ├── Special_Attribute_FencedCode.text │ ├── Special_Attribute_Headers.html │ ├── Special_Attribute_Headers.text │ ├── Special_Attribute_Links.html │ ├── Special_Attribute_Links.text │ ├── Special_Attribute_Lists.html │ ├── Special_Attribute_Lists.text │ ├── Special_Attribute_Multiline_Table.html │ ├── Special_Attribute_Multiline_Table.text │ ├── Special_Attribute_Paragraphs.html │ ├── Special_Attribute_Paragraphs.text │ ├── Special_Attribute_Tables.html │ ├── Special_Attribute_Tables.text │ ├── Table_Escape_Pipe.html │ ├── Table_Escape_Pipe.text │ ├── Tasks.html │ ├── Tasks.text │ ├── Toc.html │ ├── Toc.text │ ├── Toc_Header_Empty.html │ ├── Toc_Header_Empty.text │ ├── Toc_Header_Empty_Attribute.html │ ├── Toc_Header_Empty_Attribute.text │ ├── Toc_Render.html │ ├── Toc_Render.text │ ├── issues_46.html │ ├── issues_46.text │ ├── issues_47.html │ └── issues_47.text ├── config.json ├── hoedown_fuzzer.c └── runner.py /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | name: "CodeQL" 7 | 8 | on: 9 | push: 10 | branches: [master] 11 | pull_request: 12 | # The branches below must be a subset of the branches above 13 | branches: [master] 14 | schedule: 15 | - cron: '0 1 * * 1' 16 | 17 | jobs: 18 | analyze: 19 | name: Analyze 20 | runs-on: ubuntu-latest 21 | 22 | strategy: 23 | fail-fast: false 24 | matrix: 25 | # Override automatic language detection by changing the below list 26 | # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python'] 27 | language: ['cpp'] 28 | # Learn more... 29 | # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection 30 | 31 | steps: 32 | - name: Checkout repository 33 | uses: actions/checkout@v2 34 | 35 | # Initializes the CodeQL tools for scanning. 36 | - name: Initialize CodeQL 37 | uses: github/codeql-action/init@v1 38 | with: 39 | languages: ${{ matrix.language }} 40 | # If you wish to specify custom queries, you can do so here or in a config file. 41 | # By default, queries listed here will override any specified in a config file. 42 | # Prefix the list here with "+" to use these queries and those in the config file. 43 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 44 | 45 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 46 | # If this step fails, then you should remove it and run the build manually (see below) 47 | - name: Autobuild 48 | uses: github/codeql-action/autobuild@v1 49 | 50 | # ℹ️ Command-line programs to run using the OS shell. 51 | # 📚 https://git.io/JvXDl 52 | 53 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 54 | # and modify them (or add more) to build your code if your project 55 | # uses a compiled language 56 | 57 | #- run: | 58 | # make bootstrap 59 | # make release 60 | 61 | - name: Perform CodeQL Analysis 62 | uses: github/codeql-action/analyze@v1 63 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.obj 3 | *.exe 4 | *.gcda 5 | *.gcno 6 | *.gcov 7 | hoedown 8 | hoedown.dll 9 | hoedown.exp 10 | hoedown.lib 11 | smartypants 12 | libhoedown.so* 13 | libhoedown.a 14 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | compiler: 3 | - clang 4 | - gcc 5 | perl: 6 | - "5.12" 7 | before_install: 8 | - sudo apt-get install -qq tidy 9 | - pip install --user codecov 10 | script: 11 | - make COVERAGE=1 12 | - make test 13 | 14 | after_success: 15 | # - bash <(curl -s https://codecov.io/bash) 16 | # Fixed gcov 4.6.3 in codecov 17 | - curl -s -o codecov https://codecov.io/bash 18 | - sed -i "/\.gcno/c for f in \`find \$proj_root -type f -name '*.gcno' \$gcov_ignore\`; do o=\`dirname \$f\`; \$gcov_exe \$gcovargs -pb \$f -o \$o; done" codecov 19 | - bash codecov 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2008, Natacha Porté 2 | Copyright (c) 2011, Vicent Martí 3 | Copyright (c) 2014, Xavier Mendez, Devin Torres and the Hoedown authors 4 | Copyright (c) 2015, Google Inc 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | 'Software'), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be 15 | included in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS = -g -O3 -std=c99 -D_DEFAULT_SOURCE -pedantic -Wall -Wextra -Wno-unused-parameter 2 | PREFIX = /usr/local 3 | BINDIR = $(PREFIX)/bin 4 | LIBDIR = $(PREFIX)/lib 5 | INCLUDEDIR = $(PREFIX)/include 6 | 7 | HOEDOWN_CFLAGS = $(CFLAGS) -Isrc 8 | ifneq ($(OS),Windows_NT) 9 | HOEDOWN_CFLAGS += -fPIC 10 | endif 11 | 12 | ifdef COVERAGE 13 | HOEDOWN_CFLAGS := $(HOEDOWN_CFLAGS) -coverage 14 | endif 15 | 16 | SONAME = -soname 17 | ifeq ($(shell uname -s),Darwin) 18 | SONAME = -install_name 19 | endif 20 | 21 | HOEDOWN_SRC=\ 22 | src/autolink.o \ 23 | src/buffer.o \ 24 | src/context_test.o \ 25 | src/document.o \ 26 | src/escape.o \ 27 | src/html.o \ 28 | src/html_blocks.o \ 29 | src/html5_blocks.o \ 30 | src/html_smartypants.o \ 31 | src/stack.o \ 32 | src/hash.o \ 33 | src/version.o 34 | 35 | .PHONY: all test test-pl clean 36 | 37 | all: libhoedown.so libhoedown.a hoedown smartypants 38 | 39 | # Libraries 40 | 41 | libhoedown.so: libhoedown.so.3 42 | ln -f -s $^ $@ 43 | 44 | libhoedown.so.3: $(HOEDOWN_SRC) 45 | $(CC) -Wl,$(SONAME),$(@F) -shared $^ $(LDFLAGS) -o $@ 46 | 47 | libhoedown.a: $(HOEDOWN_SRC) 48 | $(AR) rcs libhoedown.a $^ 49 | 50 | # Executables 51 | 52 | hoedown: bin/hoedown.o $(HOEDOWN_SRC) 53 | $(CC) $(HOEDOWN_CFLAGS) $^ $(LDFLAGS) -o $@ 54 | 55 | smartypants: bin/smartypants.o $(HOEDOWN_SRC) 56 | $(CC) $(HOEDOWN_CFLAGS) $^ $(LDFLAGS) -o $@ 57 | 58 | # Perfect hashing 59 | 60 | src/html_blocks.c: html_block_names.gperf 61 | gperf -L ANSI-C -N hoedown_find_block_tag -c -C -E -S 1 --ignore-case -m100 $^ > $@ 62 | 63 | src/html5_blocks.c: html5_block_names.gperf 64 | gperf -L ANSI-C -N hoedown_find_html5_block_tag -c -C -E -S 1 --ignore-case -m100 $^ > $@ 65 | 66 | # Testing 67 | 68 | test: hoedown 69 | python test/runner.py 70 | 71 | test-pl: hoedown 72 | perl test/MarkdownTest_1.0.3/MarkdownTest.pl \ 73 | --script=./hoedown --testdir=test/MarkdownTest_1.0.3/Tests --tidy 74 | 75 | # Housekeeping 76 | 77 | clean: 78 | $(RM) src/*.o bin/*.o 79 | $(RM) libhoedown.so libhoedown.so.3 libhoedown.a 80 | $(RM) hoedown smartypants hoedown.exe smartypants.exe 81 | $(RM) bin/*.gc* src/*.gc* *.gcov 82 | 83 | # Installing 84 | 85 | install: 86 | install -m755 -d $(DESTDIR)$(LIBDIR) 87 | install -m755 -d $(DESTDIR)$(BINDIR) 88 | install -m755 -d $(DESTDIR)$(INCLUDEDIR) 89 | 90 | install -m644 libhoedown.a $(DESTDIR)$(LIBDIR) 91 | install -m755 libhoedown.so.3 $(DESTDIR)$(LIBDIR) 92 | ln -f -s libhoedown.so.3 $(DESTDIR)$(LIBDIR)/libhoedown.so 93 | 94 | install -m755 hoedown $(DESTDIR)$(BINDIR) 95 | install -m755 smartypants $(DESTDIR)$(BINDIR) 96 | 97 | install -m755 -d $(DESTDIR)$(INCLUDEDIR)/hoedown 98 | install -m644 src/*.h $(DESTDIR)$(INCLUDEDIR)/hoedown 99 | 100 | # Generic object compilations 101 | 102 | %.o: %.c 103 | $(CC) $(HOEDOWN_CFLAGS) -c -o $@ $< 104 | 105 | src/html_blocks.o: src/html_blocks.c 106 | $(CC) $(HOEDOWN_CFLAGS) -Wno-static-in-inline -c -o $@ $< 107 | -------------------------------------------------------------------------------- /Makefile.win: -------------------------------------------------------------------------------- 1 | CC = cl 2 | CFLAGS = /O2 /sdl /Isrc /D_CRT_SECURE_NO_WARNINGS 3 | 4 | HOEDOWN_SRC = \ 5 | src\autolink.obj \ 6 | src\buffer.obj \ 7 | src\document.obj \ 8 | src\escape.obj \ 9 | src\html.obj \ 10 | src\html_blocks.obj \ 11 | src\html_smartypants.obj \ 12 | src\stack.obj \ 13 | src\hash.obj \ 14 | src\version.obj 15 | 16 | all: hoedown.dll hoedown.exe smartypants.exe 17 | 18 | hoedown.dll: $(HOEDOWN_SRC) hoedown.def 19 | $(CC) $(HOEDOWN_SRC) hoedown.def /link /DLL $(LDFLAGS) /out:$@ 20 | 21 | hoedown.exe: bin\hoedown.obj $(HOEDOWN_SRC) 22 | $(CC) bin\hoedown.obj $(HOEDOWN_SRC) /link $(LDFLAGS) /out:$@ 23 | 24 | smartypants.exe: bin\smartypants.obj $(HOEDOWN_SRC) 25 | $(CC) bin\smartypants.obj $(HOEDOWN_SRC) /link $(LDFLAGS) /out:$@ 26 | 27 | # Housekeeping 28 | 29 | clean: 30 | del $(HOEDOWN_SRC) 31 | del hoedown.dll hoedown.exp hoedown.lib 32 | del hoedown.exe smartypants.exe 33 | 34 | # Generic object compilations 35 | 36 | .c.obj: 37 | $(CC) $(CFLAGS) /c $< /Fo$@ 38 | 39 | # Testing 40 | 41 | test: hoedown.exe 42 | python test\runner.py 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hoextdown 2 | 3 | [![Build Status](https://api.travis-ci.org/kjdev/hoextdown.png?branch=master)](https://travis-ci.org/kjdev/hoextdown) 4 | [![codecov.io](https://codecov.io/github/kjdev/hoextdown/coverage.svg?branch=master)](https://codecov.io/github/kjdev/hoextdown?branch=master) 5 | ![CodeQL](https://github.com/kjdev/hoextdown/workflows/CodeQL/badge.svg?branch=master) 6 | 7 | `Hoextdown` is an extension to [Hoedown](https://github.com/hoedown/hoedown). 8 | 9 | Extended the following functions. 10 | 11 | * [Special Attributes](#special-attributes) 12 | * [Task Lists](#task-lists) 13 | * [Line Continue](#line-continue) 14 | * [Header ID](#header-id) 15 | * [Fenced Script](#fenced-script) 16 | * [Script Tags](#script-tags) 17 | * [Meta Block](#meta-block) 18 | * [Definition Lists](#definition-lists) 19 | 20 | ## Special Attributes 21 | 22 | Add the `HOEDOWN_EXT_SPECIAL_ATTRIBUTE` to Hoedown document flags. 23 | 24 | Set the id and class attribute on certain elements using an attribute block. 25 | 26 | For instance, put the desired id prefixed by a hash inside curly brackets after 27 | the header at the end of the line, like this 28 | 29 | ``` 30 | Header 1 {#header1} 31 | ======== 32 | 33 | ## Header 2 ## {#header2} 34 | ``` 35 | 36 | Then you can create links to different parts of the same document like this: 37 | 38 | ``` 39 | [Link back to header 1](#header1) 40 | ``` 41 | 42 | To add a class name, which can be used as a hook for a style sheet, use a dot 43 | like this: 44 | 45 | ``` 46 | ## The Site ## {.main} 47 | ``` 48 | 49 | The id and multiple class names can be combined by putting them all into the 50 | same special attribute block: 51 | 52 | ``` 53 | ## The Site ## {.main .shine #the-site} 54 | ``` 55 | 56 | To add a other than id and class names, use a colon like this: 57 | 58 | ``` 59 | ## The Site ## {.main .shine #the-site :color=red} 60 | ``` 61 | 62 | At this time, special attribute blocks can be used with 63 | 64 | * headers 65 | * fenced code blocks 66 | * links 67 | * images 68 | * tables 69 | * paragraphs 70 | 71 | For image and links, put the special attribute block immediately after the 72 | parenthesis containing the address: 73 | 74 | ``` 75 | [link](url){#id .class} 76 | ![img](url){#id .class} 77 | ``` 78 | 79 | Or if using reference-style links and images, put it at the end of the 80 | definition line like this: 81 | 82 | ``` 83 | [link][linkref] or [linkref] 84 | ![img][linkref] 85 | 86 | [linkref]: url "optional title" {#id .class} 87 | ``` 88 | 89 | For paragraphs, put the special identifier `@paragraph` after the attribute. 90 | This helps prevent accidental parsing. 91 | 92 | ``` 93 | This is a paragraph. {@paragraph #id} 94 | ``` 95 | 96 | ## Task Lists 97 | 98 | Add the `HOEDOWN_HTML_USE_TASK_LIST` to Hoedown html flags. 99 | 100 | Add to support task lists, Task lists are lists with items marked as either [ ] 101 | or [x] (incomplete or complete), like this 102 | 103 | ``` 104 | - [ ] a task list item 105 | - [ ] list syntax required 106 | - [ ] normal **formatting**, @mentions, #1234 refs 107 | - [ ] incomplete 108 | - [x] completed 109 | ``` 110 | 111 | ## Line Continue 112 | 113 | Add the `HOEDOWN_HTML_LINE_CONTINUE` to Hoedown html flags. 114 | 115 | Remove the line breaks at the end of the line. 116 | 117 | ## Header ID 118 | 119 | Add the `HOEDOWN_HTML_HEADER_ID` to Hoedown html flags. 120 | 121 | Output header id. 122 | 123 | ``` 124 | # Header 1 125 | ``` 126 | 127 | becomes: 128 | 129 | ``` 130 |

Header 1

131 | ``` 132 | 133 | ## Fenced Script 134 | 135 | Add the `HOEDOWN_HTML_FENCED_CODE_SCRIPT` to Hoedown html flags. 136 | (`HOEDOWN_EXT_FENCED_CODE` also need to be specified at the same time) 137 | 138 | Output the script tag in the fenced code style. 139 | 140 | ``` script@text/javascript 141 | alert("Example"); 142 | ``` 143 | 144 | becomes: 145 | 146 | ``` 147 | 150 | ``` 151 | 152 | ## Script Tags 153 | 154 | Add the `HOEDOWN_EXT_SCRIPT_TAGS` to Hoedown document flags. 155 | 156 | Add the parsing process of script tags ``. 157 | 158 | ``` 159 | This is test. 160 | 161 | 164 | ``` 165 | 166 | becomes: 167 | 168 | ``` 169 |

This is test.

170 | 171 | 174 | ``` 175 | 176 | ## Meta Block 177 | 178 | Add the `HOEDOWN_EXT_META_BLOCK` to Hoedown document flags. 179 | 180 | Add the parsing process of meta block ``. 181 | 182 | Get a meta block by running in the following program. 183 | 184 | ```c 185 | /* 186 | Allocate meta block buffer 187 | */ 188 | hoedown_buffer *meta; 189 | meta = hoedown_buffer_new(64); 190 | 191 | /* 192 | Set HOEDOWN_EXT_META_BLOCK to hoedown_extensions. 193 | Specifies the meta block buffer to fifth argument. 194 | */ 195 | document = hoedown_document_new(renderer, HOEDOWN_EXT_META_BLOCK, 6, NULL, meta); 196 | 197 | /* 198 | Print meta block buffer 199 | */ 200 | if (meta->size > 0) { 201 | fprintf(stdout, "-- Meta Block --\n"); 202 | (void)fwrite(meta->data, 1, meta->size, stdout); 203 | } 204 | 205 | hoedown_buffer_free(meta); 206 | ``` 207 | 208 | Execution parse result. 209 | 210 | ``` 211 | 215 | 216 | This is hoextdown example. 217 | ``` 218 | 219 | becomes: 220 | 221 | ``` 222 |

This is hoextdown example.

223 | --- Meta Block -- 224 | author: user 225 | title: Readme markdown parser 226 | ``` 227 | 228 | ## Definition Lists 229 | 230 | Add the `HOEXTDOWN_EXT_DEFINITION_LISTS` to Hoedown document flags. 231 | 232 | Add to support definition lists. Syntax follows [PHP Markdown Extra's syntax](https://michelf.ca/projects/php-markdown/extra/#def-list). 233 | 234 | ``` 235 | Term 236 | : Definition 237 | 238 | Term 1 239 | Term 2 240 | : Definition 2 241 | 242 | Term 3 243 | : Definition Line 1 244 | Definition Line 2 245 | 246 | Extra paragraphs need four spaces. 247 | ``` 248 | 249 | becomes: 250 | 251 | ``` 252 |
253 |
Term
254 |
Definition
255 |
Term 1
256 |
Term 2
257 |
Definition 2
258 |
Term 3
259 |
260 |

Definition Line 1 Definition Line 2

261 |

Extra paragraphs need four spaces.

262 |
263 |
264 | ``` 265 | -------------------------------------------------------------------------------- /bin/common.h: -------------------------------------------------------------------------------- 1 | #include "version.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define str(x) __str(x) 9 | #define __str(x) #x 10 | 11 | #define count_of(arr) (sizeof(arr)/sizeof(0[arr])) 12 | 13 | int 14 | parseint(const char *string, long *result) 15 | { 16 | char *end; 17 | errno = 0; 18 | *result = strtol(string, &end, 10); 19 | return !(*end || errno); 20 | } 21 | 22 | const char * 23 | strprefix(const char *str, const char *prefix) 24 | { 25 | while (*prefix) { 26 | if (!(*str && *str == *prefix)) return 0; 27 | prefix++; str++; 28 | } 29 | return str; 30 | } 31 | 32 | void 33 | print_option(char short_opt, const char *long_opt, const char *description) 34 | { 35 | if (short_opt) 36 | printf(" -%c, ", short_opt); 37 | else 38 | printf(" "); 39 | 40 | printf("--%-13s %s\n", long_opt, description); 41 | } 42 | 43 | void 44 | print_version() 45 | { 46 | int major, minor, revision, extras; 47 | hoedown_version(&major, &minor, &revision, &extras); 48 | printf("Built with Hoedown v%d.%d.%d.%d.\n", major, minor, revision, extras); 49 | } 50 | 51 | int 52 | parse_options( 53 | int argc, char **argv, 54 | int(*parse_short_option)(char opt, char *next, void *opaque), 55 | int(*parse_long_option)(char *opt, char *next, void *opaque), 56 | int(*parse_argument)(int argn, char *arg, int is_forced, void *opaque), 57 | void *opaque) 58 | { 59 | int result; 60 | int i = 1, regular_args = 0; 61 | 62 | /* Parse options mixed with arguments */ 63 | while (i < argc) { 64 | char *arg = argv[i]; 65 | 66 | if (arg[0] == '-' && arg[1]) { 67 | char *next_arg = (i+1 < argc) ? argv[i+1] : NULL; 68 | 69 | if (arg[1] == '-' && !arg[2]) { 70 | /* '--' signals end of options */ 71 | i++; 72 | break; 73 | } 74 | 75 | if (arg[1] == '-') { 76 | /* Long option */ 77 | result = parse_long_option(arg + 2, next_arg, opaque); 78 | if (!result) return 0; 79 | i += result; 80 | } else { 81 | /* Sequence of short options */ 82 | size_t pos; 83 | for (pos = 1; arg[pos]; pos++) { 84 | char *next = (arg[pos+1]) ? arg + pos+1 : next_arg; 85 | result = parse_short_option(arg[pos], next, opaque); 86 | if (!result) return 0; 87 | if (result == 2) { 88 | if (next == next_arg) i++; 89 | break; 90 | } 91 | } 92 | i++; 93 | } 94 | } else { 95 | /* Argument */ 96 | result = parse_argument(regular_args++, arg, 0, opaque); 97 | if (!result) return 0; 98 | i++; 99 | } 100 | } 101 | 102 | /* Parse rest as forced arguments */ 103 | while (i < argc) { 104 | result = parse_argument(regular_args++, argv[i], 1, opaque); 105 | if (!result) return 0; 106 | i++; 107 | } 108 | 109 | return 1; 110 | } 111 | -------------------------------------------------------------------------------- /bin/smartypants.c: -------------------------------------------------------------------------------- 1 | #include "html.h" 2 | 3 | #include "common.h" 4 | /*#include */ 5 | 6 | 7 | /* FEATURES INFO / DEFAULTS */ 8 | 9 | #define DEF_IUNIT 1024 10 | #define DEF_OUNIT 64 11 | 12 | 13 | /* PRINT HELP */ 14 | 15 | void 16 | print_help(const char *basename) 17 | { 18 | /* usage */ 19 | printf("Usage: %s [OPTION]... [FILE]\n\n", basename); 20 | 21 | /* description */ 22 | printf("Apply SmartyPants smart punctuation to the HTML in FILE (or standard input), and output the resulting HTML to standard output.\n\n"); 23 | 24 | /* main options */ 25 | printf("Main options:\n"); 26 | print_option('T', "time", "Show time spent in SmartyPants processing."); 27 | print_option('i', "input-unit=N", "Reading block size. Default is " str(DEF_IUNIT) "."); 28 | print_option('o', "output-unit=N", "Writing block size. Default is " str(DEF_OUNIT) "."); 29 | print_option('h', "help", "Print this help text."); 30 | print_option('v', "version", "Print Hoedown version."); 31 | printf("\n"); 32 | 33 | /* ending */ 34 | printf("Options are processed in order, so in case of contradictory options the last specified stands.\n\n"); 35 | 36 | printf("When FILE is '-', read standard input. If no FILE was given, read standard input. Use '--' to signal end of option parsing. " 37 | "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"); 38 | } 39 | 40 | 41 | /* OPTION PARSING */ 42 | 43 | struct option_data { 44 | char *basename; 45 | int done; 46 | 47 | /* time reporting */ 48 | int show_time; 49 | 50 | /* I/O */ 51 | size_t iunit; 52 | size_t ounit; 53 | const char *filename; 54 | }; 55 | 56 | int 57 | parse_short_option(char opt, char *next, void *opaque) 58 | { 59 | struct option_data *data = opaque; 60 | long int num; 61 | int isNum = next ? parseint(next, &num) : 0; 62 | 63 | if (opt == 'h') { 64 | print_help(data->basename); 65 | data->done = 1; 66 | return 0; 67 | } 68 | 69 | if (opt == 'v') { 70 | print_version(); 71 | data->done = 1; 72 | return 0; 73 | } 74 | 75 | if (opt == 'T') { 76 | data->show_time = 1; 77 | return 1; 78 | } 79 | 80 | /* options requiring value */ 81 | /* FIXME: add validation */ 82 | 83 | if (opt == 'i' && isNum) { 84 | data->iunit = num; 85 | return 2; 86 | } 87 | 88 | if (opt == 'o' && isNum) { 89 | data->ounit = num; 90 | return 2; 91 | } 92 | 93 | fprintf(stderr, "Wrong option '-%c' found.\n", opt); 94 | return 0; 95 | } 96 | 97 | int 98 | parse_long_option(char *opt, char *next, void *opaque) 99 | { 100 | struct option_data *data = opaque; 101 | long int num; 102 | int isNum = next ? parseint(next, &num) : 0; 103 | 104 | if (strcmp(opt, "help")==0) { 105 | print_help(data->basename); 106 | data->done = 1; 107 | return 0; 108 | } 109 | 110 | if (strcmp(opt, "version")==0) { 111 | print_version(); 112 | data->done = 1; 113 | return 0; 114 | } 115 | 116 | if (strcmp(opt, "time")==0) { 117 | data->show_time = 1; 118 | return 1; 119 | } 120 | 121 | /* FIXME: validation */ 122 | 123 | if (strcmp(opt, "input-unit")==0 && isNum) { 124 | data->iunit = num; 125 | return 2; 126 | } 127 | if (strcmp(opt, "output-unit")==0 && isNum) { 128 | data->ounit = num; 129 | return 2; 130 | } 131 | 132 | fprintf(stderr, "Wrong option '--%s' found.\n", opt); 133 | return 0; 134 | } 135 | 136 | int 137 | parse_argument(int argn, char *arg, int is_forced, void *opaque) 138 | { 139 | struct option_data *data = opaque; 140 | 141 | if (argn == 0) { 142 | /* Input file */ 143 | if (strcmp(arg, "-")!=0 || is_forced) data->filename = arg; 144 | return 1; 145 | } 146 | 147 | fprintf(stderr, "Too many arguments.\n"); 148 | return 0; 149 | } 150 | 151 | 152 | /* MAIN LOGIC */ 153 | 154 | int 155 | main(int argc, char **argv) 156 | { 157 | struct option_data data; 158 | /*struct timespec start, end;*/ 159 | FILE *file = stdin; 160 | hoedown_buffer *ib, *ob; 161 | 162 | /* Parse options */ 163 | data.basename = argv[0]; 164 | data.done = 0; 165 | data.show_time = 0; 166 | data.iunit = DEF_IUNIT; 167 | data.ounit = DEF_OUNIT; 168 | data.filename = NULL; 169 | 170 | argc = parse_options(argc, argv, parse_short_option, parse_long_option, parse_argument, &data); 171 | if (data.done) return 0; 172 | if (!argc) return 1; 173 | 174 | /* Open input file, if needed */ 175 | if (data.filename) { 176 | file = fopen(data.filename, "r"); 177 | if (!file) { 178 | fprintf(stderr, "Unable to open input file \"%s\": %s\n", data.filename, strerror(errno)); 179 | return 5; 180 | } 181 | } 182 | 183 | /* Read everything */ 184 | ib = hoedown_buffer_new(data.iunit); 185 | 186 | while (!feof(file)) { 187 | if (ferror(file)) { 188 | fprintf(stderr, "I/O errors found while reading input.\n"); 189 | return 5; 190 | } 191 | hoedown_buffer_grow(ib, ib->size + data.iunit); 192 | ib->size += fread(ib->data + ib->size, 1, data.iunit, file); 193 | } 194 | 195 | if (file != stdin) fclose(file); 196 | 197 | /* Perform SmartyPants processing */ 198 | ob = hoedown_buffer_new(data.ounit); 199 | 200 | /*clock_gettime(CLOCK_MONOTONIC, &start);*/ 201 | hoedown_html_smartypants(ob, ib->data, ib->size); 202 | /*clock_gettime(CLOCK_MONOTONIC, &end);*/ 203 | 204 | /* Write the result to stdout */ 205 | (void)fwrite(ob->data, 1, ob->size, stdout); 206 | 207 | /* Show rendering time */ 208 | if (data.show_time) { 209 | /*TODO: enable this 210 | long long elapsed = (end.tv_sec - start.tv_sec)*1e9 + (end.tv_nsec - start.tv_nsec); 211 | if (elapsed < 1e9) 212 | fprintf(stderr, "Time spent on rendering: %.2f ms.\n", ((double)elapsed)/1e6); 213 | else 214 | fprintf(stderr, "Time spent on rendering: %.3f s.\n", ((double)elapsed)/1e9); 215 | */ 216 | } 217 | 218 | /* Cleanup */ 219 | hoedown_buffer_free(ib); 220 | hoedown_buffer_free(ob); 221 | 222 | if (ferror(stdout)) { 223 | fprintf(stderr, "I/O errors found while writing output.\n"); 224 | return 5; 225 | } 226 | 227 | return 0; 228 | } 229 | -------------------------------------------------------------------------------- /hoedown.def: -------------------------------------------------------------------------------- 1 | LIBRARY HOEDOWN 2 | EXPORTS 3 | hoedown_autolink_is_safe 4 | hoedown_autolink__www 5 | hoedown_autolink__email 6 | hoedown_autolink__url 7 | hoedown_buffer_init 8 | hoedown_buffer_new 9 | hoedown_buffer_reset 10 | hoedown_buffer_grow 11 | hoedown_buffer_put 12 | hoedown_buffer_puts 13 | hoedown_buffer_putc 14 | hoedown_buffer_set 15 | hoedown_buffer_sets 16 | hoedown_buffer_eq 17 | hoedown_buffer_eqs 18 | hoedown_buffer_prefix 19 | hoedown_buffer_slurp 20 | hoedown_buffer_cstr 21 | hoedown_buffer_printf 22 | hoedown_buffer_free 23 | hoedown_document_new 24 | hoedown_document_render 25 | hoedown_document_render_inline 26 | hoedown_document_free 27 | hoedown_escape_href 28 | hoedown_escape_html 29 | hoedown_html_smartypants 30 | hoedown_html_is_tag 31 | hoedown_html_renderer_new 32 | hoedown_html_toc_renderer_new 33 | hoedown_html_renderer_free 34 | hoedown_stack_init 35 | hoedown_stack_uninit 36 | hoedown_stack_grow 37 | hoedown_stack_push 38 | hoedown_stack_pop 39 | hoedown_stack_top 40 | hoedown_version 41 | -------------------------------------------------------------------------------- /html5_block_names.gperf: -------------------------------------------------------------------------------- 1 | p 2 | dl 3 | h1 4 | h2 5 | h3 6 | h4 7 | h5 8 | h6 9 | ol 10 | ul 11 | del 12 | div 13 | ins 14 | nav 15 | pre 16 | form 17 | math 18 | aside 19 | style 20 | table 21 | video 22 | canvas 23 | figure 24 | footer 25 | header 26 | hgroup 27 | iframe 28 | output 29 | script 30 | article 31 | section 32 | fieldset 33 | noscript 34 | blockquote 35 | figcaption 36 | -------------------------------------------------------------------------------- /html_block_names.gperf: -------------------------------------------------------------------------------- 1 | p 2 | dl 3 | h1 4 | h2 5 | h3 6 | h4 7 | h5 8 | h6 9 | ol 10 | ul 11 | del 12 | div 13 | ins 14 | pre 15 | form 16 | math 17 | style 18 | table 19 | figure 20 | iframe 21 | script 22 | fieldset 23 | noscript 24 | blockquote 25 | -------------------------------------------------------------------------------- /src/autolink.c: -------------------------------------------------------------------------------- 1 | #include "autolink.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #ifndef _MSC_VER 9 | #include 10 | #else 11 | #define strncasecmp _strnicmp 12 | #endif 13 | 14 | int 15 | hoedown_autolink_is_safe(const uint8_t *data, size_t size) 16 | { 17 | static const size_t valid_uris_count = 6; 18 | static const char *valid_uris[] = { 19 | "http://", "https://", "/", "#", "ftp://", "mailto:" 20 | }; 21 | static const size_t valid_uris_size[] = { 7, 8, 1, 1, 6, 7 }; 22 | size_t i; 23 | 24 | for (i = 0; i < valid_uris_count; ++i) { 25 | size_t len = valid_uris_size[i]; 26 | 27 | if (size > len && 28 | strncasecmp((char *)data, valid_uris[i], len) == 0 && 29 | isalnum(data[len])) 30 | return 1; 31 | } 32 | 33 | return 0; 34 | } 35 | 36 | static size_t 37 | autolink_delim(uint8_t *data, size_t link_end, size_t max_rewind, size_t size) 38 | { 39 | uint8_t cclose, copen = 0; 40 | size_t i; 41 | 42 | for (i = 0; i < link_end; ++i) 43 | if (data[i] == '<') { 44 | link_end = i; 45 | break; 46 | } 47 | 48 | while (link_end > 0) { 49 | if (strchr("?!.,:", data[link_end - 1]) != NULL) 50 | link_end--; 51 | 52 | else if (data[link_end - 1] == ';') { 53 | size_t new_end = link_end - 2; 54 | 55 | while (new_end > 0 && isalpha(data[new_end])) 56 | new_end--; 57 | 58 | if (new_end < link_end - 2 && data[new_end] == '&') 59 | link_end = new_end; 60 | else 61 | link_end--; 62 | } 63 | else break; 64 | } 65 | 66 | if (link_end == 0) 67 | return 0; 68 | 69 | cclose = data[link_end - 1]; 70 | 71 | switch (cclose) { 72 | case '"': copen = '"'; break; 73 | case '\'': copen = '\''; break; 74 | case ')': copen = '('; break; 75 | case ']': copen = '['; break; 76 | case '}': copen = '{'; break; 77 | } 78 | 79 | if (copen != 0) { 80 | size_t closing = 0; 81 | size_t opening = 0; 82 | size_t i = 0; 83 | 84 | /* Try to close the final punctuation sign in this same line; 85 | * if we managed to close it outside of the URL, that means that it's 86 | * not part of the URL. If it closes inside the URL, that means it 87 | * is part of the URL. 88 | * 89 | * Examples: 90 | * 91 | * foo http://www.pokemon.com/Pikachu_(Electric) bar 92 | * => http://www.pokemon.com/Pikachu_(Electric) 93 | * 94 | * foo (http://www.pokemon.com/Pikachu_(Electric)) bar 95 | * => http://www.pokemon.com/Pikachu_(Electric) 96 | * 97 | * foo http://www.pokemon.com/Pikachu_(Electric)) bar 98 | * => http://www.pokemon.com/Pikachu_(Electric)) 99 | * 100 | * (foo http://www.pokemon.com/Pikachu_(Electric)) bar 101 | * => foo http://www.pokemon.com/Pikachu_(Electric) 102 | */ 103 | 104 | while (i < link_end) { 105 | if (data[i] == copen) 106 | opening++; 107 | else if (data[i] == cclose) 108 | closing++; 109 | 110 | i++; 111 | } 112 | 113 | if (closing != opening) 114 | link_end--; 115 | } 116 | 117 | return link_end; 118 | } 119 | 120 | static size_t 121 | check_domain(uint8_t *data, size_t size, int allow_short) 122 | { 123 | size_t i, np = 0; 124 | 125 | if (!isalnum(data[0])) 126 | return 0; 127 | 128 | for (i = 1; i < size - 1; ++i) { 129 | if (strchr(".:", data[i]) != NULL) np++; 130 | else if (!isalnum(data[i]) && data[i] != '-') break; 131 | } 132 | 133 | if (allow_short) { 134 | /* We don't need a valid domain in the strict sense (with 135 | * least one dot; so just make sure it's composed of valid 136 | * domain characters and return the length of the the valid 137 | * sequence. */ 138 | return i; 139 | } else { 140 | /* a valid domain needs to have at least a dot. 141 | * that's as far as we get */ 142 | return np ? i : 0; 143 | } 144 | } 145 | 146 | size_t 147 | hoedown_autolink__www( 148 | size_t *rewind_p, 149 | hoedown_buffer *link, 150 | uint8_t *data, 151 | size_t max_rewind, 152 | size_t size, 153 | unsigned int flags) 154 | { 155 | size_t link_end; 156 | 157 | if (max_rewind > 0 && !ispunct(data[-1]) && !isspace(data[-1])) 158 | return 0; 159 | 160 | if (size < 4 || memcmp(data, "www.", strlen("www.")) != 0) 161 | return 0; 162 | 163 | link_end = check_domain(data, size, 0); 164 | 165 | if (link_end == 0) 166 | return 0; 167 | 168 | while (link_end < size && !isspace(data[link_end])) 169 | link_end++; 170 | 171 | link_end = autolink_delim(data, link_end, max_rewind, size); 172 | 173 | if (link_end == 0) 174 | return 0; 175 | 176 | hoedown_buffer_put(link, data, link_end); 177 | *rewind_p = 0; 178 | 179 | return (int)link_end; 180 | } 181 | 182 | size_t 183 | hoedown_autolink__email( 184 | size_t *rewind_p, 185 | hoedown_buffer *link, 186 | uint8_t *data, 187 | size_t max_rewind, 188 | size_t size, 189 | unsigned int flags) 190 | { 191 | size_t link_end, rewind; 192 | int nb = 0, np = 0; 193 | 194 | for (rewind = 0; rewind < max_rewind; ++rewind) { 195 | uint8_t c = data[-1 - rewind]; 196 | 197 | if (isalnum(c)) 198 | continue; 199 | 200 | if (strchr(".+-_", c) != NULL) 201 | continue; 202 | 203 | break; 204 | } 205 | 206 | if (rewind == 0) 207 | return 0; 208 | 209 | for (link_end = 0; link_end < size; ++link_end) { 210 | uint8_t c = data[link_end]; 211 | 212 | if (isalnum(c)) 213 | continue; 214 | 215 | if (c == '@') 216 | nb++; 217 | else if (c == '.' && link_end < size - 1) 218 | np++; 219 | else if (c != '-' && c != '_') 220 | break; 221 | } 222 | 223 | if (link_end < 2 || nb != 1 || np == 0 || 224 | !isalpha(data[link_end - 1])) 225 | return 0; 226 | 227 | link_end = autolink_delim(data, link_end, max_rewind, size); 228 | 229 | if (link_end == 0) 230 | return 0; 231 | 232 | hoedown_buffer_put(link, data - rewind, link_end + rewind); 233 | *rewind_p = rewind; 234 | 235 | return link_end; 236 | } 237 | 238 | size_t 239 | hoedown_autolink__url( 240 | size_t *rewind_p, 241 | hoedown_buffer *link, 242 | uint8_t *data, 243 | size_t max_rewind, 244 | size_t size, 245 | unsigned int flags) 246 | { 247 | size_t link_end, rewind = 0, domain_len; 248 | 249 | if (size < 4 || data[1] != '/' || data[2] != '/') 250 | return 0; 251 | 252 | while (rewind < max_rewind && isalpha(data[-1 - rewind])) 253 | rewind++; 254 | 255 | if (!hoedown_autolink_is_safe(data - rewind, size + rewind)) 256 | return 0; 257 | 258 | link_end = strlen("://"); 259 | 260 | domain_len = check_domain( 261 | data + link_end, 262 | size - link_end, 263 | flags & HOEDOWN_AUTOLINK_SHORT_DOMAINS); 264 | 265 | if (domain_len == 0) 266 | return 0; 267 | 268 | link_end += domain_len; 269 | while (link_end < size && !isspace(data[link_end])) 270 | link_end++; 271 | 272 | link_end = autolink_delim(data, link_end, max_rewind, size); 273 | 274 | if (link_end == 0) 275 | return 0; 276 | 277 | hoedown_buffer_put(link, data - rewind, link_end + rewind); 278 | *rewind_p = rewind; 279 | 280 | return link_end; 281 | } 282 | -------------------------------------------------------------------------------- /src/autolink.h: -------------------------------------------------------------------------------- 1 | /* autolink.h - versatile autolinker */ 2 | 3 | #ifndef HOEDOWN_AUTOLINK_H 4 | #define HOEDOWN_AUTOLINK_H 5 | 6 | #include "buffer.h" 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | 13 | /************* 14 | * CONSTANTS * 15 | *************/ 16 | 17 | typedef enum hoedown_autolink_flags { 18 | HOEDOWN_AUTOLINK_SHORT_DOMAINS = (1 << 0) 19 | } hoedown_autolink_flags; 20 | 21 | 22 | /************* 23 | * FUNCTIONS * 24 | *************/ 25 | 26 | /* hoedown_autolink_is_safe: verify that a URL has a safe protocol */ 27 | int hoedown_autolink_is_safe(const uint8_t *data, size_t size); 28 | 29 | /* hoedown_autolink__www: search for the next www link in data */ 30 | size_t hoedown_autolink__www(size_t *rewind_p, hoedown_buffer *link, 31 | uint8_t *data, size_t offset, size_t size, hoedown_autolink_flags flags); 32 | 33 | /* hoedown_autolink__email: search for the next email in data */ 34 | size_t hoedown_autolink__email(size_t *rewind_p, hoedown_buffer *link, 35 | uint8_t *data, size_t offset, size_t size, hoedown_autolink_flags flags); 36 | 37 | /* hoedown_autolink__url: search for the next URL in data */ 38 | size_t hoedown_autolink__url(size_t *rewind_p, hoedown_buffer *link, 39 | uint8_t *data, size_t offset, size_t size, hoedown_autolink_flags flags); 40 | 41 | 42 | #ifdef __cplusplus 43 | } 44 | #endif 45 | 46 | #endif /** HOEDOWN_AUTOLINK_H **/ 47 | -------------------------------------------------------------------------------- /src/buffer.c: -------------------------------------------------------------------------------- 1 | #include "buffer.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | void * 9 | hoedown_malloc(size_t size) 10 | { 11 | void *ret = malloc(size); 12 | 13 | if (!ret) { 14 | fprintf(stderr, "Allocation failed.\n"); 15 | abort(); 16 | } 17 | 18 | return ret; 19 | } 20 | 21 | void * 22 | hoedown_calloc(size_t nmemb, size_t size) 23 | { 24 | void *ret = calloc(nmemb, size); 25 | 26 | if (!ret) { 27 | fprintf(stderr, "Allocation failed.\n"); 28 | abort(); 29 | } 30 | 31 | return ret; 32 | } 33 | 34 | void * 35 | hoedown_realloc(void *ptr, size_t size) 36 | { 37 | void *ret = realloc(ptr, size); 38 | 39 | if (!ret) { 40 | fprintf(stderr, "Allocation failed.\n"); 41 | abort(); 42 | } 43 | 44 | return ret; 45 | } 46 | 47 | void 48 | hoedown_buffer_init( 49 | hoedown_buffer *buf, 50 | size_t unit, 51 | hoedown_realloc_callback data_realloc, 52 | hoedown_free_callback data_free, 53 | hoedown_free_callback buffer_free) 54 | { 55 | assert(buf); 56 | 57 | buf->data = NULL; 58 | buf->size = buf->asize = 0; 59 | buf->unit = unit; 60 | buf->data_realloc = data_realloc; 61 | buf->data_free = data_free; 62 | buf->buffer_free = buffer_free; 63 | } 64 | 65 | void 66 | hoedown_buffer_uninit(hoedown_buffer *buf) 67 | { 68 | assert(buf && buf->unit); 69 | buf->data_free(buf->data); 70 | } 71 | 72 | hoedown_buffer * 73 | hoedown_buffer_new(size_t unit) 74 | { 75 | hoedown_buffer *ret = hoedown_malloc(sizeof (hoedown_buffer)); 76 | hoedown_buffer_init(ret, unit, hoedown_realloc, free, free); 77 | return ret; 78 | } 79 | 80 | void 81 | hoedown_buffer_free(hoedown_buffer *buf) 82 | { 83 | if (!buf) return; 84 | assert(buf && buf->unit); 85 | 86 | buf->data_free(buf->data); 87 | 88 | if (buf->buffer_free) 89 | buf->buffer_free(buf); 90 | } 91 | 92 | void 93 | hoedown_buffer_reset(hoedown_buffer *buf) 94 | { 95 | assert(buf && buf->unit); 96 | 97 | buf->data_free(buf->data); 98 | buf->data = NULL; 99 | buf->size = buf->asize = 0; 100 | } 101 | 102 | void 103 | hoedown_buffer_grow(hoedown_buffer *buf, size_t neosz) 104 | { 105 | size_t neoasz; 106 | assert(buf && buf->unit); 107 | 108 | if (buf->asize >= neosz) 109 | return; 110 | 111 | neoasz = buf->asize + buf->unit; 112 | while (neoasz < neosz) 113 | neoasz += buf->unit; 114 | 115 | buf->data = buf->data_realloc(buf->data, neoasz); 116 | buf->asize = neoasz; 117 | } 118 | 119 | void 120 | hoedown_buffer_put(hoedown_buffer *buf, const uint8_t *data, size_t size) 121 | { 122 | assert(buf && buf->unit); 123 | 124 | if (buf->size + size > buf->asize) 125 | hoedown_buffer_grow(buf, buf->size + size); 126 | 127 | memcpy(buf->data + buf->size, data, size); 128 | buf->size += size; 129 | } 130 | 131 | void 132 | hoedown_buffer_puts(hoedown_buffer *buf, const char *str) 133 | { 134 | hoedown_buffer_put(buf, (const uint8_t *)str, strlen(str)); 135 | } 136 | 137 | void 138 | hoedown_buffer_putc(hoedown_buffer *buf, uint8_t c) 139 | { 140 | assert(buf && buf->unit); 141 | 142 | if (buf->size >= buf->asize) 143 | hoedown_buffer_grow(buf, buf->size + 1); 144 | 145 | buf->data[buf->size] = c; 146 | buf->size += 1; 147 | } 148 | 149 | int 150 | hoedown_buffer_putf(hoedown_buffer *buf, FILE *file) 151 | { 152 | assert(buf && buf->unit); 153 | 154 | while (!(feof(file) || ferror(file))) { 155 | hoedown_buffer_grow(buf, buf->size + buf->unit); 156 | buf->size += fread(buf->data + buf->size, 1, buf->unit, file); 157 | } 158 | 159 | return ferror(file); 160 | } 161 | 162 | void 163 | hoedown_buffer_set(hoedown_buffer *buf, const uint8_t *data, size_t size) 164 | { 165 | assert(buf && buf->unit); 166 | 167 | if (size > buf->asize) 168 | hoedown_buffer_grow(buf, size); 169 | 170 | memcpy(buf->data, data, size); 171 | buf->size = size; 172 | } 173 | 174 | void 175 | hoedown_buffer_sets(hoedown_buffer *buf, const char *str) 176 | { 177 | hoedown_buffer_set(buf, (const uint8_t *)str, strlen(str)); 178 | } 179 | 180 | int 181 | hoedown_buffer_eq(const hoedown_buffer *buf, const uint8_t *data, size_t size) 182 | { 183 | if (buf->size != size) return 0; 184 | return memcmp(buf->data, data, size) == 0; 185 | } 186 | 187 | int 188 | hoedown_buffer_eqs(const hoedown_buffer *buf, const char *str) 189 | { 190 | return hoedown_buffer_eq(buf, (const uint8_t *)str, strlen(str)); 191 | } 192 | 193 | int 194 | hoedown_buffer_prefix(const hoedown_buffer *buf, const char *prefix) 195 | { 196 | size_t i; 197 | 198 | for (i = 0; i < buf->size; ++i) { 199 | if (prefix[i] == 0) 200 | return 0; 201 | 202 | if (buf->data[i] != prefix[i]) 203 | return buf->data[i] - prefix[i]; 204 | } 205 | 206 | return 0; 207 | } 208 | 209 | void 210 | hoedown_buffer_slurp(hoedown_buffer *buf, size_t size) 211 | { 212 | assert(buf && buf->unit); 213 | 214 | if (size >= buf->size) { 215 | buf->size = 0; 216 | return; 217 | } 218 | 219 | buf->size -= size; 220 | memmove(buf->data, buf->data + size, buf->size); 221 | } 222 | 223 | const char * 224 | hoedown_buffer_cstr(hoedown_buffer *buf) 225 | { 226 | assert(buf && buf->unit); 227 | 228 | if (buf->size < buf->asize && buf->data[buf->size] == 0) 229 | return (char *)buf->data; 230 | 231 | hoedown_buffer_grow(buf, buf->size + 1); 232 | buf->data[buf->size] = 0; 233 | 234 | return (char *)buf->data; 235 | } 236 | 237 | void 238 | hoedown_buffer_printf(hoedown_buffer *buf, const char *fmt, ...) 239 | { 240 | va_list ap; 241 | int n; 242 | 243 | assert(buf && buf->unit); 244 | 245 | if (buf->size >= buf->asize) 246 | hoedown_buffer_grow(buf, buf->size + 1); 247 | 248 | va_start(ap, fmt); 249 | n = vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap); 250 | va_end(ap); 251 | 252 | if (n < 0) { 253 | #ifndef _MSC_VER 254 | return; 255 | #else 256 | va_start(ap, fmt); 257 | n = _vscprintf(fmt, ap); 258 | va_end(ap); 259 | #endif 260 | } 261 | 262 | if ((size_t)n >= buf->asize - buf->size) { 263 | hoedown_buffer_grow(buf, buf->size + n + 1); 264 | 265 | va_start(ap, fmt); 266 | n = vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap); 267 | va_end(ap); 268 | } 269 | 270 | if (n < 0) 271 | return; 272 | 273 | buf->size += n; 274 | } 275 | 276 | void hoedown_buffer_put_utf8(hoedown_buffer *buf, unsigned int c) { 277 | unsigned char unichar[4]; 278 | 279 | assert(buf && buf->unit); 280 | 281 | if (c < 0x80) { 282 | hoedown_buffer_putc(buf, c); 283 | } 284 | else if (c < 0x800) { 285 | unichar[0] = 192 + (c / 64); 286 | unichar[1] = 128 + (c % 64); 287 | hoedown_buffer_put(buf, unichar, 2); 288 | } 289 | else if (c - 0xd800u < 0x800) { 290 | HOEDOWN_BUFPUTSL(buf, "\xef\xbf\xbd"); 291 | } 292 | else if (c < 0x10000) { 293 | unichar[0] = 224 + (c / 4096); 294 | unichar[1] = 128 + (c / 64) % 64; 295 | unichar[2] = 128 + (c % 64); 296 | hoedown_buffer_put(buf, unichar, 3); 297 | } 298 | else if (c < 0x110000) { 299 | unichar[0] = 240 + (c / 262144); 300 | unichar[1] = 128 + (c / 4096) % 64; 301 | unichar[2] = 128 + (c / 64) % 64; 302 | unichar[3] = 128 + (c % 64); 303 | hoedown_buffer_put(buf, unichar, 4); 304 | } 305 | else { 306 | HOEDOWN_BUFPUTSL(buf, "\xef\xbf\xbd"); 307 | } 308 | } 309 | -------------------------------------------------------------------------------- /src/buffer.h: -------------------------------------------------------------------------------- 1 | /* buffer.h - simple, fast buffers */ 2 | 3 | #ifndef HOEDOWN_BUFFER_H 4 | #define HOEDOWN_BUFFER_H 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | #if defined(_MSC_VER) 17 | #define __attribute__(x) 18 | #define inline __inline 19 | #define __builtin_expect(x,n) x 20 | #endif 21 | 22 | 23 | /********* 24 | * TYPES * 25 | *********/ 26 | 27 | typedef void *(*hoedown_realloc_callback)(void *, size_t); 28 | typedef void (*hoedown_free_callback)(void *); 29 | 30 | struct hoedown_buffer { 31 | uint8_t *data; /* actual character data */ 32 | size_t size; /* size of the string */ 33 | size_t asize; /* allocated size (0 = volatile buffer) */ 34 | size_t unit; /* reallocation unit size (0 = read-only buffer) */ 35 | 36 | hoedown_realloc_callback data_realloc; 37 | hoedown_free_callback data_free; 38 | hoedown_free_callback buffer_free; 39 | }; 40 | 41 | typedef struct hoedown_buffer hoedown_buffer; 42 | 43 | 44 | /************* 45 | * FUNCTIONS * 46 | *************/ 47 | 48 | /* allocation wrappers */ 49 | void *hoedown_malloc(size_t size) __attribute__ ((malloc)); 50 | void *hoedown_calloc(size_t nmemb, size_t size) __attribute__ ((malloc)); 51 | void *hoedown_realloc(void *ptr, size_t size) __attribute__ ((malloc)); 52 | 53 | /* hoedown_buffer_init: initialize a buffer with custom allocators */ 54 | void hoedown_buffer_init( 55 | hoedown_buffer *buffer, 56 | size_t unit, 57 | hoedown_realloc_callback data_realloc, 58 | hoedown_free_callback data_free, 59 | hoedown_free_callback buffer_free 60 | ); 61 | 62 | /* hoedown_buffer_uninit: uninitialize an existing buffer */ 63 | void hoedown_buffer_uninit(hoedown_buffer *buf); 64 | 65 | /* hoedown_buffer_new: allocate a new buffer */ 66 | hoedown_buffer *hoedown_buffer_new(size_t unit) __attribute__ ((malloc)); 67 | 68 | /* hoedown_buffer_reset: free internal data of the buffer */ 69 | void hoedown_buffer_reset(hoedown_buffer *buf); 70 | 71 | /* hoedown_buffer_grow: increase the allocated size to the given value */ 72 | void hoedown_buffer_grow(hoedown_buffer *buf, size_t neosz); 73 | 74 | /* hoedown_buffer_put: append raw data to a buffer */ 75 | void hoedown_buffer_put(hoedown_buffer *buf, const uint8_t *data, size_t size); 76 | 77 | /* hoedown_buffer_puts: append a NUL-terminated string to a buffer */ 78 | void hoedown_buffer_puts(hoedown_buffer *buf, const char *str); 79 | 80 | /* hoedown_buffer_putc: append a single char to a buffer */ 81 | void hoedown_buffer_putc(hoedown_buffer *buf, uint8_t c); 82 | 83 | /* hoedown_buffer_putf: read from a file and append to a buffer, until EOF or error */ 84 | int hoedown_buffer_putf(hoedown_buffer *buf, FILE* file); 85 | 86 | /* hoedown_buffer_set: replace the buffer's contents with raw data */ 87 | void hoedown_buffer_set(hoedown_buffer *buf, const uint8_t *data, size_t size); 88 | 89 | /* hoedown_buffer_sets: replace the buffer's contents with a NUL-terminated string */ 90 | void hoedown_buffer_sets(hoedown_buffer *buf, const char *str); 91 | 92 | /* hoedown_buffer_eq: compare a buffer's data with other data for equality */ 93 | int hoedown_buffer_eq(const hoedown_buffer *buf, const uint8_t *data, size_t size); 94 | 95 | /* hoedown_buffer_eq: compare a buffer's data with NUL-terminated string for equality */ 96 | int hoedown_buffer_eqs(const hoedown_buffer *buf, const char *str); 97 | 98 | /* hoedown_buffer_prefix: compare the beginning of a buffer with a string */ 99 | int hoedown_buffer_prefix(const hoedown_buffer *buf, const char *prefix); 100 | 101 | /* hoedown_buffer_slurp: remove a given number of bytes from the head of the buffer */ 102 | void hoedown_buffer_slurp(hoedown_buffer *buf, size_t size); 103 | 104 | /* hoedown_buffer_cstr: NUL-termination of the string array (making a C-string) */ 105 | const char *hoedown_buffer_cstr(hoedown_buffer *buf); 106 | 107 | /* hoedown_buffer_printf: formatted printing to a buffer */ 108 | void hoedown_buffer_printf(hoedown_buffer *buf, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); 109 | 110 | /* hoedown_buffer_put_utf8: put a Unicode character encoded as UTF-8 */ 111 | void hoedown_buffer_put_utf8(hoedown_buffer *buf, unsigned int codepoint); 112 | 113 | /* hoedown_buffer_free: free the buffer */ 114 | void hoedown_buffer_free(hoedown_buffer *buf); 115 | 116 | 117 | /* HOEDOWN_BUFPUTSL: optimized hoedown_buffer_puts of a string literal */ 118 | #define HOEDOWN_BUFPUTSL(output, literal) \ 119 | hoedown_buffer_put(output, (const uint8_t *)literal, sizeof(literal) - 1) 120 | 121 | /* HOEDOWN_BUFSETSL: optimized hoedown_buffer_sets of a string literal */ 122 | #define HOEDOWN_BUFSETSL(output, literal) \ 123 | hoedown_buffer_set(output, (const uint8_t *)literal, sizeof(literal) - 1) 124 | 125 | /* HOEDOWN_BUFEQSL: optimized hoedown_buffer_eqs of a string literal */ 126 | #define HOEDOWN_BUFEQSL(output, literal) \ 127 | hoedown_buffer_eq(output, (const uint8_t *)literal, sizeof(literal) - 1) 128 | 129 | 130 | #ifdef __cplusplus 131 | } 132 | #endif 133 | 134 | #endif /** HOEDOWN_BUFFER_H **/ 135 | -------------------------------------------------------------------------------- /src/context_test.h: -------------------------------------------------------------------------------- 1 | /* context_test.h - context test renderer used to test parser state functions */ 2 | 3 | #ifndef CONTEXT_TEST_H 4 | #define CONTEXT_TEST_H 5 | 6 | #include "document.h" 7 | #include "buffer.h" 8 | #include "hash.h" 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | 15 | /********* 16 | * TYPES * 17 | *********/ 18 | 19 | struct hoedown_context_test_renderer_state { 20 | hoedown_document *doc; 21 | }; 22 | typedef struct hoedown_context_test_renderer_state hoedown_context_test_renderer_state; 23 | 24 | 25 | /************* 26 | * FUNCTIONS * 27 | *************/ 28 | 29 | /* hoedown_context_test_renderer_new: allocates a context test renderer */ 30 | hoedown_renderer *hoedown_context_test_renderer_new() __attribute__ ((malloc)); 31 | 32 | /* hoedown_context_test_renderer_free: deallocate a context test renderer */ 33 | void hoedown_context_test_renderer_free(hoedown_renderer *renderer); 34 | 35 | 36 | #ifdef __cplusplus 37 | } 38 | #endif 39 | 40 | #endif /** CONTEXT_TEST_H **/ 41 | -------------------------------------------------------------------------------- /src/escape.c: -------------------------------------------------------------------------------- 1 | #include "escape.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | #define likely(x) __builtin_expect((x),1) 9 | #define unlikely(x) __builtin_expect((x),0) 10 | 11 | 12 | /* 13 | * The following characters will not be escaped: 14 | * 15 | * -_.+!*'(),%#@?=;:/,+&$ alphanum 16 | * 17 | * Note that this character set is the addition of: 18 | * 19 | * - The characters which are safe to be in an URL 20 | * - The characters which are *not* safe to be in 21 | * an URL because they are RESERVED characters. 22 | * 23 | * We assume (lazily) that any RESERVED char that 24 | * appears inside an URL is actually meant to 25 | * have its native function (i.e. as an URL 26 | * component/separator) and hence needs no escaping. 27 | * 28 | * There are two exceptions: the chacters & (amp) 29 | * and ' (single quote) do not appear in the table. 30 | * They are meant to appear in the URL as components, 31 | * yet they require special HTML-entity escaping 32 | * to generate valid HTML markup. 33 | * 34 | * All other characters will be escaped to %XX. 35 | * 36 | */ 37 | static const uint8_t HREF_SAFE[UINT8_MAX+1] = { 38 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40 | 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 41 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 42 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 43 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 44 | 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 45 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 46 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54 | }; 55 | 56 | void 57 | hoedown_escape_href(hoedown_buffer *ob, const uint8_t *data, size_t size) 58 | { 59 | static const char hex_chars[] = "0123456789ABCDEF"; 60 | size_t i = 0, mark; 61 | char hex_str[3]; 62 | 63 | hex_str[0] = '%'; 64 | 65 | while (i < size) { 66 | mark = i; 67 | while (i < size && HREF_SAFE[data[i]]) i++; 68 | 69 | /* Optimization for cases where there's nothing to escape */ 70 | if (mark == 0 && i >= size) { 71 | hoedown_buffer_put(ob, data, size); 72 | return; 73 | } 74 | 75 | if (likely(i > mark)) { 76 | hoedown_buffer_put(ob, data + mark, i - mark); 77 | } 78 | 79 | /* escaping */ 80 | if (i >= size) 81 | break; 82 | 83 | switch (data[i]) { 84 | /* amp appears all the time in URLs, but needs 85 | * HTML-entity escaping to be inside an href */ 86 | case '&': 87 | HOEDOWN_BUFPUTSL(ob, "&"); 88 | break; 89 | 90 | /* the single quote is a valid URL character 91 | * according to the standard; it needs HTML 92 | * entity escaping too */ 93 | case '\'': 94 | HOEDOWN_BUFPUTSL(ob, "'"); 95 | break; 96 | 97 | /* the space can be escaped to %20 or a plus 98 | * sign. we're going with the generic escape 99 | * for now. the plus thing is more commonly seen 100 | * when building GET strings */ 101 | #if 0 102 | case ' ': 103 | hoedown_buffer_putc(ob, '+'); 104 | break; 105 | #endif 106 | 107 | /* every other character goes with a %XX escaping */ 108 | default: 109 | hex_str[1] = hex_chars[(data[i] >> 4) & 0xF]; 110 | hex_str[2] = hex_chars[data[i] & 0xF]; 111 | hoedown_buffer_put(ob, (uint8_t *)hex_str, 3); 112 | } 113 | 114 | i++; 115 | } 116 | } 117 | 118 | 119 | /** 120 | * According to the OWASP rules: 121 | * 122 | * & --> & 123 | * < --> < 124 | * > --> > 125 | * " --> " 126 | * ' --> ' ' is not recommended 127 | * / --> / forward slash is included as it helps end an HTML entity 128 | * 129 | */ 130 | static const uint8_t HTML_ESCAPE_TABLE[UINT8_MAX+1] = { 131 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 132 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 133 | 0, 0, 1, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 4, 134 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 6, 0, 135 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 137 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 139 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 141 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 147 | }; 148 | 149 | static const char *HTML_ESCAPES[] = { 150 | "", 151 | """, 152 | "&", 153 | "'", 154 | "/", 155 | "<", 156 | ">" 157 | }; 158 | 159 | void 160 | hoedown_escape_html(hoedown_buffer *ob, const uint8_t *data, size_t size, int secure) 161 | { 162 | size_t i = 0, mark; 163 | 164 | while (1) { 165 | mark = i; 166 | while (i < size && HTML_ESCAPE_TABLE[data[i]] == 0) i++; 167 | 168 | /* Optimization for cases where there's nothing to escape */ 169 | if (mark == 0 && i >= size) { 170 | hoedown_buffer_put(ob, data, size); 171 | return; 172 | } 173 | 174 | if (likely(i > mark)) 175 | hoedown_buffer_put(ob, data + mark, i - mark); 176 | 177 | if (i >= size) break; 178 | 179 | /* The forward slash is only escaped in secure mode */ 180 | if (!secure && data[i] == '/') { 181 | hoedown_buffer_putc(ob, '/'); 182 | } else { 183 | hoedown_buffer_puts(ob, HTML_ESCAPES[HTML_ESCAPE_TABLE[data[i]]]); 184 | } 185 | 186 | i++; 187 | } 188 | } 189 | -------------------------------------------------------------------------------- /src/escape.h: -------------------------------------------------------------------------------- 1 | /* escape.h - escape utilities */ 2 | 3 | #ifndef HOEDOWN_ESCAPE_H 4 | #define HOEDOWN_ESCAPE_H 5 | 6 | #include "buffer.h" 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | 13 | /************* 14 | * FUNCTIONS * 15 | *************/ 16 | 17 | /* hoedown_escape_href: escape (part of) a URL inside HTML */ 18 | void hoedown_escape_href(hoedown_buffer *ob, const uint8_t *data, size_t size); 19 | 20 | /* hoedown_escape_html: escape HTML */ 21 | void hoedown_escape_html(hoedown_buffer *ob, const uint8_t *data, size_t size, int secure); 22 | 23 | 24 | #ifdef __cplusplus 25 | } 26 | #endif 27 | 28 | #endif /** HOEDOWN_ESCAPE_H **/ 29 | -------------------------------------------------------------------------------- /src/hash.c: -------------------------------------------------------------------------------- 1 | #include "hash.h" 2 | 3 | #include 4 | #include 5 | 6 | #define HOEDOWN_HASH_ITEM_SIZE 255 7 | #define HOEDOWN_HASH_FNV_PRIME 0x01000193 8 | #define HOEDOWN_HASH_FNV_OFFSET_BASIS 0x811c9dc5 9 | 10 | static char * 11 | hoedown_hash_strndup(const char* str, size_t n) 12 | { 13 | if (str) { 14 | char *s = (char *)malloc(sizeof(char) * (n + 1)); 15 | if (s) { 16 | memcpy(s, str, n); 17 | s[n] = '\0'; 18 | } 19 | return s; 20 | } 21 | return NULL; 22 | } 23 | 24 | static char * 25 | hoedown_hash_strdup(const char* str) 26 | { 27 | if (str) { 28 | return hoedown_hash_strndup(str, strlen(str)); 29 | } 30 | return NULL; 31 | } 32 | 33 | static unsigned int 34 | hoedown_hash_fnv(const char *key, const char *max, size_t limit) 35 | { 36 | unsigned int hash = HOEDOWN_HASH_FNV_OFFSET_BASIS; 37 | 38 | if (max == NULL) { 39 | if (key) { 40 | max = key + strlen(key); 41 | } else { 42 | max = key; 43 | } 44 | } 45 | 46 | while (key < max) { 47 | hash *= HOEDOWN_HASH_FNV_PRIME; 48 | hash ^= *key; 49 | key++; 50 | } 51 | 52 | hash %= limit; 53 | 54 | return hash; 55 | } 56 | 57 | static hoedown_hash_item * 58 | hoedown_hash_item_new(void) 59 | { 60 | hoedown_hash_item *item; 61 | 62 | item = (hoedown_hash_item *)malloc(sizeof(hoedown_hash_item)); 63 | if (!item) { 64 | return NULL; 65 | } 66 | 67 | item->key = NULL; 68 | item->value = NULL; 69 | item->destruct = NULL; 70 | item->next = NULL; 71 | item->tail = NULL; 72 | 73 | return item; 74 | } 75 | 76 | static void 77 | hoedown_hash_item_free(hoedown_hash_item *item) 78 | { 79 | if (item) { 80 | if (item->next) { 81 | hoedown_hash_item_free(item->next); 82 | } 83 | if (item->key) { 84 | free(item->key); 85 | } 86 | if (item->destruct) { 87 | (item->destruct)(item->value); 88 | } 89 | free(item); 90 | } 91 | } 92 | 93 | static int 94 | hoedown_hash_item_push(hoedown_hash_item *item, const char *key, size_t key_len, 95 | void *value, hoedown_hash_value_destruct *destruct) 96 | { 97 | hoedown_hash_item *entry; 98 | 99 | if (!item || !key || !value) { 100 | return 1; 101 | } 102 | 103 | if (item->key != NULL) { 104 | entry = hoedown_hash_item_new(); 105 | if (!entry) { 106 | return 1; 107 | } 108 | } else { 109 | entry = item; 110 | } 111 | 112 | if (key_len > 0) { 113 | entry->key = hoedown_hash_strndup(key, key_len); 114 | } else { 115 | entry->key = hoedown_hash_strdup(key); 116 | } 117 | entry->value = value; 118 | entry->destruct = destruct; 119 | 120 | if (item->tail) { 121 | item->tail->next = entry; 122 | } else if (item != entry) { 123 | item->next = entry; 124 | } 125 | item->tail = entry; 126 | 127 | return 0; 128 | } 129 | 130 | hoedown_hash * 131 | hoedown_hash_new(size_t size) 132 | { 133 | hoedown_hash *hash; 134 | size_t items_size; 135 | 136 | hash = (hoedown_hash *)malloc(sizeof(hoedown_hash)); 137 | if (!hash) { 138 | return NULL; 139 | } 140 | 141 | if (size == 0) { 142 | size = HOEDOWN_HASH_ITEM_SIZE; 143 | } 144 | 145 | items_size = sizeof(hoedown_hash_item *) * size; 146 | 147 | hash->items = (hoedown_hash_item **)malloc(items_size); 148 | if (!hash->items) { 149 | free(hash); 150 | return NULL; 151 | } 152 | 153 | memset(hash->items, 0, items_size); 154 | 155 | hash->asize = size; 156 | 157 | return hash; 158 | } 159 | 160 | void 161 | hoedown_hash_free(hoedown_hash *hash) 162 | { 163 | if (hash) { 164 | if (hash->items) { 165 | size_t i = 0; 166 | while (i < hash->asize) { 167 | if (hash->items[i]) { 168 | hoedown_hash_item_free(hash->items[i]); 169 | } 170 | ++i; 171 | } 172 | free(hash->items); 173 | } 174 | free(hash); 175 | } 176 | } 177 | 178 | int 179 | hoedown_hash_add(hoedown_hash *hash, const char *key, size_t key_len, 180 | void *value, hoedown_hash_value_destruct *destruct) 181 | { 182 | unsigned int h; 183 | 184 | if (!hash || !key || !value) { 185 | return 1; 186 | } 187 | 188 | h = hoedown_hash_fnv(key, key + key_len, hash->asize); 189 | 190 | if (!hash->items[h]) { 191 | hash->items[h] = hoedown_hash_item_new(); 192 | if (!hash->items[h]) { 193 | return 1; 194 | } 195 | } 196 | 197 | if (hoedown_hash_item_push(hash->items[h], key, key_len, 198 | value, destruct) != 0) { 199 | return 1; 200 | } 201 | 202 | return 0; 203 | } 204 | 205 | void * 206 | hoedown_hash_find(hoedown_hash *hash, char *key, size_t key_len) 207 | { 208 | unsigned int h; 209 | 210 | if (!hash || !key) { 211 | return NULL; 212 | } 213 | 214 | h = hoedown_hash_fnv(key, key + key_len, hash->asize); 215 | 216 | if (hash->items[h]) { 217 | hoedown_hash_item *item = hash->items[h]; 218 | while (item != NULL) { 219 | if (item->key && strncmp(item->key, key, key_len) == 0) { 220 | return item->value; 221 | } 222 | item = item->next; 223 | } 224 | } 225 | 226 | return NULL; 227 | } 228 | -------------------------------------------------------------------------------- /src/hash.h: -------------------------------------------------------------------------------- 1 | /* hash.h - generic markdown parser */ 2 | 3 | #ifndef HOEDOWN_HASH_H 4 | #define HOEDOWN_HASH_H 5 | 6 | #include 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | typedef struct hoedown_hash_item hoedown_hash_item; 13 | typedef struct hoedown_hash hoedown_hash; 14 | typedef void (hoedown_hash_value_destruct) (void *data); 15 | 16 | struct hoedown_hash_item { 17 | char *key; 18 | void *value; 19 | hoedown_hash_value_destruct *destruct; 20 | hoedown_hash_item *next; 21 | hoedown_hash_item *tail; 22 | }; 23 | 24 | struct hoedown_hash { 25 | hoedown_hash_item **items; 26 | size_t asize; 27 | }; 28 | 29 | hoedown_hash * hoedown_hash_new(size_t size); 30 | void hoedown_hash_free(hoedown_hash *hash); 31 | int hoedown_hash_add(hoedown_hash *hash, const char *key, size_t key_len, void *value, hoedown_hash_value_destruct *destruct); 32 | void * hoedown_hash_find(hoedown_hash *hash, char *key, size_t key_len); 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif 37 | 38 | #endif /** HOEDOWN_HASH_H **/ 39 | -------------------------------------------------------------------------------- /src/html.h: -------------------------------------------------------------------------------- 1 | /* html.h - HTML renderer and utilities */ 2 | 3 | #ifndef HOEDOWN_HTML_H 4 | #define HOEDOWN_HTML_H 5 | 6 | #include "document.h" 7 | #include "buffer.h" 8 | #include "hash.h" 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | 15 | /************* 16 | * CONSTANTS * 17 | *************/ 18 | 19 | typedef enum hoedown_html_flags { 20 | HOEDOWN_HTML_SKIP_HTML = (1 << 0), 21 | HOEDOWN_HTML_ESCAPE = (1 << 1), 22 | HOEDOWN_HTML_HARD_WRAP = (1 << 2), 23 | HOEDOWN_HTML_USE_XHTML = (1 << 3), 24 | HOEDOWN_HTML_USE_TASK_LIST = (1 << 4), 25 | HOEDOWN_HTML_LINE_CONTINUE = (1 << 5), 26 | HOEDOWN_HTML_HEADER_ID = (1 << 6), 27 | HOEDOWN_HTML_FENCED_CODE_SCRIPT = (1 << 7), 28 | HOEDOWN_HTML_USE_RADIO_LIST = (1 << 8), 29 | } hoedown_html_flags; 30 | 31 | typedef enum hoedown_html_tag { 32 | HOEDOWN_HTML_TAG_NONE = 0, 33 | HOEDOWN_HTML_TAG_OPEN, 34 | HOEDOWN_HTML_TAG_CLOSE 35 | } hoedown_html_tag; 36 | 37 | 38 | /********* 39 | * TYPES * 40 | *********/ 41 | 42 | struct hoedown_html_renderer_state { 43 | void *opaque; 44 | 45 | struct { 46 | int header_count; 47 | int current_level; 48 | int level_offset; 49 | int nesting_level; 50 | char *header; 51 | char *footer; 52 | } toc_data; 53 | 54 | struct { 55 | hoedown_hash *header_id; 56 | } hash; 57 | 58 | hoedown_html_flags flags; 59 | 60 | int cur_list_id; 61 | 62 | /* extra callbacks */ 63 | void (*link_attributes)(hoedown_buffer *ob, const hoedown_buffer *url, const hoedown_renderer_data *data); 64 | }; 65 | typedef struct hoedown_html_renderer_state hoedown_html_renderer_state; 66 | 67 | 68 | /************* 69 | * FUNCTIONS * 70 | *************/ 71 | 72 | /* hoedown_html_smartypants: process an HTML snippet using SmartyPants for smart punctuation */ 73 | void hoedown_html_smartypants(hoedown_buffer *ob, const uint8_t *data, size_t size); 74 | 75 | /* hoedown_html_is_tag: checks if data starts with a specific tag, returns the tag type or NONE */ 76 | hoedown_html_tag hoedown_html_is_tag(const uint8_t *data, size_t size, const char *tagname); 77 | 78 | 79 | /* hoedown_html_renderer_new: allocates a regular HTML renderer */ 80 | hoedown_renderer *hoedown_html_renderer_new( 81 | hoedown_html_flags render_flags, 82 | int nesting_level 83 | ) __attribute__ ((malloc)); 84 | 85 | /* hoedown_html_toc_renderer_new: like hoedown_html_renderer_new, but the returned renderer produces the Table of Contents */ 86 | hoedown_renderer *hoedown_html_toc_renderer_new( 87 | int nesting_level 88 | ) __attribute__ ((malloc)); 89 | 90 | /* hoedown_html_renderer_free: deallocate an HTML renderer */ 91 | void hoedown_html_renderer_free(hoedown_renderer *renderer); 92 | 93 | 94 | #ifdef __cplusplus 95 | } 96 | #endif 97 | 98 | #endif /** HOEDOWN_HTML_H **/ 99 | -------------------------------------------------------------------------------- /src/html5_blocks.c: -------------------------------------------------------------------------------- 1 | /* ANSI-C code produced by gperf version 3.0.4 */ 2 | /* Command-line: gperf -L ANSI-C -N hoedown_find_html5_block_tag -c -C -E -S 1 --ignore-case -m100 html5_block_names.gperf */ 3 | /* Computed positions: -k'1-2' */ 4 | 5 | #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ 6 | && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ 7 | && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ 8 | && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ 9 | && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ 10 | && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ 11 | && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ 12 | && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ 13 | && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ 14 | && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ 15 | && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ 16 | && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ 17 | && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ 18 | && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ 19 | && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ 20 | && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ 21 | && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ 22 | && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ 23 | && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ 24 | && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ 25 | && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ 26 | && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ 27 | && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) 28 | /* The character set is not based on ISO-646. */ 29 | #error "gperf generated tables don't work with this execution character set. Please report a bug to ." 30 | #endif 31 | 32 | /* maximum key range = 37, duplicates = 0 */ 33 | 34 | #ifndef GPERF_DOWNCASE 35 | #define GPERF_DOWNCASE 1 36 | static unsigned char gperf_downcase[256] = 37 | { 38 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 39 | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 40 | 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 41 | 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 42 | 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 43 | 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 44 | 122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 45 | 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 46 | 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 47 | 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 48 | 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 49 | 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 50 | 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 51 | 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 52 | 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 53 | 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 54 | 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 55 | 255 56 | }; 57 | #endif 58 | 59 | #ifndef GPERF_CASE_STRNCMP 60 | #define GPERF_CASE_STRNCMP 1 61 | static int 62 | gperf_case_strncmp (register const char *s1, register const char *s2, register unsigned int n) 63 | { 64 | for (; n > 0;) 65 | { 66 | unsigned char c1 = gperf_downcase[(unsigned char)*s1++]; 67 | unsigned char c2 = gperf_downcase[(unsigned char)*s2++]; 68 | if (c1 != 0 && c1 == c2) 69 | { 70 | n--; 71 | continue; 72 | } 73 | return (int)c1 - (int)c2; 74 | } 75 | return 0; 76 | } 77 | #endif 78 | 79 | #ifdef __GNUC__ 80 | __inline 81 | #else 82 | #ifdef __cplusplus 83 | inline 84 | #endif 85 | #endif 86 | static unsigned int 87 | hash (register const char *str, register unsigned int len) 88 | { 89 | static const unsigned char asso_values[] = 90 | { 91 | 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 92 | 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 93 | 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 94 | 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 95 | 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 96 | 26, 25, 24, 23, 22, 21, 38, 38, 38, 38, 97 | 38, 38, 38, 38, 38, 17, 14, 9, 10, 38, 98 | 2, 16, 8, 6, 1, 38, 38, 0, 13, 18, 99 | 0, 38, 38, 1, 4, 1, 13, 38, 38, 38, 100 | 38, 38, 38, 38, 38, 38, 38, 17, 14, 9, 101 | 10, 38, 2, 16, 8, 6, 1, 38, 38, 0, 102 | 13, 18, 0, 38, 38, 1, 4, 1, 13, 38, 103 | 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 104 | 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 105 | 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 106 | 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 107 | 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 108 | 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 109 | 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 110 | 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 111 | 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 112 | 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 113 | 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 114 | 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 115 | 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 116 | 38, 38, 38, 38, 38, 38, 38 117 | }; 118 | register int hval = len; 119 | 120 | switch (hval) 121 | { 122 | default: 123 | hval += asso_values[(unsigned char)str[1]+1]; 124 | /*FALLTHROUGH*/ 125 | case 1: 126 | hval += asso_values[(unsigned char)str[0]]; 127 | break; 128 | } 129 | return hval; 130 | } 131 | 132 | #ifdef __GNUC__ 133 | __inline 134 | #if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__ 135 | __attribute__ ((__gnu_inline__)) 136 | #endif 137 | #endif 138 | const char * 139 | hoedown_find_html5_block_tag (register const char *str, register unsigned int len) 140 | { 141 | enum 142 | { 143 | TOTAL_KEYWORDS = 35, 144 | MIN_WORD_LENGTH = 1, 145 | MAX_WORD_LENGTH = 10, 146 | MIN_HASH_VALUE = 1, 147 | MAX_HASH_VALUE = 37 148 | }; 149 | 150 | if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) 151 | { 152 | register int key = hash (str, len); 153 | 154 | if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE) 155 | { 156 | register const char *resword; 157 | 158 | switch (key - 1) 159 | { 160 | case 0: 161 | resword = "p"; 162 | goto compare; 163 | case 2: 164 | resword = "ul"; 165 | goto compare; 166 | case 3: 167 | resword = "pre"; 168 | goto compare; 169 | case 5: 170 | resword = "form"; 171 | goto compare; 172 | case 6: 173 | resword = "style"; 174 | goto compare; 175 | case 7: 176 | resword = "footer"; 177 | goto compare; 178 | case 8: 179 | resword = "figure"; 180 | goto compare; 181 | case 9: 182 | resword = "section"; 183 | goto compare; 184 | case 10: 185 | resword = "fieldset"; 186 | goto compare; 187 | case 11: 188 | resword = "dl"; 189 | goto compare; 190 | case 12: 191 | resword = "figcaption"; 192 | goto compare; 193 | case 13: 194 | resword = "div"; 195 | goto compare; 196 | case 14: 197 | resword = "del"; 198 | goto compare; 199 | case 15: 200 | resword = "header"; 201 | goto compare; 202 | case 16: 203 | resword = "script"; 204 | goto compare; 205 | case 17: 206 | resword = "math"; 207 | goto compare; 208 | case 18: 209 | resword = "video"; 210 | goto compare; 211 | case 19: 212 | resword = "ol"; 213 | goto compare; 214 | case 20: 215 | resword = "noscript"; 216 | goto compare; 217 | case 21: 218 | resword = "hgroup"; 219 | goto compare; 220 | case 22: 221 | resword = "table"; 222 | goto compare; 223 | case 23: 224 | resword = "blockquote"; 225 | goto compare; 226 | case 24: 227 | resword = "article"; 228 | goto compare; 229 | case 25: 230 | resword = "aside"; 231 | goto compare; 232 | case 26: 233 | resword = "ins"; 234 | goto compare; 235 | case 27: 236 | resword = "iframe"; 237 | goto compare; 238 | case 28: 239 | resword = "canvas"; 240 | goto compare; 241 | case 29: 242 | resword = "nav"; 243 | goto compare; 244 | case 30: 245 | resword = "h6"; 246 | goto compare; 247 | case 31: 248 | resword = "h5"; 249 | goto compare; 250 | case 32: 251 | resword = "h4"; 252 | goto compare; 253 | case 33: 254 | resword = "h3"; 255 | goto compare; 256 | case 34: 257 | resword = "h2"; 258 | goto compare; 259 | case 35: 260 | resword = "h1"; 261 | goto compare; 262 | case 36: 263 | resword = "output"; 264 | goto compare; 265 | } 266 | return 0; 267 | compare: 268 | if ((((unsigned char)*str ^ (unsigned char)*resword) & ~32) == 0 && !gperf_case_strncmp (str, resword, len) && resword[len] == '\0') 269 | return resword; 270 | } 271 | } 272 | return 0; 273 | } 274 | -------------------------------------------------------------------------------- /src/html_blocks.c: -------------------------------------------------------------------------------- 1 | /* ANSI-C code produced by gperf version 3.0.3 */ 2 | /* Command-line: gperf -L ANSI-C -N hoedown_find_block_tag -c -C -E -S 1 --ignore-case -m100 html_block_names.gperf */ 3 | /* Computed positions: -k'1-2' */ 4 | 5 | #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ 6 | && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ 7 | && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ 8 | && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ 9 | && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ 10 | && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ 11 | && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ 12 | && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ 13 | && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ 14 | && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ 15 | && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ 16 | && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ 17 | && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ 18 | && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ 19 | && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ 20 | && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ 21 | && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ 22 | && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ 23 | && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ 24 | && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ 25 | && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ 26 | && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ 27 | && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) 28 | /* The character set is not based on ISO-646. */ 29 | #error "gperf generated tables don't work with this execution character set. Please report a bug to ." 30 | #endif 31 | 32 | /* maximum key range = 24, duplicates = 0 */ 33 | 34 | #ifndef GPERF_DOWNCASE 35 | #define GPERF_DOWNCASE 1 36 | static unsigned char gperf_downcase[256] = 37 | { 38 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 39 | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 40 | 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 41 | 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 42 | 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 43 | 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 44 | 122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 45 | 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 46 | 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 47 | 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 48 | 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 49 | 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 50 | 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 51 | 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 52 | 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 53 | 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 54 | 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 55 | 255 56 | }; 57 | #endif 58 | 59 | #ifndef GPERF_CASE_STRNCMP 60 | #define GPERF_CASE_STRNCMP 1 61 | static int 62 | gperf_case_strncmp (register const char *s1, register const char *s2, register unsigned int n) 63 | { 64 | for (; n > 0;) 65 | { 66 | unsigned char c1 = gperf_downcase[(unsigned char)*s1++]; 67 | unsigned char c2 = gperf_downcase[(unsigned char)*s2++]; 68 | if (c1 != 0 && c1 == c2) 69 | { 70 | n--; 71 | continue; 72 | } 73 | return (int)c1 - (int)c2; 74 | } 75 | return 0; 76 | } 77 | #endif 78 | 79 | #ifdef __GNUC__ 80 | __inline 81 | #else 82 | #ifdef __cplusplus 83 | inline 84 | #endif 85 | #endif 86 | static unsigned int 87 | hash (register const char *str, register unsigned int len) 88 | { 89 | static const unsigned char asso_values[] = 90 | { 91 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 92 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 93 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 94 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 95 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 96 | 22, 21, 19, 18, 16, 0, 25, 25, 25, 25, 97 | 25, 25, 25, 25, 25, 25, 1, 25, 0, 25, 98 | 1, 0, 0, 13, 0, 25, 25, 11, 2, 1, 99 | 0, 25, 25, 5, 0, 2, 25, 25, 25, 25, 100 | 25, 25, 25, 25, 25, 25, 25, 25, 1, 25, 101 | 0, 25, 1, 0, 0, 13, 0, 25, 25, 11, 102 | 2, 1, 0, 25, 25, 5, 0, 2, 25, 25, 103 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 104 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 105 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 106 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 107 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 108 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 109 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 110 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 111 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 112 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 113 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 114 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 115 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 116 | 25, 25, 25, 25, 25, 25, 25 117 | }; 118 | register int hval = (int)len; 119 | 120 | switch (hval) 121 | { 122 | default: 123 | hval += asso_values[(unsigned char)str[1]+1]; 124 | /*FALLTHROUGH*/ 125 | case 1: 126 | hval += asso_values[(unsigned char)str[0]]; 127 | break; 128 | } 129 | return hval; 130 | } 131 | 132 | #ifdef __GNUC__ 133 | __inline 134 | #ifdef __GNUC_STDC_INLINE__ 135 | __attribute__ ((__gnu_inline__)) 136 | #endif 137 | #endif 138 | const char * 139 | hoedown_find_block_tag (register const char *str, register unsigned int len) 140 | { 141 | enum 142 | { 143 | TOTAL_KEYWORDS = 24, 144 | MIN_WORD_LENGTH = 1, 145 | MAX_WORD_LENGTH = 10, 146 | MIN_HASH_VALUE = 1, 147 | MAX_HASH_VALUE = 24 148 | }; 149 | 150 | if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) 151 | { 152 | register int key = hash (str, len); 153 | 154 | if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE) 155 | { 156 | register const char *resword; 157 | 158 | switch (key - 1) 159 | { 160 | case 0: 161 | resword = "p"; 162 | goto compare; 163 | case 1: 164 | resword = "h6"; 165 | goto compare; 166 | case 2: 167 | resword = "div"; 168 | goto compare; 169 | case 3: 170 | resword = "del"; 171 | goto compare; 172 | case 4: 173 | resword = "form"; 174 | goto compare; 175 | case 5: 176 | resword = "table"; 177 | goto compare; 178 | case 6: 179 | resword = "figure"; 180 | goto compare; 181 | case 7: 182 | resword = "pre"; 183 | goto compare; 184 | case 8: 185 | resword = "fieldset"; 186 | goto compare; 187 | case 9: 188 | resword = "noscript"; 189 | goto compare; 190 | case 10: 191 | resword = "script"; 192 | goto compare; 193 | case 11: 194 | resword = "style"; 195 | goto compare; 196 | case 12: 197 | resword = "dl"; 198 | goto compare; 199 | case 13: 200 | resword = "ol"; 201 | goto compare; 202 | case 14: 203 | resword = "ul"; 204 | goto compare; 205 | case 15: 206 | resword = "math"; 207 | goto compare; 208 | case 16: 209 | resword = "ins"; 210 | goto compare; 211 | case 17: 212 | resword = "h5"; 213 | goto compare; 214 | case 18: 215 | resword = "iframe"; 216 | goto compare; 217 | case 19: 218 | resword = "h4"; 219 | goto compare; 220 | case 20: 221 | resword = "h3"; 222 | goto compare; 223 | case 21: 224 | resword = "blockquote"; 225 | goto compare; 226 | case 22: 227 | resword = "h2"; 228 | goto compare; 229 | case 23: 230 | resword = "h1"; 231 | goto compare; 232 | } 233 | return 0; 234 | compare: 235 | if ((((unsigned char)*str ^ (unsigned char)*resword) & ~32) == 0 && !gperf_case_strncmp (str, resword, len) && resword[len] == '\0') 236 | return resword; 237 | } 238 | } 239 | return 0; 240 | } 241 | -------------------------------------------------------------------------------- /src/stack.c: -------------------------------------------------------------------------------- 1 | #include "stack.h" 2 | 3 | #include "buffer.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | void 10 | hoedown_stack_init(hoedown_stack *st, size_t initial_size) 11 | { 12 | assert(st); 13 | 14 | st->item = NULL; 15 | st->size = st->asize = 0; 16 | 17 | if (!initial_size) 18 | initial_size = 8; 19 | 20 | hoedown_stack_grow(st, initial_size); 21 | } 22 | 23 | void 24 | hoedown_stack_uninit(hoedown_stack *st) 25 | { 26 | assert(st); 27 | 28 | free(st->item); 29 | } 30 | 31 | void 32 | hoedown_stack_grow(hoedown_stack *st, size_t neosz) 33 | { 34 | assert(st); 35 | 36 | if (st->asize >= neosz) 37 | return; 38 | 39 | st->item = hoedown_realloc(st->item, neosz * sizeof(void *)); 40 | memset(st->item + st->asize, 0x0, (neosz - st->asize) * sizeof(void *)); 41 | 42 | st->asize = neosz; 43 | 44 | if (st->size > neosz) 45 | st->size = neosz; 46 | } 47 | 48 | void 49 | hoedown_stack_push(hoedown_stack *st, void *item) 50 | { 51 | assert(st); 52 | 53 | if (st->size >= st->asize) 54 | hoedown_stack_grow(st, st->size * 2); 55 | 56 | st->item[st->size++] = item; 57 | } 58 | 59 | void * 60 | hoedown_stack_pop(hoedown_stack *st) 61 | { 62 | assert(st); 63 | 64 | if (!st->size) 65 | return NULL; 66 | 67 | return st->item[--st->size]; 68 | } 69 | 70 | void * 71 | hoedown_stack_top(const hoedown_stack *st) 72 | { 73 | assert(st); 74 | 75 | if (!st->size) 76 | return NULL; 77 | 78 | return st->item[st->size - 1]; 79 | } 80 | -------------------------------------------------------------------------------- /src/stack.h: -------------------------------------------------------------------------------- 1 | /* stack.h - simple stacking */ 2 | 3 | #ifndef HOEDOWN_STACK_H 4 | #define HOEDOWN_STACK_H 5 | 6 | #include 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | 13 | /********* 14 | * TYPES * 15 | *********/ 16 | 17 | struct hoedown_stack { 18 | void **item; 19 | size_t size; 20 | size_t asize; 21 | }; 22 | typedef struct hoedown_stack hoedown_stack; 23 | 24 | 25 | /************* 26 | * FUNCTIONS * 27 | *************/ 28 | 29 | /* hoedown_stack_init: initialize a stack */ 30 | void hoedown_stack_init(hoedown_stack *st, size_t initial_size); 31 | 32 | /* hoedown_stack_uninit: free internal data of the stack */ 33 | void hoedown_stack_uninit(hoedown_stack *st); 34 | 35 | /* hoedown_stack_grow: increase the allocated size to the given value */ 36 | void hoedown_stack_grow(hoedown_stack *st, size_t neosz); 37 | 38 | /* hoedown_stack_push: push an item to the top of the stack */ 39 | void hoedown_stack_push(hoedown_stack *st, void *item); 40 | 41 | /* hoedown_stack_pop: retrieve and remove the item at the top of the stack */ 42 | void *hoedown_stack_pop(hoedown_stack *st); 43 | 44 | /* hoedown_stack_top: retrieve the item at the top of the stack */ 45 | void *hoedown_stack_top(const hoedown_stack *st); 46 | 47 | 48 | #ifdef __cplusplus 49 | } 50 | #endif 51 | 52 | #endif /** HOEDOWN_STACK_H **/ 53 | -------------------------------------------------------------------------------- /src/version.c: -------------------------------------------------------------------------------- 1 | #include "version.h" 2 | 3 | void 4 | hoedown_version(int *major, int *minor, int *revision, int *extras) 5 | { 6 | *major = HOEDOWN_VERSION_MAJOR; 7 | *minor = HOEDOWN_VERSION_MINOR; 8 | *revision = HOEDOWN_VERSION_REVISION; 9 | *extras = HOEDOWN_VERSION_EXTRAS; 10 | } 11 | -------------------------------------------------------------------------------- /src/version.h: -------------------------------------------------------------------------------- 1 | /* version.h - holds Hoedown's version */ 2 | 3 | #ifndef HOEDOWN_VERSION_H 4 | #define HOEDOWN_VERSION_H 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | 11 | /************* 12 | * CONSTANTS * 13 | *************/ 14 | 15 | #define HOEDOWN_VERSION "3.0.7.20" 16 | #define HOEDOWN_VERSION_MAJOR 3 17 | #define HOEDOWN_VERSION_MINOR 0 18 | #define HOEDOWN_VERSION_REVISION 7 19 | #define HOEDOWN_VERSION_EXTRAS 20 20 | 21 | 22 | /************* 23 | * FUNCTIONS * 24 | *************/ 25 | 26 | /* hoedown_version: retrieve Hoedown's version numbers */ 27 | void hoedown_version(int *major, int *minor, int *revision, int *extras); 28 | 29 | 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | 34 | #endif /** HOEDOWN_VERSION_H **/ 35 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/MarkdownTest.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | # 4 | # MarkdownTester -- Run tests for Markdown implementations 5 | # 6 | # Copyright (c) 2004-2005 John Gruber 7 | # 8 | # 9 | 10 | use strict; 11 | use warnings; 12 | use Getopt::Long; 13 | use Benchmark; 14 | 15 | our $VERSION = '1.0.2'; 16 | # Sat 24 Dec 2005 17 | 18 | my $time_start = new Benchmark; 19 | my $test_dir = "Tests"; 20 | my $script = "./Markdown.pl"; 21 | my $use_tidy = 0; 22 | my ($flag_version); 23 | 24 | GetOptions ( 25 | "script=s" => \$script, 26 | "testdir=s" => \$test_dir, 27 | "tidy" => \$use_tidy, 28 | "version" => \$flag_version, 29 | ); 30 | 31 | if($flag_version) { 32 | my $progname = $0; 33 | $progname =~ s{.*/}{}; 34 | die "$progname version $VERSION\n"; 35 | } 36 | 37 | unless (-d $test_dir) { die "'$test_dir' is not a directory.\n"; } 38 | unless (-f $script) { die "$script does not exist.\n"; } 39 | unless (-x $script) { die "$script is not executable.\n"; } 40 | 41 | my $tests_passed = 0; 42 | my $tests_failed = 0; 43 | 44 | TEST: 45 | foreach my $testfile (glob "$test_dir/*.text") { 46 | my $testname = $testfile; 47 | $testname =~ s{.*/(.+)\.text$}{$1}i; 48 | print "$testname ... "; 49 | 50 | # Look for a corresponding .html file for each .text file: 51 | my $resultfile = $testfile; 52 | $resultfile =~ s{\.text$}{\.html}i; 53 | unless (-f $resultfile) { 54 | print "'$resultfile' does not exist.\n\n"; 55 | next TEST; 56 | } 57 | 58 | # open(TEST, $testfile) || die("Can't open testfile: $!"); 59 | open(RESULT, $resultfile) || die("Can't open resultfile: $!"); 60 | undef $/; 61 | # my $t_input = ; 62 | my $t_result = ; 63 | 64 | my $t_output = `'$script' '$testfile'`; 65 | 66 | # Normalize the output and expected result strings: 67 | $t_result =~ s/\s+\z//; # trim trailing whitespace 68 | $t_output =~ s/\s+\z//; # trim trailing whitespace 69 | if ($use_tidy) { 70 | # Escape the strings, pass them through to CLI tidy tool for tag-level equivalency 71 | $t_result =~ s{'}{'\\''}g; # escape ' chars for shell 72 | $t_output =~ s{'}{'\\''}g; 73 | $t_result = `echo '$t_result' | tidy --show-body-only 1 --quiet 1 --show-warnings 0`; 74 | $t_output = `echo '$t_output' | tidy --show-body-only 1 --quiet 1 --show-warnings 0`; 75 | } 76 | 77 | if ($t_output eq $t_result) { 78 | print "OK\n"; 79 | $tests_passed++; 80 | } 81 | else { 82 | print "FAILED\n\n"; 83 | # This part added by JM to print diffs 84 | open(OUT, '>tmp1') or die $!; 85 | print OUT $t_output or die $!; 86 | open(RES, '>tmp2') or die $!; 87 | print RES $t_result or die $!; 88 | print `diff tmp1 tmp2`; 89 | close RES; 90 | close OUT; 91 | print "\n"; 92 | `rm tmp?`; 93 | # End of added part 94 | $tests_failed++; 95 | } 96 | } 97 | 98 | print "\n\n"; 99 | print "$tests_passed passed; $tests_failed failed.\n"; 100 | 101 | my $time_end = new Benchmark; 102 | my $time_diff = timediff($time_end, $time_start); 103 | print "Benchmark: ", timestr($time_diff), "\n"; 104 | 105 | exit 1 if $tests_failed; 106 | 107 | __END__ 108 | 109 | =pod 110 | 111 | =head1 NAME 112 | 113 | B 114 | 115 | 116 | =head1 SYNOPSIS 117 | 118 | B [ B<--options> ] [ I ... ] 119 | 120 | 121 | =head1 DESCRIPTION 122 | 123 | 124 | =head1 OPTIONS 125 | 126 | Use "--" to end switch parsing. For example, to open a file named "-z", use: 127 | 128 | MarkdownTest.pl -- -z 129 | 130 | =over 4 131 | 132 | =item B<--script> 133 | 134 | Specify the path to the Markdown script to test. Defaults to 135 | "./Markdown.pl". Example: 136 | 137 | ./MarkdownTest.pl --script ./PHP-Markdown/php-markdown 138 | 139 | =item B<--testdir> 140 | 141 | Specify the path to a directory containing test data. Defaults to "Tests". 142 | 143 | =item B<--tidy> 144 | 145 | Flag to turn on using the command line 'tidy' tool to normalize HTML 146 | output before comparing script output to the expected test result. 147 | Assumes that the 'tidy' command is available in your PATH. Defaults to 148 | off. 149 | 150 | =back 151 | 152 | 153 | 154 | =head1 BUGS 155 | 156 | 157 | 158 | =head1 VERSION HISTORY 159 | 160 | 1.0 Mon 13 Dec 2004-2005 161 | 162 | 1.0.1 Mon 19 Sep 2005 163 | 164 | + Better handling of case when foo.text exists, but foo.html doesn't. 165 | It now prints a message and moves on, rather than dying. 166 | 167 | 168 | =head1 COPYRIGHT AND LICENSE 169 | 170 | Copyright (c) 2004-2005 John Gruber 171 | 172 | All rights reserved. 173 | 174 | This is free software; you may redistribute it and/or modify it under 175 | the same terms as Perl itself. 176 | 177 | =cut 178 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Amps and angle encoding.html: -------------------------------------------------------------------------------- 1 |

AT&T has an ampersand in their name.

2 | 3 |

AT&T is another way to write it.

4 | 5 |

This & that.

6 | 7 |

4 < 5.

8 | 9 |

6 > 5.

10 | 11 |

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

12 | 13 |

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

14 | 15 |

Here's an inline link.

16 | 17 |

Here's an inline link.

18 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Amps and angle encoding.text: -------------------------------------------------------------------------------- 1 | AT&T has an ampersand in their name. 2 | 3 | AT&T is another way to write it. 4 | 5 | This & that. 6 | 7 | 4 < 5. 8 | 9 | 6 > 5. 10 | 11 | Here's a [link] [1] with an ampersand in the URL. 12 | 13 | Here's a link with an amersand in the link text: [AT&T] [2]. 14 | 15 | Here's an inline [link](/script?foo=1&bar=2). 16 | 17 | Here's an inline [link](). 18 | 19 | 20 | [1]: http://example.com/?foo=1&bar=2 21 | [2]: http://att.com/ "AT&T" -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Auto links.html: -------------------------------------------------------------------------------- 1 |

Link: http://example.com/.

2 | 3 |

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

4 | 5 | 10 | 11 |
12 |

Blockquoted: http://example.com/

13 |
14 | 15 |

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

16 | 17 |
or here: <http://example.com/>
18 | 
19 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Auto links.text: -------------------------------------------------------------------------------- 1 | Link: . 2 | 3 | With an ampersand: 4 | 5 | * In a list? 6 | * 7 | * It should. 8 | 9 | > Blockquoted: 10 | 11 | Auto-links should not occur here: `` 12 | 13 | or here: -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Backslash escapes.html: -------------------------------------------------------------------------------- 1 |

These should all get escaped:

2 | 3 |

Backslash: \

4 | 5 |

Backtick: `

6 | 7 |

Asterisk: *

8 | 9 |

Underscore: _

10 | 11 |

Left brace: {

12 | 13 |

Right brace: }

14 | 15 |

Left bracket: [

16 | 17 |

Right bracket: ]

18 | 19 |

Left paren: (

20 | 21 |

Right paren: )

22 | 23 |

Greater-than: >

24 | 25 |

Hash: #

26 | 27 |

Period: .

28 | 29 |

Bang: !

30 | 31 |

Plus: +

32 | 33 |

Minus: -

34 | 35 |

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

36 | 37 |
Backslash: \\
 38 | 
 39 | Backtick: \`
 40 | 
 41 | Asterisk: \*
 42 | 
 43 | Underscore: \_
 44 | 
 45 | Left brace: \{
 46 | 
 47 | Right brace: \}
 48 | 
 49 | Left bracket: \[
 50 | 
 51 | Right bracket: \]
 52 | 
 53 | Left paren: \(
 54 | 
 55 | Right paren: \)
 56 | 
 57 | Greater-than: \>
 58 | 
 59 | Hash: \#
 60 | 
 61 | Period: \.
 62 | 
 63 | Bang: \!
 64 | 
 65 | Plus: \+
 66 | 
 67 | Minus: \-
 68 | 
69 | 70 |

Nor should these, which occur in code spans:

71 | 72 |

Backslash: \\

73 | 74 |

Backtick: \`

75 | 76 |

Asterisk: \*

77 | 78 |

Underscore: \_

79 | 80 |

Left brace: \{

81 | 82 |

Right brace: \}

83 | 84 |

Left bracket: \[

85 | 86 |

Right bracket: \]

87 | 88 |

Left paren: \(

89 | 90 |

Right paren: \)

91 | 92 |

Greater-than: \>

93 | 94 |

Hash: \#

95 | 96 |

Period: \.

97 | 98 |

Bang: \!

99 | 100 |

Plus: \+

101 | 102 |

Minus: \-

103 | 104 | 105 |

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

107 | 108 |

*asterisks*

109 | 110 |

_underscores_

111 | 112 |

`backticks`

113 | 114 |

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

115 | 116 |

This is a tag with unescaped backticks bar.

117 | 118 |

This is a tag with backslashes bar.

119 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Backslash escapes.text: -------------------------------------------------------------------------------- 1 | These should all get escaped: 2 | 3 | Backslash: \\ 4 | 5 | Backtick: \` 6 | 7 | Asterisk: \* 8 | 9 | Underscore: \_ 10 | 11 | Left brace: \{ 12 | 13 | Right brace: \} 14 | 15 | Left bracket: \[ 16 | 17 | Right bracket: \] 18 | 19 | Left paren: \( 20 | 21 | Right paren: \) 22 | 23 | Greater-than: \> 24 | 25 | Hash: \# 26 | 27 | Period: \. 28 | 29 | Bang: \! 30 | 31 | Plus: \+ 32 | 33 | Minus: \- 34 | 35 | 36 | 37 | These should not, because they occur within a code block: 38 | 39 | Backslash: \\ 40 | 41 | Backtick: \` 42 | 43 | Asterisk: \* 44 | 45 | Underscore: \_ 46 | 47 | Left brace: \{ 48 | 49 | Right brace: \} 50 | 51 | Left bracket: \[ 52 | 53 | Right bracket: \] 54 | 55 | Left paren: \( 56 | 57 | Right paren: \) 58 | 59 | Greater-than: \> 60 | 61 | Hash: \# 62 | 63 | Period: \. 64 | 65 | Bang: \! 66 | 67 | Plus: \+ 68 | 69 | Minus: \- 70 | 71 | 72 | Nor should these, which occur in code spans: 73 | 74 | Backslash: `\\` 75 | 76 | Backtick: `` \` `` 77 | 78 | Asterisk: `\*` 79 | 80 | Underscore: `\_` 81 | 82 | Left brace: `\{` 83 | 84 | Right brace: `\}` 85 | 86 | Left bracket: `\[` 87 | 88 | Right bracket: `\]` 89 | 90 | Left paren: `\(` 91 | 92 | Right paren: `\)` 93 | 94 | Greater-than: `\>` 95 | 96 | Hash: `\#` 97 | 98 | Period: `\.` 99 | 100 | Bang: `\!` 101 | 102 | Plus: `\+` 103 | 104 | Minus: `\-` 105 | 106 | 107 | These should get escaped, even though they're matching pairs for 108 | other Markdown constructs: 109 | 110 | \*asterisks\* 111 | 112 | \_underscores\_ 113 | 114 | \`backticks\` 115 | 116 | This is a code span with a literal backslash-backtick sequence: `` \` `` 117 | 118 | This is a tag with unescaped backticks bar. 119 | 120 | This is a tag with backslashes bar. 121 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Blockquotes with code blocks.html: -------------------------------------------------------------------------------- 1 |
2 |

Example:

3 | 4 |
sub status {
 5 |     print "working";
 6 | }
 7 | 
8 | 9 |

Or:

10 | 11 |
sub status {
12 |     return "working";
13 | }
14 | 
15 |
16 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Blockquotes with code blocks.text: -------------------------------------------------------------------------------- 1 | > Example: 2 | > 3 | > sub status { 4 | > print "working"; 5 | > } 6 | > 7 | > Or: 8 | > 9 | > sub status { 10 | > return "working"; 11 | > } 12 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Code Blocks.html: -------------------------------------------------------------------------------- 1 |
code block on the first line
 2 | 
3 | 4 |

Regular text.

5 | 6 |
code block indented by spaces
 7 | 
8 | 9 |

Regular text.

10 | 11 |
the lines in this block  
12 | all contain trailing spaces  
13 | 
14 | 15 |

Regular Text.

16 | 17 |
code block on the last line
18 | 
19 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Code Blocks.text: -------------------------------------------------------------------------------- 1 | code block on the first line 2 | 3 | Regular text. 4 | 5 | code block indented by spaces 6 | 7 | Regular text. 8 | 9 | the lines in this block 10 | all contain trailing spaces 11 | 12 | Regular Text. 13 | 14 | code block on the last line -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Code Spans.html: -------------------------------------------------------------------------------- 1 |

<test a=" content of attribute ">

2 | 3 |

Fix for backticks within HTML tag: like this

4 | 5 |

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

6 | 7 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Code Spans.text: -------------------------------------------------------------------------------- 1 | `` 2 | 3 | Fix for backticks within HTML tag: like this 4 | 5 | Here's how you put `` `backticks` `` in a code span. 6 | 7 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.html: -------------------------------------------------------------------------------- 1 |

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

6 | 7 |

Here's one with a bullet. 8 | * criminey.

9 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.text: -------------------------------------------------------------------------------- 1 | In Markdown 1.0.0 and earlier. Version 2 | 8. This line turns into a list item. 3 | Because a hard-wrapped line in the 4 | middle of a paragraph looked like a 5 | list item. 6 | 7 | Here's one with a bullet. 8 | * criminey. 9 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Horizontal rules.html: -------------------------------------------------------------------------------- 1 |

Dashes:

2 | 3 |
4 | 5 |
6 | 7 |
8 | 9 |
10 | 11 |
---
12 | 
13 | 14 |
15 | 16 |
17 | 18 |
19 | 20 |
21 | 22 |
- - -
23 | 
24 | 25 |

Asterisks:

26 | 27 |
28 | 29 |
30 | 31 |
32 | 33 |
34 | 35 |
***
36 | 
37 | 38 |
39 | 40 |
41 | 42 |
43 | 44 |
45 | 46 |
* * *
47 | 
48 | 49 |

Underscores:

50 | 51 |
52 | 53 |
54 | 55 |
56 | 57 |
58 | 59 |
___
60 | 
61 | 62 |
63 | 64 |
65 | 66 |
67 | 68 |
69 | 70 |
_ _ _
71 | 
72 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Horizontal rules.text: -------------------------------------------------------------------------------- 1 | Dashes: 2 | 3 | --- 4 | 5 | --- 6 | 7 | --- 8 | 9 | --- 10 | 11 | --- 12 | 13 | - - - 14 | 15 | - - - 16 | 17 | - - - 18 | 19 | - - - 20 | 21 | - - - 22 | 23 | 24 | Asterisks: 25 | 26 | *** 27 | 28 | *** 29 | 30 | *** 31 | 32 | *** 33 | 34 | *** 35 | 36 | * * * 37 | 38 | * * * 39 | 40 | * * * 41 | 42 | * * * 43 | 44 | * * * 45 | 46 | 47 | Underscores: 48 | 49 | ___ 50 | 51 | ___ 52 | 53 | ___ 54 | 55 | ___ 56 | 57 | ___ 58 | 59 | _ _ _ 60 | 61 | _ _ _ 62 | 63 | _ _ _ 64 | 65 | _ _ _ 66 | 67 | _ _ _ 68 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Inline HTML (Advanced).html: -------------------------------------------------------------------------------- 1 |

Simple block on one line:

2 | 3 |
foo
4 | 5 |

And nested without indentation:

6 | 7 |
8 |
9 |
10 | foo 11 |
12 |
13 |
14 |
bar
15 |
16 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Inline HTML (Advanced).text: -------------------------------------------------------------------------------- 1 | Simple block on one line: 2 | 3 |
foo
4 | 5 | And nested without indentation: 6 | 7 |
8 |
9 |
10 | foo 11 |
12 |
13 |
14 |
bar
15 |
16 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Inline HTML (Simple).html: -------------------------------------------------------------------------------- 1 |

Here's a simple block:

2 | 3 |
4 | foo 5 |
6 | 7 |

This should be a code block, though:

8 | 9 |
<div>
10 |     foo
11 | </div>
12 | 
13 | 14 |

As should this:

15 | 16 |
<div>foo</div>
17 | 
18 | 19 |

Now, nested:

20 | 21 |
22 |
23 |
24 | foo 25 |
26 |
27 |
28 | 29 |

This should just be an HTML comment:

30 | 31 | 32 | 33 |

Multiline:

34 | 35 | 39 | 40 |

Code block:

41 | 42 |
<!-- Comment -->
43 | 
44 | 45 |

Just plain comment, with trailing spaces on the line:

46 | 47 | 48 | 49 |

Code:

50 | 51 |
<hr />
52 | 
53 | 54 |

Hr's:

55 | 56 |
57 | 58 |
59 | 60 |
61 | 62 |
63 | 64 |
65 | 66 |
67 | 68 |
69 | 70 |
71 | 72 |
73 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Inline HTML (Simple).text: -------------------------------------------------------------------------------- 1 | Here's a simple block: 2 | 3 |
4 | foo 5 |
6 | 7 | This should be a code block, though: 8 | 9 |
10 | foo 11 |
12 | 13 | As should this: 14 | 15 |
foo
16 | 17 | Now, nested: 18 | 19 |
20 |
21 |
22 | foo 23 |
24 |
25 |
26 | 27 | This should just be an HTML comment: 28 | 29 | 30 | 31 | Multiline: 32 | 33 | 37 | 38 | Code block: 39 | 40 | 41 | 42 | Just plain comment, with trailing spaces on the line: 43 | 44 | 45 | 46 | Code: 47 | 48 |
49 | 50 | Hr's: 51 | 52 |
53 | 54 |
55 | 56 |
57 | 58 |
59 | 60 |
61 | 62 |
63 | 64 |
65 | 66 |
67 | 68 |
69 | 70 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Inline HTML comments.html: -------------------------------------------------------------------------------- 1 |

Paragraph one.

2 | 3 | 4 | 5 | 8 | 9 |

Paragraph two.

10 | 11 | 12 | 13 |

The end.

14 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Inline HTML comments.text: -------------------------------------------------------------------------------- 1 | Paragraph one. 2 | 3 | 4 | 5 | 8 | 9 | Paragraph two. 10 | 11 | 12 | 13 | The end. 14 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Links, inline style.html: -------------------------------------------------------------------------------- 1 |

Just a URL.

2 | 3 |

URL and title.

4 | 5 |

URL and title.

6 | 7 |

URL and title.

8 | 9 |

URL and title.

10 | 11 |

Empty.

12 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Links, inline style.text: -------------------------------------------------------------------------------- 1 | Just a [URL](/url/). 2 | 3 | [URL and title](/url/ "title"). 4 | 5 | [URL and title](/url/ "title preceded by two spaces"). 6 | 7 | [URL and title](/url/ "title preceded by a tab"). 8 | 9 | [URL and title](/url/ "title has spaces afterward" ). 10 | 11 | 12 | [Empty](). 13 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Links, reference style.html: -------------------------------------------------------------------------------- 1 |

Foo bar.

2 | 3 |

Foo bar.

4 | 5 |

Foo bar.

6 | 7 |

With embedded [brackets].

8 | 9 |

Indented once.

10 | 11 |

Indented twice.

12 | 13 |

Indented thrice.

14 | 15 |

Indented [four][] times.

16 | 17 |
[four]: /url
18 | 
19 | 20 |
21 | 22 |

this should work

23 | 24 |

So should this.

25 | 26 |

And this.

27 | 28 |

And this.

29 | 30 |

And this.

31 | 32 |

But not [that] [].

33 | 34 |

Nor [that][].

35 | 36 |

Nor [that].

37 | 38 |

[Something in brackets like this should work]

39 | 40 |

[Same with this.]

41 | 42 |

In this case, this points to something else.

43 | 44 |

Backslashing should suppress [this] and [this].

45 | 46 |
47 | 48 |

Here's one where the link 49 | breaks across lines.

50 | 51 |

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

53 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Links, reference style.text: -------------------------------------------------------------------------------- 1 | Foo [bar] [1]. 2 | 3 | Foo [bar][1]. 4 | 5 | Foo [bar] 6 | [1]. 7 | 8 | [1]: /url/ "Title" 9 | 10 | 11 | With [embedded [brackets]] [b]. 12 | 13 | 14 | Indented [once][]. 15 | 16 | Indented [twice][]. 17 | 18 | Indented [thrice][]. 19 | 20 | Indented [four][] times. 21 | 22 | [once]: /url 23 | 24 | [twice]: /url 25 | 26 | [thrice]: /url 27 | 28 | [four]: /url 29 | 30 | 31 | [b]: /url/ 32 | 33 | * * * 34 | 35 | [this] [this] should work 36 | 37 | So should [this][this]. 38 | 39 | And [this] []. 40 | 41 | And [this][]. 42 | 43 | And [this]. 44 | 45 | But not [that] []. 46 | 47 | Nor [that][]. 48 | 49 | Nor [that]. 50 | 51 | [Something in brackets like [this][] should work] 52 | 53 | [Same with [this].] 54 | 55 | In this case, [this](/somethingelse/) points to something else. 56 | 57 | Backslashing should suppress \[this] and [this\]. 58 | 59 | [this]: foo 60 | 61 | 62 | * * * 63 | 64 | Here's one where the [link 65 | breaks] across lines. 66 | 67 | Here's another where the [link 68 | breaks] across lines, but with a line-ending space. 69 | 70 | 71 | [link breaks]: /url/ 72 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Links, shortcut references.html: -------------------------------------------------------------------------------- 1 |

This is the simple case.

2 | 3 |

This one has a line 4 | break.

5 | 6 |

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

8 | 9 |

this and the other

10 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Links, shortcut references.text: -------------------------------------------------------------------------------- 1 | This is the [simple case]. 2 | 3 | [simple case]: /simple 4 | 5 | 6 | 7 | This one has a [line 8 | break]. 9 | 10 | This one has a [line 11 | break] with a line-ending space. 12 | 13 | [line break]: /foo 14 | 15 | 16 | [this] [that] and the [other] 17 | 18 | [this]: /this 19 | [that]: /that 20 | [other]: /other 21 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Literal quotes in titles.html: -------------------------------------------------------------------------------- 1 |

Foo bar.

2 | 3 |

Foo bar.

4 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Literal quotes in titles.text: -------------------------------------------------------------------------------- 1 | Foo [bar][]. 2 | 3 | Foo [bar](/url/ "Title with "quotes" inside"). 4 | 5 | 6 | [bar]: /url/ "Title with "quotes" inside" 7 | 8 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Markdown Documentation - Basics.text: -------------------------------------------------------------------------------- 1 | Markdown: Basics 2 | ================ 3 | 4 | 11 | 12 | 13 | Getting the Gist of Markdown's Formatting Syntax 14 | ------------------------------------------------ 15 | 16 | This page offers a brief overview of what it's like to use Markdown. 17 | The [syntax page] [s] provides complete, detailed documentation for 18 | every feature, but Markdown should be very easy to pick up simply by 19 | looking at a few examples of it in action. The examples on this page 20 | are written in a before/after style, showing example syntax and the 21 | HTML output produced by Markdown. 22 | 23 | It's also helpful to simply try Markdown out; the [Dingus] [d] is a 24 | web application that allows you type your own Markdown-formatted text 25 | and translate it to XHTML. 26 | 27 | **Note:** This document is itself written using Markdown; you 28 | can [see the source for it by adding '.text' to the URL] [src]. 29 | 30 | [s]: /projects/markdown/syntax "Markdown Syntax" 31 | [d]: /projects/markdown/dingus "Markdown Dingus" 32 | [src]: /projects/markdown/basics.text 33 | 34 | 35 | ## Paragraphs, Headers, Blockquotes ## 36 | 37 | A paragraph is simply one or more consecutive lines of text, separated 38 | by one or more blank lines. (A blank line is any line that looks like a 39 | blank line -- a line containing nothing spaces or tabs is considered 40 | blank.) Normal paragraphs should not be intended with spaces or tabs. 41 | 42 | Markdown offers two styles of headers: *Setext* and *atx*. 43 | Setext-style headers for `

` and `

` are created by 44 | "underlining" with equal signs (`=`) and hyphens (`-`), respectively. 45 | To create an atx-style header, you put 1-6 hash marks (`#`) at the 46 | beginning of the line -- the number of hashes equals the resulting 47 | HTML header level. 48 | 49 | Blockquotes are indicated using email-style '`>`' angle brackets. 50 | 51 | Markdown: 52 | 53 | A First Level Header 54 | ==================== 55 | 56 | A Second Level Header 57 | --------------------- 58 | 59 | Now is the time for all good men to come to 60 | the aid of their country. This is just a 61 | regular paragraph. 62 | 63 | The quick brown fox jumped over the lazy 64 | dog's back. 65 | 66 | ### Header 3 67 | 68 | > This is a blockquote. 69 | > 70 | > This is the second paragraph in the blockquote. 71 | > 72 | > ## This is an H2 in a blockquote 73 | 74 | 75 | Output: 76 | 77 |

A First Level Header

78 | 79 |

A Second Level Header

80 | 81 |

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

84 | 85 |

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

87 | 88 |

Header 3

89 | 90 |
91 |

This is a blockquote.

92 | 93 |

This is the second paragraph in the blockquote.

94 | 95 |

This is an H2 in a blockquote

96 |
97 | 98 | 99 | 100 | ### Phrase Emphasis ### 101 | 102 | Markdown uses asterisks and underscores to indicate spans of emphasis. 103 | 104 | Markdown: 105 | 106 | Some of these words *are emphasized*. 107 | Some of these words _are emphasized also_. 108 | 109 | Use two asterisks for **strong emphasis**. 110 | Or, if you prefer, __use two underscores instead__. 111 | 112 | Output: 113 | 114 |

Some of these words are emphasized. 115 | Some of these words are emphasized also.

116 | 117 |

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

119 | 120 | 121 | 122 | ## Lists ## 123 | 124 | Unordered (bulleted) lists use asterisks, pluses, and hyphens (`*`, 125 | `+`, and `-`) as list markers. These three markers are 126 | interchangable; this: 127 | 128 | * Candy. 129 | * Gum. 130 | * Booze. 131 | 132 | this: 133 | 134 | + Candy. 135 | + Gum. 136 | + Booze. 137 | 138 | and this: 139 | 140 | - Candy. 141 | - Gum. 142 | - Booze. 143 | 144 | all produce the same output: 145 | 146 |
    147 |
  • Candy.
  • 148 |
  • Gum.
  • 149 |
  • Booze.
  • 150 |
151 | 152 | Ordered (numbered) lists use regular numbers, followed by periods, as 153 | list markers: 154 | 155 | 1. Red 156 | 2. Green 157 | 3. Blue 158 | 159 | Output: 160 | 161 |
    162 |
  1. Red
  2. 163 |
  3. Green
  4. 164 |
  5. Blue
  6. 165 |
166 | 167 | If you put blank lines between items, you'll get `

` tags for the 168 | list item text. You can create multi-paragraph list items by indenting 169 | the paragraphs by 4 spaces or 1 tab: 170 | 171 | * A list item. 172 | 173 | With multiple paragraphs. 174 | 175 | * Another item in the list. 176 | 177 | Output: 178 | 179 |

    180 |
  • A list item.

    181 |

    With multiple paragraphs.

  • 182 |
  • Another item in the list.

  • 183 |
184 | 185 | 186 | 187 | ### Links ### 188 | 189 | Markdown supports two styles for creating links: *inline* and 190 | *reference*. With both styles, you use square brackets to delimit the 191 | text you want to turn into a link. 192 | 193 | Inline-style links use parentheses immediately after the link text. 194 | For example: 195 | 196 | This is an [example link](http://example.com/). 197 | 198 | Output: 199 | 200 |

This is an 201 | example link.

202 | 203 | Optionally, you may include a title attribute in the parentheses: 204 | 205 | This is an [example link](http://example.com/ "With a Title"). 206 | 207 | Output: 208 | 209 |

This is an 210 | example link.

211 | 212 | Reference-style links allow you to refer to your links by names, which 213 | you define elsewhere in your document: 214 | 215 | I get 10 times more traffic from [Google][1] than from 216 | [Yahoo][2] or [MSN][3]. 217 | 218 | [1]: http://google.com/ "Google" 219 | [2]: http://search.yahoo.com/ "Yahoo Search" 220 | [3]: http://search.msn.com/ "MSN Search" 221 | 222 | Output: 223 | 224 |

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

228 | 229 | The title attribute is optional. Link names may contain letters, 230 | numbers and spaces, but are *not* case sensitive: 231 | 232 | I start my morning with a cup of coffee and 233 | [The New York Times][NY Times]. 234 | 235 | [ny times]: http://www.nytimes.com/ 236 | 237 | Output: 238 | 239 |

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

241 | 242 | 243 | ### Images ### 244 | 245 | Image syntax is very much like link syntax. 246 | 247 | Inline (titles are optional): 248 | 249 | ![alt text](/path/to/img.jpg "Title") 250 | 251 | Reference-style: 252 | 253 | ![alt text][id] 254 | 255 | [id]: /path/to/img.jpg "Title" 256 | 257 | Both of the above examples produce the same output: 258 | 259 | alt text 260 | 261 | 262 | 263 | ### Code ### 264 | 265 | In a regular paragraph, you can create code span by wrapping text in 266 | backtick quotes. Any ampersands (`&`) and angle brackets (`<` or 267 | `>`) will automatically be translated into HTML entities. This makes 268 | it easy to use Markdown to write about HTML example code: 269 | 270 | I strongly recommend against using any `` tags. 271 | 272 | I wish SmartyPants used named entities like `—` 273 | instead of decimal-encoded entites like `—`. 274 | 275 | Output: 276 | 277 |

I strongly recommend against using any 278 | <blink> tags.

279 | 280 |

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

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

For example.

296 |
297 | 298 | Output: 299 | 300 |

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

302 | 303 |
<blockquote>
304 |         <p>For example.</p>
305 |     </blockquote>
306 |     
307 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Nested blockquotes.html: -------------------------------------------------------------------------------- 1 |
2 |

foo

3 | 4 |
5 |

bar

6 |
7 | 8 |

foo

9 |
10 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Nested blockquotes.text: -------------------------------------------------------------------------------- 1 | > foo 2 | > 3 | > > bar 4 | > 5 | > foo 6 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Ordered and unordered lists.html: -------------------------------------------------------------------------------- 1 |

Unordered

2 | 3 |

Asterisks tight:

4 | 5 |
    6 |
  • asterisk 1
  • 7 |
  • asterisk 2
  • 8 |
  • asterisk 3
  • 9 |
10 | 11 |

Asterisks loose:

12 | 13 |
    14 |
  • asterisk 1

  • 15 |
  • asterisk 2

  • 16 |
  • asterisk 3

  • 17 |
18 | 19 |
20 | 21 |

Pluses tight:

22 | 23 |
    24 |
  • Plus 1
  • 25 |
  • Plus 2
  • 26 |
  • Plus 3
  • 27 |
28 | 29 |

Pluses loose:

30 | 31 |
    32 |
  • Plus 1

  • 33 |
  • Plus 2

  • 34 |
  • Plus 3

  • 35 |
36 | 37 |
38 | 39 |

Minuses tight:

40 | 41 |
    42 |
  • Minus 1
  • 43 |
  • Minus 2
  • 44 |
  • Minus 3
  • 45 |
46 | 47 |

Minuses loose:

48 | 49 |
    50 |
  • Minus 1

  • 51 |
  • Minus 2

  • 52 |
  • Minus 3

  • 53 |
54 | 55 |

Ordered

56 | 57 |

Tight:

58 | 59 |
    60 |
  1. First
  2. 61 |
  3. Second
  4. 62 |
  5. Third
  6. 63 |
64 | 65 |

and:

66 | 67 |
    68 |
  1. One
  2. 69 |
  3. Two
  4. 70 |
  5. Three
  6. 71 |
72 | 73 |

Loose using tabs:

74 | 75 |
    76 |
  1. First

  2. 77 |
  3. Second

  4. 78 |
  5. Third

  6. 79 |
80 | 81 |

and using spaces:

82 | 83 |
    84 |
  1. One

  2. 85 |
  3. Two

  4. 86 |
  5. Three

  6. 87 |
88 | 89 |

Multiple paragraphs:

90 | 91 |
    92 |
  1. Item 1, graf one.

    93 | 94 |

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

  2. 96 |
  3. Item 2.

  4. 97 |
  5. Item 3.

  6. 98 |
99 | 100 |

Nested

101 | 102 |
    103 |
  • Tab 104 |
      105 |
    • Tab 106 |
        107 |
      • Tab
      • 108 |
    • 109 |
  • 110 |
111 | 112 |

Here's another:

113 | 114 |
    115 |
  1. First
  2. 116 |
  3. Second: 117 |
      118 |
    • Fee
    • 119 |
    • Fie
    • 120 |
    • Foe
    • 121 |
  4. 122 |
  5. Third
  6. 123 |
124 | 125 |

Same thing but with paragraphs:

126 | 127 |
    128 |
  1. First

  2. 129 |
  3. Second:

    130 | 131 |
      132 |
    • Fee
    • 133 |
    • Fie
    • 134 |
    • Foe
    • 135 |
  4. 136 |
  5. Third

  6. 137 |
138 | 139 | 140 |

This was an error in Markdown 1.0.1:

141 | 142 |
    143 |
  • this

    144 | 145 |
    • sub
    146 | 147 |

    that

  • 148 |
149 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Ordered and unordered lists.text: -------------------------------------------------------------------------------- 1 | ## Unordered 2 | 3 | Asterisks tight: 4 | 5 | * asterisk 1 6 | * asterisk 2 7 | * asterisk 3 8 | 9 | 10 | Asterisks loose: 11 | 12 | * asterisk 1 13 | 14 | * asterisk 2 15 | 16 | * asterisk 3 17 | 18 | * * * 19 | 20 | Pluses tight: 21 | 22 | + Plus 1 23 | + Plus 2 24 | + Plus 3 25 | 26 | 27 | Pluses loose: 28 | 29 | + Plus 1 30 | 31 | + Plus 2 32 | 33 | + Plus 3 34 | 35 | * * * 36 | 37 | 38 | Minuses tight: 39 | 40 | - Minus 1 41 | - Minus 2 42 | - Minus 3 43 | 44 | 45 | Minuses loose: 46 | 47 | - Minus 1 48 | 49 | - Minus 2 50 | 51 | - Minus 3 52 | 53 | 54 | ## Ordered 55 | 56 | Tight: 57 | 58 | 1. First 59 | 2. Second 60 | 3. Third 61 | 62 | and: 63 | 64 | 1. One 65 | 2. Two 66 | 3. Three 67 | 68 | 69 | Loose using tabs: 70 | 71 | 1. First 72 | 73 | 2. Second 74 | 75 | 3. Third 76 | 77 | and using spaces: 78 | 79 | 1. One 80 | 81 | 2. Two 82 | 83 | 3. Three 84 | 85 | Multiple paragraphs: 86 | 87 | 1. Item 1, graf one. 88 | 89 | Item 2. graf two. The quick brown fox jumped over the lazy dog's 90 | back. 91 | 92 | 2. Item 2. 93 | 94 | 3. Item 3. 95 | 96 | 97 | 98 | ## Nested 99 | 100 | * Tab 101 | * Tab 102 | * Tab 103 | 104 | Here's another: 105 | 106 | 1. First 107 | 2. Second: 108 | * Fee 109 | * Fie 110 | * Foe 111 | 3. Third 112 | 113 | Same thing but with paragraphs: 114 | 115 | 1. First 116 | 117 | 2. Second: 118 | * Fee 119 | * Fie 120 | * Foe 121 | 122 | 3. Third 123 | 124 | 125 | This was an error in Markdown 1.0.1: 126 | 127 | * this 128 | 129 | * sub 130 | 131 | that 132 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Strong and em together.html: -------------------------------------------------------------------------------- 1 |

This is strong and em.

2 | 3 |

So is this word.

4 | 5 |

This is strong and em.

6 | 7 |

So is this word.

8 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Strong and em together.text: -------------------------------------------------------------------------------- 1 | ***This is strong and em.*** 2 | 3 | So is ***this*** word. 4 | 5 | ___This is strong and em.___ 6 | 7 | So is ___this___ word. 8 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Tabs.html: -------------------------------------------------------------------------------- 1 |
    2 |
  • this is a list item 3 | indented with tabs

  • 4 |
  • this is a list item 5 | indented with spaces

  • 6 |
7 | 8 |

Code:

9 | 10 |
this code block is indented by one tab
11 | 
12 | 13 |

And:

14 | 15 |
    this code block is indented by two tabs
16 | 
17 | 18 |

And:

19 | 20 |
+   this is an example list item
21 |     indented with tabs
22 | 
23 | +   this is an example list item
24 |     indented with spaces
25 | 
26 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Tabs.text: -------------------------------------------------------------------------------- 1 | + this is a list item 2 | indented with tabs 3 | 4 | + this is a list item 5 | indented with spaces 6 | 7 | Code: 8 | 9 | this code block is indented by one tab 10 | 11 | And: 12 | 13 | this code block is indented by two tabs 14 | 15 | And: 16 | 17 | + this is an example list item 18 | indented with tabs 19 | 20 | + this is an example list item 21 | indented with spaces 22 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Tidyness.html: -------------------------------------------------------------------------------- 1 |
2 |

A list within a blockquote:

3 |
    4 |
  • asterisk 1
  • 5 |
  • asterisk 2
  • 6 |
  • asterisk 3
  • 7 |
8 |
9 | -------------------------------------------------------------------------------- /test/MarkdownTest_1.0.3/Tests/Tidyness.text: -------------------------------------------------------------------------------- 1 | > A list within a blockquote: 2 | > 3 | > * asterisk 1 4 | > * asterisk 2 5 | > * asterisk 3 6 | -------------------------------------------------------------------------------- /test/Tests/CommentsInMiddleOfLine.html: -------------------------------------------------------------------------------- 1 |

It would be super-keen to be able to use MOE directives in Markdown.

3 | 4 |

But I'd really, really 5 | 6 | like to be able to use them in the middle of a line.

7 | -------------------------------------------------------------------------------- /test/Tests/CommentsInMiddleOfLine.text: -------------------------------------------------------------------------------- 1 | It would be super-keen to be able to use [MOE](https://github.com/google/moe) 2 | directives in Markdown. 3 | 4 | 5 | 6 | But I'd really, really 7 | like to be able to use them in the middle of a line. 8 | 9 | -------------------------------------------------------------------------------- /test/Tests/EmptyHeaders.html: -------------------------------------------------------------------------------- 1 |

Some header

2 | 3 |

4 | -------------------------------------------------------------------------------- /test/Tests/EmptyHeaders.text: -------------------------------------------------------------------------------- 1 | # Some header 2 | 3 | {#another-header-that-is-empty} 4 | === 5 | -------------------------------------------------------------------------------- /test/Tests/Escape character.html: -------------------------------------------------------------------------------- 1 |

==Highlight==

2 | 3 |

~~Strikethrough~~

4 | 5 |

_Underscore_

6 | 7 |

_Underscore_

8 | 9 |

_Underscore_

10 | 11 |

_Underscore_

12 | 13 |

_Underscore_

14 | 15 |

*Asterisk*

16 | 17 |

*Asterisk*

18 | 19 |

*Asterisk*

20 | 21 |

*Asterisk*

22 | 23 |

*Asterisk*

24 | 25 |

[Bracket]

26 | 27 |

(Parenthesis)

28 | 29 |

<Chevron>

30 | 31 |

Super^script

32 | 33 |

`Backtick`

34 | 35 |

"Quote"

36 | 37 |

Foo\

38 | 39 |

Foo\*

40 | 41 |

Foo\\Bar\

42 | 43 |

*Foo\Bar\*

44 | 45 |

Foo]

46 | 47 |

Foo\

48 | 49 |

Foo\]

50 | 51 |

Foo\\

52 | -------------------------------------------------------------------------------- /test/Tests/Escape character.text: -------------------------------------------------------------------------------- 1 | \==Highlight\== 2 | 3 | \~~Strikethrough\~~ 4 | 5 | \_Underscore\_ 6 | 7 | \__Underscore\__ 8 | 9 | _\_Underscore_\_ 10 | 11 | \__Underscore_\_ 12 | 13 | _\_Underscore\__ 14 | 15 | \*Asterisk\* 16 | 17 | \**Asterisk\** 18 | 19 | \**Asterisk*\* 20 | 21 | *\*Asterisk\** 22 | 23 | *\*Asterisk*\* 24 | 25 | \[Bracket\] 26 | 27 | \(Parenthesis\) 28 | 29 | \ 30 | 31 | Super\^script 32 | 33 | \`Backtick\` 34 | 35 | \"Quote\" 36 | 37 | **Foo\\** 38 | 39 | *Foo\\\** 40 | 41 | **Foo\\\Bar\\** 42 | 43 | *Foo\\Bar\\\* 44 | 45 | [Foo\]](http://example.com) 46 | 47 | [Foo\\](http://example.com) 48 | 49 | [Foo\\\]](http://example.com) 50 | 51 | [Foo\\\\](http://example.com) 52 | -------------------------------------------------------------------------------- /test/Tests/Formatting in Table of Contents.html: -------------------------------------------------------------------------------- 1 |
2 | 17 |
18 | -------------------------------------------------------------------------------- /test/Tests/Formatting in Table of Contents.text: -------------------------------------------------------------------------------- 1 | # Header with special & characters 2 | 3 | ## With `Code` 4 | 5 | ### With *Emphasis* 6 | -------------------------------------------------------------------------------- /test/Tests/Headers.html: -------------------------------------------------------------------------------- 1 |

A level 1 header

2 | 3 |

## {#not-a-header .only-attributes}

4 | 5 |

{

6 | 7 |

{

8 | 9 |

The two cases above are headers with incomplete attributes.

10 | 11 |

{ I'm a header, too...

12 | -------------------------------------------------------------------------------- /test/Tests/Headers.text: -------------------------------------------------------------------------------- 1 | # A level 1 header 2 | 3 | ## {#not-a-header .only-attributes} 4 | 5 | ###{ 6 | 7 | ### { 8 | 9 | The two cases above are headers with incomplete attributes. 10 | 11 | ####{ I'm a header, too... 12 | -------------------------------------------------------------------------------- /test/Tests/Images.html: -------------------------------------------------------------------------------- 1 |

This is an image.

2 | 3 |

This is a tricky !image.

4 | 5 |

This is another tricky case: !not image.

6 | 7 |

This is a reference image.

8 | 9 |

Terminating !

10 | -------------------------------------------------------------------------------- /test/Tests/Images.text: -------------------------------------------------------------------------------- 1 | This is an ![image](/url). 2 | 3 | This is a tricky !![image](/url). 4 | 5 | This is another tricky case: \![not image](/url). 6 | 7 | This is a reference ![image][ref]. 8 | 9 | [ref]: /url2 10 | 11 | Terminating ! 12 | -------------------------------------------------------------------------------- /test/Tests/Math.html: -------------------------------------------------------------------------------- 1 |

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

4 | 5 |

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

6 | 7 |

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

8 | 9 |

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

10 | 11 |

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

12 | 13 |

( not really math )

14 | 15 |

$$ also not math $$

16 | 17 |

this \(*should* be\) math

18 | 19 |

this\( *should* also be\) math

20 | 21 |

and \(this *should* \)too

22 | 23 |

Something \{ like math but \} is not

24 | 25 |

Also \(like math but \) is not

26 | 27 |

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

28 | 29 |

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

30 | 31 |

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

32 | -------------------------------------------------------------------------------- /test/Tests/Math.text: -------------------------------------------------------------------------------- 1 | \\[ 2 | 1*2*3 multi-line math 3 | \\] 4 | 5 | \\( 1*2*3 inline-math \\) 6 | 7 | $$ 1*2*3 math with dollar $$ 8 | 9 | $$ 1*2*3 \$ \\ \text{dollar with escapes} $$ 10 | 11 | \\( \\ \text{backslash with escapes} \$ 1*2*3 \\) 12 | 13 | \( not *really* math \) 14 | 15 | \$$ also *not* math \$$ 16 | 17 | this $$*should* be$$ math 18 | 19 | this$$ *should* also be$$ math 20 | 21 | and $$this *should* $$too 22 | 23 | Something \\{ like *math* but \\} is not 24 | 25 | Also \\\(like *math* but \\\) is not 26 | 27 | \\\\( should be *math* as well \\\\) 28 | 29 | This is \\( math, and the \\\( inner one \\\) should be \\) preserved 30 | 31 | $$ did you know this is math? $$ 32 | -------------------------------------------------------------------------------- /test/Tests/Table.html: -------------------------------------------------------------------------------- 1 |

Standard table

2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
headline1headline2
123
17 | 18 | 19 |

Cell alignment

20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
headline1headline2headline3
123
37 | 38 | 39 |

Malformed table: missing cell at row in body

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 | 65 | 66 |
headline1headline2headline3
12
34
56
67 | -------------------------------------------------------------------------------- /test/Tests/Table.text: -------------------------------------------------------------------------------- 1 | # Standard table 2 | 3 | |headline1|headline2| 4 | |---------|---------| 5 | |123 | | 6 | 7 | 8 | # Cell alignment 9 | 10 | |headline1|headline2|headline3| 11 | |:-------|:------:|------:| 12 | |123||| 13 | 14 | 15 | # Malformed table: missing cell at row in body 16 | 17 | |headline1|headline2|headline3| 18 | |-------|-------|-------| 19 | |12 20 | |34|| 21 | |56| 22 | -------------------------------------------------------------------------------- /test/Tests/Underline.html: -------------------------------------------------------------------------------- 1 |

This underline will work.

2 | -------------------------------------------------------------------------------- /test/Tests/Underline.text: -------------------------------------------------------------------------------- 1 | This _underline_ will work. 2 | -------------------------------------------------------------------------------- /test/Tests/context/Blockcode.input: -------------------------------------------------------------------------------- 1 | ``` 2 | foo 3 | ``` 4 | 5 | ~~~ 6 | bar 7 | ~~~ 8 | 9 | baz 10 | -------------------------------------------------------------------------------- /test/Tests/context/Blockcode.output: -------------------------------------------------------------------------------- 1 | ` 2 | 3 | ~ 4 | 5 | unfenced blockcode 6 | -------------------------------------------------------------------------------- /test/Tests/context/Depth.input: -------------------------------------------------------------------------------- 1 | * foo 2 | 3 | * bar 4 | 5 | * baz 6 | 7 | bat 8 | 9 | > foo 10 | > 11 | > > bar 12 | > > 13 | > > > baz 14 | 15 | * foo 16 | 17 | > bar 18 | > 19 | > * baz 20 | > 21 | > > bat 22 | -------------------------------------------------------------------------------- /test/Tests/context/Depth.output: -------------------------------------------------------------------------------- 1 | * list depth: 1 blockquote depth: 0 paragraph: foo 2 | 3 | * list depth: 2 blockquote depth: 0 paragraph: bar 4 | 5 | * list depth: 3 blockquote depth: 0 paragraph: baz 6 | list depth: 3 blockquote depth: 0 paragraph: bat 7 | 8 | list depth: 0 blockquote depth: 1 paragraph: foo 9 | 10 | list depth: 0 blockquote depth: 2 paragraph: bar 11 | 12 | list depth: 0 blockquote depth: 3 paragraph: baz 13 | 14 | * list depth: 1 blockquote depth: 0 paragraph: foo 15 | 16 | list depth: 1 blockquote depth: 1 paragraph: bar 17 | 18 | * list depth: 2 blockquote depth: 1 paragraph: baz 19 | 20 | list depth: 2 blockquote depth: 2 paragraph: bat 21 | -------------------------------------------------------------------------------- /test/Tests/context/Escaping.input: -------------------------------------------------------------------------------- 1 | \==a=b\== 2 | -------------------------------------------------------------------------------- /test/Tests/context/Escaping.output: -------------------------------------------------------------------------------- 1 | list depth: 0 blockquote depth: 0 paragraph: 2 | \==a=b\== 3 | -------------------------------------------------------------------------------- /test/Tests/context/Footnotes.input: -------------------------------------------------------------------------------- 1 | [^foo] 2 | 3 | [^foo]: bar 4 | -------------------------------------------------------------------------------- /test/Tests/context/Footnotes.output: -------------------------------------------------------------------------------- 1 | Footnote Reference Definition: [^foo]: bar 2 | 3 | list depth: 0 blockquote depth: 0 paragraph: 4 | id: foo 5 | 6 | id: foo list 7 | depth: 0 blockquote depth: 0 paragraph: 8 | bar 9 | -------------------------------------------------------------------------------- /test/Tests/context/HRules.input: -------------------------------------------------------------------------------- 1 | ----- 2 | 3 | _____ 4 | 5 | ***** 6 | -------------------------------------------------------------------------------- /test/Tests/context/HRules.output: -------------------------------------------------------------------------------- 1 | - 2 | 3 | _ 4 | 5 | * 6 | -------------------------------------------------------------------------------- /test/Tests/context/Headers.input: -------------------------------------------------------------------------------- 1 | # atx 2 | 3 | setext 4 | ====== 5 | -------------------------------------------------------------------------------- /test/Tests/context/Headers.output: -------------------------------------------------------------------------------- 1 | HOEDOWN_HEADER_ATX 2 | 3 | HOEDOWN_HEADER_SETEXT 4 | -------------------------------------------------------------------------------- /test/Tests/context/Links.input: -------------------------------------------------------------------------------- 1 | [foo](/url/) 2 | 3 | [foo](/url/){.inline_attr} 4 | 5 | [foo][bar] 6 | 7 | [foo][] 8 | 9 | [foo] 10 | 11 | [foo]{.inline_attr} 12 | 13 | [foo][attr] 14 | 15 | [foo][attr]{.inline_attr} 16 | 17 | ![foo](/url/) 18 | 19 | ![foo](/url/){.inline_attr} 20 | 21 | ![foo][bar] 22 | 23 | ![foo][] 24 | 25 | ![foo] 26 | 27 | ![foo]{.inline_attr} 28 | 29 | ![foo][attr] 30 | 31 | ![foo][attr]{.inline_attr} 32 | 33 | [bar]: /url/ 34 | [foo]: /url2/ 35 | [attr]: /url3 "attr_title" {.ref_attr} 36 | -------------------------------------------------------------------------------- /test/Tests/context/Links.output: -------------------------------------------------------------------------------- 1 | Reference Definition: [bar]: /url/ 2 | 3 | Reference Definition: [foo]: /url2/ 4 | 5 | Reference Definition: [attr]: /url3 "attr_title" {.ref_attr} 6 | 7 | list depth: 0 blockquote depth: 0 paragraph: 8 | id: no id HOEDOWN_LINK_INLINE 9 | 10 | list depth: 0 blockquote depth: 0 paragraph: 11 | id: no id HOEDOWN_LINK_INLINE 12 | inline_attr: .inline_attr 13 | 14 | list depth: 0 blockquote depth: 0 paragraph: 15 | id: bar HOEDOWN_LINK_REFERENCE 16 | 17 | list depth: 0 blockquote depth: 0 paragraph: 18 | id: foo HOEDOWN_LINK_EMPTY_REFERENCE 19 | 20 | list depth: 0 blockquote depth: 0 paragraph: 21 | id: foo HOEDOWN_LINK_SHORTCUT 22 | 23 | list depth: 0 blockquote depth: 0 paragraph: 24 | id: foo HOEDOWN_LINK_SHORTCUT 25 | inline_attr: .inline_attr 26 | 27 | list depth: 0 blockquote depth: 0 paragraph: 28 | id: attr HOEDOWN_LINK_REFERENCE 29 | ref_attr: .ref_attr 30 | 31 | list depth: 0 blockquote depth: 0 paragraph: 32 | id: attr HOEDOWN_LINK_REFERENCE 33 | ref_attr: .ref_attr 34 | inline_attr: .inline_attr 35 | 36 | list depth: 0 blockquote depth: 0 paragraph: 37 | id: no id HOEDOWN_LINK_INLINE 38 | 39 | list depth: 0 blockquote depth: 0 paragraph: 40 | id: no id HOEDOWN_LINK_INLINE 41 | inline_attr: .inline_attr 42 | 43 | list depth: 0 blockquote depth: 0 paragraph: 44 | id: bar HOEDOWN_LINK_REFERENCE 45 | 46 | list depth: 0 blockquote depth: 0 paragraph: 47 | id: foo HOEDOWN_LINK_EMPTY_REFERENCE 48 | 49 | list depth: 0 blockquote depth: 0 paragraph: 50 | id: foo HOEDOWN_LINK_SHORTCUT 51 | 52 | list depth: 0 blockquote depth: 0 paragraph: 53 | id: foo HOEDOWN_LINK_SHORTCUT 54 | inline_attr: .inline_attr 55 | 56 | list depth: 0 blockquote depth: 0 paragraph: 57 | id: attr HOEDOWN_LINK_REFERENCE 58 | ref_attr: .ref_attr 59 | 60 | list depth: 0 blockquote depth: 0 paragraph: 61 | id: attr HOEDOWN_LINK_REFERENCE 62 | ref_attr: .ref_attr 63 | inline_attr: .inline_attr 64 | -------------------------------------------------------------------------------- /test/Tests/context/Ordered_Lists.input: -------------------------------------------------------------------------------- 1 | 1. foo 2 | 23. bar 3 | 0. baz 4 | 82938. bat 5 | 7. foo 6 | 16. bar 7 | -------------------------------------------------------------------------------- /test/Tests/context/Ordered_Lists.output: -------------------------------------------------------------------------------- 1 | 1. foo 2 | 23. bar 3 | 0. baz 4 | 82938. bat 5 | 7. foo 6 | 16. bar 7 | -------------------------------------------------------------------------------- /test/Tests/context/Unordered_Lists.input: -------------------------------------------------------------------------------- 1 | * foo 2 | 3 | - bar 4 | 5 | + baz 6 | -------------------------------------------------------------------------------- /test/Tests/context/Unordered_Lists.output: -------------------------------------------------------------------------------- 1 | * list depth: 1 blockquote depth: 0 2 | paragraph: foo 3 | 4 | - list depth: 1 blockquote depth: 0 5 | paragraph: bar 6 | 7 | + list depth: 1 blockquote depth: 0 8 | paragraph: baz 9 | -------------------------------------------------------------------------------- /test/Tests/extras/Attributes.html: -------------------------------------------------------------------------------- 1 |

Basic attributes

2 | 3 |
    4 |
  • basic test
  • 5 |
  • valid and invalid cases
  • 6 |
7 | 8 |

Class support

9 | 10 |
    11 |
  • empty class
  • 12 |
  • single-letter class
  • 13 |
  • two-letter class
  • 14 |
  • quoted class
  • 15 |
  • a mix of classes
  • 16 |
17 | 18 |

ID support

19 | 20 |
    21 |
  • empty id
  • 22 |
  • single-letter id
  • 23 |
  • quoted id
  • 24 |
  • id with hash
  • 25 |
  • multiple ids, should take the first
  • 26 |
  • mixed with other attrs
  • 27 |
28 | 29 |

Corner cases

30 | 31 |
    32 |
  • this is not supported :( {foo="bar
  • 33 |
  • escaping quotes does not work :(
  • 34 |
  • quotes for args containing spaces
  • 35 |
  • single quotes work, too
  • 36 |
  • we support extra spaces between attrs
  • 37 |
  • we allow lots of chars for keys/values :/
  • 38 |
39 | -------------------------------------------------------------------------------- /test/Tests/extras/Attributes.text: -------------------------------------------------------------------------------- 1 | ### Basic attributes 2 | 3 | - basic test {#id .class foo=bar} 4 | - valid and invalid cases {#id .cls foo=bar bar="baz" = !yippie =quux =} 5 | 6 | ### Class support 7 | 8 | - empty class {class=} 9 | - single-letter class {class=a} 10 | - two-letter class {class=ab} 11 | - quoted class {class="abc"} 12 | - a mix of classes {.foo class="abc" .bar class=def} 13 | 14 | ### ID support 15 | 16 | - empty id {id=} 17 | - single-letter id {id=w} 18 | - quoted id {id="x"} 19 | - id with hash {#y} 20 | - multiple ids, should take the first {#z id=foo} 21 | - mixed with other attrs {w=xy #z} 22 | 23 | ### Corner cases 24 | 25 | - this is not supported :( {foo="bar {} baz"} 26 | - escaping quotes does not work :( {foo="bar \" baz" x=y} 27 | - quotes for args containing spaces {foo="bar baz" a=b c width=200} 28 | - single quotes work, too {foo='bar "quotes in quotes" baz'} 29 | - we support extra spaces between attrs 30 | { this=works so="does this" .with-spaces } 31 | - we allow lots of chars for keys/values :/ {!=width=200} 32 | -------------------------------------------------------------------------------- /test/Tests/extras/Blockquote_Empty_Line.html: -------------------------------------------------------------------------------- 1 |
2 |

NOTE: This is a blockquote.

3 |
4 |
5 |

FIXME: This is a separate blockquote.

6 |
7 | -------------------------------------------------------------------------------- /test/Tests/extras/Blockquote_Empty_Line.text: -------------------------------------------------------------------------------- 1 | > NOTE: This is a blockquote. 2 | 3 | > FIXME: This is a separate blockquote. 4 | -------------------------------------------------------------------------------- /test/Tests/extras/Codespans.html: -------------------------------------------------------------------------------- 1 |

foo

2 | 3 |

bar

4 | 5 |

baz

6 | 7 |

bat

8 | 9 |

foo bar

10 | 11 |

a \` b \` c

12 | -------------------------------------------------------------------------------- /test/Tests/extras/Codespans.text: -------------------------------------------------------------------------------- 1 | ` foo ` 2 | 3 | `bar 4 | ` 5 | 6 | ` 7 | baz` 8 | 9 | ` 10 | bat 11 | ` 12 | 13 | ` 14 | foo 15 | bar 16 | ` 17 | 18 | ` a \` b \` c ` 19 | -------------------------------------------------------------------------------- /test/Tests/extras/Definition_Lists.html: -------------------------------------------------------------------------------- 1 |

Tight Definition List

2 | 3 |
4 |
Apple
5 |
A fruit
6 |
An apple
7 | 8 |
Orange
9 |
A citrus fruit
10 |
An orange
11 |
12 | 13 |

Tight Definition Lists, Variant

14 | 15 |
16 |
Apple
17 |
A fruit
18 |
An apple
19 | 20 |
Orange
21 |
A citrus fruit
22 |
An orange
23 |
24 | 25 |

Loose Definition List

26 | 27 |
28 |
Apple
29 |
30 |

A fruit

31 |
32 |
33 |

An apple

34 |
35 | 36 |
Orange
37 |
38 |

A citrus fruit

39 |
40 |
41 |

An orange

42 |
43 |
44 | 45 |

Tight Tabs

46 | 47 |
48 |
Apple
49 |
A fruit
50 |
An apple
51 | 52 |
Orange
53 |
A citrus fruit
54 |
An orange
55 |
56 | 57 |

Tight Tabs, Variant

58 | 59 |
60 |
Apple
61 |
A fruit
62 |
An apple
63 | 64 |
Orange
65 |
A citrus fruit
66 |
An orange
67 |
68 | 69 |

Multiple Paragraphs

70 | 71 |
72 |
Apple
73 |
74 |

An apples

75 |

An apple is an apple. Sometimes apples are necessary and sometimes not. Sometimes apples can also have code inside them for various reasons.

76 |

Situations involving apples include doctors and orchards.

77 |
78 |
79 |

A fruit

80 |

Fruits are fruity.

81 |
82 | 83 |
Orange
84 |
85 |

An orange

86 |

Oranges live in the city, unlike apples which live on orchards. 87 |

88 |

Many skyscrapers bare oranges, but only some cities allow picking without a license.

89 |
90 | 91 |
Multiple Terms
92 |
Are also Allowed
93 |
No limits
94 |
95 |

Multiple implies more than one.

96 |
97 |
98 | 99 |

Special Attributes

100 | 101 |
102 |
Apples
103 |
104 |

A lifestyle.

105 |

The Apple lifestyle is a type of lifestyle commonly found in the lifestyle forests.

106 |
107 |
108 |

A fruit.

109 |

Sometimes fruits are bought and then sold to fruit vendors who then buy and sell from other fruit vendors. Many fruit vendors buy fruit and sell them but sometimes the fruits are the ones buying vendors.

110 |
111 | 112 |
This is
113 |
Another
114 |
Three Things
115 |
Four Things
116 |
117 |

Orange

118 |
119 |
120 | 121 |

Just colon things.

122 |

: thing : a thing : another thing

123 |

Another test

124 | 125 |

of

126 | 127 |
128 |
Header interference
129 |
Check that your headers are on different bands before contacting support.
130 |
131 | 132 |

Thing should not be

133 |

: a list

134 | 135 |

but

136 | 137 |
138 |
this is
139 |
okay
140 |
141 | 142 |

Unordered Lists

143 | 144 |
    145 |
  • Test Me
  • 146 |
  • 147 |

    Nothing should interfere here

    148 |
  • 149 |
  • 150 |

    Definitely nothing

    151 |
  • 152 |
153 | 154 |

Ordered Lists

155 | 156 |
    157 |
  1. Apples
  2. 158 |
  3. Apples
  4. 159 |
  5. 160 |

    Apples

    161 |
  6. 162 |
  7. 163 |

    Apples

    164 |
  8. 165 |
166 | 167 |

Example in Readme

168 | 169 |
170 |
Term
171 |
Definition
172 | 173 |
Term 1
174 |
Term 2
175 |
Definition 2
176 | 177 |
Term 3
178 |
179 |

Definition Line 1 Definition Line 2

180 |

Extra paragraphs need four spaces.

181 |
182 |
183 | 184 |

PHP Markdown Examples

185 | 186 |
187 |
Term 1
188 |
189 |

This is a definition with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. 190 |

191 |

Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. 192 |

193 |
194 |
195 |

Second definition for term 1, also wrapped in a paragraph because of the blank line preceding it.

196 |
197 | 198 |
Term 2
199 |
200 |

This definition has a code block, a blockquote and a list.

201 |
code block.
202 | 
203 |
204 |

block quote on two lines.

205 |
206 |
    207 |
  1. first list item
  2. 208 |
  3. second list item
  4. 209 |
210 |
211 |
212 | 213 |

Indentation Fun

214 | 215 |
    216 |
  1. 217 |

    Ordered Item 1

    218 |
    219 |
    Indented Term 1
    220 |
    221 |

    Definition

    222 |
    223 |
    224 |

    Definition 2

    225 |
    226 |
    227 |
  2. 228 | 229 |
  3. 230 |
    231 |
    Ordered Term 1
    232 |
    Definition 1
    233 |
    Definition 2
    234 |
    235 |
  4. 236 | 237 |
  5. 238 |
    239 |
    Ordered Term 2
    240 |
    Ordered Term 3
    241 |
    Definition 1
    242 |
    243 |
  6. 244 |
245 | 246 |

Blockquotes

247 |
248 |
249 |
This line is a blockquote
250 |
and it is a definition list
251 |
This should also
252 |
Play rather
253 |
nicely
254 |
255 |

This is actually

256 |
257 |
258 |
Pretty cool that it
259 |
Automagically works
260 |
Pretty cool, huh?
261 |
262 |
263 |
264 |
Embedded List
265 |
This is a definition
266 |
267 |
268 |

Another block quote

269 |
270 |
271 |
Why would
272 |
> Anyone do this? > Is this reality?
273 |
274 |
275 |
    276 |
  1. In any case, that wasn't supported
  2. 277 |
  3. > Because this isn't supported and it isn't specced
  4. 278 |
  5. Blockquotes are also > Not supported > Inside list items 279 |
  6. 280 |
281 |
282 |
This is a term
283 |
284 |

This will be a para

285 |
286 |

a blockquote

287 |
288 |

A header

289 |
290 |
291 | 292 |

Tables

293 | 294 |
295 |
This is a definition list
296 |
297 |

Example11

298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 |
11 1312
1516 18
19110
111 113112
320 |
321 |
322 |

This is another definition

323 |
324 |
This is another term
325 |
326 |

Example22

327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 |
21 23 25 2722 24 26 28
29 211 213 215210 212 214 216
341 |
342 |
Term me more
343 |
Term me 3
344 |
345 |

Example33

346 |
347 |
348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 |
1 32
56 8
910
11 1312
370 | 371 |

HTML and Codeblocks

372 | 373 |

hey whats this what about this

374 |
is this html
375 | : maybe 376 |

do this thing : maybe 377 |

378 |
neither should
379 | : this really work
380 | 
381 | -------------------------------------------------------------------------------- /test/Tests/extras/Definition_Lists.text: -------------------------------------------------------------------------------- 1 | ## Tight Definition List 2 | 3 | Apple 4 | : A fruit 5 | : An apple 6 | 7 | Orange 8 | : A citrus fruit 9 | : An orange 10 | 11 | ## Tight Definition Lists, Variant 12 | 13 | Apple 14 | 15 | : A fruit 16 | : An apple 17 | 18 | Orange 19 | 20 | : A citrus fruit 21 | : An orange 22 | 23 | ## Loose Definition List 24 | 25 | Apple 26 | 27 | : A fruit 28 | 29 | : An apple 30 | 31 | Orange 32 | 33 | : A citrus fruit 34 | 35 | : An orange 36 | 37 | ## Tight Tabs 38 | 39 | Apple 40 | 41 | : A fruit 42 | : An apple 43 | 44 | Orange 45 | 46 | : A citrus fruit 47 | : An orange 48 | 49 | ## Tight Tabs, Variant 50 | 51 | Apple 52 | : A fruit 53 | : An apple 54 | 55 | Orange 56 | : A citrus fruit 57 | : An orange 58 | 59 | ## Multiple Paragraphs 60 | 61 | Apple 62 | 63 | : An apples 64 | 65 | An apple is an apple. Sometimes apples are necessary and sometimes not. 66 | Sometimes apples can also have `code` inside them for various reasons. 67 | 68 | Situations involving apples include doctors and orchards. 69 | 70 | : A fruit 71 | 72 | Fruits are fruity. 73 | 74 | Orange 75 | 76 | : An orange 77 | 78 | Oranges live in the city, unlike apples which live on orchards. 79 | 80 | Many skyscrapers bare oranges, but only some cities allow picking without a license. 81 | 82 | Multiple Terms 83 | Are also Allowed 84 | No limits 85 | 86 | : Multiple implies more than one. 87 | 88 | ## Special Attributes 89 | 90 | Apples {#apple .apple-class} 91 | 92 | : A lifestyle. {.apples} 93 | 94 | The Apple lifestyle is a type of lifestyle commonly found in the lifestyle forests. 95 | 96 | : A fruit. {.fruit} 97 | 98 | Sometimes fruits are bought and then sold to fruit vendors who then buy and sell from other fruit vendors. 99 | Many fruit vendors buy fruit and sell them but sometimes the fruits are the ones buying vendors. 100 | 101 | This is {.apple-class} 102 | Another {#apple-id} 103 | Three Things 104 | Four Things {#id .classy} 105 | 106 | : Orange 107 | 108 | ## Just colon things. 109 | 110 | : thing 111 | : a thing 112 | : another thing 113 | 114 | Another test 115 | ## of 116 | Header interference 117 | : Check that your headers are on different bands before contacting support. 118 | 119 | Thing should not be 120 | --- 121 | : a list 122 | 123 | but 124 | --- 125 | this is 126 | : okay 127 | 128 | ## Unordered Lists 129 | 130 | + Test Me 131 | + Nothing should interfere here 132 | 133 | - Definitely nothing 134 | 135 | ## Ordered Lists 136 | 137 | 1. Apples 138 | 1. Apples 139 | 1. Apples 140 | 141 | 2. Apples 142 | 143 | ## Example in Readme 144 | 145 | Term 146 | : Definition 147 | 148 | Term 1 149 | Term 2 150 | : Definition 2 151 | 152 | Term 3 153 | : Definition Line 1 154 | Definition Line 2 155 | 156 | Extra paragraphs need four spaces. 157 | 158 | ## PHP Markdown Examples 159 | 160 | Term 1 161 | 162 | : This is a definition with two paragraphs. Lorem ipsum 163 | dolor sit amet, consectetuer adipiscing elit. Aliquam 164 | hendrerit mi posuere lectus. 165 | 166 | Vestibulum enim wisi, viverra nec, fringilla in, laoreet 167 | vitae, risus. 168 | 169 | : Second definition for term 1, also wrapped in a paragraph 170 | because of the blank line preceding it. 171 | 172 | Term 2 173 | 174 | : This definition has a code block, a blockquote and a list. 175 | 176 | code block. 177 | 178 | > block quote 179 | > on two lines. 180 | 181 | 1. first list item 182 | 2. second list item 183 | 184 | ## Indentation Fun 185 | 186 | 1. Ordered Item 1 187 | 188 | Indented Term 1 189 | 190 | : Definition 191 | 192 | : Definition 2 193 | 194 | 2. Ordered Term 1 195 | : Definition 1 196 | : Definition 2 197 | 198 | 3. Ordered Term 2 199 | Ordered Term 3 200 | 201 | : Definition 1 202 | 203 | ## Blockquotes 204 | 205 | > This line is a blockquote 206 | : and it is a definition list 207 | 208 | > This should also 209 | > Play rather 210 | > : nicely 211 | 212 | > This is actually 213 | > > Pretty cool that it 214 | > > Automagically works 215 | > > : Pretty cool, huh? 216 | 217 | > Embedded List 218 | > : This is a definition 219 | > 220 | > > Another block quote 221 | 222 | > Why would 223 | > : > Anyone do this? 224 | > > Is this reality? 225 | 226 | 1. In any case, that wasn't supported 227 | 2. > Because this isn't supported and it isn't specced 228 | 3. Blockquotes are also 229 | > Not supported 230 | > Inside list items 231 | 232 | This *is* a term 233 | 234 | : This will be a para 235 | 236 | > a blockquote 237 | 238 | # A header 239 | 240 | ## Tables 241 | 242 | This is a definition list 243 | 244 | : Example11 245 | 246 | 11 | 12 247 | : 13 : : 248 | --- | --- 249 | 15 | 16 250 | : : 18 251 | 19 | 110 252 | 111 | 112 253 | : 113 : : 254 | 255 | 256 | : This is another definition 257 | 258 | This is another term 259 | : Example22 260 | 261 | | 21 | 22 | 262 | : 23 : 24 : 263 | : 25 : 26 : 264 | : 27 : 28 : 265 | | --- | --- | 266 | | 29 | 210 | 267 | : 211 : 212 : 268 | : 213 : 214 : 269 | : 215 : 216 : 270 | 271 | Term me more 272 | Term me 3 273 | : Example33 274 | 275 | 1 | 2 276 | : 3 : : 277 | --- | --- 278 | 5 | 6 279 | : : 8 280 | 9 | 10 281 | 11 | 12 282 | : 13 : : 283 | 284 | ## HTML and Codeblocks 285 | 286 | hey whats this 287 | what about this 288 |
is this html
289 | ``` 290 | : maybe 291 | ``` 292 | 293 | do this thing 294 | ``` 295 | : maybe 296 | ``` 297 | 298 | ``` 299 | neither should 300 | : this really work 301 | ``` -------------------------------------------------------------------------------- /test/Tests/extras/Emphases_Intra_Underline.html: -------------------------------------------------------------------------------- 1 |

a

2 | 3 |

b

4 | 5 |

_a_b_c

6 | 7 |

a_b_c_d

8 | 9 |

"a"

10 | 11 |

.a.

12 | -------------------------------------------------------------------------------- /test/Tests/extras/Emphases_Intra_Underline.text: -------------------------------------------------------------------------------- 1 | _a_ 2 | 3 | __b__ 4 | 5 | _a_b_c 6 | 7 | a_b_c_d 8 | 9 | "*a*" 10 | 11 | .*a*. 12 | -------------------------------------------------------------------------------- /test/Tests/extras/Escape_Backticks.html: -------------------------------------------------------------------------------- 1 |

`bar 2 | \`\``

3 | -------------------------------------------------------------------------------- /test/Tests/extras/Escape_Backticks.text: -------------------------------------------------------------------------------- 1 | \``` 2 | bar 3 | \```` 4 | \``` 5 | -------------------------------------------------------------------------------- /test/Tests/extras/FencedCode_Script.html: -------------------------------------------------------------------------------- 1 | 2 |

alert("Example");
 3 | 
4 | 5 | 8 | 9 |
@found "You", ->
10 |   @message "get", "JUMLY"
11 | 
12 | 13 | 17 | -------------------------------------------------------------------------------- /test/Tests/extras/FencedCode_Script.text: -------------------------------------------------------------------------------- 1 | 2 | ``` text/javascript 3 | alert("Example"); 4 | ``` 5 | 6 | ``` script@text/javascript 7 | alert("Example"); 8 | ``` 9 | 10 | ``` text/jumly+sequence 11 | @found "You", -> 12 | @message "get", "JUMLY" 13 | ``` 14 | 15 | ``` script@text/jumly+sequence 16 | @found "You", -> 17 | @message "get", "JUMLY" 18 | ``` 19 | 20 | -------------------------------------------------------------------------------- /test/Tests/extras/Footnotes.html: -------------------------------------------------------------------------------- 1 | 2 |

foo1

3 | 4 |

Here's a footnote 2.

5 | 6 |

Here is a footnote reference,3 and another.4

7 | 8 |

This paragraph won't be part of the note, because it 9 | isn't indented.

10 | 11 |
12 |
13 |
    14 | 15 |
  1. 16 |

    foo 

    17 | 18 |
      19 |
    • list
    • 20 |
    21 | 22 |

    not in list

    23 |
  2. 24 | 25 |
  3. 26 |

    Footnote text goes here. 

    27 |
  4. 28 | 29 |
  5. 30 |

    Here is the footnote. 

    31 |
  6. 32 | 33 |
  7. 34 |

    Here's one with multiple blocks. 

    35 | 36 |

    Subsequent paragraphs are indented to show that they belong to the previous footnote.

    37 | 38 |
    { some.code }
    39 | 
    40 | 41 |

    The whole paragraph can be indented, or just the first 42 | line. In this way, multi-paragraph footnotes work like 43 | multi-paragraph list items.

    44 |
  8. 45 | 46 |
47 |
48 | -------------------------------------------------------------------------------- /test/Tests/extras/Footnotes.text: -------------------------------------------------------------------------------- 1 | 2 | foo[^1] 3 | 4 | [^1]: foo 5 | 6 | * list 7 | 8 | not in list 9 | 10 | Here's a footnote [^2]. 11 | 12 | [^2]: Footnote text goes here. 13 | 14 | Here is a footnote reference,[^3] and another.[^longnote] 15 | 16 | [^3]: Here is the footnote. 17 | 18 | [^longnote]: Here's one with multiple blocks. 19 | 20 | Subsequent paragraphs are indented to show that they belong to the previous footnote. 21 | 22 | { some.code } 23 | 24 | The whole paragraph can be indented, or just the first 25 | line. In this way, multi-paragraph footnotes work like 26 | multi-paragraph list items. 27 | 28 | This paragraph won't be part of the note, because it 29 | isn't indented. 30 | -------------------------------------------------------------------------------- /test/Tests/extras/HTML5_Block.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
something
4 | 5 |
hello hello
6 | 7 |
8 |

hello

9 |

hello

10 |
11 | -------------------------------------------------------------------------------- /test/Tests/extras/HTML5_Block.text: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | something 6 | 7 |
8 | 9 |
hello 10 | 11 | hello
12 | 13 |

hello

14 | 15 |

hello

16 | -------------------------------------------------------------------------------- /test/Tests/extras/HTML_Block.html: -------------------------------------------------------------------------------- 1 |

foo

2 | 3 |

bar

4 | 5 |

foo

6 | 7 |

bar

8 | 9 |

baz

10 | -------------------------------------------------------------------------------- /test/Tests/extras/HTML_Block.text: -------------------------------------------------------------------------------- 1 |

foo

2 |

bar

3 | 4 | foo 5 | 6 | bar 7 | 8 |

baz

9 | -------------------------------------------------------------------------------- /test/Tests/extras/HTML_Nested.html: -------------------------------------------------------------------------------- 1 |
2 |
text 3 |
4 |
5 |
6 | *dont parse* 7 |
8 | -------------------------------------------------------------------------------- /test/Tests/extras/HTML_Nested.text: -------------------------------------------------------------------------------- 1 |
2 |
text 3 |
4 |
5 |
6 | *dont parse* 7 |
8 | -------------------------------------------------------------------------------- /test/Tests/extras/Header_Empty.html: -------------------------------------------------------------------------------- 1 |

==

2 | 3 |

#

4 | 5 |

{#id}

6 | 7 |

==

8 | 9 |

#

10 | 11 |

{#id}

12 | 13 |

14 | -------------------------------------------------------------------------------- /test/Tests/extras/Header_Empty.text: -------------------------------------------------------------------------------- 1 | 2 | == 3 | 4 | # 5 | 6 | #{#id} 7 | 8 | 9 | == 10 | 11 | # 12 | 13 | # {#id} 14 | 15 | ## ## 16 | -------------------------------------------------------------------------------- /test/Tests/extras/Header_Empty_Attribute.html: -------------------------------------------------------------------------------- 1 |

==

2 | 3 |

#

4 | 5 |

#{#id}

6 | 7 |

==

8 | 9 |

#

10 | 11 |

# {#id}

12 | 13 |

14 | -------------------------------------------------------------------------------- /test/Tests/extras/Header_Empty_Attribute.text: -------------------------------------------------------------------------------- 1 | 2 | == 3 | 4 | # 5 | 6 | #{#id} 7 | 8 | 9 | == 10 | 11 | # 12 | 13 | # {#id} 14 | 15 | ## ## 16 | -------------------------------------------------------------------------------- /test/Tests/extras/Header_ID.html: -------------------------------------------------------------------------------- 1 |

Test

2 | 3 |

Title

4 | 5 |

Not Title

6 | -------------------------------------------------------------------------------- /test/Tests/extras/Header_ID.text: -------------------------------------------------------------------------------- 1 | # Test 2 | 3 | # Title {.not-title} 4 | 5 | # Not Title {#is-title} 6 | -------------------------------------------------------------------------------- /test/Tests/extras/Line_Continue.html: -------------------------------------------------------------------------------- 1 |

This is a Pen.

2 | 3 |

あいうえおかきくけこさしすせそ

4 | 5 |

あいうえお abc かきくけこ def

6 | -------------------------------------------------------------------------------- /test/Tests/extras/Line_Continue.text: -------------------------------------------------------------------------------- 1 | This 2 | is 3 | a 4 | Pen. 5 | 6 | あいうえお 7 | かきくけこ 8 | さしすせそ 9 | 10 | あいうえお 11 | abc 12 | かきくけこ 13 | def 14 | -------------------------------------------------------------------------------- /test/Tests/extras/Link_Attributes.html: -------------------------------------------------------------------------------- 1 | 2 |

http://example.com

3 | 4 |

Example

5 | 6 |

Example

7 | -------------------------------------------------------------------------------- /test/Tests/extras/Link_Attributes.text: -------------------------------------------------------------------------------- 1 | 2 | http://example.com 3 | 4 | [Example](http://example.com) 5 | 6 | [Example](http://example.com){#id .class foo=bar} 7 | -------------------------------------------------------------------------------- /test/Tests/extras/List_Item_FencedCode.html: -------------------------------------------------------------------------------- 1 |

10 | -------------------------------------------------------------------------------- /test/Tests/extras/List_Item_FencedCode.text: -------------------------------------------------------------------------------- 1 | * This is a test 2 | * This is some code: 3 | 4 | ``` 5 | int main() { 6 | printf("Hello world!"); 7 | } 8 | ``` 9 | -------------------------------------------------------------------------------- /test/Tests/extras/List_Item_Fenced_Code_First_Line.html: -------------------------------------------------------------------------------- 1 |

hoedown/hoedown#236 = 2 | kjdev/hoextdown#57

3 | 4 |
    5 |
  1. First item.

  2. 6 |
  3. Some code.
     7 | More code.
     8 | 
    9 | 10 |

    There is code here.

  4. 11 |
  5. Triple quoted code is not fenced code.

  6. 12 |
  7. Some ``nested `quotes` code`` may require it.

  8. 13 |
  9. Having some

    14 | 15 |

    triple quoted code

    16 | 17 |

    inside your item should work, too.

  10. 18 |
  11. This last item is still in the same list.

  12. 19 |
20 | 21 |

End of this list.

22 | 23 |
    24 |
  1.     print("Hello!")
    25 |   else:
    26 |     print("Good bye.")
    27 | 
    28 | 29 |

    The item has one more space than it needs.

  2. 30 |
  3. And a last item.

  4. 31 |
32 | -------------------------------------------------------------------------------- /test/Tests/extras/List_Item_Fenced_Code_First_Line.text: -------------------------------------------------------------------------------- 1 | [hoedown/hoedown#236](https://github.com/hoedown/hoedown/issues/236) = 2 | [kjdev/hoextdown#57](https://github.com/kjdev/hoextdown/issues/57) 3 | 4 | 1. First item. 5 | 6 | 1. ``` 7 | Some code. 8 | More code. 9 | ``` 10 | 11 | There is code here. 12 | 13 | 1. ```Triple quoted code``` is not fenced code. 14 | 15 | 1. ```Some ``nested `quotes` code`` may``` require it. 16 | 17 | 1. Having some 18 | 19 | ```triple quoted code``` 20 | 21 | inside your item should work, too. 22 | 23 | 1. This last item is still in the same list. 24 | 25 | End of this list. 26 | 27 | 1. ```python 28 | print("Hello!") 29 | else: 30 | print("Good bye.") 31 | ``` 32 | 33 | The item has one more space than it needs. 34 | 1. And a last item. 35 | -------------------------------------------------------------------------------- /test/Tests/extras/List_Item_First_Line.html: -------------------------------------------------------------------------------- 1 |
    2 |
  • foo

    3 | 4 |

    bar

  • 5 |
  • foo

    6 | 7 |

    bar

  • 8 |
9 | -------------------------------------------------------------------------------- /test/Tests/extras/List_Item_First_Line.text: -------------------------------------------------------------------------------- 1 | * # foo 2 | 3 | # bar 4 | 5 | * # foo 6 | 7 | # bar 8 | -------------------------------------------------------------------------------- /test/Tests/extras/Meta_Block.html: -------------------------------------------------------------------------------- 1 | 2 |

This is hoextdown example.

3 | -- Meta Block -- 4 | author: user 5 | title: Readme markdown parser 6 | -------------------------------------------------------------------------------- /test/Tests/extras/Meta_Block.text: -------------------------------------------------------------------------------- 1 | 5 | 6 | This is hoextdown example. 7 | -------------------------------------------------------------------------------- /test/Tests/extras/Meta_Block_Multi.html: -------------------------------------------------------------------------------- 1 |

This is example 1.

2 | 3 |

This is example 2.

4 | 5 |

This is example 3.

6 | -- Meta Block -- 7 | block-1: first block 8 | block-2: second block 9 | block-3: third block 10 | -------------------------------------------------------------------------------- /test/Tests/extras/Meta_Block_Multi.text: -------------------------------------------------------------------------------- 1 | 4 | 5 | This is example 1. 6 | 7 | 8 | 9 | This is example 2. 10 | 11 | 12 | 13 | This is example 3. 14 | -------------------------------------------------------------------------------- /test/Tests/extras/More_Tables.html: -------------------------------------------------------------------------------- 1 |

Minimal table:

2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
foobarbaz
oofrabzab
oforbabza
24 | 25 |

Leading pipes only:

26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |
foobarbaz
oofrabzab
oforbabza
48 | 49 |

Trailing pipes only:

50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 |
foobarbaz
oofrabzab
oforbabza
72 | 73 |

Leading and trailing pipes:

74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 |
foobarbaz
oofrabzab
oforbabza
96 | 97 |

Extra padding:

98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 |
foobarbaz
oofrabzab
oforbabza
120 | 121 |

No padding:

122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 |
foobarbaz
oofrabzab
oforbabza
144 | 145 |

Single column, leading pipe style:

146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 |
foo
bar
baz
162 | 163 |

Single column, trailing pipe style:

164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 |
foo
bar
baz
180 | 181 |

With plus header separator:

182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 |
foobarbaz
oofrabzab
oforbabza
204 | -------------------------------------------------------------------------------- /test/Tests/extras/More_Tables.text: -------------------------------------------------------------------------------- 1 | Minimal table: 2 | 3 | foo | bar | baz 4 | --- | --- | --- 5 | oof | rab | zab 6 | ofo | rba | bza 7 | 8 | Leading pipes only: 9 | 10 | | foo | bar | baz 11 | | --- | --- | --- 12 | | oof | rab | zab 13 | | ofo | rba | bza 14 | 15 | Trailing pipes only: 16 | 17 | foo | bar | baz | 18 | --- | --- | --- | 19 | oof | rab | zab | 20 | ofo | rba | bza | 21 | 22 | Leading and trailing pipes: 23 | 24 | | foo | bar | baz | 25 | | --- | --- | --- | 26 | | oof | rab | zab | 27 | | ofo | rba | bza | 28 | 29 | Extra padding: 30 | 31 | foo | bar | baz 32 | --- | --- | --- 33 | oof | rab | zab 34 | ofo | rba | bza 35 | 36 | No padding: 37 | 38 | foo|bar|baz 39 | ---|---|--- 40 | oof|rab|zab 41 | ofo|rba|bza 42 | 43 | Single column, leading pipe style: 44 | 45 | | foo 46 | | --- 47 | | bar 48 | | baz 49 | 50 | Single column, trailing pipe style: 51 | 52 | foo | 53 | --- | 54 | bar | 55 | baz | 56 | 57 | With plus header separator: 58 | 59 | foo | bar | baz 60 | ----+-----+---- 61 | oof | rab | zab 62 | ofo | rba | bza 63 | -------------------------------------------------------------------------------- /test/Tests/extras/Multiline_Table.text: -------------------------------------------------------------------------------- 1 | Minimal header and body row continuation, with interior row and end row: 2 | 3 | 1 | 2 4 | : 3 : 4 5 | --- | --- 6 | 5 | 6 7 | : 7 : 8 8 | 9 | 10 9 | 11 | 12 10 | : 13 : 14 11 | 12 | With leading pipes: 13 | 14 | | 1 | 2 15 | : 3 : 4 16 | --- | --- 17 | | 5 | 6 18 | : 7 : 8 19 | | 9 | 10 20 | | 11 | 12 21 | : 13 : 14 22 | 23 | With trailing pipes only: 24 | 25 | | 1 | 2 | 26 | : 3 : 4 27 | --- | --- 28 | | 5 | 6 | 29 | : 7 : 8 30 | | 9 | 10 | 31 | | 11 | 12 | 32 | : 13 : 14 33 | 34 | With trailing colons only: 35 | 36 | | 1 | 2 37 | : 3 : 4 : 38 | --- | --- 39 | | 5 | 6 40 | : 7 : 8 : 41 | | 9 | 10 42 | | 11 | 12 43 | : 13 : 14 : 44 | 45 | With trailing pipes and colons: 46 | 47 | | 1 | 2 | 48 | : 3 : 4 : 49 | --- | --- 50 | | 5 | 6 | 51 | : 7 : 8 : 52 | | 9 | 10 | 53 | | 11 | 12 | 54 | : 13 : 14 : 55 | 56 | Without body padding: 57 | 58 | | 1 | 2 | 59 | : 3 : 4 : 60 | ---|--- 61 | |5|6| 62 | :7:8: 63 | |9|10| 64 | |11|12| 65 | :13:14: 66 | 67 | Without header padding (except mandatory leading space): 68 | 69 | |1|2| 70 | : 3:4: 71 | --- | --- 72 | | 5 | 6 | 73 | : 7 : 8 : 74 | | 9 | 10 | 75 | | 11 | 12 | 76 | : 13 : 14 : 77 | 78 | Many continuation lines: 79 | 80 | | 1 | 2 | 81 | : 3 : 4 : 82 | : 5 : 6 : 83 | : 7 : 8 : 84 | | --- | --- | 85 | | 9 | 10 | 86 | : 11 : 12 : 87 | : 13 : 14 : 88 | : 15 : 16 : 89 | 90 | Single column: 91 | 92 | | 1 93 | : 2 94 | | --- 95 | | 3 96 | : 4 97 | | --- 98 | | 5 99 | : 6 100 | | 7 101 | 102 | Empty continued cells: 103 | 104 | 1 | 2 105 | : 3 : : 106 | --- | --- 107 | 5 | 6 108 | : : 8 109 | 9 | 10 110 | 11 | 12 111 | : 13 : : 112 | 113 | Squished empty continued cells: 114 | 115 | 1 | 2 116 | : 3 :: 117 | --- | --- 118 | 5 | 6 119 | :: 8 120 | 9 | 10 121 | 11 | 12 122 | : 13 :: 123 | 124 | Empty then not empty continued cells: 125 | 126 | 1 | 2 127 | : 3 : : 128 | : : 4 129 | --- | --- 130 | 5 | 6 131 | : : 8 132 | : 7 : : 133 | 9 | 10 134 | 11 | 12 135 | : 13 : : 136 | : : 14 : 137 | 138 | Inside another element: 139 | 140 | * foo 141 | 142 | 1 | 2 143 | : 3 : 4 144 | --- | --- 145 | 5 | 6 146 | : 7 : 8 147 | 9 | 10 148 | 11 | 12 149 | : 13 : 14 150 | 151 | Pipes on continued lines: 152 | 153 | 1 | 2 154 | : 3 | : 4 | 155 | --- | --- 156 | 5 | 6 157 | : 7 | : | 8 158 | 9 | 10 159 | 11 | 12 160 | : 13 | : 14 161 | 162 | Colons on regular lines: 163 | 164 | 1: | : 2 165 | : 3 : 4 166 | --- | --- 167 | 5 : | :6 168 | : 7 : 8 169 | : 9 | 10 170 | 11 :: | 12 171 | : 13 : 14 172 | 173 | Escaped pipes with continued lines: 174 | 175 | 1 \| | 2 176 | : 3 : 4 177 | --- | --- 178 | 5 | 6 \| 179 | : 7 : 8 180 | 9 | 10 181 | 11 \| | 12 \| 182 | : 13 : 14 183 | 184 | Escaped colons on continued lines: 185 | 186 | 1 | 2 187 | : 3\: : 4 188 | --- | --- 189 | 5 | 6 190 | : \: 7 : 8 \: 191 | 9 | 10 192 | 11 | 12 193 | : 13 \: : \: 14 194 | 195 | Inline elements spanning multiple lines: 196 | 197 | 1 | 2 198 | : 3 : 4 199 | --- | --- 200 | **5 | 6 201 | : 7** : 8 202 | 9 | 10 203 | 11 | [12] 204 | : 13 : (/14) 205 | 206 | Optional row separators: 207 | 208 | 1 | 2 209 | : 3 : 4 210 | --- | --- 211 | 5 | 6 212 | : 7 : 8 213 | --- | --- 214 | 9 | 10 215 | --- | --- 216 | 11 | 12 217 | : 13 : 14 218 | --- | --- 219 | 220 | Optional row separators with leading pipes: 221 | 222 | 1 | 2 223 | : 3 : 4 224 | | --- | --- 225 | 5 | 6 226 | : 7 : 8 227 | | --- | --- 228 | 9 | 10 229 | | --- | --- 230 | 11 | 12 231 | : 13 : 14 232 | | --- | --- 233 | 234 | Optional row separators with trailing pipes: 235 | 236 | 1 | 2 237 | : 3 : 4 238 | --- | --- | 239 | 5 | 6 240 | : 7 : 8 241 | --- | --- | 242 | 9 | 10 243 | --- | --- | 244 | 11 | 12 245 | : 13 : 14 246 | --- | --- | 247 | 248 | Optional row separators with leading and trailing pipes: 249 | 250 | 1 | 2 251 | : 3 : 4 252 | | --- | --- | 253 | 5 | 6 254 | : 7 : 8 255 | | --- | --- | 256 | 9 | 10 257 | | --- | --- | 258 | 11 | 12 259 | : 13 : 14 260 | | --- | --- | 261 | 262 | Optional row separators without padding: 263 | 264 | 1 | 2 265 | : 3 : 4 266 | |---|---| 267 | 5 | 6 268 | : 7 : 8 269 | |---|---| 270 | 9 | 10 271 | |---|---| 272 | 11 | 12 273 | : 13 : 14 274 | |---|---| 275 | 276 | Escaped colons in codespans: 277 | 278 | | foo | bar | baz | 279 | : `\:` : `\\:` : `\\\:` : 280 | | ---- | ----- | ------ | 281 | | foo | bar | baz | 282 | : `\:` : `\\:` : `\\\:` : 283 | -------------------------------------------------------------------------------- /test/Tests/extras/Multiline_Table_Malformed.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
ab
c
:d
20 | -------------------------------------------------------------------------------- /test/Tests/extras/Multiline_Table_Malformed.text: -------------------------------------------------------------------------------- 1 | a |b 2 | ---|--- 3 | |c 4 | : |d 5 | -------------------------------------------------------------------------------- /test/Tests/extras/Radio.html: -------------------------------------------------------------------------------- 1 |

Unordered list:

2 |
    3 |
  • Option 1
  • 4 |
  • Option 2
  • 5 |
  • Option 3
  • 6 |
7 | 8 |

Ordered list:

9 |
    10 |
  1. Option 1
  2. 11 |
  3. Option 2
  4. 12 |
  5. Option 3
  6. 13 |
14 | 15 |

Nested list:

16 |
    17 |
  • Option A 18 |
      19 |
    • Option A1
    • 20 |
    • Option A2
    • 21 |
    • Option A3
    • 22 |
    23 |
  • 24 |
  • Option B 25 |
      26 |
    1. Option B1
    2. 27 |
    3. Option B2
    4. 28 |
    5. Option B3
    6. 29 |
    30 |
  • 31 |
32 | 33 |
    34 |
  1. 35 |

    A loose list

    36 |

    ... can also ...

    37 |
  2. 38 |
  3. 39 |

    contain radios

    40 |
  4. 41 |
  5. 42 |

    ... mixed with other items ...

    43 |
  6. 44 |
45 |
46 |
Definition lists
47 |
( ) cannot contain tasks (this renders as ( )).
48 |
49 | 50 | 51 | -------------------------------------------------------------------------------- /test/Tests/extras/Radio.text: -------------------------------------------------------------------------------- 1 | 2 | Unordered list: 3 | 4 | * (X) Option 1 5 | * ( ) Option 2 6 | * ( ) Option 3 7 | 8 | Ordered list: 9 | 10 | 1. ( ) Option 1 11 | 2. (x) Option 2 12 | 3. ( ) Option 3 13 | 14 | Nested list: 15 | 16 | * ( ) Option A 17 | * ( ) Option A1 18 | * ( ) Option A2 19 | * ( ) Option A3 20 | * ( ) Option B 21 | 1. ( ) Option B1 22 | 2. ( ) Option B2 23 | 3. ( ) Option B3 24 | 25 | 26 | 1. ( ) A loose list 27 | 28 | ... can also ... 29 | 30 | 2. (x) contain radios 31 | 3. ... mixed with other items ... 32 | 33 | Definition lists 34 | : ( ) cannot contain tasks (this renders as `( )`). 35 | -------------------------------------------------------------------------------- /test/Tests/extras/Script_Tags.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

This is inline link.

4 | 5 | 9 | 10 |

See my About page for details.

11 | 12 |

This is the

13 | 14 |

This is the

15 | 16 |

This is the

18 | 19 |

This is the

22 | -------------------------------------------------------------------------------- /test/Tests/extras/Script_Tags.text: -------------------------------------------------------------------------------- 1 | 2 | 3 | This is inline link. 4 | 5 | 9 | 10 | See my [About](/about/) page for details. 11 | 12 | This is the 13 | 14 | This is the 15 | 16 | This is the 18 | 19 | This is the 22 | -------------------------------------------------------------------------------- /test/Tests/extras/Special_Attribute_Activation.html: -------------------------------------------------------------------------------- 1 |

Not {.activated}

2 | 3 |

{.activated}

4 | 5 |

{{.activated}} content

6 | 7 |

Is

8 | 9 |

10 | This tests links{.link-me} and 11 | block code{.code-me} 12 |

13 | 14 |

15 | This tests links and 16 | block code 17 |

18 | 19 |
    20 |
  • list {.do-nothing}
  • 21 |
  • list
  • 22 |
23 | 24 |
print "hello"
 25 | 
26 | 27 |
print "hello"
 28 | 
29 | 30 |

hello {.not-title}

31 | 32 |

hello

33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 |
NameAge {.not-table}
Fred29
Jim47
Harry32
53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 |
NameAge
Fred29
Jim47
Harry32
73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 |
foo bazbar {.not-table} bat
foo bazbar bat
88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 |
foo bazbar bat
foo bazbar bat
104 | -------------------------------------------------------------------------------- /test/Tests/extras/Special_Attribute_Activation.text: -------------------------------------------------------------------------------- 1 | # Not {.activated} 2 | 3 | # {.activated} 4 | 5 | # {{.activated}} content 6 | 7 | # Is {: .activated} 8 | 9 | This tests [links](notreal.com){.link-me} and `block code`{.code-me} 10 | 11 | This tests [links](notreal.com){: .link-me} and `block code`{: .code-me} 12 | 13 | * list {.do-nothing} 14 | * list {:.do-something} 15 | 16 | ```{.codefence-me} 17 | print "hello" 18 | ``` 19 | 20 | ```{:.codefence-me} 21 | print "hello" 22 | ``` 23 | 24 | hello {.not-title} 25 | ----- 26 | 27 | hello {:.title} 28 | ----- 29 | 30 | Name | Age {.not-table} 31 | --------|------ 32 | Fred | 29 33 | Jim | 47 34 | Harry | 32 35 | 36 | 37 | Name | Age {:.table} 38 | --------|------ 39 | Fred | 29 40 | Jim | 47 41 | Harry | 32 42 | 43 | foo | bar {.not-table} 44 | : baz : bat 45 | --- | --- 46 | foo | bar 47 | : baz : bat 48 | 49 | foo | bar {:.table} 50 | : baz : bat 51 | --- | --- 52 | foo | bar 53 | : baz : bat 54 | -------------------------------------------------------------------------------- /test/Tests/extras/Special_Attribute_CodeBlock.html: -------------------------------------------------------------------------------- 1 |

This is a space-indented code block.

2 | 3 |
{
 4 |   /** JavaDoc with a {@link #somewhere}
 5 |    */
 6 | }
 7 | 
8 | 9 |

The link is not an extended attribute!

10 | 11 |
{
12 |   /** Code with attribute
13 |    */
14 | }
15 | 
16 | 17 |

The above is an extended attribute, at least for now. 18 | See #62 for a discussion about 19 | whether this kind of syntax should be supported.

20 | -------------------------------------------------------------------------------- /test/Tests/extras/Special_Attribute_CodeBlock.text: -------------------------------------------------------------------------------- 1 | This is a space-indented code block. 2 | 3 | { 4 | /** JavaDoc with a {@link #somewhere} 5 | */ 6 | } 7 | 8 | The link is *not* an extended attribute! 9 | 10 | { 11 | /** Code with attribute 12 | */ 13 | } {@ .codesample } 14 | 15 | The above *is* an extended attribute, at least for now. 16 | See [#62](https://github.com/kjdev/hoextdown/issues/62) for a discussion about 17 | whether this kind of syntax should be supported. 18 | -------------------------------------------------------------------------------- /test/Tests/extras/Special_Attribute_Codespan.html: -------------------------------------------------------------------------------- 1 |

Test that space {.breaks}

2 | 3 |

Test that nospace

4 | -------------------------------------------------------------------------------- /test/Tests/extras/Special_Attribute_Codespan.text: -------------------------------------------------------------------------------- 1 | Test that `space` {.breaks} 2 | 3 | Test that `nospace`{.does-not-break} 4 | -------------------------------------------------------------------------------- /test/Tests/extras/Special_Attribute_Escaped.html: -------------------------------------------------------------------------------- 1 |

Test case

2 | 3 |
    4 |
  • It does not repro in the first bullet in a list.

  • 5 |
  • This is a {@link com.example.Class link} 6 | that does not work. The link must be at the end of a line.

  • 7 |
8 | 9 |

This is a {@link com.example.Class link} that does work.

10 | 11 |

Another link at the end of the line works: {@link com.example.Class link}

12 | -------------------------------------------------------------------------------- /test/Tests/extras/Special_Attribute_Escaped.text: -------------------------------------------------------------------------------- 1 | # Test case 2 | 3 | * It does not repro in the first bullet in a list. 4 | 5 | * This is a \{@link com.example.Class link\} 6 | that does not work. The link must be at the end of a line. 7 | 8 | This is a \{@link com.example.Class link\} that does work. 9 | 10 | Another link at the end of the line works: \{@link com.example.Class link\} 11 | -------------------------------------------------------------------------------- /test/Tests/extras/Special_Attribute_FencedCode.html: -------------------------------------------------------------------------------- 1 |
code test
 2 | 
3 | 4 |
code test
 5 | 
6 | 7 |
code test
 8 | 
9 | 10 |
code test
11 | 
12 | 13 |
code test
14 | 
15 | 16 |
code test
17 | 
18 | 19 |
code test
20 | 
21 | 22 |
code test
23 | 
24 | -------------------------------------------------------------------------------- /test/Tests/extras/Special_Attribute_FencedCode.text: -------------------------------------------------------------------------------- 1 | 2 | ``` 3 | code test 4 | ``` 5 | 6 | ``` sh 7 | code test 8 | ``` 9 | 10 | ``` a b 11 | code test 12 | ``` 13 | 14 | ``` {.class-1} 15 | code test 16 | ``` 17 | 18 | ``` c {.class-2 #id-2} 19 | code test 20 | ``` 21 | 22 | ``` d{#id-3 .class-3 .class-4} 23 | code test 24 | ``` 25 | 26 | ``` {#id-5 .class-5} 27 | code test 28 | ``` 29 | 30 | 31 | ``` a b {#id-6 .class-6} 32 | code test 33 | ``` 34 | -------------------------------------------------------------------------------- /test/Tests/extras/Special_Attribute_Headers.html: -------------------------------------------------------------------------------- 1 |

Header

2 | 3 |

Header 2

4 | 5 |

Header 3

6 | 7 |

header

8 | 9 |

header 2

10 | -------------------------------------------------------------------------------- /test/Tests/extras/Special_Attribute_Headers.text: -------------------------------------------------------------------------------- 1 | # Header {.h1} 2 | 3 | ## Header 2 {#h2} 4 | 5 | ### Header 3 {.h3 #h3} 6 | 7 | header {.header #H2 .H1} 8 | ======================== 9 | 10 | header 2 {.header .H2 #H2} 11 | -------- 12 | -------------------------------------------------------------------------------- /test/Tests/extras/Special_Attribute_Links.html: -------------------------------------------------------------------------------- 1 |

This is an example inline link.

2 | 3 |

This link has no title attribute.

4 | 5 |

See my About page for details.

6 | 7 |

This is the simple case

8 | 9 |

This is the [simple case with space] {.example}

10 | 11 |

This is the simple case

12 | 13 |

This is the simple case

14 | 15 |

This is the simple case

16 | 17 |

link

18 | 19 |

link

20 | 21 |

link

22 | -------------------------------------------------------------------------------- /test/Tests/extras/Special_Attribute_Links.text: -------------------------------------------------------------------------------- 1 | This is [an example](http://example.com/ "Title"){.example} inline link. 2 | 3 | [This link](http://example.net/){#link} has no title attribute. 4 | 5 | See my [About](/about/){#about .about} page for details. 6 | 7 | This is the [simple case]{.example} 8 | 9 | This is the [simple case with space] {.example} 10 | 11 | This is the [simple case]{#link} 12 | 13 | This is the [simple case]{#about .abount} 14 | 15 | This is the [simple case]{target="_blank"} 16 | 17 | [simple case]: /simple 18 | 19 | [link] 20 | 21 | [link]{ .class-link } 22 | 23 | [link]{ target="_blank" } 24 | 25 | [link]: url "optional title" { #id .class } 26 | -------------------------------------------------------------------------------- /test/Tests/extras/Special_Attribute_Lists.html: -------------------------------------------------------------------------------- 1 |
    2 |
  • Red
  • 3 |
  • Green
  • 4 |
  • Blue
  • 5 |
6 | 7 |
    8 |
  1. Bird
  2. 9 |
  3. McHale
  4. 10 |
  5. Parish
  6. 11 |
12 | 13 |
    14 |
  • Red 15 | 16 |
      17 |
    • Green 18 | 19 |
        20 |
      • Blue
      • 21 |
    • 22 |
  • 23 |
24 | 25 |
26 | 27 |
    28 |
  • Red
  • 29 |
  • Green
  • 30 |
  • Blue
  • 31 |
32 | 33 |
    34 |
  1. Bird
  2. 35 |
  3. McHale
  4. 36 |
  5. Parish
  6. 37 |
38 | 39 |
    40 |
  • Red 41 | 42 |
      43 |
    • Green 44 | 45 |
        46 |
      • Blue
      • 47 |
    • 48 |
  • 49 |
50 | 51 |
    52 |
  1. Alpha
  2. 53 |
  3. Beta
  4. 54 |
  5. Gamma {@random #not-real}
  6. 55 |
56 | 57 |
58 | 59 |
    60 |
  1. Blah:

    61 | 62 |
    $ ls test/{foo,bar}
     63 | 
  2. 64 |
65 | 66 |
67 | 68 |
    69 |
  • item

    70 | 71 |
      72 |
    • item

      73 | 74 |

      blah blah

    • 75 |
  • 76 |
  • item

  • 77 |
78 | 79 |
80 | 81 |
    82 |
  • foo 83 | bar

  • 84 |
  • foo 85 | bar

  • 86 |
87 | 88 |
89 | 90 |
    91 |
  • foo

    92 | 93 |

    bar

  • 94 |
95 | 96 |
97 | 98 |
    99 |
  • foo

    100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 |
    foobar
    foobar
  • 116 |
117 | 118 |
119 | 120 |
    121 |
  • foo

    122 | 123 |

    bar

  • 124 |
125 | -------------------------------------------------------------------------------- /test/Tests/extras/Special_Attribute_Lists.text: -------------------------------------------------------------------------------- 1 | * Red {.red} 2 | * Green {.green} 3 | * Blue {.blue} 4 | 5 | 1. Bird {#bird .list .1} 6 | 2. McHale {#mchale .list .2} 7 | 3. Parish {#parish .list .3} 8 | 9 | * Red {#1 .red} 10 | * Green {#2 .green} 11 | * Blue {#3 .blue} 12 | 13 | --- 14 | 15 | * Red {.red} 16 | * Green {.green} 17 | * Blue {.blue} 18 | {@list .class-list .ul} 19 | 20 | 1. Bird {#bird .list .1} 21 | 2. McHale {#mchale .list .2} 22 | 3. Parish {#parish .list .3} 23 | {@list .class-list .ol} 24 | 25 | * Red {#1 .red} 26 | {@list .class-list .level-1} 27 | * Green {#2 .green} 28 | {@list .class-list .level-2} 29 | * Blue {#3 .blue} 30 | {@list .class-list .level-3} 31 | 32 | 1. Alpha 33 | 2. Beta 34 | 3. Gamma {@random #not-real} 35 | 36 | --- 37 | 38 | 1. Blah: 39 | 40 | $ ls test/{foo,bar} 41 | 42 | --- 43 | 44 | * item {.foo} 45 | 46 | * item {#bar} 47 | 48 | blah blah 49 | 50 | * item {baz="goo"} 51 | 52 | --- 53 | 54 | * foo 55 | bar 56 | 57 | * foo 58 | bar 59 | 60 | --- 61 | 62 | * foo 63 | 64 | bar 65 | 66 | --- 67 | 68 | * foo 69 | 70 | foo | bar 71 | --- | --- 72 | foo | bar 73 | 74 | --- 75 | 76 | * foo {.attr} 77 | 78 | bar 79 | -------------------------------------------------------------------------------- /test/Tests/extras/Special_Attribute_Multiline_Table.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
foo bazbar bat
foo bazbar bat
15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |
foo bazbar bat
foo bazbar bat
30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
foo bazbar bat
foo bazbar bat
45 | -------------------------------------------------------------------------------- /test/Tests/extras/Special_Attribute_Multiline_Table.text: -------------------------------------------------------------------------------- 1 | foo | bar {#table1} 2 | : baz : bat 3 | --- | --- 4 | foo | bar 5 | : baz : bat 6 | 7 | | foo | bar {#table2} 8 | : baz : bat 9 | | --- | --- 10 | | foo | bar 11 | : baz : bat 12 | 13 | | foo | bar | {#table3} 14 | : baz : bat : 15 | | --- | --- | 16 | | foo | bar | 17 | : baz : bat : 18 | -------------------------------------------------------------------------------- /test/Tests/extras/Special_Attribute_Paragraphs.html: -------------------------------------------------------------------------------- 1 |

Paragraph

2 | 3 |

Paragraph

4 | 5 |

Paragraph

6 | 7 |

Preserve {@paragraph #id .class} this

8 | 9 |

Ignore this {@paragraph #id .class} but not this

10 | 11 |

This is not processed {@paragraph #id}

12 | 13 |

This is not processed {#id}

14 | 15 |

This is not processed {@random #id}

16 | 17 |
    18 |
  • 19 |

    Testing paragraphs

    20 |

    In loose lists

    21 |

    This does not activate {@random .nop}

    22 |
  • 23 |
24 | -------------------------------------------------------------------------------- /test/Tests/extras/Special_Attribute_Paragraphs.text: -------------------------------------------------------------------------------- 1 | Paragraph {@paragraph #id .class} 2 | 3 | Paragraph {@paragraph #id .class } 4 | 5 | Paragraph 6 | {@paragraph #id .class} 7 | 8 | Preserve {@paragraph #id .class} this 9 | 10 | Ignore this {@paragraph #id .class} but not this {@paragraph #id-2} 11 | 12 | This is not processed \{@paragraph #id\} 13 | 14 | This is not processed {#id} 15 | 16 | This is not processed {@random #id} 17 | 18 | * Testing paragraphs 19 | 20 | In loose lists {@paragraph .p} 21 | 22 | This does not activate {@random .nop} 23 | -------------------------------------------------------------------------------- /test/Tests/extras/Special_Attribute_Tables.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
NameAge
Fred29
Jim47
Harry32
20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
NameAge
Fred29
Jim47
Harry32
40 | -------------------------------------------------------------------------------- /test/Tests/extras/Special_Attribute_Tables.text: -------------------------------------------------------------------------------- 1 | Name | Age {.table1} 2 | --------|------ 3 | Fred | 29 4 | Jim | 47 5 | Harry | 32 6 | 7 | | Name | Age | {.table2 #tbl2} 8 | |---------|-----:| 9 | | Fred | 29 | 10 | | Jim | 47 | 11 | | Harry | 32 | 12 | -------------------------------------------------------------------------------- /test/Tests/extras/Table_Escape_Pipe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
|\|\\|
|\|\\|
18 | 19 |

In codespan:

20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
|\|\\|
|\|\\|
38 | -------------------------------------------------------------------------------- /test/Tests/extras/Table_Escape_Pipe.text: -------------------------------------------------------------------------------- 1 | \| | \\\| | \\\\\| 2 | --- | ---- | ------ 3 | \| | \\\| | \\\\\| 4 | 5 | In codespan: 6 | 7 | `\|` | `\\|` | `\\\|` 8 | ----- | ----- | ------ 9 | `\|` | `\\|` | `\\\|` 10 | -------------------------------------------------------------------------------- /test/Tests/extras/Tasks.html: -------------------------------------------------------------------------------- 1 |
    2 |
  • Red
  • 3 |
  • Green
  • 4 |
  • Blue
  • 5 |
6 | 7 |
    8 |
  1. Bird
  2. 9 |
  3. McHale
  4. 10 |
  5. Parish
  6. 11 |
12 | 13 |
    14 |
  • Red 15 |
      16 |
    • Green 17 |
        18 |
      • Blue
      • 19 |
    • 20 |
  • 21 |
22 | 23 |
    24 |
  1. A loose list

    25 | 26 |

    ... can also ...

  2. 27 |
  3. contain tasks

  4. 28 |
  5. ... mixed with other items ...

  6. 29 |
30 | 31 |
32 |
Definition lists
33 |
[ ] cannot contain tasks (this renders as [ ]).
34 |
35 | -------------------------------------------------------------------------------- /test/Tests/extras/Tasks.text: -------------------------------------------------------------------------------- 1 | 2 | * [ ] Red 3 | * [x] Green 4 | * [ ] Blue 5 | 6 | 1. [ ] Bird {#bird .list .1} 7 | 2. [ ] McHale {#mchale .list .2} 8 | 3. [x] Parish {#parish .list .3} 9 | 10 | * [ ] Red {#1 .red} 11 | * [x] Green {#2 .green} 12 | * [ ] Blue {#3 .blue} 13 | 14 | 1. [ ] A loose list 15 | 16 | ... can also ... 17 | 18 | 2. [x] contain tasks 19 | 3. ... mixed with other items ... 20 | 21 | Definition lists 22 | : [ ] cannot contain tasks (this renders as `[ ]`). 23 | -------------------------------------------------------------------------------- /test/Tests/extras/Toc.html: -------------------------------------------------------------------------------- 1 |

a

2 | 3 |

B

4 | 5 |

c

6 | 7 |

8 | 9 |

10 | 11 |

12 | 13 |

a

14 | 15 |

b

16 | 17 |

c

18 | 19 |

A

20 | 21 |

B

22 | 23 |

C

24 | 25 |

test code

26 | -------------------------------------------------------------------------------- /test/Tests/extras/Toc.text: -------------------------------------------------------------------------------- 1 | # a 2 | 3 | ## B 4 | 5 | ### c 6 | 7 | # あ 8 | 9 | ## い 10 | 11 | ### う {#id .class} 12 | 13 | [a](#a) 14 | 15 | [b](#b) 16 | 17 | [c](#c) 18 | 19 | [A](#あ) 20 | 21 | [B](#い) 22 | 23 | [C](#id) 24 | 25 | # test `code` 26 | -------------------------------------------------------------------------------- /test/Tests/extras/Toc_Header_Empty.html: -------------------------------------------------------------------------------- 1 |
2 | 10 |
11 | -------------------------------------------------------------------------------- /test/Tests/extras/Toc_Header_Empty.text: -------------------------------------------------------------------------------- 1 | 2 | == 3 | 4 | # 5 | 6 | #{#id} 7 | 8 | 9 | == 10 | 11 | # 12 | 13 | # {#id} 14 | -------------------------------------------------------------------------------- /test/Tests/extras/Toc_Header_Empty_Attribute.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | -------------------------------------------------------------------------------- /test/Tests/extras/Toc_Header_Empty_Attribute.text: -------------------------------------------------------------------------------- 1 | 2 | == 3 | 4 | # 5 | 6 | #{#id} 7 | 8 | 9 | == 10 | 11 | # 12 | 13 | # {#id} 14 | -------------------------------------------------------------------------------- /test/Tests/extras/Toc_Render.html: -------------------------------------------------------------------------------- 1 |
2 |
    3 |
  • 4 | a 5 |
      6 |
    • 7 | B 8 |
        9 |
      • 10 | c 11 |
      • 12 |
      13 |
    • 14 |
    15 |
  • 16 |
  • 17 | 18 |
      19 |
    • 20 | 21 |
        22 |
      • 23 | 24 |
      • 25 |
      26 |
    • 27 |
    28 |
  • 29 |
  • 30 | test code 31 |
  • 32 |
33 |
34 | -------------------------------------------------------------------------------- /test/Tests/extras/Toc_Render.text: -------------------------------------------------------------------------------- 1 | # a 2 | 3 | ## B 4 | 5 | ### c 6 | 7 | # あ 8 | 9 | ## い 10 | 11 | ### う {#id .class} 12 | 13 | [a](#toc_a) 14 | 15 | [b](#toc_b) 16 | 17 | [c](#toc_c) 18 | 19 | [A](#toc_あ) 20 | 21 | [B](#toc_い) 22 | 23 | [C](#id) 24 | 25 | # test `code` 26 | -------------------------------------------------------------------------------- /test/Tests/extras/issues_46.html: -------------------------------------------------------------------------------- 1 |
In first pre
2 |  
3 | 4 |

foo

5 | 6 |
In second pre
7 | -------------------------------------------------------------------------------- /test/Tests/extras/issues_46.text: -------------------------------------------------------------------------------- 1 |
In first pre
2 |  
3 | 4 | *foo* 5 | 6 |
In second pre
7 | -------------------------------------------------------------------------------- /test/Tests/extras/issues_47.html: -------------------------------------------------------------------------------- 1 |

Link should go to example.com but goes to Wikipedia: foo

2 | 3 |

Link should go to example2.com: bar

4 | 5 | 8 | 9 |

<!-- this shouldn't break references

10 | -------------------------------------------------------------------------------- /test/Tests/extras/issues_47.text: -------------------------------------------------------------------------------- 1 | Link should go to example.com but goes to Wikipedia: [foo] 2 | 3 | Link should go to example2.com: [bar] 4 | 5 | [foo]: http://example.com/foo 6 | 7 | 10 | 11 |