gitdown 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/AUTHORS +1 -0
- data/COPYING +24 -0
- data/GPL +674 -0
- data/README +43 -0
- data/Rakefile +370 -0
- data/VERSION +1 -0
- data/benchmark/benchmark.rb +34 -0
- data/benchmark/benchmark.sh +74 -0
- data/benchmark/generate_data.rb +119 -0
- data/benchmark/mdbasics.text +306 -0
- data/benchmark/mdsyntax.text +888 -0
- data/benchmark/testing.sh +9 -0
- data/benchmark/timing.sh +10 -0
- data/bin/kramdown +78 -0
- data/data/kramdown/document.html +18 -0
- data/data/kramdown/document.latex +43 -0
- data/doc/default.scss.css +530 -0
- data/doc/default.template +80 -0
- data/doc/documentation.page +71 -0
- data/doc/index.page +98 -0
- data/doc/installation.page +88 -0
- data/doc/links.markdown +6 -0
- data/doc/news.feed +10 -0
- data/doc/news.page +28 -0
- data/doc/quickref.page +585 -0
- data/doc/syntax.page +1644 -0
- data/doc/tests.page +52 -0
- data/doc/virtual +2 -0
- data/lib/kramdown.rb +23 -0
- data/lib/kramdown/compatibility.rb +35 -0
- data/lib/kramdown/converter.rb +41 -0
- data/lib/kramdown/converter/base.rb +169 -0
- data/lib/kramdown/converter/html.rb +410 -0
- data/lib/kramdown/converter/kramdown.rb +422 -0
- data/lib/kramdown/converter/latex.rb +607 -0
- data/lib/kramdown/converter/toc.rb +82 -0
- data/lib/kramdown/document.rb +117 -0
- data/lib/kramdown/element.rb +524 -0
- data/lib/kramdown/error.rb +30 -0
- data/lib/kramdown/options.rb +373 -0
- data/lib/kramdown/parser.rb +40 -0
- data/lib/kramdown/parser/base.rb +136 -0
- data/lib/kramdown/parser/github_markdown.rb +44 -0
- data/lib/kramdown/parser/github_markdown/github_codeblock.rb +44 -0
- data/lib/kramdown/parser/html.rb +570 -0
- data/lib/kramdown/parser/kramdown.rb +338 -0
- data/lib/kramdown/parser/kramdown/abbreviation.rb +71 -0
- data/lib/kramdown/parser/kramdown/autolink.rb +53 -0
- data/lib/kramdown/parser/kramdown/blank_line.rb +43 -0
- data/lib/kramdown/parser/kramdown/block_boundary.rb +46 -0
- data/lib/kramdown/parser/kramdown/blockquote.rb +51 -0
- data/lib/kramdown/parser/kramdown/codeblock.rb +63 -0
- data/lib/kramdown/parser/kramdown/codespan.rb +56 -0
- data/lib/kramdown/parser/kramdown/emphasis.rb +70 -0
- data/lib/kramdown/parser/kramdown/eob.rb +39 -0
- data/lib/kramdown/parser/kramdown/escaped_chars.rb +38 -0
- data/lib/kramdown/parser/kramdown/extensions.rb +204 -0
- data/lib/kramdown/parser/kramdown/footnote.rb +74 -0
- data/lib/kramdown/parser/kramdown/header.rb +68 -0
- data/lib/kramdown/parser/kramdown/horizontal_rule.rb +39 -0
- data/lib/kramdown/parser/kramdown/html.rb +169 -0
- data/lib/kramdown/parser/kramdown/html_entity.rb +44 -0
- data/lib/kramdown/parser/kramdown/line_break.rb +38 -0
- data/lib/kramdown/parser/kramdown/link.rb +148 -0
- data/lib/kramdown/parser/kramdown/list.rb +240 -0
- data/lib/kramdown/parser/kramdown/math.rb +64 -0
- data/lib/kramdown/parser/kramdown/paragraph.rb +63 -0
- data/lib/kramdown/parser/kramdown/smart_quotes.rb +214 -0
- data/lib/kramdown/parser/kramdown/table.rb +178 -0
- data/lib/kramdown/parser/kramdown/typographic_symbol.rb +52 -0
- data/lib/kramdown/parser/markdown.rb +69 -0
- data/lib/kramdown/utils.rb +37 -0
- data/lib/kramdown/utils/entities.rb +348 -0
- data/lib/kramdown/utils/html.rb +85 -0
- data/lib/kramdown/utils/ordered_hash.rb +100 -0
- data/lib/kramdown/version.rb +28 -0
- data/setup.rb +1585 -0
- data/test/run_tests.rb +59 -0
- data/test/test_files.rb +197 -0
- data/test/testcases/block/01_blank_line/spaces.html +1 -0
- data/test/testcases/block/01_blank_line/spaces.text +3 -0
- data/test/testcases/block/01_blank_line/tabs.html +1 -0
- data/test/testcases/block/01_blank_line/tabs.text +6 -0
- data/test/testcases/block/02_eob/beginning.html +1 -0
- data/test/testcases/block/02_eob/beginning.text +3 -0
- data/test/testcases/block/02_eob/end.html +1 -0
- data/test/testcases/block/02_eob/end.text +3 -0
- data/test/testcases/block/02_eob/middle.html +1 -0
- data/test/testcases/block/02_eob/middle.text +5 -0
- data/test/testcases/block/03_paragraph/indented.html +18 -0
- data/test/testcases/block/03_paragraph/indented.text +19 -0
- data/test/testcases/block/03_paragraph/no_newline_at_end.html +5 -0
- data/test/testcases/block/03_paragraph/no_newline_at_end.text +5 -0
- data/test/testcases/block/03_paragraph/one_para.html +1 -0
- data/test/testcases/block/03_paragraph/one_para.text +1 -0
- data/test/testcases/block/03_paragraph/two_para.html +4 -0
- data/test/testcases/block/03_paragraph/two_para.text +4 -0
- data/test/testcases/block/04_header/atx_header.html +37 -0
- data/test/testcases/block/04_header/atx_header.text +34 -0
- data/test/testcases/block/04_header/atx_header_no_newline_at_end.html +1 -0
- data/test/testcases/block/04_header/atx_header_no_newline_at_end.text +1 -0
- data/test/testcases/block/04_header/setext_header.html +30 -0
- data/test/testcases/block/04_header/setext_header.html.19 +30 -0
- data/test/testcases/block/04_header/setext_header.text +36 -0
- data/test/testcases/block/04_header/setext_header_no_newline_at_end.html +1 -0
- data/test/testcases/block/04_header/setext_header_no_newline_at_end.text +2 -0
- data/test/testcases/block/04_header/with_auto_id_prefix.html +3 -0
- data/test/testcases/block/04_header/with_auto_id_prefix.options +2 -0
- data/test/testcases/block/04_header/with_auto_id_prefix.text +3 -0
- data/test/testcases/block/04_header/with_auto_ids.html +17 -0
- data/test/testcases/block/04_header/with_auto_ids.options +1 -0
- data/test/testcases/block/04_header/with_auto_ids.text +19 -0
- data/test/testcases/block/05_blockquote/indented.html +25 -0
- data/test/testcases/block/05_blockquote/indented.text +14 -0
- data/test/testcases/block/05_blockquote/lazy.html +34 -0
- data/test/testcases/block/05_blockquote/lazy.text +20 -0
- data/test/testcases/block/05_blockquote/nested.html +10 -0
- data/test/testcases/block/05_blockquote/nested.text +6 -0
- data/test/testcases/block/05_blockquote/no_newline_at_end.html +4 -0
- data/test/testcases/block/05_blockquote/no_newline_at_end.text +2 -0
- data/test/testcases/block/05_blockquote/very_long_line.html +3 -0
- data/test/testcases/block/05_blockquote/very_long_line.text +1 -0
- data/test/testcases/block/05_blockquote/with_code_blocks.html +15 -0
- data/test/testcases/block/05_blockquote/with_code_blocks.text +11 -0
- data/test/testcases/block/06_codeblock/error.html +4 -0
- data/test/testcases/block/06_codeblock/error.text +4 -0
- data/test/testcases/block/06_codeblock/lazy.html +4 -0
- data/test/testcases/block/06_codeblock/lazy.text +5 -0
- data/test/testcases/block/06_codeblock/no_newline_at_end.html +2 -0
- data/test/testcases/block/06_codeblock/no_newline_at_end.text +1 -0
- data/test/testcases/block/06_codeblock/no_newline_at_end_1.html +2 -0
- data/test/testcases/block/06_codeblock/no_newline_at_end_1.text +2 -0
- data/test/testcases/block/06_codeblock/normal.html +13 -0
- data/test/testcases/block/06_codeblock/normal.text +10 -0
- data/test/testcases/block/06_codeblock/tilde_syntax.html +7 -0
- data/test/testcases/block/06_codeblock/tilde_syntax.text +9 -0
- data/test/testcases/block/06_codeblock/whitespace.html +3 -0
- data/test/testcases/block/06_codeblock/whitespace.text +3 -0
- data/test/testcases/block/06_codeblock/with_blank_line.html +13 -0
- data/test/testcases/block/06_codeblock/with_blank_line.text +12 -0
- data/test/testcases/block/06_codeblock/with_eob_marker.html +6 -0
- data/test/testcases/block/06_codeblock/with_eob_marker.text +5 -0
- data/test/testcases/block/06_codeblock/with_ial.html +6 -0
- data/test/testcases/block/06_codeblock/with_ial.text +5 -0
- data/test/testcases/block/07_horizontal_rule/error.html +7 -0
- data/test/testcases/block/07_horizontal_rule/error.html.19 +7 -0
- data/test/testcases/block/07_horizontal_rule/error.text +7 -0
- data/test/testcases/block/07_horizontal_rule/normal.html +17 -0
- data/test/testcases/block/07_horizontal_rule/normal.text +17 -0
- data/test/testcases/block/07_horizontal_rule/sepspaces.html +3 -0
- data/test/testcases/block/07_horizontal_rule/sepspaces.text +3 -0
- data/test/testcases/block/07_horizontal_rule/septabs.html +3 -0
- data/test/testcases/block/07_horizontal_rule/septabs.text +3 -0
- data/test/testcases/block/08_list/escaping.html +17 -0
- data/test/testcases/block/08_list/escaping.text +17 -0
- data/test/testcases/block/08_list/item_ial.html +10 -0
- data/test/testcases/block/08_list/item_ial.text +8 -0
- data/test/testcases/block/08_list/lazy.html +39 -0
- data/test/testcases/block/08_list/lazy.text +29 -0
- data/test/testcases/block/08_list/list_and_hr.html +9 -0
- data/test/testcases/block/08_list/list_and_hr.text +5 -0
- data/test/testcases/block/08_list/list_and_others.html +40 -0
- data/test/testcases/block/08_list/list_and_others.text +26 -0
- data/test/testcases/block/08_list/mixed.html +117 -0
- data/test/testcases/block/08_list/mixed.text +66 -0
- data/test/testcases/block/08_list/nested.html +17 -0
- data/test/testcases/block/08_list/nested.text +7 -0
- data/test/testcases/block/08_list/other_first_element.html +39 -0
- data/test/testcases/block/08_list/other_first_element.text +18 -0
- data/test/testcases/block/08_list/simple_ol.html +19 -0
- data/test/testcases/block/08_list/simple_ol.text +13 -0
- data/test/testcases/block/08_list/simple_ul.html +48 -0
- data/test/testcases/block/08_list/simple_ul.text +36 -0
- data/test/testcases/block/08_list/single_item.html +3 -0
- data/test/testcases/block/08_list/single_item.text +1 -0
- data/test/testcases/block/08_list/special_cases.html +55 -0
- data/test/testcases/block/08_list/special_cases.text +35 -0
- data/test/testcases/block/09_html/comment.html +18 -0
- data/test/testcases/block/09_html/comment.text +15 -0
- data/test/testcases/block/09_html/content_model/deflists.html +6 -0
- data/test/testcases/block/09_html/content_model/deflists.options +1 -0
- data/test/testcases/block/09_html/content_model/deflists.text +6 -0
- data/test/testcases/block/09_html/content_model/tables.html +14 -0
- data/test/testcases/block/09_html/content_model/tables.options +1 -0
- data/test/testcases/block/09_html/content_model/tables.text +14 -0
- data/test/testcases/block/09_html/html_and_codeblocks.html +15 -0
- data/test/testcases/block/09_html/html_and_codeblocks.options +1 -0
- data/test/testcases/block/09_html/html_and_codeblocks.text +13 -0
- data/test/testcases/block/09_html/html_and_headers.html +5 -0
- data/test/testcases/block/09_html/html_and_headers.text +6 -0
- data/test/testcases/block/09_html/html_to_native/code.html +10 -0
- data/test/testcases/block/09_html/html_to_native/code.text +9 -0
- data/test/testcases/block/09_html/html_to_native/comment.html +7 -0
- data/test/testcases/block/09_html/html_to_native/comment.text +8 -0
- data/test/testcases/block/09_html/html_to_native/emphasis.html +6 -0
- data/test/testcases/block/09_html/html_to_native/emphasis.text +6 -0
- data/test/testcases/block/09_html/html_to_native/entity.html +1 -0
- data/test/testcases/block/09_html/html_to_native/entity.text +1 -0
- data/test/testcases/block/09_html/html_to_native/header.html +6 -0
- data/test/testcases/block/09_html/html_to_native/header.options +2 -0
- data/test/testcases/block/09_html/html_to_native/header.text +6 -0
- data/test/testcases/block/09_html/html_to_native/list_dl.html +8 -0
- data/test/testcases/block/09_html/html_to_native/list_dl.text +8 -0
- data/test/testcases/block/09_html/html_to_native/list_ol.html +15 -0
- data/test/testcases/block/09_html/html_to_native/list_ol.text +17 -0
- data/test/testcases/block/09_html/html_to_native/list_ul.html +19 -0
- data/test/testcases/block/09_html/html_to_native/list_ul.text +22 -0
- data/test/testcases/block/09_html/html_to_native/options +1 -0
- data/test/testcases/block/09_html/html_to_native/paragraph.html +3 -0
- data/test/testcases/block/09_html/html_to_native/paragraph.text +4 -0
- data/test/testcases/block/09_html/html_to_native/table_normal.html +12 -0
- data/test/testcases/block/09_html/html_to_native/table_normal.text +12 -0
- data/test/testcases/block/09_html/html_to_native/table_simple.html +48 -0
- data/test/testcases/block/09_html/html_to_native/table_simple.text +56 -0
- data/test/testcases/block/09_html/html_to_native/typography.html +1 -0
- data/test/testcases/block/09_html/html_to_native/typography.html.19 +1 -0
- data/test/testcases/block/09_html/html_to_native/typography.text +1 -0
- data/test/testcases/block/09_html/invalid_html_1.html +5 -0
- data/test/testcases/block/09_html/invalid_html_1.text +5 -0
- data/test/testcases/block/09_html/invalid_html_2.html +5 -0
- data/test/testcases/block/09_html/invalid_html_2.text +5 -0
- data/test/testcases/block/09_html/markdown_attr.html +38 -0
- data/test/testcases/block/09_html/markdown_attr.text +38 -0
- data/test/testcases/block/09_html/not_parsed.html +24 -0
- data/test/testcases/block/09_html/not_parsed.text +24 -0
- data/test/testcases/block/09_html/parse_as_raw.html +35 -0
- data/test/testcases/block/09_html/parse_as_raw.htmlinput +34 -0
- data/test/testcases/block/09_html/parse_as_raw.options +1 -0
- data/test/testcases/block/09_html/parse_as_raw.text +33 -0
- data/test/testcases/block/09_html/parse_as_span.html +12 -0
- data/test/testcases/block/09_html/parse_as_span.htmlinput +12 -0
- data/test/testcases/block/09_html/parse_as_span.options +1 -0
- data/test/testcases/block/09_html/parse_as_span.text +9 -0
- data/test/testcases/block/09_html/parse_block_html.html +21 -0
- data/test/testcases/block/09_html/parse_block_html.options +1 -0
- data/test/testcases/block/09_html/parse_block_html.text +17 -0
- data/test/testcases/block/09_html/processing_instruction.html +13 -0
- data/test/testcases/block/09_html/processing_instruction.text +12 -0
- data/test/testcases/block/09_html/simple.html +64 -0
- data/test/testcases/block/09_html/simple.html.19 +64 -0
- data/test/testcases/block/09_html/simple.options +1 -0
- data/test/testcases/block/09_html/simple.text +59 -0
- data/test/testcases/block/10_ald/simple.html +2 -0
- data/test/testcases/block/10_ald/simple.text +8 -0
- data/test/testcases/block/11_ial/auto_id_and_ial.html +1 -0
- data/test/testcases/block/11_ial/auto_id_and_ial.options +1 -0
- data/test/testcases/block/11_ial/auto_id_and_ial.text +2 -0
- data/test/testcases/block/11_ial/nested.html +11 -0
- data/test/testcases/block/11_ial/nested.text +15 -0
- data/test/testcases/block/11_ial/simple.html +25 -0
- data/test/testcases/block/11_ial/simple.text +34 -0
- data/test/testcases/block/12_extension/comment.html +8 -0
- data/test/testcases/block/12_extension/comment.text +12 -0
- data/test/testcases/block/12_extension/ignored.html +8 -0
- data/test/testcases/block/12_extension/ignored.text +8 -0
- data/test/testcases/block/12_extension/nomarkdown.html +10 -0
- data/test/testcases/block/12_extension/nomarkdown.kramdown +20 -0
- data/test/testcases/block/12_extension/nomarkdown.latex +13 -0
- data/test/testcases/block/12_extension/nomarkdown.text +21 -0
- data/test/testcases/block/12_extension/options.html +21 -0
- data/test/testcases/block/12_extension/options.text +21 -0
- data/test/testcases/block/12_extension/options2.html +10 -0
- data/test/testcases/block/12_extension/options2.text +5 -0
- data/test/testcases/block/12_extension/options3.html +7 -0
- data/test/testcases/block/12_extension/options3.text +7 -0
- data/test/testcases/block/13_definition_list/definition_at_beginning.html +1 -0
- data/test/testcases/block/13_definition_list/definition_at_beginning.text +1 -0
- data/test/testcases/block/13_definition_list/item_ial.html +12 -0
- data/test/testcases/block/13_definition_list/item_ial.text +8 -0
- data/test/testcases/block/13_definition_list/multiple_terms.html +13 -0
- data/test/testcases/block/13_definition_list/multiple_terms.text +10 -0
- data/test/testcases/block/13_definition_list/no_def_list.html +2 -0
- data/test/testcases/block/13_definition_list/no_def_list.text +2 -0
- data/test/testcases/block/13_definition_list/para_wrapping.html +10 -0
- data/test/testcases/block/13_definition_list/para_wrapping.text +6 -0
- data/test/testcases/block/13_definition_list/separated_by_eob.html +8 -0
- data/test/testcases/block/13_definition_list/separated_by_eob.text +5 -0
- data/test/testcases/block/13_definition_list/simple.html +8 -0
- data/test/testcases/block/13_definition_list/simple.text +7 -0
- data/test/testcases/block/13_definition_list/styled_terms.html +4 -0
- data/test/testcases/block/13_definition_list/styled_terms.text +2 -0
- data/test/testcases/block/13_definition_list/too_much_space.html +3 -0
- data/test/testcases/block/13_definition_list/too_much_space.text +4 -0
- data/test/testcases/block/13_definition_list/with_blocks.html +38 -0
- data/test/testcases/block/13_definition_list/with_blocks.text +24 -0
- data/test/testcases/block/14_table/errors.html +8 -0
- data/test/testcases/block/14_table/errors.text +9 -0
- data/test/testcases/block/14_table/escaping.html +52 -0
- data/test/testcases/block/14_table/escaping.text +19 -0
- data/test/testcases/block/14_table/footer.html +65 -0
- data/test/testcases/block/14_table/footer.text +25 -0
- data/test/testcases/block/14_table/header.html +96 -0
- data/test/testcases/block/14_table/header.text +32 -0
- data/test/testcases/block/14_table/no_table.html +3 -0
- data/test/testcases/block/14_table/no_table.text +3 -0
- data/test/testcases/block/14_table/simple.html +177 -0
- data/test/testcases/block/14_table/simple.html.19 +177 -0
- data/test/testcases/block/14_table/simple.text +49 -0
- data/test/testcases/block/14_table/table_with_footnote.html +25 -0
- data/test/testcases/block/14_table/table_with_footnote.latex +11 -0
- data/test/testcases/block/14_table/table_with_footnote.text +6 -0
- data/test/testcases/block/15_math/normal.html +26 -0
- data/test/testcases/block/15_math/normal.text +28 -0
- data/test/testcases/block/16_toc/no_toc.html +33 -0
- data/test/testcases/block/16_toc/no_toc.options +1 -0
- data/test/testcases/block/16_toc/no_toc.text +16 -0
- data/test/testcases/block/16_toc/toc_levels.html +24 -0
- data/test/testcases/block/16_toc/toc_levels.options +1 -0
- data/test/testcases/block/16_toc/toc_levels.text +16 -0
- data/test/testcases/block/17_github_codeblock/backtick_syntax.html +7 -0
- data/test/testcases/block/17_github_codeblock/backtick_syntax.text +9 -0
- data/test/testcases/block/17_github_codeblock/error.html +4 -0
- data/test/testcases/block/17_github_codeblock/error.text +4 -0
- data/test/testcases/block/17_github_codeblock/no_newline_at_end.html +2 -0
- data/test/testcases/block/17_github_codeblock/no_newline_at_end.text +3 -0
- data/test/testcases/encoding.html +46 -0
- data/test/testcases/encoding.text +28 -0
- data/test/testcases/span/01_link/empty.html +5 -0
- data/test/testcases/span/01_link/empty.text +5 -0
- data/test/testcases/span/01_link/image_in_a.html +5 -0
- data/test/testcases/span/01_link/image_in_a.text +5 -0
- data/test/testcases/span/01_link/imagelinks.html +14 -0
- data/test/testcases/span/01_link/imagelinks.text +16 -0
- data/test/testcases/span/01_link/inline.html +46 -0
- data/test/testcases/span/01_link/inline.html.19 +46 -0
- data/test/testcases/span/01_link/inline.text +48 -0
- data/test/testcases/span/01_link/link_defs.html +9 -0
- data/test/testcases/span/01_link/link_defs.text +26 -0
- data/test/testcases/span/01_link/links_with_angle_brackets.html +3 -0
- data/test/testcases/span/01_link/links_with_angle_brackets.text +3 -0
- data/test/testcases/span/01_link/reference.html +36 -0
- data/test/testcases/span/01_link/reference.html.19 +36 -0
- data/test/testcases/span/01_link/reference.text +50 -0
- data/test/testcases/span/02_emphasis/empty.html +3 -0
- data/test/testcases/span/02_emphasis/empty.text +3 -0
- data/test/testcases/span/02_emphasis/errors.html +9 -0
- data/test/testcases/span/02_emphasis/errors.text +9 -0
- data/test/testcases/span/02_emphasis/nesting.html +38 -0
- data/test/testcases/span/02_emphasis/nesting.text +33 -0
- data/test/testcases/span/02_emphasis/normal.html +46 -0
- data/test/testcases/span/02_emphasis/normal.text +46 -0
- data/test/testcases/span/03_codespan/empty.html +5 -0
- data/test/testcases/span/03_codespan/empty.text +5 -0
- data/test/testcases/span/03_codespan/errors.html +1 -0
- data/test/testcases/span/03_codespan/errors.text +1 -0
- data/test/testcases/span/03_codespan/highlighting.html +1 -0
- data/test/testcases/span/03_codespan/highlighting.text +1 -0
- data/test/testcases/span/03_codespan/normal.html +16 -0
- data/test/testcases/span/03_codespan/normal.text +16 -0
- data/test/testcases/span/04_footnote/definitions.html +17 -0
- data/test/testcases/span/04_footnote/definitions.latex +17 -0
- data/test/testcases/span/04_footnote/definitions.text +24 -0
- data/test/testcases/span/04_footnote/footnote_nr.html +12 -0
- data/test/testcases/span/04_footnote/footnote_nr.latex +2 -0
- data/test/testcases/span/04_footnote/footnote_nr.options +1 -0
- data/test/testcases/span/04_footnote/footnote_nr.text +4 -0
- data/test/testcases/span/04_footnote/markers.html +46 -0
- data/test/testcases/span/04_footnote/markers.latex +23 -0
- data/test/testcases/span/04_footnote/markers.text +26 -0
- data/test/testcases/span/05_html/across_lines.html +1 -0
- data/test/testcases/span/05_html/across_lines.text +2 -0
- data/test/testcases/span/05_html/invalid.html +1 -0
- data/test/testcases/span/05_html/invalid.text +1 -0
- data/test/testcases/span/05_html/link_with_mailto.html +1 -0
- data/test/testcases/span/05_html/link_with_mailto.text +1 -0
- data/test/testcases/span/05_html/markdown_attr.html +6 -0
- data/test/testcases/span/05_html/markdown_attr.text +6 -0
- data/test/testcases/span/05_html/normal.html +34 -0
- data/test/testcases/span/05_html/normal.text +34 -0
- data/test/testcases/span/abbreviations/abbrev.html +8 -0
- data/test/testcases/span/abbreviations/abbrev.text +15 -0
- data/test/testcases/span/abbreviations/abbrev_defs.html +2 -0
- data/test/testcases/span/abbreviations/abbrev_defs.text +5 -0
- data/test/testcases/span/autolinks/url_links.html +12 -0
- data/test/testcases/span/autolinks/url_links.text +12 -0
- data/test/testcases/span/escaped_chars/normal.html +47 -0
- data/test/testcases/span/escaped_chars/normal.text +47 -0
- data/test/testcases/span/extension/comment.html +6 -0
- data/test/testcases/span/extension/comment.text +6 -0
- data/test/testcases/span/extension/ignored.html +1 -0
- data/test/testcases/span/extension/ignored.text +1 -0
- data/test/testcases/span/extension/nomarkdown.html +1 -0
- data/test/testcases/span/extension/nomarkdown.text +1 -0
- data/test/testcases/span/extension/options.html +1 -0
- data/test/testcases/span/extension/options.text +1 -0
- data/test/testcases/span/ial/simple.html +6 -0
- data/test/testcases/span/ial/simple.text +6 -0
- data/test/testcases/span/line_breaks/normal.html +11 -0
- data/test/testcases/span/line_breaks/normal.latex +12 -0
- data/test/testcases/span/line_breaks/normal.text +11 -0
- data/test/testcases/span/math/normal.html +5 -0
- data/test/testcases/span/math/normal.text +5 -0
- data/test/testcases/span/text_substitutions/entities.html +6 -0
- data/test/testcases/span/text_substitutions/entities.options +1 -0
- data/test/testcases/span/text_substitutions/entities.text +6 -0
- data/test/testcases/span/text_substitutions/entities_as_char.html +1 -0
- data/test/testcases/span/text_substitutions/entities_as_char.html.19 +1 -0
- data/test/testcases/span/text_substitutions/entities_as_char.options +1 -0
- data/test/testcases/span/text_substitutions/entities_as_char.text +1 -0
- data/test/testcases/span/text_substitutions/entities_as_input.html +1 -0
- data/test/testcases/span/text_substitutions/entities_as_input.options +1 -0
- data/test/testcases/span/text_substitutions/entities_as_input.text +1 -0
- data/test/testcases/span/text_substitutions/entities_numeric.html +1 -0
- data/test/testcases/span/text_substitutions/entities_numeric.options +1 -0
- data/test/testcases/span/text_substitutions/entities_numeric.text +1 -0
- data/test/testcases/span/text_substitutions/entities_symbolic.html +1 -0
- data/test/testcases/span/text_substitutions/entities_symbolic.options +1 -0
- data/test/testcases/span/text_substitutions/entities_symbolic.text +1 -0
- data/test/testcases/span/text_substitutions/greaterthan.html +1 -0
- data/test/testcases/span/text_substitutions/greaterthan.text +1 -0
- data/test/testcases/span/text_substitutions/lowerthan.html +1 -0
- data/test/testcases/span/text_substitutions/lowerthan.text +1 -0
- data/test/testcases/span/text_substitutions/typography.html +18 -0
- data/test/testcases/span/text_substitutions/typography.html.19 +18 -0
- data/test/testcases/span/text_substitutions/typography.text +18 -0
- metadata +817 -0
data/doc/tests.page
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
---
|
2
|
+
title: Tests and Benchmark
|
3
|
+
---
|
4
|
+
|
5
|
+
# Tests
|
6
|
+
|
7
|
+
There exist several test suites for testing the correctness of a Markdown implementation. The
|
8
|
+
original [Markdown Test Suite] is the standard which one needs to test against. The [PHP Markdown
|
9
|
+
suite][MDTest] contains the original test suite and several more tests (some specifically geared
|
10
|
+
towards the extension of the PHP Markdown Extra package). I have used the latter test tool to
|
11
|
+
roughly verify that kramdown is able to parse standard Markdown. However, since the syntax used by
|
12
|
+
kramdown varies slightly from standard Markdown most of the tests fail - which is fine. When looking
|
13
|
+
at the differences one can see that the failures result from these differences.
|
14
|
+
|
15
|
+
Besides using the above mentioned test suite kramdown comes with its own set of tests which is used
|
16
|
+
to verify that the implementation matches the kramdown specification.
|
17
|
+
|
18
|
+
If you believe you have found a bug in the implementation, please follow these steps:
|
19
|
+
|
20
|
+
* Check the syntax page and see if the behaviour is not intended.
|
21
|
+
|
22
|
+
* If the behaviour is not intended and it seems that kramdown should parse some text in another
|
23
|
+
fashion, please open a bug report and attach two files: one with the text and one with the HTML
|
24
|
+
conversion you think is correct.
|
25
|
+
|
26
|
+
|
27
|
+
# Benchmark
|
28
|
+
|
29
|
+
kramdown comes with a small benchmark to test how fast it is in regard to four other Ruby Markdown
|
30
|
+
implementations: Maruku, BlueFeather, BlueCloth and RDiscount. The first two are written using only
|
31
|
+
Ruby, the latter two use the C discount library for the actual hard work (which makes them really
|
32
|
+
fast but they do not provide additional syntax elements). As one can see below, kramdown is
|
33
|
+
currently (November 2010) ~3-4x faster than Maruku, ~4-5x faster than BlueFeather but ~30x slower
|
34
|
+
than BlueCloth and rdiscount:
|
35
|
+
|
36
|
+
<pre><code>
|
37
|
+
{execute_cmd: {command: "ruby -Ilib -rubygems benchmark/benchmark.rb", process_output: false, escape_html: true}}
|
38
|
+
</code>
|
39
|
+
</pre>
|
40
|
+
|
41
|
+
And here are some graphs which show the execution times of the various kramdown releases on
|
42
|
+
different Ruby interpreters:
|
43
|
+
|
44
|
+

|
45
|
+

|
46
|
+

|
47
|
+

|
48
|
+

|
49
|
+

|
50
|
+
|
51
|
+
[Markdown Test Suite]: http://daringfireball.net/projects/downloads/MarkdownTest_1.0.zip
|
52
|
+
[MDTest]: http://www.michelf.com/docs/projets/mdtest-1.0.zip
|
data/doc/virtual
ADDED
data/lib/kramdown.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
#--
|
4
|
+
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
5
|
+
#
|
6
|
+
# This file is part of kramdown.
|
7
|
+
#
|
8
|
+
# kramdown is free software: you can redistribute it and/or modify
|
9
|
+
# it under the terms of the GNU General Public License as published by
|
10
|
+
# the Free Software Foundation, either version 3 of the License, or
|
11
|
+
# (at your option) any later version.
|
12
|
+
#
|
13
|
+
# This program is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
# GNU General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU General Public License
|
19
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
#++
|
21
|
+
#
|
22
|
+
|
23
|
+
require 'kramdown/document'
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
#--
|
4
|
+
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
5
|
+
#
|
6
|
+
# This file is part of kramdown.
|
7
|
+
#
|
8
|
+
# kramdown is free software: you can redistribute it and/or modify
|
9
|
+
# it under the terms of the GNU General Public License as published by
|
10
|
+
# the Free Software Foundation, either version 3 of the License, or
|
11
|
+
# (at your option) any later version.
|
12
|
+
#
|
13
|
+
# This program is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
# GNU General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU General Public License
|
19
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
#++
|
21
|
+
#
|
22
|
+
# All the code in this file is backported from Ruby 1.8.7 sothat kramdown works under 1.8.5
|
23
|
+
#
|
24
|
+
# :stopdoc:
|
25
|
+
|
26
|
+
if RUBY_VERSION == '1.8.5'
|
27
|
+
require 'rexml/parsers/baseparser'
|
28
|
+
module REXML
|
29
|
+
module Parsers
|
30
|
+
class BaseParser
|
31
|
+
UNAME_STR= "(?:#{NCNAME_STR}:)?#{NCNAME_STR}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
#--
|
4
|
+
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
5
|
+
#
|
6
|
+
# This file is part of kramdown.
|
7
|
+
#
|
8
|
+
# kramdown is free software: you can redistribute it and/or modify
|
9
|
+
# it under the terms of the GNU General Public License as published by
|
10
|
+
# the Free Software Foundation, either version 3 of the License, or
|
11
|
+
# (at your option) any later version.
|
12
|
+
#
|
13
|
+
# This program is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
# GNU General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU General Public License
|
19
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
#++
|
21
|
+
#
|
22
|
+
|
23
|
+
module Kramdown
|
24
|
+
|
25
|
+
# This module contains all available converters, i.e. classes that take a root Element and convert
|
26
|
+
# it to a specific output format. The result is normally a string. For example, the
|
27
|
+
# Converter::Html module converts an element tree into valid HTML.
|
28
|
+
#
|
29
|
+
# Converters use the Base class for common functionality (like applying a template to the output)
|
30
|
+
# \- see its API documentation for how to create a custom converter class.
|
31
|
+
module Converter
|
32
|
+
|
33
|
+
autoload :Base, 'kramdown/converter/base'
|
34
|
+
autoload :Html, 'kramdown/converter/html'
|
35
|
+
autoload :Latex, 'kramdown/converter/latex'
|
36
|
+
autoload :Kramdown, 'kramdown/converter/kramdown'
|
37
|
+
autoload :Toc, 'kramdown/converter/toc'
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
#--
|
4
|
+
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
5
|
+
#
|
6
|
+
# This file is part of kramdown.
|
7
|
+
#
|
8
|
+
# kramdown is free software: you can redistribute it and/or modify
|
9
|
+
# it under the terms of the GNU General Public License as published by
|
10
|
+
# the Free Software Foundation, either version 3 of the License, or
|
11
|
+
# (at your option) any later version.
|
12
|
+
#
|
13
|
+
# This program is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
# GNU General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU General Public License
|
19
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
#++
|
21
|
+
#
|
22
|
+
|
23
|
+
require 'erb'
|
24
|
+
|
25
|
+
module Kramdown
|
26
|
+
|
27
|
+
module Converter
|
28
|
+
|
29
|
+
# == \Base class for converters
|
30
|
+
#
|
31
|
+
# This class serves as base class for all converters. It provides methods that can/should be
|
32
|
+
# used by all converters (like #generate_id) as well as common functionality that is
|
33
|
+
# automatically applied to the result (for example, embedding the output into a template).
|
34
|
+
#
|
35
|
+
# A converter object is used as a throw-away object, i.e. it is only used for storing the needed
|
36
|
+
# state information during conversion. Therefore one can't instantiate a converter object
|
37
|
+
# directly but only use the Base::convert method.
|
38
|
+
#
|
39
|
+
# == Implementing a converter
|
40
|
+
#
|
41
|
+
# Implementing a new converter is rather easy: just derive a new class from this class and put
|
42
|
+
# it in the Kramdown::Converter module (the latter is only needed if auto-detection should work
|
43
|
+
# properly). Then you need to implement the #convert method which has to contain the conversion
|
44
|
+
# code for converting an element and has to return the conversion result.
|
45
|
+
#
|
46
|
+
# The actual transformation of the document tree can be done in any way. However, writing one
|
47
|
+
# method per element type is a straight forward way to do it - this is how the Html and Latex
|
48
|
+
# converters do the transformation.
|
49
|
+
#
|
50
|
+
# Have a look at the Base::convert method for additional information!
|
51
|
+
class Base
|
52
|
+
|
53
|
+
# Can be used by a converter for storing arbitrary information during the conversion process.
|
54
|
+
attr_reader :data
|
55
|
+
|
56
|
+
# The hash with the conversion options.
|
57
|
+
attr_reader :options
|
58
|
+
|
59
|
+
# The root element that is converted.
|
60
|
+
attr_reader :root
|
61
|
+
|
62
|
+
# The warnings array.
|
63
|
+
attr_reader :warnings
|
64
|
+
|
65
|
+
# Initialize the converter with the given +root+ element and +options+ hash.
|
66
|
+
def initialize(root, options)
|
67
|
+
@options = options
|
68
|
+
@root = root
|
69
|
+
@data = {}
|
70
|
+
@warnings = []
|
71
|
+
end
|
72
|
+
private_class_method(:new, :allocate)
|
73
|
+
|
74
|
+
# Convert the element tree +tree+ and return the resulting conversion object (normally a
|
75
|
+
# string) and an array with warning messages. The parameter +options+ specifies the conversion
|
76
|
+
# options that should be used.
|
77
|
+
#
|
78
|
+
# Initializes a new instance of the calling class and then calls the #convert method with
|
79
|
+
# +tree+ as parameter. If the +template+ option is specified and non-empty, the result is
|
80
|
+
# rendered into the specified template. The template resolution is done in the following way:
|
81
|
+
#
|
82
|
+
# 1. Look in the current working directory for the template.
|
83
|
+
#
|
84
|
+
# 2. Append +.convertername+ (e.g. +.html+) to the template name and look for the resulting
|
85
|
+
# file in the current working directory.
|
86
|
+
#
|
87
|
+
# 3. Append +.convertername+ to the template name and look for it in the kramdown data
|
88
|
+
# directory.
|
89
|
+
def self.convert(tree, options = {})
|
90
|
+
converter = new(tree, ::Kramdown::Options.merge(options.merge(tree.options[:options] || {})))
|
91
|
+
result = converter.convert(tree)
|
92
|
+
result = apply_template(converter, result) if !converter.options[:template].empty?
|
93
|
+
[result, converter.warnings]
|
94
|
+
end
|
95
|
+
|
96
|
+
# Convert the element +el+ and return the resulting object.
|
97
|
+
#
|
98
|
+
# This is the only method that has to be implemented by sub-classes!
|
99
|
+
def convert(el)
|
100
|
+
raise NotImplementedError
|
101
|
+
end
|
102
|
+
|
103
|
+
# Apply the +template+ using +body+ as the body string.
|
104
|
+
def self.apply_template(converter, body) # :nodoc:
|
105
|
+
erb = ERB.new(get_template(converter.options[:template]))
|
106
|
+
obj = Object.new
|
107
|
+
obj.instance_variable_set(:@converter, converter)
|
108
|
+
obj.instance_variable_set(:@body, body)
|
109
|
+
erb.result(obj.instance_eval{binding})
|
110
|
+
end
|
111
|
+
|
112
|
+
# Return the template specified by +template+.
|
113
|
+
def self.get_template(template) # :nodoc:
|
114
|
+
format_ext = '.' + self.name.split(/::/).last.downcase
|
115
|
+
shipped = File.join(::Kramdown.data_dir, template + format_ext)
|
116
|
+
if File.exist?(template)
|
117
|
+
File.read(template)
|
118
|
+
elsif File.exist?(template + format_ext)
|
119
|
+
File.read(template + format_ext)
|
120
|
+
elsif File.exist?(shipped)
|
121
|
+
File.read(shipped)
|
122
|
+
else
|
123
|
+
raise "The specified template file #{template} does not exist"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# Add the given warning +text+ to the warning array.
|
128
|
+
def warning(text)
|
129
|
+
@warnings << text
|
130
|
+
end
|
131
|
+
|
132
|
+
# Return +true+ if the header element +el+ should be used for the table of contents (as
|
133
|
+
# specified by the +toc_levels+ option).
|
134
|
+
def in_toc?(el)
|
135
|
+
@options[:toc_levels].include?(el.options[:level])
|
136
|
+
end
|
137
|
+
|
138
|
+
# Generate an unique alpha-numeric ID from the the string +str+ for use as a header ID.
|
139
|
+
#
|
140
|
+
# Uses the option +auto_id_prefix+: the value of this option is prepended to every generated
|
141
|
+
# ID.
|
142
|
+
def generate_id(str)
|
143
|
+
gen_id = str.gsub(/^[^a-zA-Z]+/, '')
|
144
|
+
gen_id.tr!('^a-zA-Z0-9 -', '')
|
145
|
+
gen_id.tr!(' ', '-')
|
146
|
+
gen_id.downcase!
|
147
|
+
gen_id = 'section' if gen_id.length == 0
|
148
|
+
@used_ids ||= {}
|
149
|
+
if @used_ids.has_key?(gen_id)
|
150
|
+
gen_id += '-' << (@used_ids[gen_id] += 1).to_s
|
151
|
+
else
|
152
|
+
@used_ids[gen_id] = 0
|
153
|
+
end
|
154
|
+
@options[:auto_id_prefix] + gen_id
|
155
|
+
end
|
156
|
+
|
157
|
+
SMART_QUOTE_INDICES = {:lsquo => 0, :rsquo => 1, :ldquo => 2, :rdquo => 3} # :nodoc:
|
158
|
+
|
159
|
+
# Return the entity that represents the given smart_quote element.
|
160
|
+
def smart_quote_entity(el)
|
161
|
+
res = @options[:smart_quotes][SMART_QUOTE_INDICES[el.value]]
|
162
|
+
::Kramdown::Utils::Entities.entity(res)
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
@@ -0,0 +1,410 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
#--
|
4
|
+
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
5
|
+
#
|
6
|
+
# This file is part of kramdown.
|
7
|
+
#
|
8
|
+
# kramdown is free software: you can redistribute it and/or modify
|
9
|
+
# it under the terms of the GNU General Public License as published by
|
10
|
+
# the Free Software Foundation, either version 3 of the License, or
|
11
|
+
# (at your option) any later version.
|
12
|
+
#
|
13
|
+
# This program is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
# GNU General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU General Public License
|
19
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
#++
|
21
|
+
#
|
22
|
+
|
23
|
+
require 'rexml/parsers/baseparser'
|
24
|
+
|
25
|
+
module Kramdown
|
26
|
+
|
27
|
+
module Converter
|
28
|
+
|
29
|
+
# Converts a Kramdown::Document to HTML.
|
30
|
+
#
|
31
|
+
# You can customize the HTML converter by sub-classing it and overriding the +convert_NAME+
|
32
|
+
# methods. Each such method takes the following parameters:
|
33
|
+
#
|
34
|
+
# [+el+] The element of type +NAME+ to be converted.
|
35
|
+
#
|
36
|
+
# [+indent+] A number representing the current amount of spaces for indent (only used for
|
37
|
+
# block-level elements).
|
38
|
+
#
|
39
|
+
# The return value of such a method has to be a string containing the element +el+ formatted as
|
40
|
+
# HTML element.
|
41
|
+
class Html < Base
|
42
|
+
|
43
|
+
begin
|
44
|
+
require 'coderay'
|
45
|
+
|
46
|
+
# Highlighting via coderay is available if this constant is +true+.
|
47
|
+
HIGHLIGHTING_AVAILABLE = true
|
48
|
+
rescue LoadError
|
49
|
+
HIGHLIGHTING_AVAILABLE = false # :nodoc:
|
50
|
+
end
|
51
|
+
|
52
|
+
include ::Kramdown::Utils::Html
|
53
|
+
|
54
|
+
|
55
|
+
# The amount of indentation used when nesting HTML tags.
|
56
|
+
attr_accessor :indent
|
57
|
+
|
58
|
+
# Initialize the HTML converter with the given Kramdown document +doc+.
|
59
|
+
def initialize(root, options)
|
60
|
+
super
|
61
|
+
@footnote_counter = @footnote_start = @options[:footnote_nr]
|
62
|
+
@footnotes = []
|
63
|
+
@toc = []
|
64
|
+
@toc_code = nil
|
65
|
+
@indent = 2
|
66
|
+
@stack = []
|
67
|
+
end
|
68
|
+
|
69
|
+
# The mapping of element type to conversion method.
|
70
|
+
DISPATCHER = Hash.new {|h,k| h[k] = "convert_#{k}"}
|
71
|
+
|
72
|
+
# Dispatch the conversion of the element +el+ to a +convert_TYPE+ method using the +type+ of
|
73
|
+
# the element.
|
74
|
+
def convert(el, indent = -@indent)
|
75
|
+
send(DISPATCHER[el.type], el, indent)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Return the converted content of the children of +el+ as a string. The parameter +indent+ has
|
79
|
+
# to be the amount of indentation used for the element +el+.
|
80
|
+
#
|
81
|
+
# Pushes +el+ onto the @stack before converting the child elements and pops it from the stack
|
82
|
+
# afterwards.
|
83
|
+
def inner(el, indent)
|
84
|
+
result = ''
|
85
|
+
indent += @indent
|
86
|
+
@stack.push(el)
|
87
|
+
el.children.each do |inner_el|
|
88
|
+
result << send(DISPATCHER[inner_el.type], inner_el, indent)
|
89
|
+
end
|
90
|
+
@stack.pop
|
91
|
+
result
|
92
|
+
end
|
93
|
+
|
94
|
+
def convert_blank(el, indent)
|
95
|
+
"\n"
|
96
|
+
end
|
97
|
+
|
98
|
+
def convert_text(el, indent)
|
99
|
+
escape_html(el.value, :text)
|
100
|
+
end
|
101
|
+
|
102
|
+
def convert_p(el, indent)
|
103
|
+
if el.options[:transparent]
|
104
|
+
inner(el, indent)
|
105
|
+
else
|
106
|
+
"#{' '*indent}<p#{html_attributes(el.attr)}>#{inner(el, indent)}</p>\n"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def convert_codeblock(el, indent)
|
111
|
+
if el.attr['lang'] && HIGHLIGHTING_AVAILABLE
|
112
|
+
attr = el.attr.dup
|
113
|
+
opts = {:wrap => @options[:coderay_wrap], :line_numbers => @options[:coderay_line_numbers],
|
114
|
+
:line_number_start => @options[:coderay_line_number_start], :tab_width => @options[:coderay_tab_width],
|
115
|
+
:bold_every => @options[:coderay_bold_every], :css => @options[:coderay_css]}
|
116
|
+
result = CodeRay.scan(el.value, attr.delete('lang').to_sym).html(opts).chomp << "\n"
|
117
|
+
"#{' '*indent}<div#{html_attributes(attr)}>#{result}#{' '*indent}</div>\n"
|
118
|
+
else
|
119
|
+
result = escape_html(el.value)
|
120
|
+
result.chomp!
|
121
|
+
if el.attr['class'].to_s =~ /\bshow-whitespaces\b/
|
122
|
+
result.gsub!(/(?:(^[ \t]+)|([ \t]+$)|([ \t]+))/) do |m|
|
123
|
+
suffix = ($1 ? '-l' : ($2 ? '-r' : ''))
|
124
|
+
m.scan(/./).map do |c|
|
125
|
+
case c
|
126
|
+
when "\t" then "<span class=\"ws-tab#{suffix}\">\t</span>"
|
127
|
+
when " " then "<span class=\"ws-space#{suffix}\">⋅</span>"
|
128
|
+
end
|
129
|
+
end.join('')
|
130
|
+
end
|
131
|
+
end
|
132
|
+
"#{' '*indent}<pre#{html_attributes(el.attr)}><code>#{result}\n</code></pre>\n"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def convert_blockquote(el, indent)
|
137
|
+
"#{' '*indent}<blockquote#{html_attributes(el.attr)}>\n#{inner(el, indent)}#{' '*indent}</blockquote>\n"
|
138
|
+
end
|
139
|
+
|
140
|
+
def convert_header(el, indent)
|
141
|
+
attr = el.attr.dup
|
142
|
+
if @options[:auto_ids] && !attr['id']
|
143
|
+
attr['id'] = generate_id(el.options[:raw_text])
|
144
|
+
end
|
145
|
+
@toc << [el.options[:level], attr['id'], el.children] if attr['id'] && in_toc?(el)
|
146
|
+
"#{' '*indent}<h#{el.options[:level]}#{html_attributes(attr)}>#{inner(el, indent)}</h#{el.options[:level]}>\n"
|
147
|
+
end
|
148
|
+
|
149
|
+
def convert_hr(el, indent)
|
150
|
+
"#{' '*indent}<hr />\n"
|
151
|
+
end
|
152
|
+
|
153
|
+
def convert_ul(el, indent)
|
154
|
+
if !@toc_code && (el.options[:ial][:refs].include?('toc') rescue nil) && (el.type == :ul || el.type == :ol)
|
155
|
+
@toc_code = [el.type, el.attr, (0..128).to_a.map{|a| rand(36).to_s(36)}.join]
|
156
|
+
@toc_code.last
|
157
|
+
else
|
158
|
+
"#{' '*indent}<#{el.type}#{html_attributes(el.attr)}>\n#{inner(el, indent)}#{' '*indent}</#{el.type}>\n"
|
159
|
+
end
|
160
|
+
end
|
161
|
+
alias :convert_ol :convert_ul
|
162
|
+
alias :convert_dl :convert_ul
|
163
|
+
|
164
|
+
def convert_li(el, indent)
|
165
|
+
output = ' '*indent << "<#{el.type}" << html_attributes(el.attr) << ">"
|
166
|
+
res = inner(el, indent)
|
167
|
+
if el.children.empty? || (el.children.first.type == :p && el.children.first.options[:transparent])
|
168
|
+
output << res << (res =~ /\n\Z/ ? ' '*indent : '')
|
169
|
+
else
|
170
|
+
output << "\n" << res << ' '*indent
|
171
|
+
end
|
172
|
+
output << "</#{el.type}>\n"
|
173
|
+
end
|
174
|
+
alias :convert_dd :convert_li
|
175
|
+
|
176
|
+
def convert_dt(el, indent)
|
177
|
+
"#{' '*indent}<dt#{html_attributes(el.attr)}>#{inner(el, indent)}</dt>\n"
|
178
|
+
end
|
179
|
+
|
180
|
+
# A list of all HTML tags that need to have a body (even if the body is empty).
|
181
|
+
HTML_TAGS_WITH_BODY=['div', 'span', 'script', 'iframe', 'textarea', 'a'] # :nodoc:
|
182
|
+
|
183
|
+
def convert_html_element(el, indent)
|
184
|
+
res = inner(el, indent)
|
185
|
+
if el.options[:category] == :span
|
186
|
+
"<#{el.value}#{html_attributes(el.attr)}" << (!res.empty? || HTML_TAGS_WITH_BODY.include?(el.value) ? ">#{res}</#{el.value}>" : " />")
|
187
|
+
else
|
188
|
+
output = ''
|
189
|
+
output << ' '*indent if @stack.last.type != :html_element || @stack.last.options[:content_model] != :raw
|
190
|
+
output << "<#{el.value}#{html_attributes(el.attr)}"
|
191
|
+
if !res.empty? && el.options[:content_model] != :block
|
192
|
+
output << ">#{res}</#{el.value}>"
|
193
|
+
elsif !res.empty?
|
194
|
+
output << ">\n#{res.chomp}\n" << ' '*indent << "</#{el.value}>"
|
195
|
+
elsif HTML_TAGS_WITH_BODY.include?(el.value)
|
196
|
+
output << "></#{el.value}>"
|
197
|
+
else
|
198
|
+
output << " />"
|
199
|
+
end
|
200
|
+
output << "\n" if @stack.last.type != :html_element || @stack.last.options[:content_model] != :raw
|
201
|
+
output
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
def convert_xml_comment(el, indent)
|
206
|
+
if el.options[:category] == :block && (@stack.last.type != :html_element || @stack.last.options[:content_model] != :raw)
|
207
|
+
' '*indent << el.value << "\n"
|
208
|
+
else
|
209
|
+
el.value
|
210
|
+
end
|
211
|
+
end
|
212
|
+
alias :convert_xml_pi :convert_xml_comment
|
213
|
+
|
214
|
+
def convert_table(el, indent)
|
215
|
+
"#{' '*indent}<table#{html_attributes(el.attr)}>\n#{inner(el, indent)}#{' '*indent}</table>\n"
|
216
|
+
end
|
217
|
+
|
218
|
+
def convert_thead(el, indent)
|
219
|
+
"#{' '*indent}<#{el.type}#{html_attributes(el.attr)}>\n#{inner(el, indent)}#{' '*indent}</#{el.type}>\n"
|
220
|
+
end
|
221
|
+
alias :convert_tbody :convert_thead
|
222
|
+
alias :convert_tfoot :convert_thead
|
223
|
+
alias :convert_tr :convert_thead
|
224
|
+
|
225
|
+
ENTITY_NBSP = ::Kramdown::Utils::Entities.entity('nbsp') # :nodoc:
|
226
|
+
|
227
|
+
def convert_td(el, indent)
|
228
|
+
res = inner(el, indent)
|
229
|
+
type = (@stack[-2].type == :thead ? :th : :td)
|
230
|
+
attr = el.attr
|
231
|
+
alignment = @stack[-3].options[:alignment][@stack.last.children.index(el)]
|
232
|
+
if alignment != :default
|
233
|
+
attr = el.attr.dup
|
234
|
+
attr['style'] = (attr.has_key?('style') ? "#{attr['style']}; ": '') << "text-align: #{alignment}"
|
235
|
+
end
|
236
|
+
"#{' '*indent}<#{type}#{html_attributes(attr)}>#{res.empty? ? entity_to_str(ENTITY_NBSP) : res}</#{type}>\n"
|
237
|
+
end
|
238
|
+
|
239
|
+
def convert_comment(el, indent)
|
240
|
+
if el.options[:category] == :block
|
241
|
+
"#{' '*indent}<!-- #{el.value} -->\n"
|
242
|
+
else
|
243
|
+
"<!-- #{el.value} -->"
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
def convert_br(el, indent)
|
248
|
+
"<br />"
|
249
|
+
end
|
250
|
+
|
251
|
+
def convert_a(el, indent)
|
252
|
+
res = inner(el, indent)
|
253
|
+
attr = el.attr.dup
|
254
|
+
if attr['href'] =~ /^mailto:/
|
255
|
+
attr['href'] = obfuscate('mailto') << ":" << obfuscate(attr['href'].sub(/^mailto:/, ''))
|
256
|
+
res = obfuscate(res)
|
257
|
+
end
|
258
|
+
"<a#{html_attributes(attr)}>#{res}</a>"
|
259
|
+
end
|
260
|
+
|
261
|
+
def convert_img(el, indent)
|
262
|
+
"<img#{html_attributes(el.attr)} />"
|
263
|
+
end
|
264
|
+
|
265
|
+
def convert_codespan(el, indent)
|
266
|
+
if el.attr['lang'] && HIGHLIGHTING_AVAILABLE
|
267
|
+
attr = el.attr.dup
|
268
|
+
result = CodeRay.scan(el.value, attr.delete('lang').to_sym).html(:wrap => :span, :css => @options[:coderay_css]).chomp
|
269
|
+
"<code#{html_attributes(attr)}>#{result}</code>"
|
270
|
+
else
|
271
|
+
"<code#{html_attributes(el.attr)}>#{escape_html(el.value)}</code>"
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
def convert_footnote(el, indent)
|
276
|
+
number = @footnote_counter
|
277
|
+
@footnote_counter += 1
|
278
|
+
@footnotes << [el.options[:name], el.value]
|
279
|
+
"<sup id=\"fnref:#{el.options[:name]}\"><a href=\"#fn:#{el.options[:name]}\" rel=\"footnote\">#{number}</a></sup>"
|
280
|
+
end
|
281
|
+
|
282
|
+
def convert_raw(el, indent)
|
283
|
+
if !el.options[:type] || el.options[:type].empty? || el.options[:type].include?('html')
|
284
|
+
el.value + (el.options[:category] == :block ? "\n" : '')
|
285
|
+
else
|
286
|
+
''
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
def convert_em(el, indent)
|
291
|
+
"<#{el.type}#{html_attributes(el.attr)}>#{inner(el, indent)}</#{el.type}>"
|
292
|
+
end
|
293
|
+
alias :convert_strong :convert_em
|
294
|
+
|
295
|
+
def convert_entity(el, indent)
|
296
|
+
entity_to_str(el.value, el.options[:original])
|
297
|
+
end
|
298
|
+
|
299
|
+
TYPOGRAPHIC_SYMS = {
|
300
|
+
:mdash => [::Kramdown::Utils::Entities.entity('mdash')],
|
301
|
+
:ndash => [::Kramdown::Utils::Entities.entity('ndash')],
|
302
|
+
:hellip => [::Kramdown::Utils::Entities.entity('hellip')],
|
303
|
+
:laquo_space => [::Kramdown::Utils::Entities.entity('laquo'), ::Kramdown::Utils::Entities.entity('nbsp')],
|
304
|
+
:raquo_space => [::Kramdown::Utils::Entities.entity('nbsp'), ::Kramdown::Utils::Entities.entity('raquo')],
|
305
|
+
:laquo => [::Kramdown::Utils::Entities.entity('laquo')],
|
306
|
+
:raquo => [::Kramdown::Utils::Entities.entity('raquo')]
|
307
|
+
} # :nodoc:
|
308
|
+
def convert_typographic_sym(el, indent)
|
309
|
+
TYPOGRAPHIC_SYMS[el.value].map {|e| entity_to_str(e)}.join('')
|
310
|
+
end
|
311
|
+
|
312
|
+
def convert_smart_quote(el, indent)
|
313
|
+
entity_to_str(smart_quote_entity(el))
|
314
|
+
end
|
315
|
+
|
316
|
+
def convert_math(el, indent)
|
317
|
+
block = (el.options[:category] == :block)
|
318
|
+
"<script type=\"math/tex#{block ? '; mode=display' : ''}\">#{el.value}</script>#{block ? "\n" : ''}"
|
319
|
+
end
|
320
|
+
|
321
|
+
def convert_abbreviation(el, indent)
|
322
|
+
title = @root.options[:abbrev_defs][el.value]
|
323
|
+
"<abbr#{!title.empty? ? " title=\"#{title}\"" : ''}>#{el.value}</abbr>"
|
324
|
+
end
|
325
|
+
|
326
|
+
def convert_root(el, indent)
|
327
|
+
result = inner(el, indent)
|
328
|
+
result << footnote_content
|
329
|
+
if @toc_code
|
330
|
+
toc_tree = generate_toc_tree(@toc, @toc_code[0], @toc_code[1] || {})
|
331
|
+
text = if toc_tree.children.size > 0
|
332
|
+
convert(toc_tree, 0)
|
333
|
+
else
|
334
|
+
''
|
335
|
+
end
|
336
|
+
result.sub!(/#{@toc_code.last}/, text)
|
337
|
+
end
|
338
|
+
result
|
339
|
+
end
|
340
|
+
|
341
|
+
# Generate and return an element tree for the table of contents.
|
342
|
+
def generate_toc_tree(toc, type, attr)
|
343
|
+
sections = Element.new(type, nil, attr)
|
344
|
+
sections.attr['id'] ||= 'markdown-toc'
|
345
|
+
stack = []
|
346
|
+
toc.each do |level, id, children|
|
347
|
+
li = Element.new(:li, nil, nil, {:level => level})
|
348
|
+
li.children << Element.new(:p, nil, nil, {:transparent => true})
|
349
|
+
a = Element.new(:a, nil, {'href' => "##{id}"})
|
350
|
+
a.children.concat(children)
|
351
|
+
li.children.last.children << a
|
352
|
+
li.children << Element.new(type)
|
353
|
+
|
354
|
+
success = false
|
355
|
+
while !success
|
356
|
+
if stack.empty?
|
357
|
+
sections.children << li
|
358
|
+
stack << li
|
359
|
+
success = true
|
360
|
+
elsif stack.last.options[:level] < li.options[:level]
|
361
|
+
stack.last.children.last.children << li
|
362
|
+
stack << li
|
363
|
+
success = true
|
364
|
+
else
|
365
|
+
item = stack.pop
|
366
|
+
item.children.pop unless item.children.last.children.size > 0
|
367
|
+
end
|
368
|
+
end
|
369
|
+
end
|
370
|
+
while !stack.empty?
|
371
|
+
item = stack.pop
|
372
|
+
item.children.pop unless item.children.last.children.size > 0
|
373
|
+
end
|
374
|
+
sections
|
375
|
+
end
|
376
|
+
|
377
|
+
# Obfuscate the +text+ by using HTML entities.
|
378
|
+
def obfuscate(text)
|
379
|
+
result = ""
|
380
|
+
text.each_byte do |b|
|
381
|
+
result << (b > 128 ? b.chr : "&#%03d;" % b)
|
382
|
+
end
|
383
|
+
result.force_encoding(text.encoding) if RUBY_VERSION >= '1.9'
|
384
|
+
result
|
385
|
+
end
|
386
|
+
|
387
|
+
# Return a HTML ordered list with the footnote content for the used footnotes.
|
388
|
+
def footnote_content
|
389
|
+
ol = Element.new(:ol)
|
390
|
+
ol.attr['start'] = @footnote_start if @footnote_start != 1
|
391
|
+
@footnotes.each do |name, data|
|
392
|
+
li = Element.new(:li, nil, {'id' => "fn:#{name}"})
|
393
|
+
li.children = Marshal.load(Marshal.dump(data.children))
|
394
|
+
ol.children << li
|
395
|
+
|
396
|
+
ref = Element.new(:raw, "<a href=\"#fnref:#{name}\" rel=\"reference\">↩</a>")
|
397
|
+
if li.children.last.type == :p
|
398
|
+
para = li.children.last
|
399
|
+
else
|
400
|
+
li.children << (para = Element.new(:p))
|
401
|
+
end
|
402
|
+
para.children << ref
|
403
|
+
end
|
404
|
+
(ol.children.empty? ? '' : "<div class=\"footnotes\">\n#{convert(ol, 2)}</div>\n")
|
405
|
+
end
|
406
|
+
|
407
|
+
end
|
408
|
+
|
409
|
+
end
|
410
|
+
end
|